Skip to content

Commit

Permalink
[FIX] new fct templateify
Browse files Browse the repository at this point in the history
  • Loading branch information
mathix420 committed Jan 18, 2023
1 parent 6da94c9 commit 2a86761
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 19 deletions.
71 changes: 67 additions & 4 deletions packages/vuito/src/template.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,82 @@
import { VTemplateRow, VInputTemplate, VTemplate } from './types';
import { VTemplateRow, VInputTemplate, VTemplate, VRow, VKeys } from './types';


function getCheckRowFct(tests: VRow[]): VTemplateRow['check'] {
return (value, parent) => new Promise((resolve, reject) => {
for (const { message, test, onlyIf } of tests) {
// Conditional check
if (onlyIf && parent && !onlyIf(parent)) continue;

if (value && typeof value === 'string') {
value = value.trim();
}

console.log(value, message, parent, onlyIf && parent && onlyIf(parent))

// If test fail => we reject with error message
if (!test(value)) reject(message);
console.log(value, 'out')
}
// All tests passed
resolve();
})
}

function getGlobalChecker(vKeys: VKeys): VTemplate['check'] {
return function (object: Record<string, unknown>): Promise<void> {
return new Promise(async (resolve, reject) => {
for (const [key, tests] of Object.entries(vKeys)) {
// Skip `check` method in the template
// if (key === 'check') return;

// Perform all sub tests, if any fail, the exit with the error message
await tests.check(object[key], object).catch(reject);
}

// All tests passed
resolve();
});
}
}

function injectSubCheckers(template: VInputTemplate): VKeys {
return Object.fromEntries(
Object.entries(template).map(([key, tests]) => {
return [key, {
...tests,
check: getCheckRowFct(tests)
} as VTemplateRow]
})
)
}

export function templateify(template: VInputTemplate): VTemplate {
const injectedTemplate = injectSubCheckers(template)
return {
...injectedTemplate,
check: getGlobalChecker(injectedTemplate)
} as VTemplate
}


/**
* @deprecated Use templateify method instead
*/
export class Template {
[key: string]: VTemplateRow | VTemplate['check'];

constructor(template: VInputTemplate) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
console.warn('[WARN:vuito:deprecated] Use templateify method instead.')
// Map each fields checker in template
for (const [key, tests] of Object.entries(template as VTemplate)) {
// Add `check` method to all fields checkers
(tests as VTemplateRow).check = function (value, parent) {
return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => {
for (const { message, test, onlyIf } of this) {
// Conditional check
if (onlyIf && parent && !onlyIf(parent)) return;
if (onlyIf && parent && !onlyIf(parent)) continue;

if (value && typeof value === 'string') {
value = value.trim();
Expand Down Expand Up @@ -41,7 +104,7 @@ export class Template {
// if (key === 'check') return;

// Perform all sub tests, if any fail, the exit with the error message
(tests as VTemplateRow).check(object[key], object).catch(reject);
await (tests as VTemplateRow).check(object[key], object).catch(reject);
}

// All tests passed
Expand Down
2 changes: 1 addition & 1 deletion packages/vuito/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type VInputTemplate = {
};

export type VKeys = {
[key: string]: VTemplateRow;
readonly [key: string]: VTemplateRow;
};

export type VTemplate = VKeys & {
Expand Down
2 changes: 1 addition & 1 deletion packages/vuito/src/vuito.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export { default as minValue } from './validators/minValue';
export { default as onlyText } from './validators/onlyText';
export { default as required } from './validators/required';
export { default as regex } from './validators/regex';
export { Template } from './template';
export { Template, templateify } from './template';
25 changes: 12 additions & 13 deletions packages/vuito/tests/template.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { VTemplateRow } from '../src/types';
import { Template } from '../src/vuito';
import { templateify } from '../src/vuito';

describe('template constructor', () => {
const demo = new Template({
const demo = templateify({
one: [{ test: () => true, message: 'Never shown' }],
two: [{ test: () => false, message: 'Always shown' }],
});
Expand All @@ -12,44 +11,44 @@ describe('template constructor', () => {
});

test('second level checks', () => {
expect((<VTemplateRow>demo.one).check).toBeTruthy();
expect((<VTemplateRow>demo.two).check).toBeTruthy();
expect(demo.one.check).toBeTruthy();
expect(demo.two.check).toBeTruthy();
});
});

describe('template methods', () => {
const demo = new Template({
const demo = templateify({
one: [{ test: () => true, message: 'Never shown' }],
two: [{ test: () => false, message: 'Always shown', onlyIf: (p) => !!p.one }],
});

test('first level check', async () => {
await expect(demo.check({ one: 'yes' })).rejects.toBe('Always shown');
await expect(demo.check({ one: 'yes' })).rejects.toBe('Always shown')
await expect(demo.check({})).resolves.toBeUndefined();
});

test('second level checks', async () => {
await expect((<VTemplateRow>demo.one).check('any')).resolves.toBeUndefined();
await expect((<VTemplateRow>demo.two).check('any')).rejects.toBe('Always shown');
await expect((<VTemplateRow>demo.two).check('any', {})).resolves.toBeUndefined();
await expect(demo.one.check('any')).resolves.toBeUndefined();
await expect(demo.two.check('any')).rejects.toBe('Always shown');
await expect(demo.two.check('any', {})).resolves.toBeUndefined();
});
});

describe('test parameter', () => {
const myTest = jest.fn(() => true);
const demo = new Template({
const demo = templateify({
one: [{ test: myTest, message: 'Never shown' }],
});

test('string is trimmed', async () => {
const str = ' test 1 ';
await (<VTemplateRow>demo.one).check(str);
await demo.one.check(str);
expect(myTest).toBeCalledWith(str.trim());
});

test('string is trimmed 2', async () => {
const str = ' ';
await (<VTemplateRow>demo.one).check(str);
await demo.one.check(str);
expect(myTest).toBeCalledWith(str.trim());
});
});

0 comments on commit 2a86761

Please sign in to comment.