Skip to content

Commit

Permalink
patch: [N4S] bindNot for rules
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed Oct 17, 2020
1 parent 4dd0132 commit 98bd1d1
Show file tree
Hide file tree
Showing 73 changed files with 591 additions and 802 deletions.
10 changes: 6 additions & 4 deletions CONTRIBUTING.md
Expand Up @@ -97,7 +97,7 @@ Rules naming convention usually follows this structure: `is[Something]` for exam
Rules are functions that take as their first argument the value passed to the enforce function, and the rest of the arguments are what is beig passed to them by the consumer:

```js
function isGreaterThan(
export function isGreaterThan(
value /*enforceValue*/,
arg1 /*passed directly to the rule*/
) {
Expand All @@ -107,12 +107,14 @@ function isGreaterThan(

### Negative rulesList

If you also want to add a negative check to your rule, for example `isNotArray`, simply add a negativeForm property to your rule.
If you also want to add a negative check to your rule, for example `isNotArray`, add another export, wrapped with the `binNot` function. Then inside `rules/index.js` you'll have to expose both functions.

```js
function isArray(value) {
import { bindNot } from '../../lib';

export function isArray(value) {
return Array.isArray(value);
}

isArray.negativeForm = 'isNotArray';
export const isNotArray = bindNot(isArray);
```
5 changes: 5 additions & 0 deletions packages/n4s/src/lib/bindNot/index.js
@@ -0,0 +1,5 @@
export default function bindNot(fn) {
return function () {
return !fn.apply(this, arguments);
};
}
37 changes: 37 additions & 0 deletions packages/n4s/src/lib/bindNot/spec.js
@@ -0,0 +1,37 @@
import bindNot from '.';

describe('bindNot', () => {
it('Should return return a function', () => {
expect(typeof bindNot(jest.fn())).toBe('function');
});

test('calling returned function runs accepted function', () => {
const fn = jest.fn();

expect(fn).not.toHaveBeenCalled();
const not = bindNot(fn);
expect(fn).not.toHaveBeenCalled();
not();
expect(fn).toHaveBeenCalledTimes(1);
});

it('Should pass arguments to accepted function', () => {
const fn = jest.fn();

const not = bindNot(fn);
not(1, 2, 3, 4);
expect(fn).toHaveBeenCalledWith(1, 2, 3, 4);
});

it('Should return the boolean negation of the original function', () => {
expect(bindNot(() => true)()).toBe(false);
expect(bindNot(() => false)()).toBe(true);
expect(bindNot(() => 'string')()).toBe(false);
expect(bindNot(() => [])()).toBe(false);
expect(bindNot(() => '')()).toBe(true);
expect(bindNot(() => 0)()).toBe(true);
expect(bindNot(() => NaN)()).toBe(true);
expect(bindNot(() => null)()).toBe(true);
expect(bindNot(() => undefined)()).toBe(true);
});
});
24 changes: 0 additions & 24 deletions packages/n4s/src/lib/extendRules/index.js

This file was deleted.

62 changes: 0 additions & 62 deletions packages/n4s/src/lib/extendRules/spec.js

This file was deleted.

2 changes: 1 addition & 1 deletion packages/n4s/src/lib/index.js
@@ -1,4 +1,4 @@
export { default as extendRules } from './extendRules';
export { default as isRule } from './isRule';
export { default as proxySupported } from './proxySupported';
export { default as throwError } from './throwError';
export { default as bindNot } from './bindNot';
14 changes: 9 additions & 5 deletions packages/n4s/src/rules/endsWith/index.js
@@ -1,7 +1,11 @@
function endsWith(value, arg1) {
return typeof value === 'string' && typeof arg1 === 'string' && value.endsWith(arg1);
}
import { bindNot } from '../../lib';

endsWith.negativeForm = 'doesNotEndWith';
export function endsWith(value, arg1) {
return (
typeof value === 'string' &&
typeof arg1 === 'string' &&
value.endsWith(arg1)
);
}

export default endsWith;
export const doesNotEndWith = bindNot(endsWith);
48 changes: 23 additions & 25 deletions packages/n4s/src/rules/endsWith/spec.js
@@ -1,33 +1,31 @@
import endsWith from '.';
import { endsWith } from '.';

describe('Tests isArray rule', () => {
const word = 'meow';
const totallyDifferentWord = 'lorem';
it('Should return true for the same word', () => {
expect(endsWith(word, word)).toBe(true);
});
const word = 'meow';
const totallyDifferentWord = 'lorem';
it('Should return true for the same word', () => {
expect(endsWith(word, word)).toBe(true);
});

it('Should return true for a suffix', () => {
expect(endsWith(word, word.substring(word.length / 2, word.length))).toBe(true);
});
it('Should return true for a suffix', () => {
expect(endsWith(word, word.substring(word.length / 2, word.length))).toBe(
true
);
});

it('Should return true for empty suffix', () => {
expect(endsWith(word, '')).toBe(true);
});
it('Should return true for empty suffix', () => {
expect(endsWith(word, '')).toBe(true);
});

it('Should return false for a wrong suffix', () => {
expect(endsWith(word, word.substring(0, word.length - 1))).toBe(false);
});
it('Should return false for a wrong suffix', () => {
expect(endsWith(word, word.substring(0, word.length - 1))).toBe(false);
});

it('Should return false for a suffix which is a totally different word', () => {
expect(endsWith(word, totallyDifferentWord)).toBe(false);
});
it('Should return false for a suffix which is a totally different word', () => {
expect(endsWith(word, totallyDifferentWord)).toBe(false);
});

it('Should return false for a suffix longer than the word', () => {
expect(endsWith(word, word.repeat(2))).toBe(false);
});

it('Should expose negativeForm property', () => {
expect(endsWith.negativeForm).toBe('doesNotEndWith');
});
it('Should return false for a suffix longer than the word', () => {
expect(endsWith(word, word.repeat(2))).toBe(false);
});
});
8 changes: 4 additions & 4 deletions packages/n4s/src/rules/equals/index.js
@@ -1,7 +1,7 @@
function equals(value, arg1) {
import { bindNot } from '../../lib';

export function equals(value, arg1) {
return value === arg1;
}

equals.negativeForm = 'notEquals';

export default equals;
export const notEquals = bindNot(equals);
2 changes: 1 addition & 1 deletion packages/n4s/src/rules/equals/spec.js
@@ -1,6 +1,6 @@
import { random } from 'faker';
import { sample } from 'lodash';
import equals from '.';
import { equals } from '.';

const VALUES = [
random.word(),
Expand Down
8 changes: 2 additions & 6 deletions packages/n4s/src/rules/greaterThan/index.js
@@ -1,9 +1,5 @@
import isNumeric from '../isNumeric';
import { isNumeric } from '../isNumeric';

function greaterThan(value, arg1) {
export function greaterThan(value, arg1) {
return isNumeric(value) && isNumeric(arg1) && Number(value) > Number(arg1);
}

greaterThan.alias = 'gt';

export default greaterThan;
2 changes: 1 addition & 1 deletion packages/n4s/src/rules/greaterThan/spec.js
@@ -1,5 +1,5 @@
import { random } from 'faker';
import greaterThan from '.';
import { greaterThan } from '.';

describe('Tests greaterThan rule', () => {
let arg0;
Expand Down
8 changes: 2 additions & 6 deletions packages/n4s/src/rules/greaterThanOrEquals/index.js
@@ -1,9 +1,5 @@
import isNumeric from '../isNumeric';
import { isNumeric } from '../isNumeric';

function greaterThanOrEquals(value, arg1) {
export function greaterThanOrEquals(value, arg1) {
return isNumeric(value) && isNumeric(arg1) && Number(value) >= Number(arg1);
}

greaterThanOrEquals.alias = 'gte';

export default greaterThanOrEquals;
2 changes: 1 addition & 1 deletion packages/n4s/src/rules/greaterThanOrEquals/spec.js
@@ -1,5 +1,5 @@
import { random } from 'faker';
import greaterThanOrEquals from '.';
import { greaterThanOrEquals } from '.';

describe('Tests greaterThanOrEquals rule', () => {
let arg0;
Expand Down

0 comments on commit 98bd1d1

Please sign in to comment.