UNPKG

@eluvio/elv-js-helpers

Version:

A collection of Javascript helper functions used by several Eluvio libraries.

76 lines (71 loc) 4.12 kB
'use strict' const isNil = require('../Boolean/isNil') const _assertBoundedBetween = require('./assertBoundedBetween') const _assertBoundedLower = require('./assertBoundedLower') const _assertBoundedUpper = require('./assertBoundedUpper') const _assertNothing = require('./assertNothing') const compare = require('../Functional/compare') const truthTable = require('../Functional/truthTable') /** * Returns a 2-element array for use in an [ObjectModel assertion](http://objectmodel.js.org/#doc-assertions) * * The first element is a function that will take an input and return: * * * `true` if the input satisfies the specified bound(s) OR **the input is not a valid instance of the specified Model to be bounded** * * `false` if the input **is a valid instance of the specified Model** AND violates the specified bound(s) * * This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose * of this is to prevent redundant errors, e.g. 'foo' is not a Number, 'foo' must be < 1. * * The second element is either an error string or a function to generate an error message. If it is a function, it will * get called by ObjectModel when it validates a Model and fails, passing in the assertion result (generally `false`), * the failing value, and any attribute name(s) that were traversed to access the value. * * @function * @category ModelAssertion * @sig ((Boolean, *, String) -> String) ObjectModelErrMsgFn => Model -> a -> a -> Boolean -> Boolean -> [(* -> Boolean), ObjectModelErrMsgFn | String] * @param {Model} model - The Model to be bounded * @param {*} lowerBound - The lower bound that must be satisfied. If `null`, no lower bound will be checked. * @param {*} upperBound - The upper bound that must be satisfied. If `null`, no upper bound will be checked. * @param {Boolean} lowerInclusive - If `true` (and `lowerBound` is not `null`) then input is allowed to equal `lowerBound`. * @param {Boolean} upperInclusive - If `true` (and `upperBound` is not `null`) then input is allowed to equal `upperBound`. * @param {Function} [comparatorFn=compare] - Function used to compare the input against bound(s). * Must accept two values and return -1 if first value is less than the second, * 1 if the second value is less than the first, and zero otherwise. * This enables adding bounds to a Model type that cannot be compared using Javascript's * [less than (<)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than) operator. * @returns {Array} 2-element array [Function, Function | String]. See description for details. * @example * * 'use strict' * const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel') * * const assertBounded = require('@eluvio/elv-js-helpers/ModelAssertion/assertBounded') * * // Note use of spread operator (...) to unpack the array returned by assertBounded() * const NumberBetweenZeroAndOneModel = NumberModel.extend() * .assert(...assertBounded(NumberModel, 0, 1, true, true)) * .as('NumberBetweenZeroAndOne') * * NumberBetweenZeroAndOneModel(-1) //=> EXCEPTION: 'Value must be >= 0 and <= 1 (got: -1)' * * NumberBetweenZeroAndOneModel(0) //=> 0 * * NumberBetweenZeroAndOneModel(0.5) //=> 0.5 * * NumberBetweenZeroAndOneModel(1) //=> 1 * * NumberBetweenZeroAndOneModel(42) //=> EXCEPTION: 'Value must be >= 0 and <= 1 (got: 42)' * */ const assertBounded = (model, lowerBound, upperBound, lowerInclusive, upperInclusive, comparatorFn = compare) => truthTable( [ _assertBoundedBetween(model, lowerBound, upperBound, lowerInclusive, upperInclusive, comparatorFn), // false,false: both bounds present _assertBoundedLower(model, lowerBound, lowerInclusive, comparatorFn), // false,true: only check lower bound _assertBoundedUpper(model, upperBound, upperInclusive, comparatorFn), // true,false: only check upper bound _assertNothing() // true,true: no bounds passed in, value always valid (allowed for convenience) ], [isNil(lowerBound), isNil(upperBound)] ) module.exports = assertBounded