Skip to content

insert_property_defaults does not work for nested schemas (eg. oneOf) #94

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

Closed
madejejej opened this issue Aug 31, 2021 · 2 comments
Closed

Comments

@madejejej
Copy link

Hi, first of all, thank you for this wonderful gem!

I tried to set up the smallest possible reproduction script. It seems that the workaround to this issue is to use a top-level if-then-else clause, but it makes it harder to use nested schemas.

# frozen_string_literal: true

require 'json_schemer'
require 'json'

schema_def = {
  "$schema" => "http://json-schema.org/draft-07/schema#",
  "type" => "object",
  "oneOf" => [
    "$ref" => "#/definitions/a"
  ],
  "required" => ["field", "default_field"],
  "definitions" => {
    "a" => {
      "properties" => {
        "field" => { "type" => "string", "const" => "a" },
        "default_field" => { "enum" => ["f1", "f2"], "default" => "f1" },
      }
    }
  }
}.to_json

schema_def2 = {
  "$schema" => "http://json-schema.org/draft-07/schema#",
  "type" => "object",
  "required" => ["field", "default_field"],
  "properties" => {
    "field" => { "type" => "string", "const" => "a" },
    "default_field" => { "enum" => ["f1", "f2"], "default" => "f1" },
  }
}.to_json

schema = JSONSchemer.schema(schema_def, insert_property_defaults: true)
schema2 = JSONSchemer.schema(schema_def2, insert_property_defaults: true)

params = { "field" => "a" }
params2 = params.dup

schema.valid?(params) 
schema2.valid?(params2)
pp params # => {"field"=>"a"}
pp params2 # => {"field"=>"a", "default_field"=>"f1"}
@davishmcclurg
Copy link
Owner

Thanks for the report @madejejej! The behavior you're seeing is currently expected: #59

The tricky part here is knowing which default to use if multiple nested schemas are valid. For simplicity's sake, we decided to disable inserting defaults for nested schemas, but let me know if you can think of a better solution.

davishmcclurg added a commit that referenced this issue Jul 10, 2023
This uses the validation `Result` tree to support inserting property
defaults in conditional subschemas. It looks through the results for
"properties" keywords that contain defaults, groups them by instance and
property, tracks if they're in a valid subtree, and passes them to the
resolver to do the actual insertion. The default resolver inserts the
default value if there's only one available or if there's only one
unique one from a valid subtree. If any defaults are inserted, the
validation is run again and that result is returned.

I got the test examples from the issues below. I think the default
behavior should make sense in most cases. Otherwise, a custom
`property_default_resolver` can be provided. The only special case is
that results from `not` subschemas are dropped. It might make more sense
to handle that in the resolver, but for now I think it's ok.

Related:

- #53
- #94
davishmcclurg added a commit that referenced this issue Jul 23, 2023
This uses the validation `Result` tree to support inserting property
defaults in conditional subschemas. It looks through the results for
"properties" keywords that contain defaults, groups them by instance and
property, tracks if they're in a valid subtree, and passes them to the
resolver to do the actual insertion. The default resolver inserts the
default value if there's only one available or if there's only one
unique one from a valid subtree. If any defaults are inserted, the
validation is run again and that result is returned.

I got the test examples from the issues below. I think the default
behavior should make sense in most cases. Otherwise, a custom
`property_default_resolver` can be provided. The only special case is
that results from `not` subschemas are dropped. It might make more sense
to handle that in the resolver, but for now I think it's ok.

Related:

- #53
- #94
davishmcclurg added a commit that referenced this issue Jul 27, 2023
This uses the validation `Result` tree to support inserting property
defaults in conditional subschemas. It looks through the results for
"properties" keywords that contain defaults, groups them by instance and
property, tracks if they're in a valid subtree, and passes them to the
resolver to do the actual insertion. The default resolver inserts the
default value if there's only one available or if there's only one
unique one from a valid subtree. If any defaults are inserted, the
validation is run again and that result is returned.

I got the test examples from the issues below. I think the default
behavior should make sense in most cases. Otherwise, a custom
`property_default_resolver` can be provided. The only special case is
that results from `not` subschemas are dropped. It might make more sense
to handle that in the resolver, but for now I think it's ok.

Related:

- #53
- #94
davishmcclurg added a commit that referenced this issue Jul 31, 2023
Features:

- Draft 2020-12 support
- Draft 2019-09 support
- Output formats
- Annotations
- OpenAPI 3.1 schema support
- OpenAPI 3.0 schema support
- `insert_property_defaults` in conditional subschemas
- Error messages
- Non-string schema and data keys

See individual commits for more details.

Closes:

- #27
- #44
- #55
- #91
- #94
- #116
- #123
davishmcclurg added a commit that referenced this issue Aug 1, 2023
Features:

- Draft 2020-12 support
- Draft 2019-09 support
- Output formats
- Annotations
- OpenAPI 3.1 schema support
- OpenAPI 3.0 schema support
- `insert_property_defaults` in conditional subschemas
- Error messages
- Non-string schema and data keys

See individual commits for more details.

Closes:

- #27
- #44
- #55
- #91
- #94
- #116
- #123
@davishmcclurg davishmcclurg mentioned this issue Aug 1, 2023
davishmcclurg added a commit that referenced this issue Aug 19, 2023
This uses the validation `Result` tree to support inserting property
defaults in conditional subschemas. It looks through the results for
"properties" keywords that contain defaults, groups them by instance and
property, tracks if they're in a valid subtree, and passes them to the
resolver to do the actual insertion. The default resolver inserts the
default value if there's only one available or if there's only one
unique one from a valid subtree. If any defaults are inserted, the
validation is run again and that result is returned.

I got the test examples from the issues below. I think the default
behavior should make sense in most cases. Otherwise, a custom
`property_default_resolver` can be provided. The only special case is
that results from `not` subschemas are dropped. It might make more sense
to handle that in the resolver, but for now I think it's ok.

Related:

- #53
- #94
davishmcclurg added a commit that referenced this issue Aug 19, 2023
Features:

- Draft 2020-12 support
- Draft 2019-09 support
- Output formats
- Annotations
- OpenAPI 3.1 schema support
- OpenAPI 3.0 schema support
- `insert_property_defaults` in conditional subschemas
- Error messages
- Non-string schema and data keys
- Schema bundling

See individual commits for more details.

Closes:

- #27
- #44
- #55
- #91
- #94
- #116
- #123
- #136
davishmcclurg added a commit that referenced this issue Aug 20, 2023
Features:

- Draft 2020-12 support
- Draft 2019-09 support
- Output formats
- Annotations
- OpenAPI 3.1 schema support
- OpenAPI 3.0 schema support
- `insert_property_defaults` in conditional subschemas
- Error messages
- Non-string schema and data keys
- Schema bundling

See individual commits for more details.

Closes:

- #27
- #44
- #55
- #91
- #94
- #116
- #123
- #136
@davishmcclurg
Copy link
Owner

Released in 2.0.0. More info in the commit: aaafab1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants