Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dereference option schemas before giving it as props to anyOf and oneOf #2270

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
5 changes: 4 additions & 1 deletion packages/core/src/components/fields/MultiSchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ class AnyOfField extends Component {
}

const enumOptions = options.map((option, index) => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to instead just set option = retrieveSchema(option, registry.rootSchema) earlier in this function, so that everything related to the option is already dereferenced (this might fix other bugs with oneOf / refs)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I guess I'll update the samples as well then since this will ignore any title that is a sibling to a $ref.

Actually; if you look the reference sample. There you have a reference to the same schema but with different titles. That wouldn't be possible if we changed like above. We could implement your suggestion but still look for title in the $ref schema.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the logic to SchemaField instead, so props.options are now dereferenced. That also fixes #1819

label: option.title || `Option ${index + 1}`,
label:
option.title ||
retrieveSchema(option, registry.rootSchema).title ||
`Option ${index + 1}`,
value: index,
}));

Expand Down
46 changes: 46 additions & 0 deletions packages/core/test/anyOf_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,52 @@ describe("anyOf", () => {
});
});

it("should use title from refs schema before using fallback generated value as title", () => {
const schema = {
definitions: {
address: {
title: "Address",
type: "object",
properties: {
street: {
title: "Street",
type: "string",
},
},
},
person: {
title: "Person",
type: "object",
properties: {
name: {
title: "Name",
type: "string",
},
},
},
nested: {
$ref: "#/definitions/person",
},
},
anyOf: [
{
$ref: "#/definitions/address",
},
{
$ref: "#/definitions/nested",
},
],
};

const { node } = createFormComponent({
schema,
});

let options = node.querySelectorAll("option");
expect(options[0].firstChild.nodeValue).eql("Address");
expect(options[1].firstChild.nodeValue).eql("Person");
});

describe("Arrays", () => {
it("should correctly render form inputs for anyOf inside array items", () => {
const schema = {
Expand Down