diff --git a/Directory.Build.props b/Directory.Build.props index c81e613..30a5d8c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,11 +1,5 @@ - - net8.0;net9.0;net10.0 - net8.0;net9.0 - net10.0 - net8.0;net9.0;net10.0 - optional partial json undefined jsonpatch jsonmergepatch patch System.Text.Json Api unspecified @@ -37,11 +31,11 @@ portable - + - - + + @@ -49,7 +43,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -70,8 +64,11 @@ - - - + + + \ No newline at end of file diff --git a/OptionalValues.slnx b/OptionalValues.slnx index d79f941..e4203b9 100644 --- a/OptionalValues.slnx +++ b/OptionalValues.slnx @@ -11,8 +11,9 @@ - - + + @@ -20,16 +21,25 @@ - + - - + + - + + + + - - + + \ No newline at end of file diff --git a/src/OptionalValues.DataAnnotations/OptionalValues.DataAnnotations.csproj b/src/OptionalValues.DataAnnotations/OptionalValues.DataAnnotations.csproj index 04c9ae7..5c986cb 100644 --- a/src/OptionalValues.DataAnnotations/OptionalValues.DataAnnotations.csproj +++ b/src/OptionalValues.DataAnnotations/OptionalValues.DataAnnotations.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesLibraryTargetFrameworks) + net8.0;net9.0;net10.0 $(NoWarn);CA1813 @@ -15,7 +15,7 @@ - + diff --git a/src/OptionalValues.FluentValidation/OptionalValues.FluentValidation.csproj b/src/OptionalValues.FluentValidation/OptionalValues.FluentValidation.csproj index 0aff1c0..0b01e0e 100644 --- a/src/OptionalValues.FluentValidation/OptionalValues.FluentValidation.csproj +++ b/src/OptionalValues.FluentValidation/OptionalValues.FluentValidation.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesLibraryTargetFrameworks) + net8.0;net9.0;net10.0 @@ -12,11 +12,11 @@ - + - + - + \ No newline at end of file diff --git a/src/OptionalValues.NSwag/OptionalValues.NSwag.csproj b/src/OptionalValues.NSwag/OptionalValues.NSwag.csproj index e73598f..e7b64b3 100644 --- a/src/OptionalValues.NSwag/OptionalValues.NSwag.csproj +++ b/src/OptionalValues.NSwag/OptionalValues.NSwag.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesLibraryTargetFrameworks) + net8.0;net9.0;net10.0 diff --git a/src/OptionalValues.Swashbuckle/OptionalValues.Swashbuckle.csproj b/src/OptionalValues.Swashbuckle/OptionalValues.Swashbuckle.csproj index 35919e5..71396d8 100644 --- a/src/OptionalValues.Swashbuckle/OptionalValues.Swashbuckle.csproj +++ b/src/OptionalValues.Swashbuckle/OptionalValues.Swashbuckle.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesSwashbuckleTargetFrameworks) + net8.0;net9.0;net10.0 diff --git a/src/OptionalValues/OptionalValues.csproj b/src/OptionalValues/OptionalValues.csproj index d882987..f3fb206 100644 --- a/src/OptionalValues/OptionalValues.csproj +++ b/src/OptionalValues/OptionalValues.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesLibraryTargetFrameworks) + net8.0;net9.0;net10.0 @@ -15,7 +15,7 @@ - + diff --git a/test/OptionalValues.Benchmarks/OptionalValues.Benchmarks.csproj b/test/OptionalValues.Benchmarks/OptionalValues.Benchmarks.csproj index bc0eb66..9f9520d 100644 --- a/test/OptionalValues.Benchmarks/OptionalValues.Benchmarks.csproj +++ b/test/OptionalValues.Benchmarks/OptionalValues.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable diff --git a/test/OptionalValues.DataAnnotations.Tests/OptionalValues.DataAnnotations.Tests.csproj b/test/OptionalValues.DataAnnotations.Tests/OptionalValues.DataAnnotations.Tests.csproj index 05c3b8b..d27e15e 100644 --- a/test/OptionalValues.DataAnnotations.Tests/OptionalValues.DataAnnotations.Tests.csproj +++ b/test/OptionalValues.DataAnnotations.Tests/OptionalValues.DataAnnotations.Tests.csproj @@ -1,7 +1,7 @@  - $(OptionalValuesTestsTargetFrameworks) + net8.0;net9.0;net10.0 enable enable false @@ -10,10 +10,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -21,11 +21,12 @@ - + - + - + \ No newline at end of file diff --git a/test/OptionalValues.FluentValidation.Tests/OptionalValues.FluentValidation.Tests.csproj b/test/OptionalValues.FluentValidation.Tests/OptionalValues.FluentValidation.Tests.csproj index ff6926a..585364c 100644 --- a/test/OptionalValues.FluentValidation.Tests/OptionalValues.FluentValidation.Tests.csproj +++ b/test/OptionalValues.FluentValidation.Tests/OptionalValues.FluentValidation.Tests.csproj @@ -1,7 +1,7 @@ - $(OptionalValuesTestsTargetFrameworks) + net8.0;net9.0;net10.0 enable enable @@ -10,10 +10,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -21,11 +21,12 @@ - + - + - + \ No newline at end of file diff --git a/test/OptionalValues.NSwag.Tests/OptionalValues.NSwag.Tests.csproj b/test/OptionalValues.NSwag.Tests/OptionalValues.NSwag.Tests.csproj index 5691b3a..dd46711 100644 --- a/test/OptionalValues.NSwag.Tests/OptionalValues.NSwag.Tests.csproj +++ b/test/OptionalValues.NSwag.Tests/OptionalValues.NSwag.Tests.csproj @@ -1,7 +1,7 @@ - $(OptionalValuesTestsTargetFrameworks) + net8.0;net9.0;net10.0 enable enable @@ -10,12 +10,12 @@ - - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -23,11 +23,11 @@ - + - + - + \ No newline at end of file diff --git a/test/OptionalValues.Swashbuckle.Tests/OptionalValues.Swashbuckle.Tests.csproj b/test/OptionalValues.Swashbuckle.Tests/OptionalValues.Swashbuckle.Tests.csproj deleted file mode 100644 index 9eec8aa..0000000 --- a/test/OptionalValues.Swashbuckle.Tests/OptionalValues.Swashbuckle.Tests.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - $(OptionalValuesSwashbuckleTargetFrameworks) - enable - enable - - false - true - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - diff --git a/test/OptionalValues.Swashbuckle.V10.Tests/OptionalValues.Swashbuckle.V10.Tests.csproj b/test/OptionalValues.Swashbuckle.V10.Tests/OptionalValues.Swashbuckle.V10.Tests.csproj new file mode 100644 index 0000000..82c75d0 --- /dev/null +++ b/test/OptionalValues.Swashbuckle.V10.Tests/OptionalValues.Swashbuckle.V10.Tests.csproj @@ -0,0 +1,37 @@ + + + + net8.0;net9.0;net10.0 + enable + enable + + false + true + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + \ No newline at end of file diff --git a/test/OptionalValues.Swashbuckle.V10.Tests/SchemaGeneratorTest.cs b/test/OptionalValues.Swashbuckle.V10.Tests/SchemaGeneratorTest.cs new file mode 100644 index 0000000..09c3fcf --- /dev/null +++ b/test/OptionalValues.Swashbuckle.V10.Tests/SchemaGeneratorTest.cs @@ -0,0 +1,107 @@ +using System.Text.Json; + +using Microsoft.OpenApi; + +using Shouldly; + +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace OptionalValues.Swashbuckle.V10.Tests; + +public class SchemaGeneratorTest +{ + private SchemaGenerator SchemaGeneratorDefault { get; } = new SchemaGenerator(new SchemaGeneratorOptions + { + // This should be true, because Nullable Reference Support is built into the OptionalValue type + // So we set it to true to match the behavior of the OptionalValueDataContractResolver + SupportNonNullableReferenceTypes = true, + }, new JsonSerializerDataContractResolver(JsonSerializerOptions.Default)); + + private SchemaGenerator SchemaGeneratorOptionalValues { get; } = new SchemaGenerator(new SchemaGeneratorOptions + { + // This should be true, because Nullable Reference Support is built into the OptionalValue type + // So we set it to true to match the behavior of the OptionalValueDataContractResolver + SupportNonNullableReferenceTypes = true, + }, new OptionalValueDataContractResolver(new JsonSerializerDataContractResolver(JsonSerializerOptions.Default))); + + [Fact] + public void Should_Generate_The_Same_Schema_With_OptionalValues() + { + var schemaRepositoryForOptionalValues = new SchemaRepository(); + var schemaRepositoryForDefault = new SchemaRepository(); + + IOpenApiSchema schemaOptionalValuesAsRef = SchemaGeneratorOptionalValues.GenerateSchema(typeof(ExamplesOptionalValues.Primitives), schemaRepositoryForOptionalValues); + schemaOptionalValuesAsRef.ShouldNotBeNull(); + + IOpenApiSchema schemaDefaultAsRef = SchemaGeneratorDefault.GenerateSchema(typeof(ExamplesPlain.Primitives), schemaRepositoryForDefault); + schemaDefaultAsRef.ShouldNotBeNull(); + + var refId1 = ((OpenApiSchemaReference)schemaOptionalValuesAsRef).Reference.Id; + var refId2 = ((OpenApiSchemaReference)schemaDefaultAsRef).Reference.Id; + + IOpenApiSchema schemaOptionalValues = schemaRepositoryForOptionalValues.Schemas[refId1!]; + IOpenApiSchema schemaDefault = schemaRepositoryForDefault.Schemas[refId2!]; + + var schemaOptionalValuesJson = SerializeSchema(schemaOptionalValues); + var schemaDefaultJson = SerializeSchema(schemaDefault); + + schemaOptionalValuesJson.ShouldBe(schemaDefaultJson); + schemaOptionalValues.Properties?.Count.ShouldBe(4); + schemaDefault.Properties?.Count.ShouldBe(4); + } + + [Fact] + public void OptionalValue_Support_Should_Not_Change_Behavior() + { + var schemaRepositoryForOptionalValues = new SchemaRepository(); + var schemaRepositoryForDefault = new SchemaRepository(); + + IOpenApiSchema schemaOptionalValuesAsRef = SchemaGeneratorOptionalValues.GenerateSchema(typeof(ExamplesPlain.Primitives), schemaRepositoryForOptionalValues); + schemaOptionalValuesAsRef.ShouldNotBeNull(); + + IOpenApiSchema schemaDefaultAsRef = SchemaGeneratorDefault.GenerateSchema(typeof(ExamplesPlain.Primitives), schemaRepositoryForDefault); + schemaDefaultAsRef.ShouldNotBeNull(); + + var refId1 = ((OpenApiSchemaReference)schemaOptionalValuesAsRef).Reference.Id; + var refId2 = ((OpenApiSchemaReference)schemaDefaultAsRef).Reference.Id; + + IOpenApiSchema schema1 = schemaRepositoryForOptionalValues.Schemas[refId1!]; + IOpenApiSchema schema2 = schemaRepositoryForDefault.Schemas[refId2!]; + + var schema1Json = SerializeSchema(schema1); + var schema2Json = SerializeSchema(schema2); + + schema1Json.ShouldBe(schema2Json); + } + + private static string SerializeSchema(Microsoft.OpenApi.IOpenApiSchema schema) + { + using var stringWriter = new StringWriter(); + // OpenApi 2.x uses OpenApiWriterBase instead of OpenApiJsonWriter + var writer = new Microsoft.OpenApi.OpenApiJsonWriter(stringWriter); + schema.SerializeAsV31(writer); + return stringWriter.ToString(); + } + + private static class ExamplesOptionalValues + { + public class Primitives + { + public OptionalValue IntValue { get; set; } + public OptionalValue StringValue { get; set; } + public OptionalValue BoolValue { get; set; } + public OptionalValue GuidValue { get; set; } + } + } + + private static class ExamplesPlain + { + public class Primitives + { + public int IntValue { get; set; } + public string StringValue { get; set; } = null!; + public bool BoolValue { get; set; } + public Guid GuidValue { get; set; } + } + } +} diff --git a/test/OptionalValues.Swashbuckle.V7.Tests/OptionalValues.Swashbuckle.V7.Tests.csproj b/test/OptionalValues.Swashbuckle.V7.Tests/OptionalValues.Swashbuckle.V7.Tests.csproj new file mode 100644 index 0000000..0500e59 --- /dev/null +++ b/test/OptionalValues.Swashbuckle.V7.Tests/OptionalValues.Swashbuckle.V7.Tests.csproj @@ -0,0 +1,37 @@ + + + + net8.0;net9.0 + enable + enable + + false + true + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + \ No newline at end of file diff --git a/test/OptionalValues.Swashbuckle.V8.Tests/OptionalValues.Swashbuckle.V8.Tests.csproj b/test/OptionalValues.Swashbuckle.V8.Tests/OptionalValues.Swashbuckle.V8.Tests.csproj new file mode 100644 index 0000000..26a7eeb --- /dev/null +++ b/test/OptionalValues.Swashbuckle.V8.Tests/OptionalValues.Swashbuckle.V8.Tests.csproj @@ -0,0 +1,37 @@ + + + + net8.0;net9.0 + enable + enable + + false + true + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + \ No newline at end of file diff --git a/test/OptionalValues.Swashbuckle.V9.Tests/OptionalValues.Swashbuckle.V9.Tests.csproj b/test/OptionalValues.Swashbuckle.V9.Tests/OptionalValues.Swashbuckle.V9.Tests.csproj new file mode 100644 index 0000000..ffc4d20 --- /dev/null +++ b/test/OptionalValues.Swashbuckle.V9.Tests/OptionalValues.Swashbuckle.V9.Tests.csproj @@ -0,0 +1,37 @@ + + + + net8.0;net9.0 + enable + enable + + false + true + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + \ No newline at end of file diff --git a/test/OptionalValues.Swashbuckle.Tests/SchemaGeneratorTest.cs b/test/OptionalValues.Swashbuckle.V9.Tests/SchemaGeneratorTest.cs similarity index 98% rename from test/OptionalValues.Swashbuckle.Tests/SchemaGeneratorTest.cs rename to test/OptionalValues.Swashbuckle.V9.Tests/SchemaGeneratorTest.cs index a9ce6af..d7a90e9 100644 --- a/test/OptionalValues.Swashbuckle.Tests/SchemaGeneratorTest.cs +++ b/test/OptionalValues.Swashbuckle.V9.Tests/SchemaGeneratorTest.cs @@ -7,7 +7,7 @@ using Swashbuckle.AspNetCore.SwaggerGen; -namespace OptionalValues.Swashbuckle.Tests; +namespace OptionalValues.Swashbuckle.V9.Tests; public class SchemaGeneratorTest { diff --git a/test/OptionalValues.Swashbuckle.Tests/ServiceCollectionTest.cs b/test/OptionalValues.Swashbuckle.V9.Tests/ServiceCollectionTest.cs similarity index 98% rename from test/OptionalValues.Swashbuckle.Tests/ServiceCollectionTest.cs rename to test/OptionalValues.Swashbuckle.V9.Tests/ServiceCollectionTest.cs index 5b2c35f..67b1e17 100644 --- a/test/OptionalValues.Swashbuckle.Tests/ServiceCollectionTest.cs +++ b/test/OptionalValues.Swashbuckle.V9.Tests/ServiceCollectionTest.cs @@ -4,7 +4,7 @@ using Swashbuckle.AspNetCore.SwaggerGen; -namespace OptionalValues.Swashbuckle.Tests; +namespace OptionalValues.Swashbuckle.V9.Tests; public class ServiceCollectionTest { diff --git a/test/OptionalValues.Tests/OptionalValues.Tests.csproj b/test/OptionalValues.Tests/OptionalValues.Tests.csproj index 9f47d64..c1a6544 100644 --- a/test/OptionalValues.Tests/OptionalValues.Tests.csproj +++ b/test/OptionalValues.Tests/OptionalValues.Tests.csproj @@ -1,7 +1,7 @@ - $(OptionalValuesTestsTargetFrameworks) + net8.0;net9.0;net10.0 enable enable @@ -10,14 +10,15 @@ - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -25,11 +26,11 @@ - + - + - + \ No newline at end of file