Skip to content

Commit cd5b900

Browse files
irvinesundaybaywet
andauthored
Replaces instances of anyOf to oneOf (#264)
* Change from anyOf to oneOf * Update tests * Remove whitespace * Make components for floating point numbers * Update integration tests * Remove Format values from root schema * Update integration files * Fix integration files * Fix retrieval of type name * Update tests * Update src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiSchemaGenerator.cs Co-authored-by: Vincent Biret <[email protected]> * Fix PR review suggestion * Revert integration file to original * Resolve integration file * Fix integration file * Update integration test files * Update test * Update schema generator to account for v2 serializations * Update lib. version and tests and remove format from root schema * Update integration test files * Remove unnecessary variable assignment * Add and use constants * Update lib version * Update integration test files * Remove collectionFormat from integration test files This is because `Explode = false` for the OData query parameters. Co-authored-by: Vincent Biret <[email protected]>
1 parent a850df6 commit cd5b900

36 files changed

+1962
-173
lines changed

src/Microsoft.OpenApi.OData.Reader/Common/Constants.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ internal static class Constants
129129
/// Name used for reference request PUT body.
130130
/// </summary>
131131
public static string ReferencePutRequestBodyName = "refPutBody";
132+
133+
/// <summary>
134+
/// Name used to reference INF, -INF and NaN
135+
/// </summary>
136+
public static string ReferenceNumericName = "ReferenceNumeric";
132137

133138
/// <summary>
134139
/// The odata type name.
@@ -149,5 +154,25 @@ internal static class Constants
149154
/// string type
150155
/// </summary>
151156
public static string StringType = "string";
157+
158+
/// <summary>
159+
/// integer type
160+
/// </summary>
161+
public static string IntegerType = "integer";
162+
163+
/// <summary>
164+
/// number type
165+
/// </summary>
166+
public static string NumberType = "number";
167+
168+
/// <summary>
169+
/// int64 format
170+
/// </summary>
171+
public static string Int64Format = "int64";
172+
173+
/// <summary>
174+
/// decimal format
175+
/// </summary>
176+
public static string DecimalFormat = "decimal";
152177
}
153178
}

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiEdmTypeSchemaGenerator.cs

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -147,132 +147,130 @@ public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiv
147147
OneOf = null,
148148
AnyOf = null
149149
};
150+
150151
switch (primitiveType.PrimitiveKind)
151152
{
152153
case EdmPrimitiveTypeKind.Binary: // binary
153-
schema.Type = "string";
154+
schema.Type = Constants.StringType;
154155
schema.Format = "base64url";
155156
break;
156157
case EdmPrimitiveTypeKind.Boolean: // boolean
157158
schema.Type = "boolean";
158159
schema.Default = new OpenApiBoolean(false);
159160
break;
160161
case EdmPrimitiveTypeKind.Byte: // byte
161-
schema.Type = "integer";
162+
schema.Type = Constants.IntegerType;
162163
schema.Format = "uint8";
163164
break;
164165
case EdmPrimitiveTypeKind.DateTimeOffset: // datetime offset
165-
schema.Type = "string";
166+
schema.Type = Constants.StringType;
166167
schema.Format = "date-time";
167168
schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$";
168169
break;
169170
case EdmPrimitiveTypeKind.Decimal: // decimal
170171
if (context.Settings.IEEE754Compatible)
171172
{
172-
schema.AnyOf = new List<OpenApiSchema>
173+
schema.OneOf = new List<OpenApiSchema>
173174
{
174-
new OpenApiSchema { Type = "number" },
175-
new OpenApiSchema { Type = "string" },
175+
new OpenApiSchema { Type = Constants.NumberType, Format = Constants.DecimalFormat },
176+
new OpenApiSchema { Type = Constants.StringType },
176177
};
177178
}
178179
else
179180
{
180-
schema.Type = "number";
181+
schema.Type = Constants.NumberType;
182+
schema.Format = Constants.DecimalFormat;
181183
}
182-
schema.Format = "decimal";
183184
break;
184185
case EdmPrimitiveTypeKind.Double: // double
185-
schema.AnyOf = new List<OpenApiSchema>
186+
schema.OneOf = new List<OpenApiSchema>
186187
{
187-
new OpenApiSchema { Type = "number" },
188-
new OpenApiSchema { Type = "string" },
188+
new OpenApiSchema { Type = Constants.NumberType, Format = "double" },
189+
new OpenApiSchema { Type = Constants.StringType },
189190
new OpenApiSchema
190191
{
191-
Enum = new List<IOpenApiAny>
192+
UnresolvedReference = true,
193+
Reference = new OpenApiReference
192194
{
193-
new OpenApiString("-INF"),
194-
new OpenApiString("INF"),
195-
new OpenApiString("NaN")
195+
Type = ReferenceType.Schema,
196+
Id = Constants.ReferenceNumericName
196197
}
197198
}
198199
};
199-
schema.Format = "double";
200200
break;
201201
case EdmPrimitiveTypeKind.Single: // single
202-
schema.AnyOf = new List<OpenApiSchema>
202+
schema.OneOf = new List<OpenApiSchema>
203203
{
204-
new OpenApiSchema { Type = "number" },
205-
new OpenApiSchema { Type = "string" },
204+
new OpenApiSchema { Type = Constants.NumberType, Format = "float" },
205+
new OpenApiSchema { Type = Constants.StringType },
206206
new OpenApiSchema
207207
{
208-
Enum = new List<IOpenApiAny>
208+
UnresolvedReference = true,
209+
Reference = new OpenApiReference
209210
{
210-
new OpenApiString("-INF"),
211-
new OpenApiString("INF"),
212-
new OpenApiString("NaN")
211+
Type = ReferenceType.Schema,
212+
Id = Constants.ReferenceNumericName
213213
}
214214
}
215215
};
216-
schema.Format = "float";
217216
break;
218217
case EdmPrimitiveTypeKind.Guid: // guid
219-
schema.Type = "string";
218+
schema.Type = Constants.StringType;
220219
schema.Format = "uuid";
221220
schema.Pattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";
222221
break;
223222
case EdmPrimitiveTypeKind.Int16:
224-
schema.Type = "integer";
223+
schema.Type = Constants.IntegerType;
225224
schema.Format = "int16";
226225
schema.Minimum = Int16.MinValue; // -32768
227226
schema.Maximum = Int16.MaxValue; // 32767
228227
break;
229228
case EdmPrimitiveTypeKind.Int32:
230-
schema.Type = "integer";
229+
schema.Type = Constants.IntegerType;
231230
schema.Format = "int32";
232231
schema.Minimum = Int32.MinValue; // -2147483648
233232
schema.Maximum = Int32.MaxValue; // 2147483647
234233
break;
235234
case EdmPrimitiveTypeKind.Int64:
236235
if (context.Settings.IEEE754Compatible)
237236
{
238-
schema.AnyOf = new List<OpenApiSchema>
237+
schema.OneOf = new List<OpenApiSchema>
239238
{
240-
new OpenApiSchema { Type = "integer" },
241-
new OpenApiSchema { Type = "string" }
239+
new OpenApiSchema { Type = Constants.IntegerType, Format = Constants.Int64Format },
240+
new OpenApiSchema { Type = Constants.StringType }
242241
};
243242
}
244243
else
245244
{
246-
schema.Type = "integer";
245+
schema.Type = Constants.IntegerType;
246+
schema.Format = Constants.Int64Format;
247247
}
248-
249-
schema.Format = "int64";
250248
break;
251249
case EdmPrimitiveTypeKind.SByte:
252-
schema.Type = "integer";
250+
schema.Type = Constants.IntegerType;
253251
schema.Format = "int8";
254252
schema.Minimum = SByte.MinValue; // -128
255253
schema.Maximum = SByte.MaxValue; // 127
256254
break;
257255
case EdmPrimitiveTypeKind.String: // string
258-
schema.Type = "string";
256+
schema.Type = Constants.StringType;
259257
break;
260258
case EdmPrimitiveTypeKind.Stream: // stream
261-
schema.Type = "string";
259+
schema.Type = Constants.StringType;
262260
schema.Format = "base64url";
263261
break;
264262
case EdmPrimitiveTypeKind.Duration: // duration
265-
schema.Type = "string";
263+
schema.Type = Constants.StringType;
266264
schema.Format = "duration";
267265
schema.Pattern = "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$";
268266
break;
269267
case EdmPrimitiveTypeKind.Date:
270-
schema.Type = "string";
268+
schema.Type = Constants.StringType;
271269
schema.Format = "date";
272270
schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$";
273271
break;
274272
case EdmPrimitiveTypeKind.TimeOfDay:
275-
schema.Type = "string";
273+
schema.Type = Constants.StringType;
276274
schema.Format = "time";
277275
schema.Pattern = "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$";
278276
break;

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiSchemaGenerator.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ public static IDictionary<string, OpenApiSchema> CreateSchemas(this ODataContext
118118
AdditionalProperties = new OpenApiSchema { Type = Constants.ObjectType }
119119
};
120120

121+
schemas[Constants.ReferenceNumericName] = new()
122+
{
123+
Enum = new List<IOpenApiAny>
124+
{
125+
new OpenApiString("-INF"),
126+
new OpenApiString("INF"),
127+
new OpenApiString("NaN")
128+
}
129+
};
130+
121131
// @odata.nextLink + @odata.count
122132
if (context.Settings.EnablePagination || context.Settings.EnableCount)
123133
{
@@ -611,7 +621,11 @@ private static IOpenApiAny GetTypeNameForExample(ODataContext context, IEdmTypeR
611621
}
612622
else
613623
{
614-
return new OpenApiString(schema.Type ?? schema.Format);
624+
return new OpenApiString(schema.Type ??
625+
(schema.AnyOf ?? Enumerable.Empty<OpenApiSchema>())
626+
.Union(schema.AllOf ?? Enumerable.Empty<OpenApiSchema>())
627+
.Union(schema.OneOf ?? Enumerable.Empty<OpenApiSchema>())
628+
.FirstOrDefault(static x => !string.IsNullOrEmpty(x.Format))?.Format ?? schema.Format);
615629
}
616630
}
617631

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiSpatialTypeSchemaGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public static OpenApiSchema CreateEdmGeometrySchema()
214214
return new OpenApiSchema
215215
{
216216
Type = "object",
217-
AnyOf = new List<OpenApiSchema>
217+
OneOf = new List<OpenApiSchema>
218218
{
219219
new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryPoint" } },
220220
new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryLineString" } },

src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4242
</PackageReference>
4343
<PackageReference Include="Microsoft.OData.Edm" Version="7.10.0" />
44-
<PackageReference Include="Microsoft.OpenApi" Version="1.2.3" />
44+
<PackageReference Include="Microsoft.OpenApi" Version="1.4.1" />
4545
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
4646
<PrivateAssets>all</PrivateAssets>
4747
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

src/OoasGui/OoasGui.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFramework>net6.0-windows</TargetFramework>
44
<OutputType>WinExe</OutputType>
@@ -17,7 +17,7 @@
1717
<ItemGroup>
1818
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
1919
<PackageReference Include="Microsoft.OData.Edm" Version="7.12.2" />
20-
<PackageReference Include="Microsoft.OpenApi" Version="1.4.0" />
20+
<PackageReference Include="Microsoft.OpenApi" Version="1.4.1" />
2121
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
2222
</ItemGroup>
2323
</Project>

test/Microsoft.OpenAPI.OData.Reader.Tests/Generator/OpenApiEdmTypeSchemaGeneratorTest.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ------------------------------------------------------------
1+
// ------------------------------------------------------------
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
44
// ------------------------------------------------------------
@@ -407,14 +407,14 @@ public void CreateEdmTypeSchemaReturnSchemaForDecimal(bool isNullable, bool IEEE
407407
if (IEEE754Compatible)
408408
{
409409
Assert.Null(schema.Type);
410-
Assert.NotNull(schema.AnyOf);
411-
Assert.Equal(2, schema.AnyOf.Count);
412-
Assert.Equal(new[] { "number", "string" }, schema.AnyOf.Select(a => a.Type));
410+
Assert.NotNull(schema.OneOf);
411+
Assert.Equal(2, schema.OneOf.Count);
412+
Assert.Equal(new[] { "number", "string" }, schema.OneOf.Select(a => a.Type));
413413
}
414414
else
415415
{
416416
Assert.Equal("number", schema.Type);
417-
Assert.Null(schema.AnyOf);
417+
Assert.Null(schema.OneOf);
418418
}
419419

420420
Assert.Equal(isNullable, schema.Nullable);
@@ -445,9 +445,9 @@ public void CreateEdmTypeSchemaReturnSchemaForInt64(bool isNullable, bool IEEE75
445445
if (IEEE754Compatible)
446446
{
447447
Assert.Null(schema.Type);
448-
Assert.NotNull(schema.AnyOf);
449-
Assert.Equal(2, schema.AnyOf.Count);
450-
Assert.Equal(new[] { "integer", "string" }, schema.AnyOf.Select(a => a.Type));
448+
Assert.NotNull(schema.OneOf);
449+
Assert.Equal(2, schema.OneOf.Count);
450+
Assert.Equal(new[] { "integer", "string" }, schema.OneOf.Select(a => a.Type));
451451
}
452452
else
453453
{
@@ -510,13 +510,13 @@ public void CreateEdmTypeSchemaReturnSchemaForDouble(bool isNullable)
510510
// & Assert
511511
Assert.Null(schema.Type);
512512

513-
Assert.Equal("double", schema.Format);
513+
Assert.Equal("double", schema.OneOf.FirstOrDefault(x => !string.IsNullOrEmpty(x.Format))?.Format);
514514
Assert.Equal(isNullable, schema.Nullable);
515515

516-
Assert.Null(schema.OneOf);
516+
Assert.Null(schema.AnyOf);
517517

518-
Assert.NotNull(schema.AnyOf);
519-
Assert.Equal(3, schema.AnyOf.Count);
518+
Assert.NotNull(schema.OneOf);
519+
Assert.Equal(3, schema.OneOf.Count);
520520
}
521521

522522
[Theory]
@@ -536,13 +536,13 @@ public void CreateEdmTypeSchemaReturnSchemaForSingle(bool isNullable)
536536
// & Assert
537537
Assert.Null(schema.Type);
538538

539-
Assert.Equal("float", schema.Format);
539+
Assert.Equal("float", schema.OneOf.FirstOrDefault(x => !string.IsNullOrEmpty(x.Format))?.Format);
540540
Assert.Equal(isNullable, schema.Nullable);
541541

542-
Assert.Null(schema.OneOf);
542+
Assert.Null(schema.AnyOf);
543543

544-
Assert.NotNull(schema.AnyOf);
545-
Assert.Equal(3, schema.AnyOf.Count);
544+
Assert.NotNull(schema.OneOf);
545+
Assert.Equal(3, schema.OneOf.Count);
546546
}
547547
#endregion
548548
}

0 commit comments

Comments
 (0)