Skip to content

Commit 409e039

Browse files
authored
Merge pull request #418 from microsoft/dm/componentreference
Collapsed components that are references
2 parents 9d4e6a4 + 9e8a5da commit 409e039

File tree

4 files changed

+211
-4
lines changed

4 files changed

+211
-4
lines changed

src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,15 @@ public override Dictionary<string, T> CreateMapWithReference<T>(
100100
{
101101
return null; // Body Parameters shouldn't be converted to Parameters
102102
}
103-
entry.value.Reference = new OpenApiReference()
103+
// If the component isn't a reference to another component, then point it to itself.
104+
if (entry.value.Reference == null)
104105
{
105-
Type = referenceType,
106-
Id = entry.key
107-
};
106+
entry.value.Reference = new OpenApiReference()
107+
{
108+
Type = referenceType,
109+
Id = entry.key
110+
};
111+
}
108112
return entry;
109113
}
110114
);

test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<SignAssembly>true</SignAssembly>
1313
<AssemblyOriginatorKeyFile>..\..\src\Microsoft.OpenApi.snk</AssemblyOriginatorKeyFile>
1414
</PropertyGroup>
15+
<ItemGroup>
16+
<None Remove="V2Tests\Samples\ComponentRootReference.json" />
17+
</ItemGroup>
1518
<ItemGroup>
1619
<EmbeddedResource Include="OpenApiReaderTests\Samples\unsupported.v1.yaml">
1720
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
@@ -25,6 +28,9 @@
2528
<EmbeddedResource Include="V2Tests\Samples\basic.v3.yaml">
2629
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
2730
</EmbeddedResource>
31+
<EmbeddedResource Include="V2Tests\Samples\ComponentRootReference.json">
32+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
33+
</EmbeddedResource>
2834
<EmbeddedResource Include="V2Tests\Samples\minimal.v2.yaml">
2935
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
3036
</EmbeddedResource>

test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,5 +419,24 @@ public void ShouldAssignSchemaToAllResponses()
419419
xml.Schema.ShouldBeEquivalentTo(targetSchema);
420420
}
421421
}
422+
423+
424+
[Fact]
425+
public void ShouldAllowComponentsThatJustContainAReference()
426+
{
427+
using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "ComponentRootReference.json")))
428+
{
429+
OpenApiStreamReader reader = new OpenApiStreamReader();
430+
OpenApiDocument doc = reader.Read(stream, out OpenApiDiagnostic diags);
431+
OpenApiSchema schema1 = doc.Components.Schemas["AllPets"];
432+
Assert.False(schema1.UnresolvedReference);
433+
OpenApiSchema schema2 = (OpenApiSchema)doc.ResolveReference(schema1.Reference);
434+
if (schema2.UnresolvedReference && schema1.Reference.Id == schema2.Reference.Id)
435+
{
436+
// detected a cycle - this code gets triggered
437+
Assert.True(false, "A cycle should not be detected");
438+
}
439+
}
440+
}
422441
}
423442
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
{
2+
"openapi": "3.0.0",
3+
"info": {
4+
"version": "1.0.0",
5+
"title": "Swagger Petstore",
6+
"license": {
7+
"name": "MIT"
8+
}
9+
},
10+
"servers": [
11+
{
12+
"url": "http://petstore.swagger.io/v1"
13+
}
14+
],
15+
"paths": {
16+
"/pets": {
17+
"get": {
18+
"summary": "List all pets",
19+
"operationId": "listPets",
20+
"tags": [
21+
"pets"
22+
],
23+
"parameters": [
24+
{
25+
"name": "limit",
26+
"in": "query",
27+
"description": "How many items to return at one time (max 100)",
28+
"required": false,
29+
"schema": {
30+
"type": "integer",
31+
"format": "int32"
32+
}
33+
}
34+
],
35+
"responses": {
36+
"200": {
37+
"description": "A paged array of pets",
38+
"headers": {
39+
"x-next": {
40+
"description": "A link to the next page of responses",
41+
"schema": {
42+
"type": "string"
43+
}
44+
}
45+
},
46+
"content": {
47+
"application/json": {
48+
"schema": {
49+
"$ref": "#/components/schemas/AllPets"
50+
}
51+
}
52+
}
53+
},
54+
"default": {
55+
"description": "unexpected error",
56+
"content": {
57+
"application/json": {
58+
"schema": {
59+
"$ref": "#/components/schemas/Error"
60+
}
61+
}
62+
}
63+
}
64+
}
65+
},
66+
"post": {
67+
"summary": "Create a pet",
68+
"operationId": "createPets",
69+
"tags": [
70+
"pets"
71+
],
72+
"responses": {
73+
"201": {
74+
"description": "Null response"
75+
},
76+
"default": {
77+
"description": "unexpected error",
78+
"content": {
79+
"application/json": {
80+
"schema": {
81+
"$ref": "#/components/schemas/Error"
82+
}
83+
}
84+
}
85+
}
86+
}
87+
}
88+
},
89+
"/pets/{petId}": {
90+
"get": {
91+
"summary": "Info for a specific pet",
92+
"operationId": "showPetById",
93+
"tags": [
94+
"pets"
95+
],
96+
"parameters": [
97+
{
98+
"name": "petId",
99+
"in": "path",
100+
"required": true,
101+
"description": "The id of the pet to retrieve",
102+
"schema": {
103+
"type": "string"
104+
}
105+
}
106+
],
107+
"responses": {
108+
"200": {
109+
"description": "Expected response to a valid request",
110+
"content": {
111+
"application/json": {
112+
"schema": {
113+
"$ref": "#/components/schemas/Pets"
114+
}
115+
}
116+
}
117+
},
118+
"default": {
119+
"description": "unexpected error",
120+
"content": {
121+
"application/json": {
122+
"schema": {
123+
"$ref": "#/components/schemas/Error"
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
},
132+
"components": {
133+
"schemas": {
134+
"Pet": {
135+
"required": [
136+
"id",
137+
"name"
138+
],
139+
"properties": {
140+
"id": {
141+
"type": "integer",
142+
"format": "int64"
143+
},
144+
"name": {
145+
"type": "string"
146+
},
147+
"tag": {
148+
"type": "string"
149+
}
150+
}
151+
},
152+
"Pets": {
153+
"type": "array",
154+
"items": {
155+
"$ref": "#/components/schemas/Pet"
156+
}
157+
},
158+
"AllPets": {
159+
"$ref": "#/components/schemas/Pets"
160+
},
161+
"Error": {
162+
"required": [
163+
"code",
164+
"message"
165+
],
166+
"properties": {
167+
"code": {
168+
"type": "integer",
169+
"format": "int32"
170+
},
171+
"message": {
172+
"type": "string"
173+
}
174+
}
175+
}
176+
}
177+
}
178+
}

0 commit comments

Comments
 (0)