fix(striker-ui): revise input tests to handle optional, number fields

main
Tsu-ba-me 2 years ago
parent d3e4e51b86
commit 1be005669e
  1. 5
      striker-ui/lib/test_input/buildDomainTestBatch.tsx
  2. 5
      striker-ui/lib/test_input/buildIPAddressTestBatch.tsx
  3. 56
      striker-ui/lib/test_input/buildNumberTestBatch.tsx
  4. 5
      striker-ui/lib/test_input/buildPeacefulStringTestBatch.tsx
  5. 5
      striker-ui/lib/test_input/buildUUIDTestBatch.tsx
  6. 19
      striker-ui/lib/test_input/testInput.ts
  7. 7
      striker-ui/lib/toNumber.ts
  8. 5
      striker-ui/types/TestInputFunction.d.ts

@ -6,10 +6,11 @@ import { InlineMonoText } from '../../components/Text';
const buildDomainTestBatch: BuildInputTestBatchFunction = ( const buildDomainTestBatch: BuildInputTestBatchFunction = (
inputName, inputName,
onSuccess, onSuccess,
{ compare: dCompare, getValue } = {}, { onFinishBatch, ...defaults } = {},
onDomainTestFailure, onDomainTestFailure,
) => ({ ) => ({
defaults: { compare: dCompare, getValue, onSuccess }, defaults: { ...defaults, onSuccess },
onFinishBatch,
tests: [ tests: [
{ {
onFailure: (...args) => { onFailure: (...args) => {

@ -5,10 +5,11 @@ import testNotBlank from './testNotBlank';
const buildIPAddressTestBatch: BuildInputTestBatchFunction = ( const buildIPAddressTestBatch: BuildInputTestBatchFunction = (
inputName, inputName,
onSuccess, onSuccess,
{ getValue } = {}, { onFinishBatch, ...defaults } = {},
onIPv4TestFailure, onIPv4TestFailure,
) => ({ ) => ({
defaults: { getValue, onSuccess }, defaults: { ...defaults, onSuccess },
onFinishBatch,
tests: [ tests: [
{ {
onFailure: (...args) => { onFailure: (...args) => {

@ -0,0 +1,56 @@
import testRange from './testRange';
import toNumber from '../toNumber';
const buildNumberTestBatch: BuildInputTestBatchFunction = (
inputName,
onSuccess,
{ onFinishBatch, ...defaults } = {},
onIntTestFailure?,
onFloatTestFailure?,
onRangeTestFailure?,
) => {
const tests: InputTest[] = [];
if (onIntTestFailure) {
tests.push({
onFailure: (...args) => {
onIntTestFailure(<>{inputName} must be a valid integer.</>, ...args);
},
test: ({ value }) => Number.isSafeInteger(toNumber(value)),
});
} else if (onFloatTestFailure) {
tests.push({
onFailure: (...args) => {
onFloatTestFailure(
<>{inputName} must be a valid floating-point number.</>,
...args,
);
},
test: ({ value }) => Number.isFinite(toNumber(value, 'parseFloat')),
});
}
if (onRangeTestFailure) {
tests.push({
onFailure: (...args) => {
const { displayMax, displayMin } = args[0];
onRangeTestFailure(
<>
{inputName} is expected to be between {displayMin} and {displayMax}.
</>,
...args,
);
},
test: testRange,
});
}
return {
defaults: { ...defaults, onSuccess },
onFinishBatch,
tests,
};
};
export default buildNumberTestBatch;

@ -6,10 +6,11 @@ import { InlineMonoText } from '../../components/Text';
const buildPeacefulStringTestBatch: BuildInputTestBatchFunction = ( const buildPeacefulStringTestBatch: BuildInputTestBatchFunction = (
inputName, inputName,
onSuccess, onSuccess,
{ getValue } = {}, { onFinishBatch, ...defaults } = {},
onTestPeacefulStringFailureAppend, onTestPeacefulStringFailureAppend,
) => ({ ) => ({
defaults: { getValue, onSuccess }, defaults: { ...defaults, onSuccess },
onFinishBatch,
tests: [ tests: [
{ {
onFailure: (...args) => { onFailure: (...args) => {

@ -5,10 +5,11 @@ import testNotBlank from './testNotBlank';
const buildUUIDTestBatch: BuildInputTestBatchFunction = ( const buildUUIDTestBatch: BuildInputTestBatchFunction = (
inputName, inputName,
onSuccess, onSuccess,
{ getValue } = {}, { onFinishBatch, ...defaults } = {},
onUUIDTestFailure, onUUIDTestFailure,
) => ({ ) => ({
defaults: { getValue, onSuccess }, defaults: { ...defaults, onSuccess },
onFinishBatch,
tests: [ tests: [
{ {
onFailure: (...args) => { onFailure: (...args) => {

@ -32,6 +32,9 @@ const evalIsIgnoreOnCallbacks = ({
setTestCallbacks: cbSetter, setTestCallbacks: cbSetter,
}; };
const nullishSet = <T>(a: T | undefined, b: T) => a ?? b;
const orSet = <T>(a: T | undefined, b: T) => a || b;
const testInput: TestInputFunction = ({ const testInput: TestInputFunction = ({
excludeTestIds = [], excludeTestIds = [],
excludeTestIdsRe, excludeTestIdsRe,
@ -80,22 +83,28 @@ const testInput: TestInputFunction = ({
onSuccess: dOnSuccess, onSuccess: dOnSuccess,
value: dValue = null, value: dValue = null,
} = {}, } = {},
isRequired = false,
onFinishBatch, onFinishBatch,
optionalTests, optionalTests,
tests: requiredTests, tests: requiredTests,
} = tests[id]; } = tests[id];
const isOptional = !isRequired;
const { const {
getCompare = dGetCompare, getCompare = dGetCompare,
getValue = dGetValue, getValue = dGetValue,
isIgnoreOnCallbacks = dIsIgnoreOnCallbacks, isIgnoreOnCallbacks = dIsIgnoreOnCallbacks,
max = dMax, max = dMax,
min = dMin, min = dMin,
compare = getCompare?.call(null) ?? dCompare, compare = nullishSet(getCompare?.call(null), dCompare),
value = getValue?.call(null) ?? dValue, value = nullishSet(getValue?.call(null), dValue),
displayMax = dDisplayMax || String(max), displayMax = orSet(dDisplayMax, String(max)),
displayMin = dDisplayMin || String(min), displayMin = orSet(dDisplayMin, String(min)),
} = testsToRun[id]; } = testsToRun[id];
if (!value && isOptional) {
return true;
}
const { cbFinishBatch, setTestCallbacks } = evalIsIgnoreOnCallbacks({ const { cbFinishBatch, setTestCallbacks } = evalIsIgnoreOnCallbacks({
isIgnoreOnCallbacks, isIgnoreOnCallbacks,
onFinishBatch, onFinishBatch,
@ -153,7 +162,7 @@ const testInput: TestInputFunction = ({
// ); // );
// })(); // })();
cbFinishBatch?.call(null); cbFinishBatch?.call(null, requiredTestsResult, id);
return requiredTestsResult || isContinueOnFailure; return requiredTestsResult || isContinueOnFailure;
}); });

@ -0,0 +1,7 @@
const toNumber: (
value: unknown,
parser?: 'parseFloat' | 'parseInt',
) => number = (value, parser = 'parseInt') =>
typeof value === 'number' ? value : Number[parser](String(value));
export default toNumber;

@ -50,12 +50,13 @@ type InputTestInputs = {
[id: string]: Partial<InputTestArgs>; [id: string]: Partial<InputTestArgs>;
}; };
type InputTestBatchFinishCallback = () => void; type InputTestBatchFinishCallback = (result: boolean, id: string) => void;
type InputTestBatch = { type InputTestBatch = {
defaults?: InputTestArgs & { defaults?: InputTestArgs & {
onSuccess?: InputTestSuccessCallback; onSuccess?: InputTestSuccessCallback;
}; };
isRequired?: boolean;
onFinishBatch?: InputTestBatchFinishCallback; onFinishBatch?: InputTestBatchFinishCallback;
optionalTests?: Array<InputTest>; optionalTests?: Array<InputTest>;
tests: Array<InputTest>; tests: Array<InputTest>;
@ -64,7 +65,7 @@ type InputTestBatch = {
type BuildInputTestBatchFunction = ( type BuildInputTestBatchFunction = (
inputName: string, inputName: string,
onSuccess: InputTestSuccessCallback, onSuccess: InputTestSuccessCallback,
options?: InputTestBatch['defaults'], options?: InputTestBatch['defaults'] & Pick<InputTestBatch, 'onFinishBatch'>,
...onFailureAppends: InputTestFailureAppendCallback[] ...onFailureAppends: InputTestFailureAppendCallback[]
) => InputTestBatch; ) => InputTestBatch;

Loading…
Cancel
Save