-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f19f2d4
commit ed27660
Showing
4 changed files
with
125 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import type { ValidationError } from '../form' | ||
import type { JsfSchema, SchemaValue } from '../types' | ||
import { validateSchema } from './schema' | ||
|
||
/** | ||
* Validate a value against the `anyOf` keyword in a schema | ||
* @param value - The value to validate | ||
* @param schema - The schema containing the `anyOf` keyword | ||
* @returns An array of validation errors | ||
* @description | ||
* The function validates the value against each subschema in the `anyOf` array. | ||
* It returns no errors as soon as one subschema validates successfully. | ||
* If none of the subschemas validate, an error is returned. | ||
*/ | ||
export function validateAnyOf(value: SchemaValue, schema: JsfSchema): ValidationError[] { | ||
if (!schema.anyOf || !Array.isArray(schema.anyOf)) { | ||
return [] | ||
} | ||
|
||
for (const subSchema of schema.anyOf) { | ||
const errors = validateSchema(value, subSchema) | ||
if (errors.length === 0) { | ||
return [] | ||
} | ||
} | ||
|
||
return [{ | ||
path: [], | ||
validation: 'anyOf', | ||
message: 'should match at least one schema', | ||
}] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { describe, expect, it } from '@jest/globals' | ||
import { createHeadlessForm } from '../../src' | ||
|
||
describe('anyOf validation', () => { | ||
it('returns no errors if the value matches at least one subschema in anyOf (top-level)', () => { | ||
const schema = { | ||
anyOf: [ | ||
{ type: 'string', minLength: 5 }, | ||
{ type: 'number' }, | ||
], | ||
} | ||
const form = createHeadlessForm(schema) | ||
|
||
// Test with a string that meets the minLength requirement | ||
expect(form.handleValidation('hello world')).not.toHaveProperty('formErrors') | ||
|
||
// Test with a number | ||
expect(form.handleValidation(42)).not.toHaveProperty('formErrors') | ||
}) | ||
|
||
it('returns an error if the value does not match any subschema in anyOf (top-level)', () => { | ||
const schema = { | ||
anyOf: [ | ||
{ type: 'string', pattern: '^[a-z]+$' }, | ||
{ type: 'string', minLength: 5 }, | ||
], | ||
} | ||
const form = createHeadlessForm(schema) | ||
|
||
// "123" does not match the pattern nor does it meet the minLength requirement. | ||
expect(form.handleValidation('123')).toEqual({ | ||
formErrors: { '': 'should match at least one schema' }, | ||
}) | ||
}) | ||
|
||
it('validates nested anyOf in an object property', () => { | ||
const schema = { | ||
type: 'object', | ||
properties: { | ||
value: { | ||
anyOf: [ | ||
{ type: 'string', pattern: '^[0-9]+$' }, | ||
{ type: 'number' }, | ||
], | ||
}, | ||
}, | ||
} | ||
|
||
const form = createHeadlessForm(schema) | ||
|
||
// Test with a valid number value | ||
expect(form.handleValidation({ value: 123 })).not.toHaveProperty('formErrors') | ||
|
||
// Test with a valid string matching the pattern | ||
expect(form.handleValidation({ value: '456' })).not.toHaveProperty('formErrors') | ||
|
||
// Test with an invalid string value; the error path will be prefixed by the property key. | ||
expect(form.handleValidation({ value: 'abc' })).toEqual({ | ||
formErrors: { '.value': 'should match at least one schema' }, | ||
}) | ||
}) | ||
}) |