Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
87d2d9b
feat: JSON Logic skeleton and plumbing setup
brennj Jun 29, 2023
d2cc213
chore: support barebones computedAttrs
brennj Aug 22, 2023
cf8f9bd
chore: fix errors
brennj Aug 31, 2023
2eca83f
chore: fix mess ups from rebase
brennj Aug 31, 2023
b305047
chore: feedback from PR
brennj Sep 1, 2023
edbc56f
chore: pass logic down at updateFieldsProperties to prevent bugs
brennj Sep 1, 2023
55ed296
Release 0.5.0-dev.20230901130231
brennj Sep 1, 2023
54f7c42
Revert "Release 0.5.0-dev.20230901130231"
brennj Sep 4, 2023
2710f51
feat: JSON Logic skeleton and plumbing setup
brennj Jun 29, 2023
da20a93
chore: support barebones computedAttrs
brennj Aug 22, 2023
195825d
chore: computed string attributes
brennj Aug 23, 2023
9118b09
chore: fix tests
brennj Sep 4, 2023
5f32f21
chore: consistency for curly braces
brennj Sep 4, 2023
a40da7b
chore: remove unneeded code for now
brennj Sep 4, 2023
35d0fd1
feat: JSON Logic skeleton and plumbing setup
brennj Jun 29, 2023
57b90af
chore: fix tests
brennj Sep 4, 2023
a186d13
chore: review errors
brennj Sep 4, 2023
aa3432b
chore: fix up code for fixtures
brennj Sep 4, 2023
40679e5
chore: add a bunch of docs to try and make things clearer
brennj Sep 4, 2023
8d54d43
chore: add example to docs
brennj Sep 4, 2023
df9b1a6
chore: higher level console check
brennj Sep 5, 2023
81402ed
chore: use cases to clean up error tests
brennj Sep 5, 2023
827ba1b
chore: add more tests for missing vars
brennj Sep 5, 2023
02a0ff5
chore: use switch statement instead
brennj Sep 5, 2023
8cc22e0
chore: add code comments why schemas fail
brennj Sep 5, 2023
36e6845
feat: JSON Logic skeleton and plumbing setup
brennj Jun 29, 2023
70a1430
chore: changes
brennj Sep 5, 2023
d03b369
chore: add bad operator handling
brennj Sep 5, 2023
9813400
chore: fix bad naming
brennj Sep 5, 2023
2d6eac7
chore: matching after merging
brennj Sep 5, 2023
63e9424
chore: test field to be explicit in test
brennj Sep 5, 2023
deb9d6c
chore: remove unused schema
brennj Sep 5, 2023
6f14ac4
chore: fix bad var name
brennj Sep 5, 2023
482a82e
Merge remote-tracking branch 'origin/main' into inline-rule-handling
brennj Sep 13, 2023
a85d588
chore: more fixing inline rule verbage
brennj Sep 13, 2023
bb335dd
Release 0.6.2-dev.20230915095336
brennj Sep 15, 2023
78825be
Release 0.6.2-dev.20230915095420
brennj Sep 15, 2023
c2da320
Revert "Release 0.6.2-dev.20230915095420"
brennj Sep 15, 2023
6c7206b
Revert "Release 0.6.2-dev.20230915095336"
brennj Sep 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/jsonLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function replaceHandlebarsTemplates({
}

const computedTemplateValue = Object.entries(rules).reduce((prev, [key, rule]) => {
const computedValue = logic.getScope(parentID).evaluateValidation(rule, formValues);
const computedValue = logic.getScope(parentID).validate(rule, formValues);
return prev.replaceAll(`{{${key}}}`, computedValue);
}, value);

Expand Down Expand Up @@ -278,8 +278,12 @@ function handleComputedAttribute(logic, formValues, parentID, name) {
];
}
case 'const':
default:
default: {
if (typeof value === 'object' && value.rule) {
return [key, logic.getScope(parentID).validate(value.rule, formValues)];
}
return [key, logic.getScope(parentID).applyComputedValueInField(value, formValues, name)];
}
}
};
}
Expand Down
112 changes: 112 additions & 0 deletions src/tests/jsonLogic.fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,115 @@ export const schemaWithBadOperation = {
},
},
};

export const schemaWithInlineRuleForComputedAttributeWithCopy = {
properties: {
field_a: {
type: 'number',
},
field_b: {
type: 'number',
'x-jsf-logic-computedAttrs': {
title: {
value: 'I need this to work using the {{rule}}.',
rule: {
'+': [{ var: 'field_a' }, 10],
},
},
},
},
},
};

export const schemaWithInlineMultipleRulesForComputedAttributes = {
properties: {
field_a: {
type: 'number',
},
field_b: {
type: 'number',
'x-jsf-logic-computedAttrs': {
description: {
value: 'Must be between {{half_a}} and {{double_a}}.',
half_a: {
'/': [{ var: 'field_a' }, 2],
},
double_a: {
'*': [{ var: 'field_a' }, 2],
},
},
},
},
},
};

export const schemaInlineComputedAttrForTitle = {
properties: {
field_a: {
type: 'number',
},
field_b: {
type: 'number',
'x-jsf-logic-computedAttrs': {
title: {
value: '{{rule}}',
rule: {
'+': [{ var: 'field_a' }, 10],
},
},
},
},
},
};

export const schemaInlineComputedAttrForMaximumMinimumValues = {
properties: {
field_a: {
type: 'number',
default: 0,
},
field_b: {
type: 'number',
'x-jsf-logic-computedAttrs': {
maximum: {
rule: {
'+': [{ var: 'field_a' }, 10],
},
},
minimum: {
rule: {
'-': [{ var: 'field_a' }, 10],
},
},
},
},
},
};

export const schemaWithJSFLogicAndInlineRule = {
properties: {
field_a: {
type: 'number',
},
field_b: {
type: 'number',
'x-jsf-logic-computedAttrs': {
title: {
value: 'Going to use {{rule}} and {{not_inline}}',
rule: {
'+': [{ var: 'field_a' }, 10],
},
},
},
},
},
'x-jsf-logic': {
computedValues: {
not_inline: {
rule: {
'+': [1, 3],
},
},
},
},
};
72 changes: 72 additions & 0 deletions src/tests/jsonLogic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
createSchemaWithRulesOnFieldA,
createSchemaWithThreePropertiesWithRuleOnFieldA,
multiRuleSchema,
schemaInlineComputedAttrForMaximumMinimumValues,
schemaInlineComputedAttrForTitle,
schemaWithBadOperation,
schemaWithComputedAttributeThatDoesntExist,
schemaWithComputedAttributeThatDoesntExistDescription,
Expand All @@ -12,7 +14,10 @@ import {
schemaWithComputedAttributesAndErrorMessages,
schemaWithDeepVarThatDoesNotExist,
schemaWithDeepVarThatDoesNotExistOnFieldset,
schemaWithInlineMultipleRulesForComputedAttributes,
schemaWithInlineRuleForComputedAttributeWithCopy,
schemaWithInlinedRuleOnComputedAttributeThatReferencesUnknownVar,
schemaWithJSFLogicAndInlineRule,
schemaWithMissingComputedValue,
schemaWithMissingRule,
schemaWithNativeAndJSONLogicChecks,
Expand Down Expand Up @@ -344,5 +349,72 @@ describe('jsonLogic: cross-values validations', () => {
expect(fieldB.maximum).toEqual(8);
expect(fieldB.statement).toEqual({ description: 'Must be bigger than 4 and smaller than 8' });
});

it('Use a inline-rule in a schema for a title attribute', () => {
const { fields, handleValidation } = createHeadlessForm(
schemaWithInlineRuleForComputedAttributeWithCopy,
{
strictInputType: false,
}
);
const [, fieldB] = fields;
expect(handleValidation({ field_a: 0, field_b: null }).formErrors).toEqual(undefined);
expect(fieldB.label).toEqual('I need this to work using the 10.');
expect(handleValidation({ field_a: 10 }).formErrors).toEqual(undefined);
expect(fieldB.label).toEqual('I need this to work using the 20.');
});
});

it('Use multiple inline rules with different identifiers', () => {
const { fields, handleValidation } = createHeadlessForm(
schemaWithInlineMultipleRulesForComputedAttributes,
{
strictInputType: false,
}
);
const [, fieldB] = fields;
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toEqual(undefined);
expect(fieldB.description).toEqual('Must be between 5 and 20.');
});

it('Use an inline rule in a schema for a title but it just uses the value', () => {
const { fields, handleValidation } = createHeadlessForm(schemaInlineComputedAttrForTitle, {
strictInputType: false,
});
const [, fieldB] = fields;
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toEqual(undefined);
expect(fieldB.label).toEqual('20');
});

it('Use an inline rule for a minimum, maximum value', () => {
const { fields, handleValidation } = createHeadlessForm(
schemaInlineComputedAttrForMaximumMinimumValues,
{
strictInputType: false,
}
);
const [, fieldB] = fields;
expect(fieldB).toMatchObject({ minimum: -10, maximum: 10 });
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toBeUndefined();
expect(fieldB).toMatchObject({ minimum: 0, maximum: 20 });
expect(handleValidation({ field_a: 50, field_b: 20 }).formErrors).toEqual({
field_b: 'Must be greater or equal to 40',
});
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
expect(handleValidation({ field_a: 50, field_b: 70 }).formErrors).toEqual({
field_b: 'Must be smaller or equal to 60',
});
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
expect(handleValidation({ field_a: 50, field_b: 50 }).formErrors).toBeUndefined();
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
});

it('Mix use of multiple inline rules and an external rule', () => {
const { fields, handleValidation } = createHeadlessForm(schemaWithJSFLogicAndInlineRule, {
strictInputType: false,
});
handleValidation({ field_a: 10 });
const [, fieldB] = fields;
expect(fieldB.label).toEqual('Going to use 20 and 4');
});
});