Skip to content

Commit

Permalink
Add callback assert
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianooliveira committed Feb 4, 2020
1 parent ef2f546 commit b95affc
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The following set of extra asserts are provided by this package:
- [BigNumberLessThan](#bignumberlessthan) (requires `bignumber.js`)
- [BigNumberLessThanOrEqualTo](#bignumberlessthanorequalto) (requires `bignumber.js`)
- [Boolean](#boolean)
- [Callback](#callback) (requires `callback`)
- [CreditCard](#creditcard) (requires `creditcard`)
- [Date](#date) (requires `moment` for format validation only)
- [DateDiffGreaterThan](#datediffgreaterthan) (requires `moment`)
Expand Down Expand Up @@ -97,6 +98,13 @@ Tests if a `BigNumber` is less than or equal to a given threshold.
### Boolean
Tests if the value is a boolean.

### Callback
Allows you to add custom rules by giving a callback function and a custom class.

#### Arguments
- `callback` (required) - the callback function.
- `customClass` (optional) - the name of the class.

### CreditCard
Tests if the value is a valid credit card number using the Luhn10 algorithm.

Expand Down
52 changes: 52 additions & 0 deletions src/asserts/callback-assert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

/**
* Module dependencies.
*/

const _ = require('lodash');
const { Violation } = require('validator.js');

/**
* Export `CallbackAssert`.
*/

module.exports = function(fn, customClass) {
/**
* Class name.
*/

this.__class__ = customClass || 'Callback';

if (!_.isFunction(fn)) {
throw new Error('Callback must be instantiated with a function');
}

/**
* Fn.
*/

this.fn = fn;

/**
* Validation algorithm.
*/

this.validate = function(value) {
let result;

try {
result = this.fn(value);
} catch (error) {
throw new Violation(this, value, { error });
}

if (result !== true) {
throw new Violation(this, value, { result });
}

return true;
};

return this;
};
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const BigNumberGreaterThanOrEqualTo = require('./asserts/big-number-greater-than
const BigNumberLessThan = require('./asserts/big-number-less-than-assert.js');
const BigNumberLessThanOrEqualTo = require('./asserts/big-number-less-than-or-equal-to-assert.js');
const Boolean = require('./asserts/boolean-assert.js');
const Callback = require('./asserts/callback-assert');
const CreditCard = require('./asserts/credit-card-assert.js');
const Date = require('./asserts/date-assert.js');
const DateDiffGreaterThan = require('./asserts/date-diff-greater-than-assert.js');
Expand Down Expand Up @@ -53,6 +54,7 @@ module.exports = {
BigNumberLessThan,
BigNumberLessThanOrEqualTo,
Boolean,
Callback,
CreditCard,
Date,
DateDiffGreaterThan,
Expand Down
91 changes: 91 additions & 0 deletions test/asserts/callback-assert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use strict';

/**
* Module dependencies.
*/

const { Assert: BaseAssert, Violation } = require('validator.js');
const CallbackAssert = require('../../src/asserts/callback-assert');

/**
* Extend `Assert` with `CallbackAssert`.
*/

const Assert = BaseAssert.extend({
Callback: CallbackAssert
});

/**
* Test `CallbackAssert`.
*/

describe('CallbackAssert', () => {
it('should throw an error if `value` is missing', () => {
try {
Assert.callback().validate();

fail();
} catch (e) {
expect(e.message).toEqual('Callback must be instantiated with a function');
}
});

it('should throw an error if `value` is not a function', () => {
try {
Assert.callback().validate('foobar');

fail();
} catch (e) {
expect(e.message).toEqual('Callback must be instantiated with a function');
}
});

it('should throw an error if the given function is invalid', () => {
try {
// eslint-disable-next-line no-undef
Assert.callback(() => thisFunctionDoesNotExist()).validate('foobar');
} catch (e) {
expect(e).toBeInstanceOf(Violation);
expect(e.show().assert).toEqual('Callback');
expect(e.show().value).toEqual('foobar');
expect(e.show().violation).not.toBeUndefined();
expect(e.show().violation.error).toBeInstanceOf(ReferenceError);
expect(e.show().violation.error.message).toEqual('thisFunctionDoesNotExist is not defined');
}
});

it('should throw an error if the callback function returns `false`', () => {
try {
Assert.callback(value => value === 'foobiz').validate('foobar');
} catch (e) {
expect(e).toBeInstanceOf(Violation);
expect(e.show().assert).toEqual('Callback');
expect(e.show().value).toEqual('foobar');
expect(e.show().violation.result).toBeFalsy();
}
});

it('should expose `assert` equal to `Callback`', () => {
try {
Assert.callback(value => value === 'foobiz').validate('foobar');
} catch (e) {
expect(e.show().assert).toEqual('Callback');
// e.show().assert.should.equal('Callback');
}
});

it('should have a `class` option and expose it as `assert`', () => {
try {
Assert.callback(value => value === 'foobiz', 'CustomClass').validate('foobar');
} catch (e) {
expect(e).toBeInstanceOf(Violation);
expect(e.show().assert).toEqual('CustomClass');
expect(e.show().value).toEqual('foobar');
expect(e.show().violation.result).toBeFalsy();
}
});

it('should not throw an error if the callback function returns `true`', () => {
Assert.callback(value => value === 'foobar').validate('foobar');
});
});
3 changes: 2 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('validator.js-asserts', () => {
it('should export all asserts', () => {
const assertNames = Object.keys(asserts);

expect(assertNames).toHaveLength(34);
expect(assertNames).toHaveLength(35);
expect(assertNames).toEqual(
expect.arrayContaining([
'AbaRoutingNumber',
Expand All @@ -26,6 +26,7 @@ describe('validator.js-asserts', () => {
'BigNumberLessThan',
'BigNumberLessThanOrEqualTo',
'Boolean',
'Callback',
'CreditCard',
'Date',
'DateDiffGreaterThan',
Expand Down

0 comments on commit b95affc

Please sign in to comment.