Commit 43bac45d authored by Stefan Cameron's avatar Stefan Cameron

Add support for SYMBOL_args

Coverage: 100%
parent 3d682452
Pipeline #30282138 passed with stages
in 10 minutes and 11 seconds
......@@ -1927,7 +1927,7 @@ There is one disadvantage to using a custom validator: It cannot be de/serialize
| Name | Type | Description |
| --- | --- | --- |
| [oneOf] | <code>string</code> \| <code>Array.&lt;string&gt;</code> | An exact string to match (`===`). Can also be a list of strings, one of which must be an exact match. An empty string is allowed. Note, however, that the [qualifier](#rtvref.qualifiers) must not be `REQUIRED` because that will disallow an empty string as the value being checked regardless of this value/list. |
| [oneOf] | <code>string</code> \| <code>Array.&lt;string&gt;</code> | An exact string to match (`===`). Can also be a list of strings, one of which must be an exact match. An empty string is allowed. Note, however, that the [qualifier](#rtvref.qualifiers) must not be `REQUIRED` because that will disallow an empty string as the value being checked regardless of this value/list. An empty list will be ignored. |
| [partial] | <code>string</code> | A partial value to match (must be somewhere within the string). Ignored if empty string, or `exact` is specified. `min` and `max` take __precedence__ over this argument (the length will be validated first, then a partial match will be attempted). |
| [min] | <code>number</code> | Minimum inclusive length. Defaults to 1 for a `REQUIRED` string, and 0 for an `EXPECTED` or `OPTIONAL` string. Ignored if `exact` is specified, or `min` is not a [FINITE](#rtvref.types.FINITE) number >= 0. |
| [max] | <code>number</code> | Maximum inclusive length. Negative means no maximum. Ignored if `exact` is specified, `max` is not a [FINITE](#rtvref.types.FINITE) number, or `max` is less than `min`. |
......@@ -1945,7 +1945,7 @@ There is one disadvantage to using a custom validator: It cannot be de/serialize
| Name | Type | Description |
| --- | --- | --- |
| [oneOf] | <code>symbol</code> \| <code>Array.&lt;symbol&gt;</code> | An exact symbol to match (`===`). Can also be a list of symbols, one of which must be an exact match. Values to match are ignored if they are not symbols. |
| [oneOf] | <code>symbol</code> \| <code>Array.&lt;symbol&gt;</code> | An exact symbol to match (`===`). Can also be a list of symbols, one of which must be an exact match. Values to match are ignored if they are not symbols. An empty list will be ignored. |
* * *
......
......@@ -445,7 +445,7 @@ const defs = {
* Can also be a list of strings, one of which must be an exact match. An empty
* string is allowed. Note, however, that the {@link rtvref.qualifiers qualifier}
* must not be `REQUIRED` because that will disallow an empty string as the value
* being checked regardless of this value/list.
* being checked regardless of this value/list. An empty list will be ignored.
* @property {string} [partial] A partial value to match (must be somewhere
* within the string). Ignored if empty string, or `exact` is specified. `min`
* and `max` take __precedence__ over this argument (the length will be
......@@ -491,7 +491,7 @@ const defs = {
* @typedef {Object} rtvref.types.SYMBOL_args
* @property {(symbol|Array.<symbol>)} [oneOf] An exact symbol to match (`===`).
* Can also be a list of symbols, one of which must be an exact match. Values to
* match are ignored if they are not symbols.
* match are ignored if they are not symbols. An empty list will be ignored.
*/
/**
......
......@@ -2,6 +2,8 @@
import {type, default as isSymbol} from '../validation/isSymbol';
import isArray from '../validation/isArray';
import {default as qualifiers, nilPermitted} from '../qualifiers';
import RtvSuccess from '../RtvSuccess';
import RtvError from '../RtvError';
......@@ -40,16 +42,31 @@ export const config = function(settings) {
* @param {*} v Value to validate.
* @param {string} [q] Validation qualifier. Defaults to
* {@link rtvref.qualifiers.REQUIRED REQUIRED}.
* @param {rtvref.types.numeric_args} [args] Type arguments.
* @returns {(rtvref.RtvSuccess|rtvref.RtvError)} An `RtvSuccess` if valid; `RtvError` if not.
*/
export default function valSymbol(v, q = REQUIRED) {
export default function valSymbol(v, q = REQUIRED, args) {
if (nilPermitted(v, q)) {
return new RtvSuccess();
}
if (isSymbol(v)) {
let valid = isSymbol(v);
if (valid && args) {
if (isSymbol(args.oneOf) || (isArray(args.oneOf) && args.oneOf.length > 0)) {
const possibilities = [].concat(args.oneOf);
// flip the result so that valid is set to false if no values match
valid = !possibilities.every(function(possibility) {
// return false on first match to break the loop
return !(isSymbol(possibility) && v === possibility);
});
}
}
if (valid) {
return new RtvSuccess();
}
return new RtvError(v, impl.toTypeset(type, q), [], impl.toTypeset(type, q, true));
return new RtvError(v, impl.toTypeset(type, q, args), [],
impl.toTypeset(type, q, args, true));
}
......@@ -129,7 +129,7 @@ describe('module: lib/validator/valFinite', function() {
vtu.expectValidatorError(val, 7, undefined, {oneOf: [null, '7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set(null, '7', true)});
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set([6, 8])});
});
it('exact takes precedence over min/max', function() {
......
......@@ -139,7 +139,7 @@ describe('module: lib/validator/valFloat', function() {
vtu.expectValidatorError(val, 7.7, undefined, {oneOf: [null, '7.7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, 7.7, undefined, {oneOf: new Set(null, '7.7', true)});
vtu.expectValidatorSuccess(val, 7.7, undefined, {oneOf: new Set([6.1, 8.1])});
});
it('exact takes precedence over min/max', function() {
......
......@@ -136,7 +136,7 @@ describe('module: lib/validator/valInt', function() {
vtu.expectValidatorError(val, 7, undefined, {oneOf: [null, '7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set(null, '7', true)});
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set([6, 8])});
});
it('exact takes precedence over min/max', function() {
......
......@@ -123,7 +123,7 @@ describe('module: lib/validator/valNumber', function() {
vtu.expectValidatorError(val, 7, undefined, {oneOf: [null, '7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set(null, '7', true)});
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set([6, 8])});
});
it('exact takes precedence over min/max', function() {
......
......@@ -142,7 +142,7 @@ describe('module: lib/validator/valSafeInt', function() {
vtu.expectValidatorError(val, 7, undefined, {oneOf: [null, '7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set(null, '7', true)});
vtu.expectValidatorSuccess(val, 7, undefined, {oneOf: new Set([6, 8])});
});
it('exact takes precedence over min/max', function() {
......
......@@ -101,7 +101,7 @@ describe('module: lib/validator/valString', function() {
vtu.expectValidatorError(val, '7', undefined, {oneOf: [null, 7, true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, '7', undefined, {oneOf: new Set(null, 7, true)});
vtu.expectValidatorSuccess(val, '7', undefined, {oneOf: new Set(['6', '8'])});
});
it('checks for a partial value if "exact" is not specified', function() {
......
......@@ -60,4 +60,40 @@ describe('module: lib/validator/valSymbol', function() {
});
});
});
describe('arguments', function() {
const sym6 = Symbol(6);
const sym7 = Symbol(7);
const sym8 = Symbol(8);
let validTypeValues;
beforeEach(function() {
validTypeValues = vtu.getValidValues(val.type);
});
it('checks for an exact symbol', function() {
validTypeValues.forEach(function(value) {
vtu.expectValidatorSuccess(val, value, undefined, {oneOf: value});
});
// ignored: invalid type
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: null});
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: '7'});
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: 7});
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: /7/});
});
it('checks for an exact symbol in a list', function() {
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: [sym6, sym7, sym8]});
vtu.expectValidatorError(val, sym7, undefined, {oneOf: [sym6, sym8]});
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: [sym7]});
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: []}); // ignored
// ignores non-type values in a list
vtu.expectValidatorError(val, sym7, undefined, {oneOf: [null, '7', true]});
// ignores non-arrays
vtu.expectValidatorSuccess(val, sym7, undefined, {oneOf: new Set([sym6, sym8])});
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment