Skip to content

Commit f72a62c

Browse files
committed
Added tests
Added if then else logic to resolve schemas
1 parent f8c6850 commit f72a62c

File tree

4 files changed

+209
-1
lines changed

4 files changed

+209
-1
lines changed

packages/core/src/utils.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ export function optionsList(schema) {
572572
});
573573
} else {
574574
const altSchemas = schema.oneOf || schema.anyOf;
575-
return altSchemas.map((schema, i) => {
575+
return altSchemas.map(schema => {
576576
const value = toConstant(schema);
577577
const label = schema.title || String(value);
578578
return {
@@ -662,12 +662,37 @@ export function stubExistingAdditionalProperties(
662662
return schema;
663663
}
664664

665+
const _resolveCondition = (schema, rootSchema, formdata) => {
666+
let {
667+
if: expression,
668+
then,
669+
else: otherwise,
670+
...resolvedSchemaLessConditional
671+
} = schema;
672+
673+
const conditionalSchema = isValid(expression, formdata, rootSchema)
674+
? then
675+
: otherwise;
676+
677+
if (conditionalSchema) {
678+
return retrieveSchema(
679+
mergeSchemas(conditionalSchema, resolvedSchemaLessConditional),
680+
rootSchema,
681+
formdata
682+
);
683+
} else {
684+
return retrieveSchema(resolvedSchemaLessConditional, rootSchema, formdata);
685+
}
686+
};
687+
665688
export function resolveSchema(schema, rootSchema = {}, formData = {}) {
666689
if (schema.hasOwnProperty("$ref")) {
667690
return resolveReference(schema, rootSchema, formData);
668691
} else if (schema.hasOwnProperty("dependencies")) {
669692
const resolvedSchema = resolveDependencies(schema, rootSchema, formData);
670693
return retrieveSchema(resolvedSchema, rootSchema, formData);
694+
} else if (schema.hasOwnProperty("if")) {
695+
return _resolveCondition(schema, rootSchema, formData);
671696
} else if (schema.hasOwnProperty("allOf")) {
672697
return {
673698
...schema,

packages/core/test/utils_test.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,142 @@ describe("utils", () => {
23882388
});
23892389
});
23902390
});
2391+
2392+
describe("ifElseThen", () => {
2393+
it("should resolve if, then", () => {
2394+
const schema = {
2395+
type: "object",
2396+
properties: {
2397+
country: {
2398+
default: "United States of America",
2399+
enum: ["United States of America", "Canada"],
2400+
},
2401+
},
2402+
if: {
2403+
properties: { country: { const: "United States of America" } },
2404+
},
2405+
then: {
2406+
properties: { postal_code: { pattern: "[0-9]{5}(-[0-9]{4})?" } },
2407+
},
2408+
else: {
2409+
properties: {
2410+
postal_code: { pattern: "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" },
2411+
},
2412+
},
2413+
};
2414+
const definitions = {};
2415+
const formData = {
2416+
country: "United States of America",
2417+
postal_code: "20500",
2418+
};
2419+
expect(retrieveSchema(schema, { definitions }, formData)).eql({
2420+
type: "object",
2421+
properties: {
2422+
country: {
2423+
default: "United States of America",
2424+
enum: ["United States of America", "Canada"],
2425+
},
2426+
postal_code: { pattern: "[0-9]{5}(-[0-9]{4})?" },
2427+
},
2428+
});
2429+
});
2430+
it("should resolve if, else", () => {
2431+
const schema = {
2432+
type: "object",
2433+
properties: {
2434+
country: {
2435+
default: "United States of America",
2436+
enum: ["United States of America", "Canada"],
2437+
},
2438+
},
2439+
if: {
2440+
properties: { country: { const: "United States of America" } },
2441+
},
2442+
then: {
2443+
properties: { postal_code: { pattern: "[0-9]{5}(-[0-9]{4})?" } },
2444+
},
2445+
else: {
2446+
properties: {
2447+
postal_code: { pattern: "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" },
2448+
},
2449+
},
2450+
};
2451+
const definitions = {};
2452+
const formData = {
2453+
country: "Canada",
2454+
postal_code: "K1M 1M4",
2455+
};
2456+
expect(retrieveSchema(schema, { definitions }, formData)).eql({
2457+
type: "object",
2458+
properties: {
2459+
country: {
2460+
default: "United States of America",
2461+
enum: ["United States of America", "Canada"],
2462+
},
2463+
postal_code: { pattern: "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" },
2464+
},
2465+
});
2466+
});
2467+
it("should resolve multiple conditions", () => {
2468+
const schema = {
2469+
type: "object",
2470+
properties: {
2471+
animal: {
2472+
enum: ["Cat", "Fish"],
2473+
},
2474+
},
2475+
allOf: [
2476+
{
2477+
if: {
2478+
properties: { animal: { const: "Cat" } },
2479+
},
2480+
then: {
2481+
properties: {
2482+
food: { type: "string", enum: ["meat", "grass", "fish"] },
2483+
},
2484+
},
2485+
required: ["food"],
2486+
},
2487+
{
2488+
if: {
2489+
properties: { animal: { const: "Fish" } },
2490+
},
2491+
then: {
2492+
properties: {
2493+
food: {
2494+
type: "string",
2495+
enum: ["insect", "worms"],
2496+
},
2497+
water: {
2498+
type: "string",
2499+
enum: ["lake", "sea"],
2500+
},
2501+
},
2502+
required: ["food", "water"],
2503+
},
2504+
},
2505+
{
2506+
required: ["animal"],
2507+
},
2508+
],
2509+
};
2510+
const definitions = {};
2511+
const formData = {
2512+
animal: "Cat",
2513+
};
2514+
2515+
expect(retrieveSchema(schema, { definitions }, formData)).eql({
2516+
type: "object",
2517+
properties: {
2518+
animal: {
2519+
enum: ["Cat", "Fish"],
2520+
},
2521+
food: { type: "string", enum: ["meat", "grass", "fish"] },
2522+
},
2523+
required: ["animal", "food"],
2524+
});
2525+
});
2526+
});
23912527
});
23922528

23932529
describe("shouldRender", () => {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module.exports = {
2+
schema: {
3+
type: "object",
4+
properties: {
5+
animal: {
6+
enum: ["Cat", "Fish"],
7+
},
8+
},
9+
allOf: [
10+
{
11+
if: {
12+
properties: { animal: { const: "Cat" } },
13+
},
14+
then: {
15+
properties: {
16+
food: { type: "string", enum: ["meat", "grass", "fish"] },
17+
},
18+
required: ["food"],
19+
},
20+
},
21+
{
22+
if: {
23+
properties: { animal: { const: "Fish" } },
24+
},
25+
then: {
26+
properties: {
27+
food: {
28+
type: "string",
29+
enum: ["insect", "worms"],
30+
},
31+
water: {
32+
type: "string",
33+
enum: ["lake", "sea"],
34+
},
35+
},
36+
required: ["food", "water"],
37+
},
38+
},
39+
{
40+
required: ["animal"],
41+
},
42+
],
43+
},
44+
formData: {},
45+
};

packages/playground/src/samples/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import nullable from "./nullable";
2626
import nullField from "./null";
2727
import errorSchema from "./errorSchema";
2828
import defaults from "./defaults";
29+
import ifElseThen from "./ifElseThen";
2930

3031
export const samples = {
3132
Simple: simple,
@@ -52,6 +53,7 @@ export const samples = {
5253
"Any Of": anyOf,
5354
"One Of": oneOf,
5455
"All Of": allOf,
56+
"If Else Then": ifElseThen,
5557
"Null fields": nullField,
5658
Nullable: nullable,
5759
ErrorSchema: errorSchema,

0 commit comments

Comments
 (0)