Skip to content

Commit

Permalink
added(n4s): add custom message support to lazy enforcements
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed Nov 10, 2021
1 parent eeac20e commit 2b902cb
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 32 deletions.
2 changes: 1 addition & 1 deletion packages/n4s/src/compounds/oneOf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { TLazy } from 'genEnforceLazy';
import { lengthEquals } from 'lengthEquals';
import { longerThan } from 'longerThan';
import { TRuleDetailedResult, ruleReturn } from 'ruleReturn';
import ruleReturn, { TRuleDetailedResult } from 'ruleReturn';
import runLazyRule from 'runLazyRule';

export default function oneOf(
Expand Down
7 changes: 1 addition & 6 deletions packages/n4s/src/lib/ruleReturn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import defaultTo from 'defaultTo';
import type { TStringable } from 'utilityTypes';

export function ruleReturn(
export default function ruleReturn(
pass: boolean,
message?: string
): TRuleDetailedResult {
Expand Down Expand Up @@ -42,8 +42,3 @@ export type TRuleReturn =
};

export type TRuleDetailedResult = { pass: boolean; message?: string };

export type TLazyRuleMethods = {
test: (value: unknown) => boolean;
run: (value: unknown) => TRuleDetailedResult;
};
2 changes: 1 addition & 1 deletion packages/n4s/src/lib/transformResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import isBooleanValue from 'isBooleanValue';
import optionalFunctionValue from 'optionalFunctionValue';
import throwError from 'throwError';

import { TRuleReturn, TRuleDetailedResult, ruleReturn } from 'ruleReturn';
import ruleReturn, { TRuleReturn, TRuleDetailedResult } from 'ruleReturn';
import type { TRuleValue, TArgs } from 'runtimeRules';

/**
Expand Down
60 changes: 60 additions & 0 deletions packages/n4s/src/runtime/__tests__/message.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import enforce from 'enforce';
import ruleReturn from 'ruleReturn';

describe('enforce..message()', () => {
it('Should set the failure message in builtin rules', () => {
expect(
enforce.equals(false).message('oof. Expected true to be false').run(true)
).toEqual(ruleReturn(false, 'oof. Expected true to be false'));

expect(
enforce
.equals(false)
.message(() => 'oof. Expected true to be false')
.run(true)
).toEqual(ruleReturn(false, 'oof. Expected true to be false'));
});

it('Should set the failure message in custom rules', () => {
expect(
enforce.ruleWithFailureMessage().message('oof. Failed again!').run()
).toEqual(ruleReturn(false, 'oof. Failed again!'));

expect(
enforce
.ruleWithFailureMessage()
.message(() => 'oof. Failed again!')
.run()
).toEqual(ruleReturn(false, 'oof. Failed again!'));
});

describe('.message callback', () => {
it('Should be passed the rule value as the first argument', () => {
const msg = jest.fn(() => 'some message');
const arg = {};
expect(enforce.equals(false).message(msg).run(arg)).toEqual(
ruleReturn(false, 'some message')
);
expect(msg).toHaveBeenCalledWith(arg, undefined);
});

it('Should pass original messageas the second argument if exists', () => {
const msg = jest.fn(() => 'some message');
const arg = {};
expect(
enforce
.ruleWithFailureMessage(false)
.message(msg)
.run(arg, 'original message')
).toEqual(ruleReturn(false, 'some message'));
expect(msg).toHaveBeenCalledWith(arg, 'This should not be seen!');
});
});
});

enforce.extend({
ruleWithFailureMessage: () => ({
pass: false,
message: 'This should not be seen!',
}),
});
64 changes: 40 additions & 24 deletions packages/n4s/src/runtime/genEnforceLazy.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import mapFirst from 'mapFirst';
import optionalFunctionValue from 'optionalFunctionValue';
import { TStringable } from 'utilityTypes';

import eachEnforceRule from 'eachEnforceRule';
import { ctx } from 'enforceContext';
import isProxySupported from 'isProxySupported';
import type { TRuleDetailedResult, TLazyRuleMethods } from 'ruleReturn';
import * as ruleReturn from 'ruleReturn';
import ruleReturn, { defaultToPassing, TRuleDetailedResult } from 'ruleReturn';
import { TRuleValue, TArgs, KBaseRules, getRule, TRules } from 'runtimeRules';
import { transformResult } from 'transformResult';

type TRegisteredRules = Array<(value: TRuleValue) => TRuleDetailedResult>;

export default function genEnforceLazy(key: string) {
const registeredRules: TRegisteredRules = [];
let lazyMessage: void | TLazyMessage;

return addLazyRule(key);

Expand All @@ -24,8 +24,31 @@ export default function genEnforceLazy(key: string) {
);

let proxy = {
run: genRun(),
test: genTest(),
run: (value: TRuleValue): TRuleDetailedResult => {
return defaultToPassing(
mapFirst(registeredRules, (rule, breakout) => {
const res = ctx.run({ value }, () => rule(value));

if (!res.pass) {
breakout(
ruleReturn(
!!res.pass,
optionalFunctionValue(lazyMessage, value, res.message) ??
res.message
)
);
}
})
);
},
test: (value: TRuleValue): boolean => proxy.run(value).pass,
message: (message: TStringable): TLazy => {
if (message) {
lazyMessage = message;
}

return proxy;
},
} as TLazy;

if (!isProxySupported()) {
Expand All @@ -48,24 +71,6 @@ export default function genEnforceLazy(key: string) {
},
});
return proxy;

function genRun() {
return (value: TRuleValue): TRuleDetailedResult => {
return ruleReturn.defaultToPassing(
mapFirst(registeredRules, (rule, breakout) => {
const res = ctx.run({ value }, () => rule(value));

if (!res.pass) {
breakout(res);
}
})
);
};
}

function genTest() {
return (value: TRuleValue): boolean => proxy.run(value).pass;
}
};
}
}
Expand All @@ -75,3 +80,14 @@ export type TLazyRules = TRules<TLazyRuleMethods>;
export type TLazy = TLazyRules & TLazyRuleMethods;

export type TShapeObject = Record<string, TLazy>;

type TLazyRuleMethods = {
test: (value: unknown) => boolean;
run: (value: unknown) => TRuleDetailedResult;
message: (message: TLazyMessage) => TLazy;
};

type TRegisteredRules = Array<(value: TRuleValue) => TRuleDetailedResult>;
type TLazyMessage =
| string
| ((value: unknown, originalMessage?: TStringable) => string);

0 comments on commit 2b902cb

Please sign in to comment.