Skip to content

Commit 668de2f

Browse files
committed
added: [n4s] lazy evaluated enforcements (#479)
1 parent 43fa22b commit 668de2f

File tree

11 files changed

+95
-50
lines changed

11 files changed

+95
-50
lines changed

config/rollup/getPlugins.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module.exports = function ({ dev = false, format, min, libraryName, version }) {
3434
alias({ entries: aliases }),
3535
resolve(),
3636
commonjs({
37-
include: /node_modules\/(anyone|n4s)/,
37+
include: /node_modules\/(anyone|n4s|wait)/,
3838
}),
3939
babel({
4040
configFile: filePaths.BABEL_CONFIG_PATH,

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"@babel/plugin-transform-runtime": "^7.12.1",
3535
"@babel/preset-env": "^7.12.1",
3636
"@babel/register": "^7.12.1",
37-
"@lets/wait": "^2.0.2",
3837
"@rollup/plugin-alias": "^3.1.1",
3938
"@rollup/plugin-babel": "^5.2.1",
4039
"@rollup/plugin-commonjs": "^16.0.0",
@@ -64,6 +63,7 @@
6463
"rollup-plugin-terser": "^7.0.2",
6564
"semver": "^7.3.2",
6665
"typescript": "^4.0.5",
67-
"validator": "^13.1.17"
66+
"validator": "^13.1.17",
67+
"wait": "^0.4.1"
6868
}
6969
}

packages/n4s/src/enforce/__tests__/enforce.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,45 @@ const suite = ({ withProxy, requirePath }) =>
8080
});
8181
});
8282

