spec/predicates/and.spec.ts
import 'mocha';
import { given } from 'mocha-testdata';
import sinon = require('sinon');
import { and, ensure, isDefined, isGreaterThan, isInteger, isLessThan, Predicate, TinyType } from '../../src';
import { expect } from '../expect';
describe('predicates', () => {
/** @test {and} */
describe('::and', () => {
class InvestmentLengthInYears extends TinyType {
constructor(public readonly value: number) {
super();
ensure('InvestmentLengthInYears', value, and(
isDefined(),
isInteger(),
isGreaterThan(0),
isLessThan(50),
));
}
}
it('ensures that all the predicates are met', () => {
expect(() => new InvestmentLengthInYears(10)).to.not.throw();
});
given(
[ null, 'InvestmentLengthInYears should be defined' ],
[ 0.2, 'InvestmentLengthInYears should be an integer' ],
[ -2, 'InvestmentLengthInYears should be greater than 0' ],
[ 52, 'InvestmentLengthInYears should be less than 50' ],
).
it('complains upon the first unmet predicate', (value: any, errorMessage: string) => {
expect(() => new InvestmentLengthInYears(value))
.to.throw(errorMessage);
});
it('complains if there are no predicates specified', () => {
expect(() => and()).to.throw(`Looks like you haven't specified any predicates to check the value against?`);
});
it('stops evaluating the predicates upon the first failure', () => {
const predicateEvaluated = sinon.spy();
const predicateReturning = (result: boolean) => Predicate.to(result ? 'pass' : 'fail', (value: any) => {
predicateEvaluated();
return result;
});
expect(() => ensure('value', null, and(
predicateReturning(true),
predicateReturning(false),
predicateReturning(true),
))).to.throw('value should fail');
expect(predicateEvaluated.callCount).to.equal(2);
});
});
});