Commit c79a83e
fix: preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+ (#2896)
* fix: preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+
OpenApiV31Deserializer.LoadSchema short-circuits on $ref before
ParseMap, so sibling keywords ($defs, $dynamicAnchor, $dynamicRef,
$id, $anchor, $vocabulary, $comment) were never parsed into the
object model. This made Pattern B (generic template + binding)
unimplementable for any tool built on Microsoft.OpenApi.
The fix mirrors the #2369 annotation-sibling pattern across four
coordinated changes:
- Parser extraction in SetAdditional31MetadataFromMapNode (scalars
+ $vocabulary) and LoadSchema ($defs, which needs LoadSchema for
nested schema materialization)
- Storage: 7 new properties on JsonSchemaReference
- Accessor overrides on OpenApiSchemaReference (Reference.X ??
Target?.X)
- Serialization in SerializeAdditionalV3XProperties
Version-safe by call-site separation: SetAdditional31MetadataFromMapNode
is only reachable from V31/V32 LoadSchema, never V3.
Ref: #2895
* fix: align scalar extraction pattern with existing Title convention
Switch from GetPropertyValueFromNode(...) ?? X to the
if (!string.IsNullOrEmpty(...)) pattern used by the existing
Title/annotation extraction, for reviewer consistency.
Also add test for the allOf-based binding variant where $defs
sits inside allOf[0] and the nested schema has $ref +
$dynamicAnchor (the pattern from the blocker analysis).
Ref: #2895
* fix: add $schema sibling preservation and fix $defs location tracking
Add $schema dialect URI as a sibling override on JsonSchemaReference,
matching the pattern used for the other JSON Schema 2020-12 keywords.
Also fix the $defs parsing loop in V31/V32 LoadSchema to push/pop
the parsing context location stack (context.StartObject/EndObject)
around each LoadSchema call, mirroring JsonNodeHelper.CreateMap.
Without this, nested schemas inside a reference's $defs get
incorrect nodeLocation values, breaking relative $ref resolution
and source-pointer diagnostics.
Adds a scalar round-trip test covering $id, $schema, $comment,
$anchor, $dynamicRef serialization.
Ref: #2895
* test: add V32 sibling preservation tests mirroring V31
Mirrors the 6 V31 sibling preservation tests in V32Tests, using
SerializeAsV32 for the round-trip tests. Parse tests are identical
since both versions share the same LoadSchema +
SetAdditional31MetadataFromMapNode path.
Ref: #2895
* fix: don't suppress target values when sibling collections are empty
An empty $defs: {} or $vocabulary: {} sibling would assign an empty
collection to the reference, blocking fallthrough to Target via the
?? coalescing getter. Only assign when the collection has entries.
Ref: #2895
* test: add empty-collection fallthrough, 3.0 version safety, and $vocabulary round-trip tests
- Empty $defs: {} / $vocabulary: {} must fall through to Target
(guards the .Count > 0 fix in commit 4666f2c)
- 3.0 document with $ref + siblings must drop siblings per spec
(guards the version-safety guarantee)
- $vocabulary round-trip (parse -> serialize -> parse)
Ref: #2895
* test: add CreateShallowCopy test to cover JsonSchemaReference copy constructor
Achieves 100% diff coverage on all changed files.
Ref: #2895
* fix: address PR review feedback
- Replace OpenApiSpecVersion branching with Action<IOpenApiWriter,
IOpenApiSerializable> callback for future-proof serialization
- Add $defs context segment + try/catch error handling in V31/V32
$defs parsing (mirrors ParseField error pattern)
- Convert all FluentAssertions calls to Assert.* per repo convention
Ref: #2896
* chore: refactor to avoid duplication iterating on schemas
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
* tests: reduce the usage of bang operators
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
* tests: use assertions instead of null forgiving to make investigations easier
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
---------
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>1 parent 20191c7 commit c79a83e
13 files changed
Lines changed: 702 additions & 132 deletions
File tree
- performance/benchmark/BenchmarkDotNet.Artifacts/results
- src/Microsoft.OpenApi
- Models
- References
- Reader/V31
- test/Microsoft.OpenApi.Readers.Tests/V31Tests
Lines changed: 10 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
Lines changed: 6 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
Lines changed: 11 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 32 additions & 32 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
0 commit comments