From 8d8c915bbfd06363286fc6cd4138554d961116da Mon Sep 17 00:00:00 2001 From: Qingqi Shi Date: Tue, 23 Mar 2021 17:11:32 +0000 Subject: [PATCH 1/4] fix: oneOf anyOf default value always using first option --- packages/core/src/utils.js | 4 ++-- packages/core/test/oneOf_test.js | 37 ++++++++++++++++++++++++++++++++ packages/core/test/utils_test.js | 34 +++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 7bece94742..404843543b 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -220,10 +220,10 @@ function computeDefaults( ); } else if ("oneOf" in schema) { schema = - schema.oneOf[getMatchingOption(undefined, schema.oneOf, rootSchema)]; + schema.oneOf[getMatchingOption(formData, schema.oneOf, rootSchema)]; } else if ("anyOf" in schema) { schema = - schema.anyOf[getMatchingOption(undefined, schema.anyOf, rootSchema)]; + schema.anyOf[getMatchingOption(formData, schema.anyOf, rootSchema)]; } // Not defaults defined for this node, fallback to generic typed ones. diff --git a/packages/core/test/oneOf_test.js b/packages/core/test/oneOf_test.js index 2060d99052..bc69fe76be 100644 --- a/packages/core/test/oneOf_test.js +++ b/packages/core/test/oneOf_test.js @@ -503,6 +503,43 @@ describe("oneOf", () => { expect(node.querySelector("input#root").value).eql(""); }); + it("should use only the selected option when generating default values", () => { + const schema = { + type: "object", + oneOf: [ + { + additionalProperties: false, + properties: { lorem: { type: "object" } }, + }, + { + additionalProperties: false, + properties: { ipsum: { type: "object" } }, + }, + { + additionalProperties: false, + properties: { pyot: { type: "object" } }, + }, + ], + }; + + const { node, onChange } = createFormComponent({ + schema, + formData: { lorem: {} }, + }); + + const $select = node.querySelector("select"); + + Simulate.change($select, { + target: { value: $select.options[1].value }, + }); + + expect($select.value).eql("1"); + + sinon.assert.calledWithMatch(onChange.lastCall, { + formData: { lorem: undefined, ipsum: {} }, + }); + }); + describe("Arrays", () => { it("should correctly render mixed types for oneOf inside array items", () => { const schema = { diff --git a/packages/core/test/utils_test.js b/packages/core/test/utils_test.js index 200ce167cc..22ca54ad0a 100644 --- a/packages/core/test/utils_test.js +++ b/packages/core/test/utils_test.js @@ -656,6 +656,23 @@ describe("utils", () => { }); }); + it("should populate defaults for oneOf second option", () => { + const schema = { + type: "object", + properties: { + test: { + oneOf: [ + { properties: { a: { type: "string", default: "a" } } }, + { properties: { b: { type: "string", default: "b" } } }, + ], + }, + }, + }; + expect(getDefaultFormState(schema, { test: { b: "b" } })).eql({ + test: { b: "b" }, + }); + }); + it("should populate defaults for oneOf when 'type': 'object' is missing", () => { const schema = { type: "object", @@ -753,6 +770,23 @@ describe("utils", () => { }); }); + it("should populate defaults for anyOf second option", () => { + const schema = { + type: "object", + properties: { + test: { + anyOf: [ + { properties: { a: { type: "string", default: "a" } } }, + { properties: { b: { type: "string", default: "b" } } }, + ], + }, + }, + }; + expect(getDefaultFormState(schema, { test: { b: "b" } })).eql({ + test: { b: "b" }, + }); + }); + it("should populate nested default values for anyOf", () => { const schema = { type: "object", From 14e75b14104a84d42f1e026f8ea0f84ca6399ccd Mon Sep 17 00:00:00 2001 From: Qingqi Shi Date: Wed, 21 Apr 2021 20:30:16 +0100 Subject: [PATCH 2/4] fix: use undefined when formData is empty object --- packages/core/src/utils.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index f770b28922..6d9e850eed 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -220,10 +220,22 @@ function computeDefaults( ); } else if ("oneOf" in schema) { schema = - schema.oneOf[getMatchingOption(formData, schema.oneOf, rootSchema)]; + schema.oneOf[ + getMatchingOption( + JSON.stringify(formData) !== "{}" ? formData : undefined, + schema.oneOf, + rootSchema + ) + ]; } else if ("anyOf" in schema) { schema = - schema.anyOf[getMatchingOption(formData, schema.anyOf, rootSchema)]; + schema.anyOf[ + getMatchingOption( + JSON.stringify(formData) !== "{}" ? formData : undefined, + schema.anyOf, + rootSchema + ) + ]; } // Not defaults defined for this node, fallback to generic typed ones. From 2536be083ccfe55e044f7b2dadb542a5be3ea521 Mon Sep 17 00:00:00 2001 From: Qingqi Shi Date: Wed, 21 Apr 2021 22:29:18 +0100 Subject: [PATCH 3/4] Use lodash isEmpty instead of JSON.stringify --- packages/core/src/utils.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 6d9e850eed..e6597f15e5 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -3,6 +3,7 @@ import * as ReactIs from "react-is"; import mergeAllOf from "json-schema-merge-allof"; import fill from "core-js-pure/features/array/fill"; import union from "lodash/union"; +import isEmpty from "lodash/isEmpty"; import jsonpointer from "jsonpointer"; import fields from "./components/fields"; import widgets from "./components/widgets"; @@ -222,7 +223,7 @@ function computeDefaults( schema = schema.oneOf[ getMatchingOption( - JSON.stringify(formData) !== "{}" ? formData : undefined, + isEmpty(formData) ? formData : undefined, schema.oneOf, rootSchema ) @@ -231,7 +232,7 @@ function computeDefaults( schema = schema.anyOf[ getMatchingOption( - JSON.stringify(formData) !== "{}" ? formData : undefined, + isEmpty(formData) ? formData : undefined, schema.anyOf, rootSchema ) From 440132ec7ca64f72726729ce6a2e0a9e82ac9d4a Mon Sep 17 00:00:00 2001 From: Qingqi Shi Date: Wed, 21 Apr 2021 22:47:11 +0100 Subject: [PATCH 4/4] Fix boo boo --- packages/core/src/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index e6597f15e5..c0a20e65ea 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -223,7 +223,7 @@ function computeDefaults( schema = schema.oneOf[ getMatchingOption( - isEmpty(formData) ? formData : undefined, + isEmpty(formData) ? undefined : formData, schema.oneOf, rootSchema ) @@ -232,7 +232,7 @@ function computeDefaults( schema = schema.anyOf[ getMatchingOption( - isEmpty(formData) ? formData : undefined, + isEmpty(formData) ? undefined : formData, schema.anyOf, rootSchema )