83+
describe('lazy enforcements', () => {
84+
it('Should expose all rules on top of the enforce function', () => {
85+
allRules.forEach(rule => expect(typeof enforce[rule]).toBe('function'));
86+
87+
expect(enforce.isAbc).toBeUndefined();
88+
enforce.extend({ isAbc: v => v === 'abc' });
89+
expect(typeof enforce.isAbc).toBe('function');
90+
});
91+
92+
test('Each rule returns a function', () => {
93+
allRules.forEach(rule =>
94+
expect(typeof enforce[rule]()).toBe('function')
95+
);
96+
});
97+
98+
test('Returned function returns a boolean value', () => {
99+
expect(enforce.isArray()([])).toBe(true);
100+
expect(enforce.isNumber()('not_a_number')).toBe(false);
101+
});
102+
103+
it("Should use the second function's argument as the enforce value, and the first function's arguments as the ...rest", () => {
104+
expect(enforce.isEmpty()([])).toBe(true);
105+
expect(enforce.isEmpty()([1, 2, 3])).toBe(false);
106+
expect(enforce.isNumeric()('555')).toBe(true);
107+
expect(enforce.greaterThan(10)(20)).toBe(true);
108+
expect(enforce.greaterThan(10)(4)).toBe(false);
109+
110+
const fn = jest.fn(() => true);
111+
112+
enforce.extend({
113+
getArgs: fn,
114+
});
115+
116+
enforce.getArgs(2, 3, 4, 5, 6, 7)(1);
117+
// One should be first
118+
expect(fn).toHaveBeenCalledWith(1, 2, 3, 4, 5, 6, 7);
119+
});
120+
});
121+
83122
it('Should throw errors on failing enforces', () => {
84123
const isNumber = () => enforce('a').isNumber(true);
85124
expect(isNumber).toThrow(Error);

packages/n4s/src/enforce/enforce.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,24 @@ const rulesObject = rules();
77

88
let enforce, rulesList;
99

10+
const bindLazyRule = ruleName => (...args) => value =>
11+
rulesObject[ruleName](value, ...args);
12+
13+
const bindLazyRules = rules =>
14+
rules.reduce(
15+
(enforce, ruleName) =>
16+
Object.assign(enforce, {
17+
[ruleName]: bindLazyRule(ruleName),
18+
}),
19+
enforce
20+
);
21+
1022
if (proxySupported()) {
11-
enforce = value => {
23+
const enforceMain = value => {
1224
const proxy = new Proxy(rulesObject, {
1325
get: (rules, fnName) => {
1426
if (!isRule(rules, fnName)) {
15-
return;
27+
return enforce[fnName];
1628
}
1729

1830
return (...args) => {
@@ -23,29 +35,43 @@ if (proxySupported()) {
2335
});
2436
return proxy;
2537
};
38+
39+
// This is for lazy enforcement: enforce.isArray()([]) // true
40+
enforce = new Proxy(enforceMain, {
41+
get: (enforce, fnName) => {
42+
if (!isRule(rulesObject, fnName)) {
43+
return enforce[fnName];
44+
}
45+
46+
return bindLazyRule(fnName);
47+
},
48+
});
2649
} else {
2750
rulesList = Object.keys(rulesObject);
2851

52+
// This is for lazy enforcement: enforce.isArray()([]) // true
2953
enforce = value =>
30-
rulesList.reduce(
31-
(allRules, fnName) =>
32-
Object.assign(allRules, {
33-
...(isRule(rulesObject, fnName) && {
34-
[fnName]: (...args) => {
35-
runner(rulesObject[fnName], value, ...args);
36-
return allRules;
37-
},
38-
}),
39-
}),
40-
{}
41-
);
54+
rulesList.reduce((allRules, fnName) => {
55+
if (!isRule(rulesObject, fnName)) {
56+
return enforce[fnName];
57+
}
58+
return Object.assign(allRules, {
59+
[fnName]: (...args) => {
60+
runner(rulesObject[fnName], value, ...args);
61+
return allRules;
62+
},
63+
});
64+
}, {});
65+
66+
bindLazyRules(rulesList);
4267
}
4368

4469
enforce.extend = customRules => {
4570
Object.assign(rulesObject, customRules);
4671

4772
if (!proxySupported()) {
4873
rulesList = Object.keys(rulesObject);
74+
bindLazyRules(Object.keys(customRules));
4975
}
5076

5177
return enforce;

packages/n4s/src/enforce/enforceRunner.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import isFunction from 'isFunction';
21
import { transformResult } from 'transformResult';
32

43
/**
@@ -10,10 +9,6 @@ import { transformResult } from 'transformResult';
109
* @throws
1110
*/
1211
function runner(rule, value, ...args) {
13-
if (!isFunction(rule)) {
14-
return;
15-
}
16-
1712
const ruleResult = rule(value, ...args);
1813
const result = transformResult(ruleResult, { rule, value });
1914
if (!result.pass) {

packages/n4s/src/lib/isRule.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
11
import isFunction from 'isFunction';
2-
import throwError from 'throwError';
32

43
const isRule = (rulesObject, name) => {
5-
const ruleExists =
6-
Object.prototype.hasOwnProperty.call(rulesObject, name) &&
7-
isFunction(rulesObject[name]);
8-
9-
if (!ruleExists) {
10-
throwError(
11-
`Rule "${name}" was not found in rules object. Make sure you typed it correctly.`
12-
);
13-
}
14-
15-
return ruleExists;
4+
return rulesObject.hasOwnProperty(name) && isFunction(rulesObject[name]);
165
};
176

187
export default isRule;

packages/n4s/src/lib/transformResult.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,15 @@ export function transformResult(result, { rule, value }) {
3838

3939
// if result is boolean
4040
if (!!result === result) {
41-
return { ...defaultResult, pass: result };
41+
return (defaultResult.pass = result), defaultResult;
4242
} else {
43-
const formattedResult = {
44-
pass: result.pass,
45-
};
43+
defaultResult.pass = result.pass;
4644
if (result.message) {
47-
formattedResult.message = formatResultMessage(
45+
defaultResult.message = formatResultMessage(
4846
rule,
4947
isFunction(result.message) ? result.message() : result.message
5048
);
5149
}
52-
return { ...defaultResult, ...formattedResult };
50+
return defaultResult;
5351
}
5452
}

packages/vest/src/core/test/__tests__/memo.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import wait from '@lets/wait';
21
import enforce from 'n4s';
2+
import wait from 'wait';
33

44
import vest from '../../..';
55

packages/vest/src/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import enforce from 'n4s';
2-
31
import create from 'createSuite';
2+
import enforce from 'enforce';
43
import { only, skip, warn, group } from 'hooks';
54
import test from 'test';
65

packages/vest/src/index.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import enforce from 'n4s';
2-
31
import create from 'createSuite';
2+
import enforce from 'enforce';
43
import { only, skip, warn, group } from 'hooks';
54
import test from 'test';
65

0 commit comments

Comments
 (0)