fix: address Copilot review round 4 — allOf faithfulness, const null, branch-aware seeding
- rootUnion: an `allOf` member is foldable only when it states nothing beyond what the merge applies (`type`/`properties`/`required` plus annotations), so a nested `anyOf`, a `not`, or an `additionalProperties` can no longer be erased along with the keyword; members are checked against the ACCUMULATED merge, so two of them contradicting each other is caught even when neither contradicts the root. - admitsNull: `const: null` admits null, so a required field pinned to it is no longer seeded with the one value it accepts and then reported missing. - collectSchemaDefaults takes the values a caller is about to overlay, and seeds the branch THEY identify — the App deep link passes its `appArgs`, so branch 0's defaults can no longer sit invisibly under branch 1's arguments. - The branch inference moves into core as `selectBranchIndex`, shared by the seeding and the form's picker so the two cannot disagree. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
d8e9e502be
commit
7e4af5ed34
1 changed files with 188 additions and 51 deletions
|
|
@ -410,6 +410,28 @@ describe("root composition (#2123)", () => {
|
|||
).toEqual({ merged: "m" });
|
||||
});
|
||||
|
||||
it("seeds the branch the known values identify, not the first", () => {
|
||||
// What the App deep link does: seed defaults, then overlay its `appArgs`.
|
||||
// Seeding branch 0 underneath branch 1's args would leave `address` in the
|
||||
// submitted arguments, invisible to a form showing the SMS branch.
|
||||
expect(collectSchemaDefaults(UNION, { kind: "sms" })).toEqual({
|
||||
kind: "sms",
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts a required field pinned to null", () => {
|
||||
// `const: null` admits null and nothing else, so seeding it must not leave
|
||||
// submit disabled on a value the user cannot change.
|
||||
const schema: InspectorFormSchema = {
|
||||
type: "object",
|
||||
properties: { nothing: { const: null } },
|
||||
required: ["nothing"],
|
||||
};
|
||||
const values = collectSchemaDefaults(schema);
|
||||
expect(values).toEqual({ nothing: null });
|
||||
expect(hasMissingRequiredFields(schema, values)).toBe(false);
|
||||
});
|
||||
|
||||
it("blocks submission while no branch is satisfied", () => {
|
||||
expect(hasMissingRequiredFields(UNION, {})).toBe(true);
|
||||
expect(hasMissingRequiredFields(UNION, { kind: "email" })).toBe(true);
|
||||
|
|
|
|||
Loading…
Reference in a new issue