diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 8bef85221..d29a6192a 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -69,7 +69,7 @@ extends: - task: UseDotNet@2 displayName: 'Use .NET 10' inputs: - version: 10.x + useGlobalJson: true # Install the nuget tool. - task: NuGetToolInstaller@1 @@ -79,6 +79,20 @@ extends: checkLatest: true # Build the Product project + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to Azure Artifacts' + + - pwsh: | + @" + + + + + + + + "@ | Set-Content -Path "$(Build.SourcesDirectory)/nuget.config" -Encoding UTF8 + displayName: 'Create nuget.config (central feed)' - task: DotNetCoreCLI@2 displayName: 'build' inputs: @@ -93,7 +107,7 @@ extends: projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' arguments: '--configuration $(BuildConfiguration) --no-build' - - task: EsrpCodeSigning@5 + - task: EsrpCodeSigning@6 displayName: 'ESRP CodeSigning binaries' inputs: ConnectedServiceName: 'Federated DevX ESRP Managed Identity Connection' @@ -159,7 +173,7 @@ extends: - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --include-symbols --include-source /p:SymbolPackageFormat=snupkg displayName: 'pack Hidi' - - task: EsrpCodeSigning@5 + - task: EsrpCodeSigning@6 displayName: 'ESRP CodeSigning Nuget Packages' inputs: ConnectedServiceName: 'Federated DevX ESRP Managed Identity Connection' @@ -198,7 +212,7 @@ extends: displayName: publish Hidi as executable inputs: command: 'publish' - arguments: -c Release --runtime win-x64 /p:PublishSingleFile=true /p:PackAsTool=false --self-contained --output $(Build.ArtifactStagingDirectory)/Microsoft.OpenApi.Hidi + arguments: -c Release --runtime win-x64 -p:RestoreConfigFile=$(Build.SourcesDirectory)\nuget.config /p:PublishSingleFile=true /p:PackAsTool=false --self-contained --output $(Build.ArtifactStagingDirectory)/Microsoft.OpenApi.Hidi projects: 'src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj' publishWebProjects: False zipAfterPublish: false diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e6c39adb9..0746cbe20 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.11.0" + ".": "2.12.0" } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 186b10bea..619467ff3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ }, "cSpell.words": [ "csdl", - "Hidi" + "Hidi", + "Xunit" ] } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 37d5a3f3b..e49317408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [2.12.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.11.0...v2.12.0) (2026-08-12) + + +### Features + +* adds deserialization of the example extension ([095ae3b](https://github.com/microsoft/OpenAPI.NET/commit/095ae3bbdf3c248ba18db17278889cf5a8faf01c)) +* serialize license identifier as extension for earlier versions ([d5cdce8](https://github.com/microsoft/OpenAPI.NET/commit/d5cdce83cfc210806afbd8850bb5ebe14eef5116)) +* serialize license identifier as extension for earlier versions ([fde38d8](https://github.com/microsoft/OpenAPI.NET/commit/fde38d8bec7af0304b0f522683ccda2d245cd860)) + + +### Bug Fixes + +* better nullability round-tripping ([7a25659](https://github.com/microsoft/OpenAPI.NET/commit/7a25659a1cdd544f6b4bcc8bf1ed9797882b5ced)) +* bound YAML anchor/alias expansion to prevent OOM (billion laughs) ([#3000](https://github.com/microsoft/OpenAPI.NET/issues/3000)) ([a361360](https://github.com/microsoft/OpenAPI.NET/commit/a3613606a90d86d3e22454890c694fbb854f4bc9)) +* bound YAML anchor/alias expansion to prevent OOM (billion laughs) ([#3000](https://github.com/microsoft/OpenAPI.NET/issues/3000)) ([4db9af0](https://github.com/microsoft/OpenAPI.NET/commit/4db9af07d112cdf45170b7a946f956ffe74fa14e)) +* **library:** serialize multiple schema types as anyOf/oneOf for OpenAPI 3.0 ([6568896](https://github.com/microsoft/OpenAPI.NET/commit/6568896ccf14380e234bae481a83be2d58d7c0cb)) +* marks deprecated properties from the specification as obsolete ([26aba69](https://github.com/microsoft/OpenAPI.NET/commit/26aba69cd9c7ab1ecb8b1c61dd0094d291980af4)) +* marks deprecated properties from the specification as obsolete ([abc5301](https://github.com/microsoft/OpenAPI.NET/commit/abc5301a82cb913fea696aa1248a2e17b317ce10)) +* **schema:** serialize compatibility examples from examples list ([be57a7c](https://github.com/microsoft/OpenAPI.NET/commit/be57a7c4cf1e4ae2025b987520316420c897cb46)) +* serialize examples as extension in v2/v3 ([d27141b](https://github.com/microsoft/OpenAPI.NET/commit/d27141b5203e5895f0fb812b913dd7621274e6a3)) + ## [2.11.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.10.0...v2.11.0) (2026-07-15) diff --git a/Directory.Build.props b/Directory.Build.props index 2986e23aa..dc7b5623f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,7 +12,7 @@ https://github.com/Microsoft/OpenAPI.NET © Microsoft Corporation. All rights reserved. OpenAPI .NET - 2.11.0 + 2.12.0 diff --git a/Dockerfile b/Dockerfile index 25f1ec589..46cb00637 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build-env WORKDIR /app COPY ./src ./hidi/src diff --git a/global.json b/global.json index 12f5b9de6..d0c1ec64c 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "10.0.301" + "version": "10.0.302" } } \ No newline at end of file diff --git a/performance/resultsComparer/resultsComparer.csproj b/performance/resultsComparer/resultsComparer.csproj index c409872f6..80a964ca2 100644 --- a/performance/resultsComparer/resultsComparer.csproj +++ b/performance/resultsComparer/resultsComparer.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj index 5ebf5bb4a..f21ca3bbe 100644 --- a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj +++ b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj @@ -37,8 +37,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + diff --git a/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj b/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj index 1ab76c96e..a686a0de4 100644 --- a/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj +++ b/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj @@ -1,5 +1,7 @@ - + + + net8.0-windows WinExe false @@ -8,29 +10,56 @@ true NU1903 - + + + + net8.0 + Library + false + NU1903 + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + + - + + + + + - - - + + + + + + + + + + + + - + + + + \ No newline at end of file diff --git a/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs b/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs index 0bf2627ec..cea996152 100644 --- a/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs +++ b/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs @@ -74,6 +74,17 @@ public ReadResult Read(MemoryStream input, Diagnostic = diagnostic, }; } + catch (OpenApiReaderException ex) + { + var diagnostic = new OpenApiDiagnostic(); + diagnostic.Errors.Add(new(ex)); + diagnostic.Format = OpenApiConstants.Yaml; + return new() + { + Document = null, + Diagnostic = diagnostic, + }; + } return UpdateFormat(Read(jsonNode, location, settings)); } diff --git a/src/Microsoft.OpenApi.YamlReader/PublicAPI.Shipped.txt b/src/Microsoft.OpenApi.YamlReader/PublicAPI.Shipped.txt index 202fde962..1d7c628ca 100644 --- a/src/Microsoft.OpenApi.YamlReader/PublicAPI.Shipped.txt +++ b/src/Microsoft.OpenApi.YamlReader/PublicAPI.Shipped.txt @@ -14,4 +14,10 @@ static Microsoft.OpenApi.YamlReader.YamlConverter.ToJsonNode(this SharpYaml.Seri static Microsoft.OpenApi.YamlReader.YamlConverter.ToJsonNode(this SharpYaml.Serialization.YamlNode! yaml) -> System.Text.Json.Nodes.JsonNode! static Microsoft.OpenApi.YamlReader.YamlConverter.ToJsonNode(this SharpYaml.Serialization.YamlStream! yaml) -> System.Collections.Generic.IEnumerable! static Microsoft.OpenApi.YamlReader.YamlConverter.ToJsonObject(this SharpYaml.Serialization.YamlMappingNode! yaml) -> System.Text.Json.Nodes.JsonObject! -static Microsoft.OpenApi.YamlReader.YamlConverter.ToYamlNode(this System.Text.Json.Nodes.JsonNode! json) -> SharpYaml.Serialization.YamlNode! \ No newline at end of file +static Microsoft.OpenApi.YamlReader.YamlConverter.ToYamlNode(this System.Text.Json.Nodes.JsonNode! json) -> SharpYaml.Serialization.YamlNode! +const Microsoft.OpenApi.YamlReader.YamlConverter.DefaultMaxDepth = 64 -> uint +const Microsoft.OpenApi.YamlReader.YamlConverter.DefaultMaxNodeCount = 5000000 -> uint +static Microsoft.OpenApi.YamlReader.YamlConverter.MaxDepth.get -> uint +static Microsoft.OpenApi.YamlReader.YamlConverter.MaxDepth.set -> void +static Microsoft.OpenApi.YamlReader.YamlConverter.MaxNodeCount.get -> uint +static Microsoft.OpenApi.YamlReader.YamlConverter.MaxNodeCount.set -> void diff --git a/src/Microsoft.OpenApi.YamlReader/YamlConverter.cs b/src/Microsoft.OpenApi.YamlReader/YamlConverter.cs index 1cafea77b..3a09ff876 100644 --- a/src/Microsoft.OpenApi.YamlReader/YamlConverter.cs +++ b/src/Microsoft.OpenApi.YamlReader/YamlConverter.cs @@ -14,6 +14,94 @@ namespace Microsoft.OpenApi.YamlReader /// public static class YamlConverter { + /// + /// Default maximum nesting depth allowed when converting a YAML node graph into JSON nodes. + /// Mirrors the default System.Text.Json depth limit (64) that already bounds the JSON reader path, + /// protecting the recursive conversion from stack exhaustion on deeply nested documents. + /// + public const uint DefaultMaxDepth = 64; + + /// + /// Default maximum number of JSON nodes that may be materialized from a single YAML document. + /// Guards against YAML anchor/alias expansion ("billion laughs") attacks, where a tiny document + /// expands exponentially when its shared node graph is materialized into an independent JSON tree. + /// + public const uint DefaultMaxNodeCount = 5_000_000; + + private static uint _maxDepth = DefaultMaxDepth; + private static uint _maxNodeCount = DefaultMaxNodeCount; + + /// + /// Gets or sets the maximum nesting depth allowed when converting a YAML node graph into JSON nodes. + /// Defaults to . Raise this if legitimate deeply nested documents are + /// being rejected, or lower it to fail faster when only shallow documents are expected. + /// + /// Thrown when set to zero. + public static uint MaxDepth + { + get => _maxDepth; + set + { + if (value == 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "MaxDepth must be greater than zero."); + } + + _maxDepth = value; + } + } + + /// + /// Gets or sets the maximum number of JSON nodes that may be materialized from a single YAML document. + /// Defaults to , guarding against YAML anchor/alias expansion + /// ("billion laughs") attacks. Raise this if legitimate large documents are being rejected, or lower + /// it to fail faster when only small documents are expected. + /// + /// Thrown when set to zero. + public static uint MaxNodeCount + { + get => _maxNodeCount; + set + { + if (value == 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "MaxNodeCount must be greater than zero."); + } + + _maxNodeCount = value; + } + } + + /// + /// Tracks and enforces resource limits while converting a YAML node graph into JSON nodes, + /// failing fast when a hostile document would otherwise exhaust memory or the stack. + /// + private sealed class YamlConversionBudget + { + private readonly uint _maxDepth; + private readonly uint _maxNodeCount; + private uint _nodeCount; + + public YamlConversionBudget(uint maxDepth, uint maxNodeCount) + { + _maxDepth = maxDepth; + _maxNodeCount = maxNodeCount; + } + + public void EnterNode(uint depth) + { + if (depth > _maxDepth) + { + throw new OpenApiReaderException($"The YAML document exceeds the maximum supported nesting depth of {_maxDepth}."); + } + + if (++_nodeCount > _maxNodeCount) + { + throw new OpenApiReaderException($"The YAML document expands to more than the maximum supported number of nodes ({_maxNodeCount}). This may indicate a YAML anchor/alias expansion (billion laughs) attack."); + } + } + } + /// /// Converts all of the documents in a YAML stream to s. /// @@ -42,10 +130,16 @@ public static JsonNode ToJsonNode(this YamlDocument yaml) /// Thrown for YAML that is not compatible with JSON. public static JsonNode ToJsonNode(this YamlNode yaml) { + return yaml.ToJsonNode(new YamlConversionBudget(MaxDepth, MaxNodeCount), 0); + } + + private static JsonNode ToJsonNode(this YamlNode yaml, YamlConversionBudget budget, uint depth) + { + budget.EnterNode(depth); return yaml switch { - YamlMappingNode map => map.ToJsonObject(), - YamlSequenceNode seq => seq.ToJsonArray(), + YamlMappingNode map => map.ToJsonObject(budget, depth), + YamlSequenceNode seq => seq.ToJsonArray(budget, depth), YamlScalarNode scalar => scalar.ToJsonValue(), _ => throw new NotSupportedException("This yaml isn't convertible to JSON") }; @@ -78,12 +172,17 @@ public static YamlNode ToYamlNode(this JsonNode json) /// /// public static JsonObject ToJsonObject(this YamlMappingNode yaml) + { + return yaml.ToJsonObject(new YamlConversionBudget(MaxDepth, MaxNodeCount), 0); + } + + private static JsonObject ToJsonObject(this YamlMappingNode yaml, YamlConversionBudget budget, uint depth) { var node = new JsonObject(); foreach (var keyValuePair in yaml) { var key = ((YamlScalarNode)keyValuePair.Key).Value!; - node[key] = keyValuePair.Value.ToJsonNode(); + node[key] = keyValuePair.Value.ToJsonNode(budget, depth + 1); } return node; @@ -103,11 +202,16 @@ private static YamlMappingNode ToYamlMapping(this JsonObject obj) /// /// public static JsonArray ToJsonArray(this YamlSequenceNode yaml) + { + return yaml.ToJsonArray(new YamlConversionBudget(MaxDepth, MaxNodeCount), 0); + } + + private static JsonArray ToJsonArray(this YamlSequenceNode yaml, YamlConversionBudget budget, uint depth) { var node = new JsonArray(); foreach (var value in yaml) { - node.Add(value.ToJsonNode()); + node.Add(value.ToJsonNode(budget, depth + 1)); } return node; diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs b/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs index 8d557b4d1..1ad3a5b8f 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs @@ -69,7 +69,12 @@ internal static string ToFirstIdentifier(this JsonSchemaType schemaType) /// internal static string ToSingleIdentifier(this JsonSchemaType schemaType) { - return schemaType.ToIdentifiersInternal().Single(); + if (allSchemaTypes.TryGetValue(schemaType, out var schemaTypeString)) + { + return schemaTypeString; + } + + throw new InvalidOperationException($"ToSingleIdentifier is called with unexpected value '{schemaType}'. Callers must ensure this is called with a valid single value JsonSchemaType."); } /// diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs index 312517acb..8be831628 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Text.Json.Nodes; namespace Microsoft.OpenApi; @@ -42,6 +43,7 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// If style is used, and if behavior is n/a (cannot be serialized), /// the value of allowEmptyValue SHALL be ignored. /// + [Obsolete("Use of AllowEmptyValue is not recommended and it is likely to be removed in a later revision.")] public bool AllowEmptyValue { get; } /// diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs index 7cb85f100..476b2a853 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs @@ -243,6 +243,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// You must use the method to check whether Default was assigned a null value in the document. /// Assign to use get null as a serialized value. /// + [Obsolete("Use Examples instead.")] public JsonNode? Example { get; } /// diff --git a/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs b/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs index 860bd3b56..e57a8f1f7 100644 --- a/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs @@ -8,6 +8,8 @@ namespace Microsoft.OpenApi; +#pragma warning disable CS0618 + /// /// Schema reference information that includes metadata annotations from JSON Schema 2020-12. /// This class extends OpenApiReference to provide schema-specific metadata override capabilities. @@ -267,6 +269,7 @@ public string? Const /// A free-form property to include an example of an instance for this schema. /// Follow OpenAPI Schema Object definition. /// + [Obsolete("Use Examples instead.")] public JsonNode? Example { get; set; } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs index 3a24bfb60..3cfc9f357 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs @@ -230,6 +230,11 @@ public static class OpenApiConstants /// public const string Identifier = "identifier"; + /// + /// Field: x-oai-license-identifier + /// + public const string OaiLicenseIdentifier = "x-oai-license-identifier"; + /// /// Field: Namespace /// @@ -750,6 +755,11 @@ public static class OpenApiConstants /// public const string ExamplesExtension = "x-examples"; + /// + /// Extension: x-jsonschema-examples + /// + public const string JsonSchemaExamplesExtension = "x-jsonschema-examples"; + /// /// Field: version3_0_0 /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs index 04a267bdc..6297c03a9 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs @@ -63,6 +63,7 @@ public virtual void SerializeAsV31(IOpenApiWriter writer) public virtual void SerializeAsV3(IOpenApiWriter writer) { WriteInternal(writer, OpenApiSpecVersion.OpenApi3_0); + writer.WriteProperty(OpenApiConstants.OaiLicenseIdentifier, Identifier); writer.WriteEndObject(); } @@ -72,6 +73,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) public virtual void SerializeAsV2(IOpenApiWriter writer) { WriteInternal(writer, OpenApiSpecVersion.OpenApi2_0); + writer.WriteProperty(OpenApiConstants.OaiLicenseIdentifier, Identifier); writer.WriteEndObject(); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index 63b3735e2..eb226c908 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -8,6 +8,7 @@ namespace Microsoft.OpenApi { +#pragma warning disable CS0618 /// /// Parameter Object. /// @@ -32,6 +33,7 @@ public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter public bool Deprecated { get; set; } /// + [Obsolete("Use of AllowEmptyValue is not recommended and it is likely to be removed in a later revision.")] public bool AllowEmptyValue { get; set; } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 814dc1923..970d036a0 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -21,7 +21,7 @@ namespace Microsoft.OpenApi /// public class OpenApiSchema : IOpenApiExtensible, IOpenApiSchema, IOpenApiSchemaMissingProperties, IOpenApiSchemaWithUnevaluatedProperties, IMetadataContainer { - private static readonly IEnumerable s_singleNullElementList = [ JsonNullSentinel.JsonNull ]; + private static readonly IEnumerable s_singleNullElementList = [JsonNullSentinel.JsonNull]; /// public string? Title { get; set; } @@ -251,6 +251,7 @@ public string? Minimum public OpenApiDiscriminator? Discriminator { get; set; } /// + [Obsolete("Use Examples instead.")] public JsonNode? Example { get; set; } /// @@ -544,7 +545,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version } // type - var serializedTypeProperty = TrySerializeTypeProperty(writer, version); + SerializeTypePropertyForVersion3AndLater(writer, version, callback); // allOf writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, callback); @@ -589,13 +590,13 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d)); // nullable - if (version == OpenApiSpecVersion.OpenApi3_0 && serializedTypeProperty) + if (version == OpenApiSpecVersion.OpenApi3_0) { // https://spec.openapis.org/oas/v3.0.4.html#fixed-fields-20 // This keyword only takes effect if type is explicitly defined within the same Schema Object. // - // If the user explicitly set IsNullable to true, we serialize it even if redundant. - // But if **we** are inferring it (from oneOf/anyOf), we don't serialize it when it's redundant. + // We don't care to avoid an unnecessary serialization. + // So, we attempt to serialize it regardless of whether or not a type property was serialized. SerializeNullable(writer, version); } @@ -615,7 +616,10 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, callback); // example - writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e)); + writer.WriteOptionalObject( + OpenApiConstants.Example, + version < OpenApiSpecVersion.OpenApi3_1 ? GetCompatibilityExample() : Example, + (w, e) => w.WriteAny(e)); // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); @@ -676,7 +680,7 @@ internal void WriteJsonSchemaKeywords(IOpenApiWriter writer, Action nodeWriter.WriteAny(s)); } internal void WriteAsItemsProperties(IOpenApiWriter writer) @@ -828,7 +833,7 @@ private void SerializeAsV2( writer.WriteStartObject(); // type - TrySerializeTypeProperty(writer, OpenApiSpecVersion.OpenApi2_0); + SerializeTypePropertyForVersion2(writer); // description writer.WriteProperty(OpenApiConstants.Description, Description); @@ -910,7 +915,7 @@ private void SerializeAsV2( // oneOf (Not Supported in V2) - Write the first schema only as an allOf. writer.WriteOptionalCollection(OpenApiConstants.AllOf, OneOf?.Take(1), (w, s) => s.SerializeAsV2(w)); } - #pragma warning restore CS0618 +#pragma warning restore CS0618 } // properties @@ -954,7 +959,10 @@ private void SerializeAsV2( writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, s) => s.SerializeAsV2(w)); // example +#pragma warning disable CS0618 + writer.WriteOptionalObject(OpenApiConstants.Example, GetCompatibilityExample(), (w, e) => w.WriteAny(e)); writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e)); +#pragma warning restore CS0618 // x-nullable extension SerializeNullable(writer, OpenApiSpecVersion.OpenApi2_0); @@ -985,70 +993,147 @@ private void SerializeAsV2( writer.WriteOptionalMap(OpenApiConstants.PatternPropertiesExtension, PatternProperties, (w, s) => s.SerializeAsV2(w)); } + writer.WriteOptionalCollection(OpenApiConstants.JsonSchemaExamplesExtension, GetCompatibilityExamplesExtension(), (nodeWriter, s) => nodeWriter.WriteAny(s)); + // extensions writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0); writer.WriteEndObject(); } - private bool TrySerializeTypeProperty(IOpenApiWriter writer, OpenApiSpecVersion version, JsonSchemaType? inferredType = null) + private void SerializeTypePropertyForVersion2(IOpenApiWriter writer) { - // Use original type or inferred type when the explicit type is not set - var typeToUse = Type ?? inferredType; + if (Type is not { } type || type == JsonSchemaType.Null) + { + return; + } - if (typeToUse is null) + var typeWithoutNull = type & ~JsonSchemaType.Null; + if (!HasMultipleTypes(typeWithoutNull)) { - return false; + writer.WriteProperty(OpenApiConstants.Type, typeWithoutNull.ToFirstIdentifier()); } + } - switch (version) + /// + /// Serializes the "type" property for OpenAPI v3 and later versions, + /// falling back to anyOf/oneOf when multiple types cannot be expressed + /// using the "type" property alone (OpenAPI 3.0). + /// + private void SerializeTypePropertyForVersion3AndLater(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) + { + if (Type is not { } type) + { + return; + } + + if (version == OpenApiSpecVersion.OpenApi3_0) { - case OpenApiSpecVersion.OpenApi2_0 or OpenApiSpecVersion.OpenApi3_0: - var typeWithoutNull = typeToUse.Value & ~JsonSchemaType.Null; - if (typeWithoutNull != 0 && !HasMultipleTypes(typeWithoutNull)) + if (type == JsonSchemaType.Null) + { + return; + } + + var typeWithoutNull = type & ~JsonSchemaType.Null; + var hasNull = typeWithoutNull != type; + var arrayWithoutNull = (from JsonSchemaType flag in jsonSchemaTypeValues + where typeWithoutNull.HasFlag(flag) + select flag).ToArray(); + + // - If we have more than one type (excluding null), we have to use anyOf/oneOf. + // - If we have exactly one type alone (without null), we emit the type property. + // - If we have exactly one non-null type and also we have the null type, we emit the type property and nullable: true (handled in SerializeNullable) + if (arrayWithoutNull.Length > 1) + { + // If the schema doesn't already have anyOf/oneOf, we can write multiple types as such. + var canWriteAsAnyOf = AnyOf is not { Count: > 0 }; + var canWriteAsOneOf = OneOf is not { Count: > 0 }; + if (canWriteAsAnyOf) { - writer.WriteProperty(OpenApiConstants.Type, typeWithoutNull.ToFirstIdentifier()); - return true; + writer.WriteOptionalCollection(OpenApiConstants.AnyOf, ConstructChildSchemasForTypes(arrayWithoutNull, hasNull), callback); + return; } - break; - default: - WriteUnifiedSchemaType(typeToUse.Value, writer); - return true; + else if (canWriteAsOneOf) + { + writer.WriteOptionalCollection(OpenApiConstants.OneOf, ConstructChildSchemasForTypes(arrayWithoutNull, hasNull), callback); + return; + } + } + else if (arrayWithoutNull.Length == 1) + { + writer.WriteProperty(OpenApiConstants.Type, arrayWithoutNull[0].ToSingleIdentifier()); + return; + } } + else + { + var array = (from JsonSchemaType flag in jsonSchemaTypeValues + where type.HasFlag(flag) + select flag).ToArray(); - return false; - } + if (array.Length > 1) + { + writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => w.WriteValue(s.ToSingleIdentifier())); + } + else if (array.Length == 1) + { + writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier()); + } + } - private static bool IsPowerOfTwo(int x) - { - return x != 0 && (x & (x - 1)) == 0; + static OpenApiSchema[] ConstructChildSchemasForTypes(JsonSchemaType[] types, bool hasNull) + { + var schemas = new OpenApiSchema[types.Length + (hasNull ? 1 : 0)]; + for (int i = 0; i < types.Length; i++) + { + schemas[i] = new OpenApiSchema() + { + Type = types[i] + }; + } + + if (hasNull) + { + schemas[schemas.Length - 1] = new OpenApiSchema() { Type = JsonSchemaType.Null }; + } + + return schemas; + } } - private static bool HasMultipleTypes(JsonSchemaType schemaType) + private JsonNode? GetCompatibilityExample() { - var schemaTypeNumeric = (int)schemaType; - return !IsPowerOfTwo(schemaTypeNumeric); +#pragma warning disable CS0618 // Type or member is obsolete + return Example ?? Examples?.FirstOrDefault(); +#pragma warning restore CS0618 // Type or member is obsolete } - private static void WriteUnifiedSchemaType(JsonSchemaType type, IOpenApiWriter writer) + private IEnumerable? GetCompatibilityExamplesExtension() { - var array = (from JsonSchemaType flag in jsonSchemaTypeValues - where type.HasFlag(flag) - select flag.ToFirstIdentifier()).ToArray(); - if (array.Length > 1) + if (Examples is null || Examples.Count == 0) { - writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => - { - if (!string.IsNullOrEmpty(s) && s is not null) - { - w.WriteValue(s); - } - }); + return null; } - else + +#pragma warning disable CS0618 // Type or member is obsolete + if (Example is not null) { - writer.WriteProperty(OpenApiConstants.Type, array[0]); + return Examples; } +#pragma warning restore CS0618 // Type or member is obsolete + + return Examples.Count > 1 ? Examples.Skip(1) : null; + } + + private static bool IsPowerOfTwo(int x) + { + return x != 0 && (x & (x - 1)) == 0; + } + + private static bool HasMultipleTypes(JsonSchemaType schemaType) + { + var schemaTypeNumeric = (int)schemaType; + return !IsPowerOfTwo(schemaTypeNumeric); } private void SerializeNullable(IOpenApiWriter writer, OpenApiSpecVersion version) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs index 665669ea2..a2ebdb1b6 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs @@ -1,11 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System; using System.Collections.Generic; using System.Text.Json.Nodes; namespace Microsoft.OpenApi { +#pragma warning disable CS0618 /// /// Parameter Object Reference. /// @@ -50,6 +52,7 @@ public string? Description public bool Deprecated { get => Target?.Deprecated ?? default; } /// + [Obsolete("Use of AllowEmptyValue is not recommended and it is likely to be removed in a later revision.")] public bool AllowEmptyValue { get => Target?.AllowEmptyValue ?? default; } /// diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs index fe55f974c..427541a78 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs @@ -9,7 +9,11 @@ namespace Microsoft.OpenApi { #pragma warning disable CS0618 /// - /// Schema reference object + /// Schema reference object. + /// Convenience getters return $ref-sibling keyword values authored on + /// before falling back to resolved values from . + /// These getters are object-model conveniences and do not represent JSON Schema + /// evaluation semantics. /// public class OpenApiSchemaReference : BaseOpenApiReferenceHolder, IOpenApiSchema, IOpenApiSchemaMissingProperties, IOpenApiSchemaWithUnevaluatedProperties, IOpenApiExtensible { @@ -163,6 +167,7 @@ public bool WriteOnly /// public OpenApiDiscriminator? Discriminator { get => Reference.Discriminator ?? Target?.Discriminator; set => Reference.Discriminator = value; } /// + [Obsolete("Use Examples instead.")] public JsonNode? Example { get => Reference.Example ?? Target?.Example; set => Reference.Example = value; } /// public IList? Examples diff --git a/src/Microsoft.OpenApi/PublicAPI.Shipped.txt b/src/Microsoft.OpenApi/PublicAPI.Shipped.txt index 1fb13bd87..62f7f1d40 100644 --- a/src/Microsoft.OpenApi/PublicAPI.Shipped.txt +++ b/src/Microsoft.OpenApi/PublicAPI.Shipped.txt @@ -2146,3 +2146,5 @@ override Microsoft.OpenApi.JsonSchemaReference.SerializeAsV31(Microsoft.OpenApi. override Microsoft.OpenApi.OpenApiSchemaReference.Target.get -> Microsoft.OpenApi.IOpenApiSchema? Microsoft.OpenApi.OpenApiWorkspace.GetDynamicAnchorCandidates(Microsoft.OpenApi.OpenApiDocument! hostDocument, string! anchorName) -> System.Collections.Generic.IReadOnlyList! static Microsoft.OpenApi.OpenApiWorkspace.ResolveDynamicAnchorInContext(Microsoft.OpenApi.IOpenApiSchema? contextSchema, string! anchorName) -> Microsoft.OpenApi.IOpenApiSchema? +const Microsoft.OpenApi.OpenApiConstants.OaiLicenseIdentifier = "x-oai-license-identifier" -> string! +const Microsoft.OpenApi.OpenApiConstants.JsonSchemaExamplesExtension = "x-jsonschema-examples" -> string! diff --git a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs index 684e72c3b..db285f078 100644 --- a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs +++ b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs @@ -42,7 +42,13 @@ public static List CreateListOfAny(this JsonNode? node, ParsingContext throw new OpenApiReaderException("Cannot create a list from this type of node.", context); } - return jsonArray.OfType().ToList(); + var list = new List(jsonArray.Count); + foreach (var element in jsonArray) + { + list.Add(element ?? JsonNullSentinel.JsonNull); + } + + return list; } public static List CreateSimpleList(this JsonNode? node, Func map, OpenApiDocument? openApiDocument, ParsingContext context) diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index e020aedc1..5fb2ec88a 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using System.Globalization; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V2 { /// diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs index af7f33d9c..9e181fdcd 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs @@ -8,6 +8,8 @@ using System.Text.Json; using System.Text.Json.Nodes; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V2 { /// @@ -267,6 +269,10 @@ internal static partial class OpenApiV2Deserializer "example", (o, n, _, _) => o.Example = n }, + { + OpenApiConstants.JsonSchemaExamplesExtension, + (o, n, _, c) => o.Examples = n.CreateListOfAny(c) + }, { OpenApiConstants.PatternPropertiesExtension, (o, n, t, c) => o.PatternProperties = n.CreateMap(LoadSchema, t, c) diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index 1f589e2ff..435515658 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -5,6 +5,8 @@ using System; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V3 { /// diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs index 48dde9d5e..7bb9327b6 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs @@ -9,6 +9,8 @@ using System.Text.Json; using System.Text.Json.Nodes; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V3 { /// @@ -280,6 +282,10 @@ internal static partial class OpenApiV3Deserializer "example", (o, n, _, _) => o.Example = n }, + { + OpenApiConstants.JsonSchemaExamplesExtension, + (o, n, _, c) => o.Examples = n.CreateListOfAny(c) + }, { "deprecated", (o, n, _, _) => @@ -407,7 +413,120 @@ public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocum } } + if (schema.Type is null && schema.Enum is { Count: 1 } && + schema.Enum[0].IsJsonNullSentinel()) + { + schema.Enum = null; + schema.Type = JsonSchemaType.Null; + } + + if (schema.Type is null) + { + if (schema.AnyOf is not null && + schema.AnyOf.All(s => s is OpenApiSchema child && DoesSchemaRepresentSingleType(child))) + { + JsonSchemaType types = GetAllTypes(schema.AnyOf); + schema.AnyOf = null; + schema.Type = types; + } + else if (schema.OneOf is not null && + schema.OneOf.All(s => s is OpenApiSchema child && DoesSchemaRepresentSingleType(child))) + { + JsonSchemaType types = GetAllTypes(schema.OneOf); + schema.OneOf = null; + schema.Type = types; + } + } + return schema; } + + private static JsonSchemaType GetAllTypes(IList schemas) + { + JsonSchemaType types = 0; + foreach (var schema in schemas) + { + types |= schema.Type!.Value; + } + + return types; + } + + private static bool DoesSchemaRepresentSingleType(OpenApiSchema schema) + { + if (schema.Type is not (JsonSchemaType.Null or + JsonSchemaType.Boolean or + JsonSchemaType.Integer or + JsonSchemaType.Number or + JsonSchemaType.String or + JsonSchemaType.Object or + JsonSchemaType.Array)) + { + return false; + } + + // Folding anyOf/oneOf back into a single "type" is only safe when the child + // schema carries nothing but its type. Otherwise any additional keywords + // (format, bounds, enum, nested schemas, etc.) would be silently dropped. + // Metadata is intentionally ignored as it only holds internal bookkeeping. + return schema.Title is null && + schema.Schema is null && + schema.Id is null && + schema.Comment is null && + schema.Vocabulary is null && + schema.DynamicRef is null && + schema.DynamicAnchor is null && + schema.Definitions is null && + schema.Anchor is null && + schema.Format is null && + schema.Description is null && + schema.Maximum is null && + schema.Minimum is null && + schema.ExclusiveMaximum is null && + schema.ExclusiveMinimum is null && + schema.MaxLength is null && + schema.MinLength is null && + schema.Pattern is null && + schema.MultipleOf is null && + schema.Default is null && + !schema.ReadOnly && + !schema.WriteOnly && + schema.AllOf is null && + schema.OneOf is null && + schema.AnyOf is null && + schema.Not is null && + schema.Required is null && + schema.Items is null && + schema.MaxItems is null && + schema.MinItems is null && + schema.UniqueItems is null && + schema.Contains is null && + schema.MaxContains is null && + schema.MinContains is null && + schema.Properties is null && + schema.PatternProperties is null && + schema.MaxProperties is null && + schema.MinProperties is null && + schema.AdditionalPropertiesAllowed && + schema.AdditionalProperties is null && + schema.Discriminator is null && + schema.Enum is null && + schema.UnevaluatedProperties && + schema.UnevaluatedPropertiesSchema is null && + schema.ContentEncoding is null && + schema.ContentMediaType is null && + schema.ContentSchema is null && + schema.PropertyNames is null && + schema.DependentSchemas is null && + schema.DependentRequired is null && + schema.If is null && + schema.Then is null && + schema.Else is null && + schema.ExternalDocs is null && + !schema.Deprecated && + schema.Xml is null && + schema.Extensions is null && + schema.UnrecognizedKeywords is null; + } } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index 2755e5324..177342fb4 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -1,6 +1,8 @@ using System; using System.Text.Json.Nodes; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V31 { /// diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs index d09df2101..52ca0912b 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs @@ -8,6 +8,8 @@ using System.Text.Json; using System.Text.Json.Nodes; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Reader.V31; internal static partial class OpenApiV31Deserializer diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs index 2bc019667..b5a398cb1 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs @@ -7,6 +7,7 @@ namespace Microsoft.OpenApi { +#pragma warning disable CS0618 /// /// Defines a non-default set of rules for validating examples in header, media type and parameter objects against the schema /// diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj index 8288bb084..aa951724a 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj +++ b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs index 483deaf25..9499f3a3c 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs @@ -51,7 +51,7 @@ public void ReturnFilteredOpenApiDocumentBasedOnOperationIdsAndTags(string? oper public void ReturnFilteredOpenApiDocumentBasedOnPostmanCollection() { // Arrange - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver2.json"); + var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver2.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); @@ -158,7 +158,7 @@ public void CreateFilteredDocumentUsingPredicateFromRequestUrl() public void ShouldParseNestedPostmanCollection() { // Arrange - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver3.json"); + var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver3.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); @@ -175,7 +175,7 @@ public void ShouldParseNestedPostmanCollection() public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument() { // Arrange - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver1.json"); + var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver1.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); @@ -192,7 +192,7 @@ public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument() public void ContinueProcessingWhenUrlsInCollectionAreMissingFromSourceDocument() { // Arrange - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver4.json"); + var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "postmanCollection_ver4.json"); var fileInput = new FileInfo(filePath); var stream = fileInput.OpenRead(); @@ -225,14 +225,14 @@ public void ThrowsInvalidOperationExceptionInCreatePredicateWhenInvalidArguments public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly() { // Arrange - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "docWithReusableHeadersAndExamples.yaml"); + var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "docWithReusableHeadersAndExamples.yaml"); var operationIds = "getItems"; // Act using var stream = File.OpenRead(filePath); var settings = new OpenApiReaderSettings(); settings.AddYamlReader(); - var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings)).Document; + var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings, TestContext.Current.CancellationToken)).Document; // validated the tags are read as references var openApiOperationTags = doc?.Paths["/items"].Operations?[HttpMethod.Get].Tags?.ToArray(); @@ -278,7 +278,7 @@ public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly( } }; subsetOpenApiDocument.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var result = outputStringWriter.ToString(); Assert.NotEmpty(result); } diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs index 6342f6703..981a00558 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs @@ -134,13 +134,13 @@ public async Task ShowCommandGeneratesMermaidMarkdownFileWithMermaidDiagramAsync // create a dummy ILogger instance for testing var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml"), - Output = new("sample.md") + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml"), + Output = new($"{nameof(ShowCommandGeneratesMermaidMarkdownFileWithMermaidDiagramAsync)}.md") }; - await OpenApiService.ShowOpenApiDocumentAsync(options, _logger); + await OpenApiService.ShowOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync(options.Output.FullName); + var output = await File.ReadAllTextAsync(options.Output.FullName, TestContext.Current.CancellationToken); Assert.Contains("graph LR", output, StringComparison.Ordinal); } @@ -149,9 +149,9 @@ public async Task ShowCommandGeneratesMermaidHtmlFileWithMermaidDiagramAsync() { var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml") + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml") }; - var filePath = await OpenApiService.ShowOpenApiDocumentAsync(options, _logger); + var filePath = await OpenApiService.ShowOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); Assert.True(File.Exists(filePath)); } @@ -159,28 +159,28 @@ public async Task ShowCommandGeneratesMermaidHtmlFileWithMermaidDiagramAsync() public Task ThrowIfOpenApiUrlIsNotProvidedWhenValidatingAsync() { return Assert.ThrowsAsync(() => - OpenApiService.ValidateOpenApiDocumentAsync("", _logger)); + OpenApiService.ValidateOpenApiDocumentAsync("", _logger, TestContext.Current.CancellationToken)); } [Fact] public Task ThrowIfURLIsNotResolvableWhenValidatingAsync() { return Assert.ThrowsAsync(() => - OpenApiService.ValidateOpenApiDocumentAsync("https://example.org926F4F21-88E7-4DC5-BF88-6C529BB77844/itdoesnmatter", _logger)); + OpenApiService.ValidateOpenApiDocumentAsync("https://example.org926F4F21-88E7-4DC5-BF88-6C529BB77844/itdoesnmatter", _logger, TestContext.Current.CancellationToken)); } [Fact] public Task ThrowIfFileDoesNotExistWhenValidatingAsync() { return Assert.ThrowsAsync(() => - OpenApiService.ValidateOpenApiDocumentAsync("aFileThatBetterNotExist.fake", _logger)); + OpenApiService.ValidateOpenApiDocumentAsync("aFileThatBetterNotExist.fake", _logger, TestContext.Current.CancellationToken)); } [Fact] public async Task ValidateCommandProcessesOpenApiAsync() { // create a dummy ILogger instance for testing - await OpenApiService.ValidateOpenApiDocumentAsync(Path.Combine("UtilityFiles", "SampleOpenApi.yml"), _logger); + await OpenApiService.ValidateOpenApiDocumentAsync(Path.Join("UtilityFiles", "SampleOpenApi.yml"), _logger, TestContext.Current.CancellationToken); Assert.True(true); } @@ -188,7 +188,7 @@ public async Task ValidateCommandProcessesOpenApiAsync() [Fact] public async Task ValidFileReturnsTrueAsync() { - var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Combine("UtilityFiles", "SampleOpenApi.yml"), _logger); + var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Join("UtilityFiles", "SampleOpenApi.yml"), _logger, TestContext.Current.CancellationToken); Assert.True(isValid); } @@ -196,7 +196,7 @@ public async Task ValidFileReturnsTrueAsync() [Fact] public async Task InvalidFileReturnsFalseAsync() { - var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Combine("UtilityFiles", "InvalidSampleOpenApi.yml"), _logger); + var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Join("UtilityFiles", "InvalidSampleOpenApi.yml"), _logger, TestContext.Current.CancellationToken); Assert.False(isValid); } @@ -206,7 +206,7 @@ public async Task CancellingValidationReturnsNullAsync() { using var cts = new CancellationTokenSource(); await cts.CancelAsync(); - var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Combine("UtilityFiles", "SampleOpenApi.yml"), _logger, cts.Token); + var isValid = await OpenApiService.ValidateOpenApiDocumentAsync(Path.Join("UtilityFiles", "SampleOpenApi.yml"), _logger, cts.Token); Assert.Null(isValid); } @@ -216,17 +216,17 @@ public async Task TransformCommandConvertsOpenApiAsync() { var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml"), - Output = new("sample.json"), + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml"), + Output = new($"{nameof(TransformCommandConvertsOpenApiAsync)}.json"), CleanOutput = true, TerseOutput = false, InlineLocal = false, InlineExternal = false, }; // create a dummy ILogger instance for testing - await OpenApiService.TransformOpenApiDocumentAsync(options, _logger); + await OpenApiService.TransformOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("sample.json"); + var output = await File.ReadAllTextAsync(options.Output.FullName, TestContext.Current.CancellationToken); Assert.NotEmpty(output); } @@ -236,16 +236,17 @@ public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAsync() { var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml"), + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml"), CleanOutput = true, TerseOutput = false, InlineLocal = false, InlineExternal = false, + Output = new FileInfo($"{nameof(TransformCommandConvertsOpenApiWithDefaultOutputNameAsync)}.yml") }; // create a dummy ILogger instance for testing - await OpenApiService.TransformOpenApiDocumentAsync(options, _logger); + await OpenApiService.TransformOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("output.yml"); + var output = await File.ReadAllTextAsync(options.Output.FullName, TestContext.Current.CancellationToken); Assert.NotEmpty(output); } @@ -254,7 +255,8 @@ public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAndSwitchF { var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml"), + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml"), + Output = new($"{nameof(TransformCommandConvertsOpenApiWithDefaultOutputNameAndSwitchFormatAsync)}.yml"), CleanOutput = true, Version = "3.0", OpenApiFormat = OpenApiConstants.Yaml, @@ -263,9 +265,9 @@ public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAndSwitchF InlineExternal = false, }; // create a dummy ILogger instance for testing - await OpenApiService.TransformOpenApiDocumentAsync(options, _logger); + await OpenApiService.TransformOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("output.yml"); + var output = await File.ReadAllTextAsync(options.Output.FullName, TestContext.Current.CancellationToken); Assert.NotEmpty(output); } @@ -280,16 +282,17 @@ public Task ThrowTransformCommandIfOpenApiAndCsdlAreEmptyAsync() InlineExternal = false, }; return Assert.ThrowsAsync(() => - OpenApiService.TransformOpenApiDocumentAsync(options, _logger)); + OpenApiService.TransformOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken)); } [Fact] public async Task TransformToPowerShellCompliantOpenApiAsync() { - var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "examplepowershellsettings.json"); + var settingsPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "examplepowershellsettings.json"); var options = new HidiOptions { - OpenApi = Path.Combine("UtilityFiles", "SampleOpenApi.yml"), + OpenApi = Path.Join("UtilityFiles", "SampleOpenApi.yml"), + Output = new($"{nameof(TransformToPowerShellCompliantOpenApiAsync)}.yaml"), CleanOutput = true, Version = "3.0", OpenApiFormat = OpenApiConstants.Yaml, @@ -299,9 +302,9 @@ public async Task TransformToPowerShellCompliantOpenApiAsync() SettingsConfig = SettingsUtilities.GetConfiguration(settingsPath) }; // create a dummy ILogger instance for testing - await OpenApiService.TransformOpenApiDocumentAsync(options, _logger); + await OpenApiService.TransformOpenApiDocumentAsync(options, _logger, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("output.yaml"); + var output = await File.ReadAllTextAsync(options.Output.FullName, TestContext.Current.CancellationToken); Assert.NotEmpty(output); } @@ -309,14 +312,15 @@ public async Task TransformToPowerShellCompliantOpenApiAsync() public async Task InvokeTransformCommandAsync() { var rootCommand = Program.CreateRootCommand(); - var openapi = Path.Combine(".", "UtilityFiles", "SampleOpenApi.yml"); - var args = new[] { "transform", "-d", openapi, "-o", "sample.json", "--co" }; + var openapi = Path.Join(".", "UtilityFiles", "SampleOpenApi.yml"); + var outputPath = $"{nameof(InvokeTransformCommandAsync)}.json"; + var args = new[] { "transform", "-d", openapi, "-o", outputPath, "--co" }; var parseResult = rootCommand.Parse(args); var handler = Assert.IsType(rootCommand.Subcommands.First(c => c.Name == "transform").Action, exactMatch: false); - await handler.InvokeAsync(parseResult); + await handler.InvokeAsync(parseResult, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("sample.json"); + var output = await File.ReadAllTextAsync(outputPath, TestContext.Current.CancellationToken); Assert.NotEmpty(output); } @@ -325,14 +329,15 @@ public async Task InvokeTransformCommandAsync() public async Task InvokeShowCommandAsync() { var rootCommand = Program.CreateRootCommand(); - var openApi = Path.Combine(".", "UtilityFiles", "SampleOpenApi.yml"); - var args = new[] { "show", "-d", openApi, "-o", "sample.md" }; + var openApi = Path.Join(".", "UtilityFiles", "SampleOpenApi.yml"); + var outputPath = $"{nameof(InvokeShowCommandAsync)}.md"; + var args = new[] { "show", "-d", openApi, "-o", outputPath }; var parseResult = rootCommand.Parse(args); var handler = Assert.IsType(rootCommand.Subcommands.First(c => c.Name == "show").Action, exactMatch: false); - await handler.InvokeAsync(parseResult); + await handler.InvokeAsync(parseResult, TestContext.Current.CancellationToken); - var output = await File.ReadAllTextAsync("sample.md"); + var output = await File.ReadAllTextAsync(outputPath, TestContext.Current.CancellationToken); Assert.Contains("graph LR", output, StringComparison.Ordinal); } @@ -340,14 +345,15 @@ public async Task InvokeShowCommandAsync() public async Task InvokePluginCommandAsync() { var rootCommand = Program.CreateRootCommand(); - var manifest = Path.Combine(".", "UtilityFiles", "exampleapimanifest.json"); - var args = new[] { "plugin", "-m", manifest, "--of", AppDomain.CurrentDomain.BaseDirectory }; + var manifest = Path.Join(".", "UtilityFiles", "exampleapimanifest.json"); + var outputPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, nameof(InvokePluginCommandAsync)); + var args = new[] { "plugin", "-m", manifest, "--of", outputPath }; var parseResult = rootCommand.Parse(args); var handler = Assert.IsType(rootCommand.Subcommands.First(c => c.Name == "plugin").Action, exactMatch: false); - await handler.InvokeAsync(parseResult); + await handler.InvokeAsync(parseResult, TestContext.Current.CancellationToken); - using var jsDoc = JsonDocument.Parse(await File.ReadAllTextAsync("ai-plugin.json")); + using var jsDoc = JsonDocument.Parse(await File.ReadAllTextAsync(Path.Join(outputPath, "ai-plugin.json"), TestContext.Current.CancellationToken)); var openAiManifest = OpenAIPluginManifest.Load(jsDoc.RootElement); Assert.NotNull(openAiManifest); diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index 2f931c53e..d640c144b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs index 86adcdd5b..bb631927b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs @@ -16,7 +16,7 @@ public class OpenApiDiagnosticTests [Fact] public async Task DetectedSpecificationVersionShouldBeV2_0() { - var actual = await OpenApiDocument.LoadAsync("V2Tests/Samples/basic.v2.yaml", SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync("V2Tests/Samples/basic.v2.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.NotNull(actual.Diagnostic); Assert.Equal(OpenApiSpecVersion.OpenApi2_0, actual.Diagnostic.SpecificationVersion); @@ -25,7 +25,7 @@ public async Task DetectedSpecificationVersionShouldBeV2_0() [Fact] public async Task DetectedSpecificationVersionShouldBeV3_0() { - var actual = await OpenApiDocument.LoadAsync("V3Tests/Samples/OpenApiDocument/minimalDocument.yaml", SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync("V3Tests/Samples/OpenApiDocument/minimalDocument.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.NotNull(actual.Diagnostic); Assert.Equal(OpenApiSpecVersion.OpenApi3_0, actual.Diagnostic.SpecificationVersion); @@ -44,7 +44,7 @@ public async Task DiagnosticReportMergedForExternalReferenceAsync() settings.AddYamlReader(); ReadResult result; - result = await OpenApiDocument.LoadAsync("OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoMain.yaml", settings); + result = await OpenApiDocument.LoadAsync("OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoMain.yaml", settings, token: TestContext.Current.CancellationToken); Assert.NotNull(result); Assert.NotNull(result.Document.Workspace); diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs index d2da0d7a4..61fc12e5b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs @@ -17,10 +17,10 @@ public class OpenApiStreamReaderTests [Fact] public async Task StreamShouldCloseIfLeaveStreamOpenSettingEqualsFalse() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "petStore.yaml")); var settings = new OpenApiReaderSettings { LeaveStreamOpen = false }; settings.AddYamlReader(); - (_, var diagnostic) = await OpenApiDocument.LoadAsync(stream, settings: settings); + (_, var diagnostic) = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); Assert.False(stream.CanRead); Assert.Equal(OpenApiConstants.Yaml, diagnostic.Format); } @@ -28,10 +28,10 @@ public async Task StreamShouldCloseIfLeaveStreamOpenSettingEqualsFalse() [Fact] public async Task StreamShouldNotCloseIfLeaveStreamOpenSettingEqualsTrue() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "petStore.yaml")); var settings = new OpenApiReaderSettings { LeaveStreamOpen = true }; settings.AddYamlReader(); - _ = await OpenApiDocument.LoadAsync(stream, settings: settings); + _ = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); Assert.True(stream.CanRead); } @@ -39,15 +39,15 @@ public async Task StreamShouldNotCloseIfLeaveStreamOpenSettingEqualsTrue() public async Task StreamShouldNotBeDisposedIfLeaveStreamOpenSettingIsTrueAsync() { var memoryStream = new MemoryStream(); - using var fileStream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); + using var fileStream = Resources.GetStream(Path.Join(SampleFolderPath, "petStore.yaml")); - await fileStream.CopyToAsync(memoryStream); + await fileStream.CopyToAsync(memoryStream, TestContext.Current.CancellationToken); memoryStream.Position = 0; var stream = memoryStream; var settings = new OpenApiReaderSettings { LeaveStreamOpen = true }; settings.AddYamlReader(); - _ = await OpenApiDocument.LoadAsync(stream, settings: settings); + _ = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); stream.Seek(0, SeekOrigin.Begin); // does not throw an object disposed exception Assert.True(stream.CanRead); } @@ -60,12 +60,12 @@ public async Task StreamShouldReadWhenInitializedAsync() BaseAddress = new Uri("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/") }; - var stream = await httpClient.GetStreamAsync("20fe7a7b720a0e48e5842d002ac418b12a8201df/tests/v3.0/pass/petstore.yaml"); + var stream = await httpClient.GetStreamAsync("20fe7a7b720a0e48e5842d002ac418b12a8201df/tests/v3.0/pass/petstore.yaml", TestContext.Current.CancellationToken); // Read V3 as YAML var settings = new OpenApiReaderSettings(); settings.AddYamlReader(); - var result = await OpenApiDocument.LoadAsync(stream, settings: settings); + var result = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs index 6c66b9d00..e695c25a4 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs @@ -14,7 +14,7 @@ public async Task ThrowOpenApiUnsupportedSpecVersionException() { try { - _ = await OpenApiDocument.LoadAsync("OpenApiReaderTests/Samples/unsupported.v1.yaml", SettingsFixture.ReaderSettings); + _ = await OpenApiDocument.LoadAsync("OpenApiReaderTests/Samples/unsupported.v1.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); } catch (OpenApiUnsupportedSpecVersionException exception) { diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs index 6d5530e3a..34f4f2d45 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs @@ -35,10 +35,10 @@ public async Task LoadingDocumentWithResolveAllReferencesShouldLoadDocumentIntoW """; var wr = new StreamWriter(stream); await wr.WriteAsync(doc); - await wr.FlushAsync(); + await wr.FlushAsync(TestContext.Current.CancellationToken); stream.Position = 0; - var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, settings: settings); + var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, settings: settings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Workspace); } @@ -56,7 +56,7 @@ public async Task LoadDocumentWithExternalReferenceShouldLoadBothDocumentsIntoWo settings.AddYamlReader(); ReadResult result; - result = await OpenApiDocument.LoadAsync("V3Tests/Samples/OpenApiWorkspace/TodoMain.yaml", settings); + result = await OpenApiDocument.LoadAsync("V3Tests/Samples/OpenApiWorkspace/TodoMain.yaml", settings, token: TestContext.Current.CancellationToken); var externalDocBaseUri = result.Document.Workspace.GetDocumentId("./TodoComponents.yaml"); var schemasPath = "#/components/schemas/"; @@ -82,14 +82,14 @@ public async Task LoadDocumentWithExternalReferencesInSubDirectories() settings.AddYamlReader(); // Act - var result = await OpenApiDocument.LoadAsync($"{sampleFolderPath}/Root.yaml", settings); + var result = await OpenApiDocument.LoadAsync($"{sampleFolderPath}/Root.yaml", settings, token: TestContext.Current.CancellationToken); var document = result.Document; var workspace = result.Document.Workspace; // Assert - Assert.True(workspace.Contains($"{Path.Combine(referenceBaseUri, "Directory", "PetsPage.yaml")}#/components/schemas/PetsPage")); - Assert.True(workspace.Contains($"{Path.Combine(referenceBaseUri, "Directory", "Pets.yaml")}#/components/schemas/Pets")); - Assert.True(workspace.Contains($"{Path.Combine(referenceBaseUri, "Directory", "Pets.yaml")}#/components/schemas/Pet")); + Assert.True(workspace.Contains($"{Path.Join(referenceBaseUri, "Directory", "PetsPage.yaml")}#/components/schemas/PetsPage")); + Assert.True(workspace.Contains($"{Path.Join(referenceBaseUri, "Directory", "Pets.yaml")}#/components/schemas/Pets")); + Assert.True(workspace.Contains($"{Path.Join(referenceBaseUri, "Directory", "Pets.yaml")}#/components/schemas/Pet")); var operationResponseSchema = document.Paths["/pets"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; Assert.IsType(operationResponseSchema); diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiYamlReaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiYamlReaderTests.cs new file mode 100644 index 000000000..ea0ef0fd9 --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiYamlReaderTests.cs @@ -0,0 +1,137 @@ +using System; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.YamlReader; +using Xunit; + +namespace Microsoft.OpenApi.Readers.Tests; + +public class OpenApiYamlReaderTests +{ + private static readonly Uri DocumentLocation = new("https://contoso.test/openapi.yaml"); + + [Fact] + public async Task ReadAsyncParsesDocumentsFromNonMemoryStreams() + { + var reader = new OpenApiYamlReader(); + await using var stream = new NonMemoryStream(CreateStream( + """ + openapi: 3.0.1 + info: + title: Sample API + version: 1.0.0 + paths: {} + """)); + + var result = await reader.ReadAsync(stream, DocumentLocation, SettingsFixture.ReaderSettings, CancellationToken.None); + + Assert.NotNull(result.Document); + Assert.Equal("Sample API", result.Document.Info.Title); + Assert.Equal(OpenApiConstants.Yaml, result.Diagnostic.Format); + } + + [Fact] + public void ReadThrowsWhenYamlDoesNotContainADocument() + { + var reader = new OpenApiYamlReader(); + using var stream = CreateStream(string.Empty); + + var exception = Assert.Throws(() => reader.Read(stream, DocumentLocation, SettingsFixture.ReaderSettings)); + + Assert.Equal("No documents found in the YAML stream.", exception.Message); + } + + [Fact] + public void ReadFragmentParsesSchemaFragments() + { + var reader = new OpenApiYamlReader(); + using var stream = CreateStream( + """ + type: string + description: A reusable schema + """); + + var schema = reader.ReadFragment( + stream, + OpenApiSpecVersion.OpenApi3_0, + new OpenApiDocument(), + out var diagnostic); + + Assert.NotNull(schema); + Assert.Empty(diagnostic.Errors); + Assert.Equal(JsonSchemaType.String, schema.Type); + Assert.Equal("A reusable schema", schema.Description); + } + + [Fact] + public void ReadThrowsWhenSettingsIsNull() + { + var reader = new OpenApiYamlReader(); + using var stream = CreateStream("openapi: 3.0.1"); + + Assert.Throws(() => reader.Read(stream, DocumentLocation, null!)); + } + + [Fact] + public void ReadReturnsDiagnosticErrorForExponentialAliasExpansion() + { + // A "billion laughs" YAML bomb must surface as a diagnostic error with no document, + // rather than throwing or exhausting memory. + var reader = new OpenApiYamlReader(); + using var stream = CreateStream( + """ + a: &a ["x","x","x","x","x","x","x","x","x"] + b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] + c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] + d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] + e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] + f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] + g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] + h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] + i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] + """); + + var result = reader.Read(stream, DocumentLocation, SettingsFixture.ReaderSettings); + + Assert.Null(result.Document); + Assert.NotEmpty(result.Diagnostic.Errors); + Assert.Equal(OpenApiConstants.Yaml, result.Diagnostic.Format); + } + + private static MemoryStream CreateStream(string yaml) + { + return new MemoryStream(Encoding.UTF8.GetBytes(yaml)); + } + + private sealed class NonMemoryStream(Stream innerStream) : Stream + { + public override bool CanRead => innerStream.CanRead; + public override bool CanSeek => innerStream.CanSeek; + public override bool CanWrite => innerStream.CanWrite; + public override long Length => innerStream.Length; + public override long Position + { + get => innerStream.Position; + set => innerStream.Position = value; + } + + public override void Flush() => innerStream.Flush(); + public override int Read(byte[] buffer, int offset, int count) => innerStream.Read(buffer, offset, count); + public override long Seek(long offset, SeekOrigin origin) => innerStream.Seek(offset, origin); + public override void SetLength(long value) => innerStream.SetLength(value); + public override void Write(byte[] buffer, int offset, int count) => innerStream.Write(buffer, offset, count); + public override ValueTask DisposeAsync() => innerStream.DisposeAsync(); + protected override void Dispose(bool disposing) + { + if (disposing) + { + innerStream.Dispose(); + } + + base.Dispose(disposing); + } + } +} diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs index b20f72e9a..3bda5fb29 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs @@ -16,7 +16,7 @@ public class TryLoadReferenceV2Tests public async Task LoadParameterReference() { // Arrange - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var reference = new OpenApiParameterReference("skipParam", result.Document); // Assert @@ -41,7 +41,7 @@ public async Task LoadParameterReference() [Fact] public async Task LoadSecuritySchemeReference() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var reference = new OpenApiSecuritySchemeReference("api_key_sample", result.Document); @@ -59,7 +59,7 @@ public async Task LoadSecuritySchemeReference() [Fact] public async Task LoadResponseReference() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var reference = new OpenApiResponseReference("NotFound", result.Document); @@ -79,7 +79,7 @@ public async Task LoadResponseReference() [Fact] public async Task LoadResponseAndSchemaReference() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "multipleReferences.v2.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var reference = new OpenApiResponseReference("GeneralError", result.Document); var expected = new OpenApiResponse diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs index 32b8a4475..7016965a3 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs @@ -22,10 +22,10 @@ public async Task EquivalentV2AndV3DocumentsShouldProduceEquivalentObjects(strin { var settings = new OpenApiReaderSettings(); settings.AddYamlReader(); - using var streamV2 = Resources.GetStream(Path.Combine(SampleFolderPath, $"{fileName}.v2.yaml")); - using var streamV3 = Resources.GetStream(Path.Combine(SampleFolderPath, $"{fileName}.v3.yaml")); - var result1 = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, $"{fileName}.v2.yaml"), SettingsFixture.ReaderSettings); - var result2 = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, $"{fileName}.v3.yaml"), SettingsFixture.ReaderSettings); + using var streamV2 = Resources.GetStream(Path.Join(SampleFolderPath, $"{fileName}.v2.yaml")); + using var streamV3 = Resources.GetStream(Path.Join(SampleFolderPath, $"{fileName}.v3.yaml")); + var result1 = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, $"{fileName}.v2.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); + var result2 = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, $"{fileName}.v3.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); result2.Document.Should().BeEquivalentTo(result1.Document, options => options.Excluding(x => x.Workspace).Excluding(y => y.BaseUri)); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs index 36ecdc849..49b9e3b04 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs @@ -67,7 +67,7 @@ public void ParseDocumentWithDifferentCultureShouldSucceed(string culture) [Fact] public async Task ShouldParseProducesInAnyOrder() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "twoResponses.json")); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "twoResponses.json"), token: TestContext.Current.CancellationToken); var okSchema = new OpenApiSchema { @@ -226,8 +226,8 @@ public async Task ShouldParseProducesInAnyOrder() [Fact] public async Task ShouldAssignSchemaToAllResponses() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "multipleProduces.json")); - var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Json); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "multipleProduces.json")); + var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Json, cancellationToken: TestContext.Current.CancellationToken); Assert.Equal(OpenApiSpecVersion.OpenApi2_0, result.Diagnostic.SpecificationVersion); @@ -257,7 +257,7 @@ public async Task ShouldAssignSchemaToAllResponses() public async Task ShouldAllowComponentsThatJustContainAReference() { // Act - var actual = (await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "ComponentRootReference.json"))).Document; + var actual = (await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "ComponentRootReference.json"), token: TestContext.Current.CancellationToken)).Document; var schema1 = actual.Components.Schemas["AllPets"]; var schema1Reference = Assert.IsType(schema1); Assert.False(schema1Reference.UnresolvedReference); @@ -279,7 +279,7 @@ public async Task ParseDocumentWithDefaultContentTypeSettingShouldSucceed() }; settings.AddYamlReader(); - var actual = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithEmptyProduces.yaml"), settings); + var actual = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithEmptyProduces.yaml"), settings, token: TestContext.Current.CancellationToken); var mediaType = actual.Document.Paths["/example"].Operations[HttpMethod.Get].Responses["200"].Content; Assert.Contains("application/json", mediaType); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs index b35344a55..789047939 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs @@ -21,7 +21,7 @@ public void ParseHeaderWithDefaultShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithDefault.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithDefault.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -50,7 +50,7 @@ public void ParseHeaderWithEnumShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithEnum.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithEnum.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs index 5e69f5da5..f2bf3fb22 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs @@ -121,7 +121,7 @@ public void ParseBasicOperationShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicOperation.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicOperation.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -139,7 +139,7 @@ public async Task ParseBasicOperationTwiceShouldYieldSameObject() // Arrange JsonNode node; using (var stream = new MemoryStream( - Encoding.Default.GetBytes(await _basicOperation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0)))) + Encoding.Default.GetBytes(await _basicOperation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken)))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -156,7 +156,7 @@ public void ParseOperationWithBodyShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithBody.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "operationWithBody.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -174,7 +174,7 @@ public async Task ParseOperationWithBodyTwiceShouldYieldSameObject() // Arrange JsonNode node; using (var stream = new MemoryStream( - Encoding.Default.GetBytes(await _operationWithBody.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0)))) + Encoding.Default.GetBytes(await _operationWithBody.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken)))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -191,7 +191,7 @@ public void ParseOperationWithResponseExamplesShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithResponseExamples.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "operationWithResponseExamples.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -257,7 +257,7 @@ public void ParseOperationWithEmptyProducesArraySetsResponseSchemaIfExists() { // Arrange JsonNode node; - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithEmptyProducesArrayInResponse.json")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "operationWithEmptyProducesArrayInResponse.json")); node = TestHelper.CreateYamlJsonNode(stream); // Act @@ -293,7 +293,7 @@ public void ParseOperationWithBodyAndEmptyConsumesSetsRequestBodySchemaIfExists( { // Arrange JsonNode node; - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithBodyAndEmptyConsumes.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "operationWithBodyAndEmptyConsumes.yaml")); node = TestHelper.CreateYamlJsonNode(stream); // Act @@ -308,14 +308,14 @@ public async Task ParseV2ResponseWithExamplesExtensionWorks() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "opWithResponseExamplesExtension.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "opWithResponseExamplesExtension.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); - var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert var expected = @"summary: Get all pets @@ -358,14 +358,14 @@ public async Task LoadV3ExamplesInResponseAsExtensionsWorks() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "v3OperationWithResponseExamples.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "v3OperationWithResponseExamples.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var operation = OpenApiV3Deserializer.LoadOperation(node, new(), new ParsingContext(new())); - var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert var expected = @"summary: Get all pets @@ -408,14 +408,14 @@ public async Task LoadV2OperationWithBodyParameterExamplesWorks() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "opWithBodyParameterExamples.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "opWithBodyParameterExamples.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); - var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert var expected = @"summary: Get all pets @@ -459,14 +459,14 @@ public async Task LoadV3ExamplesInRequestBodyParameterAsExtensionsWorks() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "v3OperationWithBodyParameterExamples.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "v3OperationWithBodyParameterExamples.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var operation = OpenApiV3Deserializer.LoadOperation(node, new(), new ParsingContext(new())); - var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert var expected = @"summary: Get all pets @@ -551,7 +551,7 @@ public async Task SerializesBodyReferencesWorks() } }); - var actual = await openApiDocument.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await openApiDocument.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); var expected = """ { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs index 43eefc5c0..c4b8f81bf 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs @@ -22,7 +22,7 @@ public void ParseBodyParameterShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "bodyParameter.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "bodyParameter.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -41,7 +41,7 @@ public void ParsePathParameterShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathParameter.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "pathParameter.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -70,7 +70,7 @@ public void ParseQueryParameterShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "queryParameter.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "queryParameter.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -105,7 +105,7 @@ public void ParseParameterWithNullLocationShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNullLocation.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithNullLocation.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -134,7 +134,7 @@ public void ParseParameterWithNoLocationShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNoLocation.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithNoLocation.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -163,7 +163,7 @@ public void ParseParameterWithNoSchemaShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNoSchema.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithNoSchema.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -188,7 +188,7 @@ public void ParseParameterWithUnknownLocationShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithUnknownLocation.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithUnknownLocation.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -217,7 +217,7 @@ public void ParseParameterWithDefaultShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithDefault.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithDefault.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -247,7 +247,7 @@ public void ParseParameterWithEnumShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithEnum.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithEnum.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -290,7 +290,7 @@ public void ParseFormDataParameterShouldSucceed() ""format"": ""binary"" }"; JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "formDataParameter.json"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "formDataParameter.json"))) { node = TestHelper.CreateYamlJsonNode(stream); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs index d064d971a..26222eb7b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs @@ -250,7 +250,7 @@ public class OpenApiPathItemTests public void ParseBasicPathItemWithFormDataShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicPathItemWithFormData.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicPathItemWithFormData.yaml")); var node = TestHelper.CreateYamlJsonNode(stream); // Act @@ -265,7 +265,7 @@ public void ParsePathItemWithFormDataPathParameterShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathItemWithFormDataPathParameter.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "pathItemWithFormDataPathParameter.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -284,7 +284,7 @@ public void ParsePathItemBodyDataPathParameterShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathItemWithBodyPathParameter.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "pathItemWithBodyPathParameter.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs index 5822d2239..ee5e4a25f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs @@ -12,6 +12,8 @@ using Microsoft.OpenApi.Tests; using Xunit; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Readers.Tests.V2Tests { [Collection("DefaultSettings")] @@ -24,7 +26,7 @@ public void ParseSchemaWithDefaultShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithDefault.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "schemaWithDefault.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -46,7 +48,7 @@ public void ParseSchemaWithExampleShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithExample.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "schemaWithExample.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -69,7 +71,7 @@ public void ParseSchemaWithEnumShouldSucceed() { // Arrange JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithEnum.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "schemaWithEnum.yaml"))) { node = TestHelper.CreateYamlJsonNode(stream); } @@ -158,10 +160,10 @@ public async Task SerializeSchemaWithNullableShouldSucceed() var expected = @"type: string x-nullable: true"; - var path = Path.Combine(SampleFolderPath, "schemaWithNullableExtension.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithNullableExtension.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV2(new OpenApiYamlWriter(writer)); @@ -178,10 +180,10 @@ public async Task SerializeSchemaWithOnlyNullableShouldSucceed() // Arrange var expected = @"{ }"; - var path = Path.Combine(SampleFolderPath, "schemaWithOnlyNullableExtension.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithOnlyNullableExtension.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV2(new OpenApiYamlWriter(writer)); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs index e108774f1..9826d90ea 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs @@ -21,7 +21,7 @@ public class OpenApiSecuritySchemeTests public void ParseHttpSecuritySchemeShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicSecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicSecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); @@ -46,7 +46,7 @@ public void ParseHttpSecuritySchemeShouldSucceed() public void ParseApiKeySecuritySchemeShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "apiKeySecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "apiKeySecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); var context = new ParsingContext(diagnostic); @@ -71,7 +71,7 @@ public void ParseApiKeySecuritySchemeShouldSucceed() [Fact] public void ParseOAuth2ImplicitSecuritySchemeShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "oauth2ImplicitSecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "oauth2ImplicitSecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); var context = new ParsingContext(diagnostic); @@ -107,7 +107,7 @@ public void ParseOAuth2ImplicitSecuritySchemeShouldSucceed() public void ParseOAuth2PasswordSecuritySchemeShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "oauth2PasswordSecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "oauth2PasswordSecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); var context = new ParsingContext(diagnostic); @@ -142,7 +142,7 @@ public void ParseOAuth2PasswordSecuritySchemeShouldSucceed() public void ParseOAuth2ApplicationSecuritySchemeShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "oauth2ApplicationSecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "oauth2ApplicationSecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); var context = new ParsingContext(diagnostic); @@ -177,7 +177,7 @@ public void ParseOAuth2ApplicationSecuritySchemeShouldSucceed() public void ParseOAuth2AccessCodeSecuritySchemeShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "oauth2AccessCodeSecurityScheme.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "oauth2AccessCodeSecurityScheme.yaml")); var document = LoadYamlDocument(stream); var diagnostic = new OpenApiDiagnostic(); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDiscriminatorTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDiscriminatorTests.cs new file mode 100644 index 000000000..3c74061ef --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDiscriminatorTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Microsoft.OpenApi.Reader; +using Xunit; + +namespace Microsoft.OpenApi.Readers.Tests.V31Tests +{ + [Collection("DefaultSettings")] + public class OpenApiDiscriminatorTests + { + private const string SampleFolderPath = "V31Tests/Samples/OpenApiDiscriminator/"; + + [Fact] + public async Task ParseBasicDiscriminatorShouldSucceed() + { + // Arrange + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicDiscriminator.yaml")); + // Copy stream to MemoryStream + using var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream, TestContext.Current.CancellationToken); + memoryStream.Position = 0; + + // Act + var openApiDocument = new OpenApiDocument(); + var discriminator = OpenApiModelFactory.Load(memoryStream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Yaml, openApiDocument, out var diagnostic, SettingsFixture.ReaderSettings); + + // Assert + Assert.Equivalent( + new OpenApiDiscriminator + { + PropertyName = "pet_type", + Mapping = new Dictionary + { + ["puppy"] = new OpenApiSchemaReference("Dog", openApiDocument), + ["kitten"] = new OpenApiSchemaReference("Cat" , openApiDocument, "https://gigantic-server.com/schemas/animals.json"), + ["monster"] = new OpenApiSchemaReference("monster" , openApiDocument, "https://gigantic-server.com/schemas/Monster/schema.json") + }, + }, discriminator); + } + } +} diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentSerializationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentSerializationTests.cs index 0e2155de3..afb27144c 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentSerializationTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentSerializationTests.cs @@ -21,8 +21,8 @@ public class OpenApiDocumentSerializationTests public async Task Serialize_DoesNotMutateDom(OpenApiSpecVersion version) { // Arrange - var filePath = Path.Combine(SampleFolderPath, "docWith31properties.json"); - var (doc, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings); + var filePath = Path.Join(SampleFolderPath, "docWith31properties.json"); + var (doc, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Act: Serialize using System.Text.Json var options = new JsonSerializerOptions diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs index d7e3509ef..60c6907ae 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs @@ -10,6 +10,8 @@ using System; using System.Net.Http; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Readers.Tests.V31Tests { public class OpenApiDocumentTests @@ -54,7 +56,7 @@ public void ParseDocumentWithMalformedReferenceShouldYieldExpectedDiagnostic() public async Task ParseDocumentWithWebhooksShouldSucceed() { // Arrange and Act - var actual = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "documentWithWebhooks.yaml"), SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "documentWithWebhooks.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var petSchema = new OpenApiSchemaReference("petSchema", actual.Document); var newPetSchema = new OpenApiSchemaReference("newPetSchema", actual.Document); @@ -249,7 +251,7 @@ public async Task ParseDocumentWithWebhooksShouldSucceed() public async Task ParseDocumentsWithReusablePathItemInWebhooksSucceeds() { // Arrange && Act - var actual = await OpenApiDocument.LoadAsync("V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml", SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync("V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var components = new OpenApiComponents { @@ -459,7 +461,7 @@ public async Task ParseDocumentWithExampleInSchemaShouldSucceed() var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = false }); // Act - var actual = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithExample.yaml"), SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithExample.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); actual.Document.SerializeAsV31(writer); // Assert @@ -470,7 +472,7 @@ public async Task ParseDocumentWithExampleInSchemaShouldSucceed() public async Task ParseDocumentWithPatternPropertiesInSchemaWorks() { // Arrange and Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithPatternPropertiesInSchema.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithPatternPropertiesInSchema.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var actualSchema = result.Document.Paths["/example"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; var expectedSchema = new OpenApiSchema @@ -516,7 +518,7 @@ public async Task ParseDocumentWithPatternPropertiesInSchemaWorks() prop3: type: string"; - var actualMediaType = await mediaType.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actualMediaType = await mediaType.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert Assert.Equivalent(expectedSchema, actualSchema); @@ -527,7 +529,7 @@ public async Task ParseDocumentWithPatternPropertiesInSchemaWorks() public async Task ParseDocumentWithReferenceByIdGetsResolved() { // Arrange and Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithReferenceById.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithReferenceById.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var responseSchema = result.Document.Paths["/resource"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; var requestBodySchema = result.Document.Paths["/resource"].Operations[HttpMethod.Post].RequestBody.Content["application/json"].Schema; @@ -544,7 +546,7 @@ public async Task ExternalDocumentDereferenceToOpenApiDocumentUsingJsonPointerWo { // Arrange var documentName = "externalRefByJsonPointer.yaml"; - var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath, documentName); + var path = Path.Join(Directory.GetCurrentDirectory(), SampleFolderPath, documentName); var settings = new OpenApiReaderSettings { @@ -554,13 +556,13 @@ public async Task ExternalDocumentDereferenceToOpenApiDocumentUsingJsonPointerWo settings.AddYamlReader(); // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, documentName), settings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, documentName), settings, token: TestContext.Current.CancellationToken); var responseSchema = result.Document.Paths["/resource"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; // Assert var externalResourceUri = new Uri( "file://" + - Path.Combine(Path.GetFullPath(SampleFolderPath), + Path.Join(Path.GetFullPath(SampleFolderPath), "externalResource.yaml#/components/schemas/todo")).AbsoluteUri; Assert.True(result.Document.Workspace.Contains(externalResourceUri)); @@ -571,7 +573,7 @@ public async Task ExternalDocumentDereferenceToOpenApiDocumentUsingJsonPointerWo public async Task ParseExternalDocumentDereferenceToOpenApiDocumentByIdWorks() { // Arrange - var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath); + var path = Path.Join(Directory.GetCurrentDirectory(), SampleFolderPath); var settings = new OpenApiReaderSettings { @@ -581,8 +583,8 @@ public async Task ParseExternalDocumentDereferenceToOpenApiDocumentByIdWorks() settings.AddYamlReader(); // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalRefById.yaml"), settings); - var doc2 = (await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalResource.yaml"), SettingsFixture.ReaderSettings)).Document; + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "externalRefById.yaml"), settings, token: TestContext.Current.CancellationToken); + var doc2 = (await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "externalResource.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var requestBodySchema = result.Document.Paths["/resource"].Operations[HttpMethod.Get].Parameters[0].Schema; result.Document.Workspace.RegisterComponents(doc2); @@ -594,8 +596,8 @@ public async Task ParseExternalDocumentDereferenceToOpenApiDocumentByIdWorks() [Fact] public async Task ParseDocumentWith31PropertiesWorks() { - var path = Path.Combine(SampleFolderPath, "documentWith31Properties.yaml"); - var doc = (await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings)).Document; + var path = Path.Join(SampleFolderPath, "documentWith31Properties.yaml"); + var doc = (await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var outputStringWriter = new StringWriter(); doc.SerializeAsV31(new OpenApiYamlWriter(outputStringWriter)); await outputStringWriter.FlushAsync(); @@ -608,16 +610,16 @@ public async Task ParseDocumentWith31PropertiesWorks() [Fact] public async Task ParseDocumentWithEmptyTagsWorks() { - var path = Path.Combine(SampleFolderPath, "documentWithEmptyTags.json"); - var doc = (await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings)).Document; + var path = Path.Join(SampleFolderPath, "documentWithEmptyTags.json"); + var doc = (await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; doc.Paths["/groups"].Operations[HttpMethod.Get].Tags.Should().BeNull("Empty tags are ignored, so we should not have any tags"); } [Fact] public async Task DocumentWithSchemaResultsInWarning() { - var path = Path.Combine(SampleFolderPath, "documentWithSchema.json"); - var (doc, diag) = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings); + var path = Path.Join(SampleFolderPath, "documentWithSchema.json"); + var (doc, diag) = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.NotNull(doc); Assert.NotNull(diag); Assert.Empty(diag.Errors); @@ -635,8 +637,8 @@ public void ParseEmptyMemoryStreamThrowsAnArgumentException() public async Task ValidateReferencedExampleInSchemaWorks() { // Arrange && Act - var path = Path.Combine(SampleFolderPath, "docWithReferencedExampleInSchemaWorks.yaml"); - var result = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings); + var path = Path.Join(SampleFolderPath, "docWithReferencedExampleInSchemaWorks.yaml"); + var result = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var actualSchemaExample = result.Document.Components.Schemas["DiffCreatedEvent"].Properties["updatedAt"].Example; var targetSchemaExample = result.Document.Components.Schemas["Timestamp"].Example; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDynamicRefTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDynamicRefTests.cs index 49921034c..a862c971b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDynamicRefTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDynamicRefTests.cs @@ -626,8 +626,8 @@ public async Task AbsoluteDynamicRefResolvesAcrossDocuments() using var streamA = new MemoryStream(Encoding.UTF8.GetBytes(yamlA)); using var streamB = new MemoryStream(Encoding.UTF8.GetBytes(yamlB)); - var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings); - var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings); + var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); + var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var docA = resultA.Document; var docB = resultB.Document; @@ -1485,8 +1485,8 @@ public async Task ExternalDynamicRefResolvesToPlainAnchorInExternalDocument() using var streamA = new MemoryStream(Encoding.UTF8.GetBytes(yamlA)); using var streamB = new MemoryStream(Encoding.UTF8.GetBytes(yamlB)); - var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings); - var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings); + var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); + var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var docA = resultA.Document; var docB = resultB.Document; @@ -1545,8 +1545,8 @@ public async Task ExternalDynamicRefWithRelativeUriResolvesAcrossDocuments() using var streamA = new MemoryStream(Encoding.UTF8.GetBytes(yamlA)); using var streamB = new MemoryStream(Encoding.UTF8.GetBytes(yamlB)); - var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings); - var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings); + var resultA = await OpenApiDocument.LoadAsync(streamA, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); + var resultB = await OpenApiDocument.LoadAsync(streamB, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var docA = resultA.Document; var docB = resultB.Document; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs index 6a03ea015..9ec9f9199 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs @@ -17,7 +17,7 @@ public class OpenApiEncodingTests public async Task ParseEncodingWithAllowReservedShouldSucceed() { // Act - var encoding = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var encoding = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs index 60ec248a0..19cf48714 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs @@ -19,10 +19,10 @@ public class OpenApiHeaderTests public async Task ParseBasicHeaderShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicHeader.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicHeader.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -40,10 +40,10 @@ public async Task ParseBasicHeaderShouldSucceed() public async Task ParseHeaderWithContentShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithContent.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithContent.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -79,10 +79,10 @@ public async Task ParseHeaderWithContentShouldSucceed() public async Task ParseHeaderWithMultipleContentTypesShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithMultipleContentTypes.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithMultipleContentTypes.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -120,10 +120,10 @@ public async Task ParseHeaderWithMultipleContentTypesShouldSucceed() public async Task ParseHeaderWithStyleAndContentShouldPreferContent() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithStyleAndContent.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithStyleAndContent.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert // Both content and style can be present, content takes precedence for serialization behavior diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs index 1af2aca13..a1bcea365 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs @@ -15,7 +15,7 @@ public class OpenApiInfoTests [Fact] public void ParseBasicInfoShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicInfo.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicInfo.yaml")); var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); var yamlNode = yamlStream.Documents[0].RootNode; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs index 26d841811..33df2da48 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs @@ -18,7 +18,7 @@ public class OpenApiLicenseTests [Fact] public void ParseLicenseWithSpdxIdentifierShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "licenseWithSpdxIdentifier.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "licenseWithSpdxIdentifier.yaml")); var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); var yamlNode = yamlStream.Documents[0].RootNode; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs index e469f8d53..c337a968f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. @@ -22,7 +22,7 @@ public class OpenApiMediaTypeTests public async Task ParseMediaTypeWithExampleShouldSucceed() { // Act - var mediaType = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "mediaTypeWithExample.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var mediaType = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "mediaTypeWithExample.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert mediaType.Should().BeEquivalentTo( @@ -43,7 +43,7 @@ public async Task ParseMediaTypeWithExampleShouldSucceed() public async Task ParseMediaTypeWithExamplesShouldSucceed() { // Act - var mediaType = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "mediaTypeWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var mediaType = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "mediaTypeWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert mediaType.Should().BeEquivalentTo( @@ -103,14 +103,14 @@ public async Task ParseMediaTypeWithEmptyArrayInExamplesWorks() } "; JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "examplesWithEmptyArray.json"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "examplesWithEmptyArray.json"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var mediaType = OpenApiV31Deserializer.LoadMediaType(node, new(), new ParsingContext(new())); - var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), serialized.MakeLineBreaksEnvironmentNeutral()); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs index 8f3314db2..8f86d8297 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs @@ -14,6 +14,8 @@ using Microsoft.OpenApi.Tests; using Xunit; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Readers.Tests.V31Tests { public class OpenApiSchemaTests @@ -23,7 +25,7 @@ public class OpenApiSchemaTests public static MemoryStream GetMemoryStream(string fileName) { - var filePath = Path.Combine(SampleFolderPath, fileName); + var filePath = Path.Join(SampleFolderPath, fileName); var fileBytes = File.ReadAllBytes(filePath); return new MemoryStream(fileBytes); } @@ -106,7 +108,7 @@ public async Task ParseBasicV31SchemaShouldSucceed() // Act var schema = await OpenApiModelFactory.LoadAsync( - Path.Combine(SampleFolderPath, "jsonSchema.json"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + Path.Join(SampleFolderPath, "jsonSchema.json"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent(expectedObject, schema); @@ -190,10 +192,10 @@ public void TestSchemaCopyConstructorWithTypeArrayWorks() [Fact] public async Task ParseV31SchemaShouldSucceed() { - var path = Path.Combine(SampleFolderPath, "schema.yaml"); + var path = Path.Join(SampleFolderPath, "schema.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var expectedSchema = new OpenApiSchema { Type = JsonSchemaType.Object, @@ -215,8 +217,8 @@ public async Task ParseV31SchemaShouldSucceed() public async Task ParseAdvancedV31SchemaShouldSucceed() { // Arrange and Act - var path = Path.Combine(SampleFolderPath, "advancedSchema.yaml"); - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var path = Path.Join(SampleFolderPath, "advancedSchema.yaml"); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var expectedSchema = new OpenApiSchema { @@ -440,10 +442,10 @@ public async Task SerializeV31SchemaWithMultipleTypesAsV3Works() var expected = @"type: string nullable: true"; - var path = Path.Combine(SampleFolderPath, "schemaWithTypeArray.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithTypeArray.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV3(new OpenApiYamlWriter(writer)); @@ -459,10 +461,10 @@ public async Task SerializeV31SchemaWithMultipleTypesAsV2Works() var expected = @"type: string x-nullable: true"; - var path = Path.Combine(SampleFolderPath, "schemaWithTypeArray.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithTypeArray.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV2(new OpenApiYamlWriter(writer)); @@ -479,10 +481,10 @@ public async Task SerializeV3SchemaWithNullableAsV31Works() - 'null' - string"; - var path = Path.Combine(SampleFolderPath, "schemaWithNullable.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithNullable.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV31(new OpenApiYamlWriter(writer)); @@ -499,10 +501,10 @@ public async Task SerializeV2SchemaWithNullableExtensionAsV31Works() - 'null' - string"; - var path = Path.Combine(SampleFolderPath, "schemaWithNullableExtension.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithNullableExtension.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi2_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV31(new OpenApiYamlWriter(writer)); @@ -538,10 +540,10 @@ public async Task LoadSchemaWithNullableExtensionAsV31ShouldNotWork(string fileP // "nullable" is only for 3.0. // and "x-nullable" is only for 2.0. // Arrange - var path = Path.Combine(SampleFolderPath, filePath); + var path = Path.Join(SampleFolderPath, filePath); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equal(JsonSchemaType.String, schema.Type); @@ -578,10 +580,10 @@ public async Task SerializeSchemaWithJsonSchemaKeywordsWorks() $dynamicRef: '#addressDef' description: Schema for a person object "; - var path = Path.Combine(SampleFolderPath, "schemaWithJsonSchemaKeywords.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithJsonSchemaKeywords.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // serialization var writer = new StringWriter(); @@ -622,10 +624,10 @@ public async Task ParseSchemaWithConstWorks() } }"; - var path = Path.Combine(SampleFolderPath, "schemaWithConst.json"); + var path = Path.Join(SampleFolderPath, "schemaWithConst.json"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.Equal("active", schema.Properties["status"].Const); Assert.Equal("admin", schema.Properties["user"].Properties["role"].Const); @@ -665,10 +667,10 @@ public async Task ParseSchemaWithConstNullWorks() } }"; - var path = Path.Combine(SampleFolderPath, "schemaWithConstNull.json"); + var path = Path.Join(SampleFolderPath, "schemaWithConstNull.json"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var statusSchema = Assert.IsType(schema.Properties["status"]); Assert.Null(statusSchema.Const); @@ -1018,7 +1020,7 @@ public async Task ParseSchemaReferencePreservesJsonSchema2020KeywordSiblings() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; @@ -1060,14 +1062,14 @@ public async Task SerializeSchemaReferencePreservesJsonSchema2020KeywordSiblings // Act — parse then serialize back using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var writer = new StringWriter(); result.Document.SerializeAsV31(new OpenApiYamlWriter(writer)); var output = writer.ToString(); // Assert — round-trip preserves $dynamicAnchor and $defs alongside $ref using var roundTripStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(output)); - var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings); + var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(roundTripResult.Document.Components); Assert.NotNull(roundTripResult.Document.Components.Schemas); var referencing = roundTripResult.Document.Components.Schemas["Referencing"]; @@ -1104,7 +1106,7 @@ public async Task ParseSchemaReferencePreservesScalarKeywordSiblings() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; @@ -1143,14 +1145,14 @@ public async Task SerializeSchemaReferencePreservesScalarKeywordSiblings() // Act — parse then serialize back using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var writer = new StringWriter(); result.Document.SerializeAsV31(new OpenApiYamlWriter(writer)); var output = writer.ToString(); // Assert — round-trip preserves scalar siblings alongside $ref using var roundTripStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(output)); - var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings); + var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(roundTripResult.Document.Components); Assert.NotNull(roundTripResult.Document.Components.Schemas); var referencing = roundTripResult.Document.Components.Schemas["Referencing"]; @@ -1186,7 +1188,7 @@ public async Task ParseSchemaReferencePreservesVocabularySibling() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; @@ -1235,7 +1237,7 @@ public async Task ParseSchemaReferencePreservesDynamicAnchorInsideDefsInAllOf() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var assetPaged = result.Document.Components.Schemas["AssetPaged"]; @@ -1282,7 +1284,7 @@ public async Task EmptySiblingCollectionsFallThroughToTarget() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; @@ -1324,7 +1326,7 @@ public async Task SiblingsOnRefAreDroppedForOpenApi30() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; @@ -1358,14 +1360,14 @@ public async Task SerializeSchemaReferencePreservesVocabularySibling() // Act — parse then serialize back using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var writer = new StringWriter(); result.Document.SerializeAsV31(new OpenApiYamlWriter(writer)); var output = writer.ToString(); // Assert — round-trip preserves $vocabulary alongside $ref using var roundTripStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(output)); - var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings); + var roundTripResult = await OpenApiDocument.LoadAsync(roundTripStream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(roundTripResult.Document.Components); Assert.NotNull(roundTripResult.Document.Components.Schemas); var referencing = roundTripResult.Document.Components.Schemas["Referencing"]; @@ -1402,7 +1404,7 @@ public async Task CreateShallowCopyPreservesKeywordSiblings() // Act using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yaml)); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(result.Document.Components); Assert.NotNull(result.Document.Components.Schemas); var referencing = result.Document.Components.Schemas["Referencing"]; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs index 0aa1cbb76..cb98d2a0f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs @@ -17,10 +17,10 @@ public class RelativeReferenceTests public async Task ParseInlineLocalReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "inlineLocalReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "inlineLocalReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schemaType = actual.Paths["/item"].Operations[HttpMethod.Get].Parameters[0].Schema.Type; // Assert @@ -40,7 +40,7 @@ public async Task ParseInlineExternalReferenceWorks() } }; - var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath); + var path = Path.Join(Directory.GetCurrentDirectory(), SampleFolderPath); var settings = new OpenApiReaderSettings { @@ -50,7 +50,7 @@ public async Task ParseInlineExternalReferenceWorks() settings.AddYamlReader(); // Act - var actual = (await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "inlineExternalReference.yaml"), settings)).Document; + var actual = (await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "inlineExternalReference.yaml"), settings, token: TestContext.Current.CancellationToken)).Document; var exampleValue = actual.Paths["/items"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Examples["item-list"].Value; // Assert @@ -63,7 +63,7 @@ public async Task ParseInlineExternalReferenceWorks() public async Task ParseComponentExternalReferenceWorks() { // Arrange - var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath); + var path = Path.Join(Directory.GetCurrentDirectory(), SampleFolderPath); var settings = new OpenApiReaderSettings { LoadExternalRefs = true, @@ -72,7 +72,7 @@ public async Task ParseComponentExternalReferenceWorks() settings.AddYamlReader(); // Act - var actual = (await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "componentExternalReference.yaml"), settings)).Document; + var actual = (await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "componentExternalReference.yaml"), settings, token: TestContext.Current.CancellationToken)).Document; var securitySchemeValue = actual.Components.SecuritySchemes["customapikey"]; // Assert @@ -83,10 +83,10 @@ public async Task ParseComponentExternalReferenceWorks() public async Task ParseRootInlineJsonSchemaReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "rootInlineSchemaReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "rootInlineSchemaReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Paths["/item"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; // Assert @@ -97,10 +97,10 @@ public async Task ParseRootInlineJsonSchemaReferenceWorks() public async Task ParseSubschemaInlineJsonSchemaReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "subschemaInlineSchemaReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "subschemaInlineSchemaReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Paths["/items"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.Items; // Assert @@ -111,10 +111,10 @@ public async Task ParseSubschemaInlineJsonSchemaReferenceWorks() public async Task ParseRootComponentJsonSchemaReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "rootComponentSchemaReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "rootComponentSchemaReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Components.Schemas["specialitem"]; // Assert @@ -126,10 +126,10 @@ public async Task ParseRootComponentJsonSchemaReferenceWorks() public async Task ParseSubschemaComponentJsonSchemaReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "subschemaComponentSchemaReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "subschemaComponentSchemaReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Components.Schemas["items"].Items; // Assert @@ -140,10 +140,10 @@ public async Task ParseSubschemaComponentJsonSchemaReferenceWorks() public async Task ParseInternalComponentSubschemaJsonSchemaReferenceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "internalComponentsSubschemaReference.yaml"); + var filePath = Path.Join(SampleFolderPath, "internalComponentsSubschemaReference.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var addressSchema = actual.Paths["/person/{id}/address"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; var itemsSchema = actual.Paths["/human"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; @@ -156,7 +156,7 @@ public async Task ParseInternalComponentSubschemaJsonSchemaReferenceWorks() public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() { // Arrange - var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath); + var path = Path.Join(Directory.GetCurrentDirectory(), SampleFolderPath); var settings = new OpenApiReaderSettings { LoadExternalRefs = true, @@ -165,7 +165,7 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() settings.AddYamlReader(); // Act - var actual = (await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalComponentSubschemaReference.yaml"), settings)).Document; + var actual = (await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "externalComponentSubschemaReference.yaml"), settings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; // Assert @@ -196,7 +196,7 @@ await File.WriteAllTextAsync(rootPath, application/json: schema: $ref: 'OAS-schemas.yaml#address' -"); +", TestContext.Current.CancellationToken); await File.WriteAllTextAsync(externalPath, @" openapi: 3.1.0 @@ -211,7 +211,7 @@ await File.WriteAllTextAsync(externalPath, address: $anchor: address type: object -"); +", TestContext.Current.CancellationToken); try { @@ -222,7 +222,7 @@ await File.WriteAllTextAsync(externalPath, }; settings.AddYamlReader(); - var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var result = await OpenApiDocument.LoadAsync(rootPath, settings, token: TestContext.Current.CancellationToken); var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; Assert.Equal(JsonSchemaType.Object, schema.Type); @@ -257,7 +257,7 @@ await File.WriteAllTextAsync(rootPath, application/json: schema: $ref: 'OAS-schemas.yaml#/person/properties/address' -"); +", TestContext.Current.CancellationToken); await File.WriteAllTextAsync(externalPath, @" person: @@ -265,7 +265,7 @@ await File.WriteAllTextAsync(externalPath, properties: address: type: object -"); +", TestContext.Current.CancellationToken); try { @@ -276,7 +276,7 @@ await File.WriteAllTextAsync(externalPath, }; settings.AddYamlReader(); - var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var result = await OpenApiDocument.LoadAsync(rootPath, settings, token: TestContext.Current.CancellationToken); var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; var schemaReference = Assert.IsType(schema); @@ -293,10 +293,10 @@ await File.WriteAllTextAsync(externalPath, public async Task ParseReferenceToInternalComponentUsingDollarIdWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "internalComponentReferenceUsingId.yaml"); + var filePath = Path.Join(SampleFolderPath, "internalComponentReferenceUsingId.yaml"); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; // Assert @@ -338,11 +338,11 @@ await File.WriteAllTextAsync(rootPath, properties: street: type: string -"); +", TestContext.Current.CancellationToken); try { - var result = await OpenApiDocument.LoadAsync(rootPath, SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(rootPath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var schema = result.Document.Paths["/person/{id}/address"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; Assert.Equal(JsonSchemaType.Object, schema.Type); @@ -358,12 +358,12 @@ await File.WriteAllTextAsync(rootPath, public async Task ParseLocalReferenceToJsonSchemaResourceWorks() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "localReferenceToJsonSchemaResource.yaml"); + var filePath = Path.Join(SampleFolderPath, "localReferenceToJsonSchemaResource.yaml"); var stringWriter = new StringWriter(); var writer = new OpenApiYamlWriter(stringWriter); // Act - var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings)).Document; + var actual = (await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var schema = actual.Components.Schemas["a"].Properties["b"].Properties["c"].Properties["b"]; schema.SerializeAsV31(writer); @@ -402,7 +402,7 @@ await File.WriteAllTextAsync(rootPath, schemas: Leaf: $ref: './shared.yaml#/Leaf' -"); +", TestContext.Current.CancellationToken); await File.WriteAllTextAsync(sharedPath, @"Leaf: @@ -412,7 +412,7 @@ await File.WriteAllTextAsync(sharedPath, type: string y: type: integer -"); +", TestContext.Current.CancellationToken); try { @@ -423,7 +423,7 @@ await File.WriteAllTextAsync(sharedPath, }; settings.AddYamlReader(); - var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var result = await OpenApiDocument.LoadAsync(rootPath, settings, token: TestContext.Current.CancellationToken); var responseSchema = result.Document.Paths["/a"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; var metaSchema = responseSchema.Properties["meta"]; var leafSchema = result.Document.Components.Schemas["Leaf"]; @@ -521,10 +521,10 @@ public void ResolveSubSchema_ShouldRecurseIntoAllOfComposition() public async Task ShouldResolveRelativeSubReference() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "relativeSubschemaReference.json"); + var filePath = Path.Join(SampleFolderPath, "relativeSubschemaReference.json"); // Act - var (actual, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings); + var (actual, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var fooComponentSchema = actual.Components.Schemas["Foo"]; var seq1Property = fooComponentSchema.Properties["seq1"]; @@ -538,9 +538,9 @@ public async Task ShouldResolveRelativeSubReference() public async Task ShouldResolveRelativeSubReferenceUsingParsingContext() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "relativeSubschemaReference.json"); + var filePath = Path.Join(SampleFolderPath, "relativeSubschemaReference.json"); using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); - var jsonNode = await JsonNode.ParseAsync(fs); + var jsonNode = await JsonNode.ParseAsync(fs, cancellationToken: TestContext.Current.CancellationToken); var schemaJsonNode = jsonNode["components"]?["schemas"]?["Foo"]; Assert.NotNull(schemaJsonNode); var diagnostic = new OpenApiDiagnostic(); @@ -631,10 +631,10 @@ public void ShouldResolveAbsoluteSubReferenceFromTheObjectModel() public async Task ShouldResolveRecursiveRelativeSubReference() { // Arrange - var filePath = Path.Combine(SampleFolderPath, "recursiveRelativeSubschemaReference.json"); + var filePath = Path.Join(SampleFolderPath, "recursiveRelativeSubschemaReference.json"); // Act - var (actual, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings); + var (actual, _) = await OpenApiDocument.LoadAsync(filePath, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var fooComponentSchema = actual.Components.Schemas["Foo"]; var fooSchemaParentProperty = fooComponentSchema.Properties["parent"]; @@ -652,9 +652,9 @@ public async Task ShouldResolveRecursiveRelativeSubReference() [Fact] public async Task ShouldResolveReferencesInSchemasFromSystemTextJson() { - var filePath = Path.Combine(SampleFolderPath, "STJSchema.json"); + var filePath = Path.Join(SampleFolderPath, "STJSchema.json"); using var fs = File.OpenRead(filePath); - var jsonNode = await JsonNode.ParseAsync(fs); + var jsonNode = await JsonNode.ParseAsync(fs, cancellationToken: TestContext.Current.CancellationToken); var parsingContext = new ParsingContext(new OpenApiDiagnostic()); var document = new OpenApiDocument(); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml new file mode 100644 index 000000000..f93798c9e --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml @@ -0,0 +1,5 @@ +propertyName: pet_type +mapping: + puppy: '#/components/schemas/Dog' + kitten: https://gigantic-server.com/schemas/animals.json#/components/schemas/Cat + monster: https://gigantic-server.com/schemas/Monster/schema.json#/components/schemas/monster \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs index 1dee79059..c619dc599 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs @@ -19,7 +19,7 @@ public class OpenApiCallbackTests public async Task ParseBasicCallbackShouldSucceed() { // Act - var callback = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "basicCallback.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var callback = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "basicCallback.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -59,10 +59,10 @@ public async Task ParseBasicCallbackShouldSucceed() [Fact] public async Task ParseCallbackWithReferenceShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "callbackWithReference.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "callbackWithReference.yaml")); // Act - var result = await OpenApiModelFactory.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings); + var result = await OpenApiModelFactory.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); // Assert var path = result.Document.Paths.First().Value; @@ -113,7 +113,7 @@ public async Task ParseCallbackWithReferenceShouldSucceed() public async Task ParseMultipleCallbacksWithReferenceShouldSucceed() { // Act - var result = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "multipleCallbacksWithReference.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "multipleCallbacksWithReference.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert var path = result.Document.Paths.First().Value; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs index 9c0a9c0b6..0bb339a08 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs @@ -18,10 +18,10 @@ public class OpenApiDiscriminatorTests public async Task ParseBasicDiscriminatorShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicDiscriminator.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicDiscriminator.yaml")); // Copy stream to MemoryStream using var memoryStream = new MemoryStream(); - await stream.CopyToAsync(memoryStream); + await stream.CopyToAsync(memoryStream, TestContext.Current.CancellationToken); memoryStream.Position = 0; // Act diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs index e34024b32..6cc8bb7a3 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs @@ -92,8 +92,8 @@ public void ParseInlineStringWithoutProvidingFormatSucceeds() [Fact] public async Task ParseBasicDocumentWithMultipleServersShouldSucceed() { - var path = Path.Combine(SampleFolderPath, "basicDocumentWithMultipleServers.yaml"); - var result = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings); + var path = Path.Join(SampleFolderPath, "basicDocumentWithMultipleServers.yaml"); + var result = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.Empty(result.Diagnostic.Errors); result.Document.Should().BeEquivalentTo( @@ -123,13 +123,13 @@ public async Task ParseBasicDocumentWithMultipleServersShouldSucceed() [Fact] public async Task ParseBrokenMinimalDocumentShouldYieldExpectedDiagnostic() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "brokenMinimalDocument.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "brokenMinimalDocument.yaml")); // Copy stream to MemoryStream using var memoryStream = new MemoryStream(); - await stream.CopyToAsync(memoryStream); + await stream.CopyToAsync(memoryStream, TestContext.Current.CancellationToken); memoryStream.Position = 0; - var result = await OpenApiDocument.LoadAsync(memoryStream, settings: SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(memoryStream, settings: SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); result.Document.Should().BeEquivalentTo( new OpenApiDocument @@ -190,7 +190,7 @@ public void ParseDocumentWithMalformedReferenceShouldYieldExpectedDiagnostic() [Fact] public async Task ParseMinimalDocumentShouldSucceed() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "minimalDocument.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "minimalDocument.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); result.Document.Should().BeEquivalentTo( new OpenApiDocument @@ -214,8 +214,8 @@ public async Task ParseMinimalDocumentShouldSucceed() [Fact] public async Task ParseStandardPetStoreDocumentShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); - var actual = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "petStore.yaml")); + var actual = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var components = new OpenApiComponents { @@ -600,8 +600,8 @@ public async Task ParseStandardPetStoreDocumentShouldSucceed() [Fact] public async Task ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStoreWithTagAndSecurity.yaml")); - var actual = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "petStoreWithTagAndSecurity.yaml")); + var actual = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var components = new OpenApiComponents { @@ -1074,7 +1074,7 @@ [new OpenApiSecuritySchemeReference("securitySchemeName2")] = [Fact] public async Task ParsePetStoreExpandedShouldSucceed() { - var actual = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "petStoreExpanded.yaml"), SettingsFixture.ReaderSettings); + var actual = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "petStoreExpanded.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // TODO: Create the object in memory and compare with the one read from YAML file. @@ -1085,7 +1085,7 @@ public async Task ParsePetStoreExpandedShouldSucceed() [Fact] public async Task GlobalSecurityRequirementShouldReferenceSecurityScheme() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "securedApi.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "securedApi.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var securityRequirement = result.Document.Security[0]; @@ -1095,7 +1095,7 @@ public async Task GlobalSecurityRequirementShouldReferenceSecurityScheme() [Fact] public async Task HeaderParameterShouldAllowExample() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "apiWithFullHeaderComponent.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "apiWithFullHeaderComponent.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var exampleHeader = result.Document.Components?.Headers?["example-header"]; Assert.NotNull(exampleHeader); @@ -1157,7 +1157,7 @@ public async Task HeaderParameterShouldAllowExample() public async Task ParseDocumentWithReferencedSecuritySchemeWorks() { // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithSecuritySchemeReference.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithSecuritySchemeReference.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var securityScheme = result.Document.Components.SecuritySchemes["OAuth2"]; // Assert @@ -1168,10 +1168,10 @@ public async Task ParseDocumentWithReferencedSecuritySchemeWorks() public async Task ParseDocumentWithJsonSchemaReferencesWorks() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "docWithJsonSchema.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "docWithJsonSchema.yaml")); // Act - var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(stream, OpenApiConstants.Yaml, SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken); var actualSchema = result.Document.Paths["/users/{userId}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; @@ -1184,7 +1184,7 @@ public async Task ParseDocumentWithJsonSchemaReferencesWorks() public async Task ValidateExampleShouldNotHaveDataTypeMismatch() { // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "documentWithDateExampleInSchema.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "documentWithDateExampleInSchema.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert var warnings = result.Diagnostic.Warnings; @@ -1249,7 +1249,7 @@ public async Task ParsesDoubleHopReferences() { using var stream = new MemoryStream(Encoding.UTF8.GetBytes(DoubleHopReferenceSerializedDoc)); - var (document, _) = await OpenApiDocument.LoadAsync(stream); + var (document, _) = await OpenApiDocument.LoadAsync(stream, cancellationToken: TestContext.Current.CancellationToken); Assert.NotNull(document); var petReferenceInResponse = Assert.IsType(document.Paths["/pets"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema); @@ -1331,7 +1331,7 @@ public async Task SerializesDoubleHopeReferences() using var stringWriter = new StringWriter(); var writer = new OpenApiJsonWriter(stringWriter); document.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var serializedDoc = stringWriter.ToString(); @@ -1418,12 +1418,12 @@ public async Task ParseDocWithRefsUsingProxyReferencesSucceeds() default: 10 """; - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "minifiedPetStore.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "minifiedPetStore.yaml")); // Act - var doc = (await OpenApiDocument.LoadAsync(stream, settings: SettingsFixture.ReaderSettings)).Document; + var doc = (await OpenApiDocument.LoadAsync(stream, settings: SettingsFixture.ReaderSettings, cancellationToken: TestContext.Current.CancellationToken)).Document; var actualParam = doc.Paths["/pets"].Operations[HttpMethod.Get].Parameters[0]; - var outputDoc = (await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0)).MakeLineBreaksEnvironmentNeutral(); + var outputDoc = (await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken)).MakeLineBreaksEnvironmentNeutral(); var expectedParam = expected.Paths["/pets"].Operations[HttpMethod.Get].Parameters[0]; var expectedParamReference = Assert.IsType(expectedParam); @@ -1513,7 +1513,7 @@ public void ParseBasicDocumentWithServerVariableAndNoDefaultShouldFail() [Fact] public async Task ParseDocumentWithEmptyPathsSucceeds() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithEmptyPaths.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithEmptyPaths.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.Empty(result.Diagnostic.Errors); } @@ -1521,17 +1521,17 @@ public async Task ParseDocumentWithEmptyPathsSucceeds() public async Task ParseDocumentWithExampleReferencesPasses() { // Act & Assert: Ensure no NullReferenceException is thrown - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "docWithExampleReferences.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "docWithExampleReferences.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.Empty(result.Diagnostic.Errors); } [Fact] public async Task ParseDocumentWithNonStandardMIMETypePasses() { - var path = Path.Combine(SampleFolderPath, "basicDocumentWithMultipleServers.yaml"); + var path = Path.Join(SampleFolderPath, "basicDocumentWithMultipleServers.yaml"); using var stream = Resources.GetStream(path); using var streamReader = new StreamReader(stream); - var contentAsString = await streamReader.ReadToEndAsync(); + var contentAsString = await streamReader.ReadToEndAsync(TestContext.Current.CancellationToken); var mockMessageHandler = new Mock(); mockMessageHandler.Protected() .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) @@ -1545,7 +1545,7 @@ public async Task ParseDocumentWithNonStandardMIMETypePasses() }; settings.AddYamlReader(); // Act & Assert: Ensure NotSupportedException is not thrown for non-standard MIME type: text/x-yaml - var result = await OpenApiDocument.LoadAsync("https://localhost/doesntmatter/foo.bar", settings); + var result = await OpenApiDocument.LoadAsync("https://localhost/doesntmatter/foo.bar", settings, token: TestContext.Current.CancellationToken); Assert.NotNull(result.Document); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs index 0c0c4e96f..240a98f3d 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs @@ -18,7 +18,7 @@ public class OpenApiEncodingTests public async Task ParseBasicEncodingShouldSucceed() { // Act - var encoding = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "basicEncoding.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var encoding = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "basicEncoding.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -31,10 +31,10 @@ public async Task ParseBasicEncodingShouldSucceed() [Fact] public async Task ParseAdvancedEncodingShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "advancedEncoding.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "advancedEncoding.yaml")); // Act - var encoding = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var encoding = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -60,7 +60,7 @@ public async Task ParseAdvancedEncodingShouldSucceed() public async Task ParseEncodingWithAllowReservedShouldSucceed() { // Act - var encoding = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var encoding = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs index ffd221d1a..6d52c4ff4 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs @@ -18,7 +18,7 @@ public class OpenApiExampleTests [Fact] public async Task ParseAdvancedExampleShouldSucceed() { - var example = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "advancedExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var example = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "advancedExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var expected = new OpenApiExample { Value = new JsonObject @@ -70,7 +70,7 @@ public async Task ParseAdvancedExampleShouldSucceed() [Fact] public async Task ParseExampleForcedStringSucceed() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "explicitString.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "explicitString.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); Assert.Empty(result.Diagnostic.Errors); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs index ba0ab49d3..1b728ffd6 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs @@ -19,10 +19,10 @@ public class OpenApiHeaderTests public async Task ParseBasicHeaderShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicHeader.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicHeader.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -40,10 +40,10 @@ public async Task ParseBasicHeaderShouldSucceed() public async Task ParseHeaderWithContentShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithContent.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithContent.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -79,10 +79,10 @@ public async Task ParseHeaderWithContentShouldSucceed() public async Task ParseHeaderWithMultipleContentTypesShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithMultipleContentTypes.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithMultipleContentTypes.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -120,10 +120,10 @@ public async Task ParseHeaderWithMultipleContentTypesShouldSucceed() public async Task ParseHeaderWithStyleAndContentShouldPreferContent() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithStyleAndContent.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "headerWithStyleAndContent.yaml")); // Act - var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert // Both content and style can be present, content takes precedence for serialization behavior diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs index 726f47e59..9379c38e8 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs @@ -21,7 +21,7 @@ public class OpenApiInfoTests public async Task ParseAdvancedInfoShouldSucceed() { // Act - var openApiInfo = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "advancedInfo.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var openApiInfo = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "advancedInfo.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert openApiInfo.Should().BeEquivalentTo( @@ -81,7 +81,7 @@ public async Task ParseAdvancedInfoShouldSucceed() public async Task ParseBasicInfoShouldSucceed() { // Act - var openApiInfo = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "basicInfo.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var openApiInfo = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "basicInfo.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -108,10 +108,10 @@ public async Task ParseBasicInfoShouldSucceed() [Fact] public async Task ParseMinimalInfoShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "minimalInfo.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "minimalInfo.yaml")); // Act - var openApiInfo = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var openApiInfo = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs index 5e437b1bd..10c0fb9a9 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. @@ -22,7 +22,7 @@ public class OpenApiMediaTypeTests public async Task ParseMediaTypeWithExampleShouldSucceed() { // Act - var mediaType = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "mediaTypeWithExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var mediaType = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "mediaTypeWithExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert mediaType.Should().BeEquivalentTo( @@ -43,7 +43,7 @@ public async Task ParseMediaTypeWithExampleShouldSucceed() public async Task ParseMediaTypeWithExamplesShouldSucceed() { // Act - var mediaType = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "mediaTypeWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var mediaType = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "mediaTypeWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert mediaType.Should().BeEquivalentTo( @@ -103,14 +103,14 @@ public async Task ParseMediaTypeWithEmptyArrayInExamplesWorks() } "; JsonNode node; - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "examplesWithEmptyArray.json"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "examplesWithEmptyArray.json"))) { node = TestHelper.CreateYamlJsonNode(stream); } // Act var mediaType = OpenApiV3Deserializer.LoadMediaType(node, new(), new ParsingContext(new())); - var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), serialized.MakeLineBreaksEnvironmentNeutral()); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs index 7b0844a9b..8756e90f6 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs @@ -20,7 +20,7 @@ public class OpenApiOperationTests [Fact] public async Task OperationWithSecurityRequirementShouldReferenceSecurityScheme() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "securedOperation.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "securedOperation.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var securityScheme = result.Document.Paths["/"].Operations[HttpMethod.Get].Security[0].Keys.First(); Assert.Equivalent(result.Document.Components.SecuritySchemes.First().Value, securityScheme); @@ -34,7 +34,7 @@ public async Task ParseOperationWithParameterWithNoLocationShouldSucceed() Tags = new HashSet { new() { Name = "user" } } }; // Act - var operation = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "operationWithParameterWithNoLocation.json"), OpenApiSpecVersion.OpenApi3_0, openApiDocument, SettingsFixture.ReaderSettings); + var operation = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "operationWithParameterWithNoLocation.json"), OpenApiSpecVersion.OpenApi3_0, openApiDocument, SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var expectedOp = new OpenApiOperation { Tags = new HashSet() diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs index fe585d969..9b28fbffe 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs @@ -21,10 +21,10 @@ public class OpenApiParameterTests public async Task ParsePathParameterShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathParameter.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "pathParameter.yaml")); // Act - var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -45,7 +45,7 @@ public async Task ParsePathParameterShouldSucceed() public async Task ParseQueryParameterShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "queryParameter.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "queryParameter.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -72,7 +72,7 @@ public async Task ParseQueryParameterShouldSucceed() public async Task ParseQueryParameterWithObjectTypeShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "queryParameterWithObjectType.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "queryParameterWithObjectType.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -96,10 +96,10 @@ public async Task ParseQueryParameterWithObjectTypeShouldSucceed() public async Task ParseQueryParameterWithObjectTypeAndContentShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "queryParameterWithObjectTypeAndContent.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "queryParameterWithObjectTypeAndContent.yaml")); // Act - var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -140,7 +140,7 @@ public async Task ParseQueryParameterWithObjectTypeAndContentShouldSucceed() public async Task ParseHeaderParameterShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "headerParameter.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "headerParameter.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -168,7 +168,7 @@ public async Task ParseHeaderParameterShouldSucceed() public async Task ParseParameterWithNullLocationShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "parameterWithNullLocation.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "parameterWithNullLocation.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -189,10 +189,10 @@ public async Task ParseParameterWithNullLocationShouldSucceed() public async Task ParseParameterWithNoLocationShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNoLocation.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithNoLocation.yaml")); // Act - var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -213,10 +213,10 @@ public async Task ParseParameterWithNoLocationShouldSucceed() public async Task ParseParameterWithUnknownLocationShouldSucceed() { // Arrange - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithUnknownLocation.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithUnknownLocation.yaml")); // Act - var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -237,7 +237,7 @@ public async Task ParseParameterWithUnknownLocationShouldSucceed() public async Task ParseParameterWithExampleShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "parameterWithExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "parameterWithExample.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert parameter.Should().BeEquivalentTo( @@ -260,7 +260,7 @@ public async Task ParseParameterWithExampleShouldSucceed() public async Task ParseParameterWithExamplesShouldSucceed() { // Act - var parameter = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "parameterWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var parameter = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "parameterWithExamples.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert parameter.Should().BeEquivalentTo( @@ -353,7 +353,7 @@ public void ParseParameterWithReferenceWorks() document.Workspace.RegisterComponents(document); - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithRef.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "parameterWithRef.yaml")); var node = TestHelper.CreateYamlJsonNode(stream); var expected = document.Components.Parameters["tagsParameter"]; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs index 0f98b40ce..f89ef938c 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs @@ -16,7 +16,7 @@ public class OpenApiResponseTests [Fact] public async Task ResponseWithReferencedHeaderShouldReferenceComponent() { - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "responseWithHeaderReference.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "responseWithHeaderReference.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var response = result.Document.Components.Responses["Test"]; var expected = response.Headers.First().Value; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs index cda5c4c72..85126723b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs @@ -15,6 +15,8 @@ using SharpYaml.Serialization; using Xunit; +#pragma warning disable CS0618 + namespace Microsoft.OpenApi.Readers.Tests.V3Tests { [Collection("DefaultSettings")] @@ -25,7 +27,7 @@ public class OpenApiSchemaTests [Fact] public void ParsePrimitiveSchemaShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "primitiveSchema.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "primitiveSchema.yaml")); var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); var yamlNode = yamlStream.Documents[0].RootNode; @@ -148,7 +150,7 @@ public void ParseSchemaWithNullableBeforeOrAfterTypePreservesNullFlag(string sch [Fact] public void ParseDictionarySchemaShouldSucceed() { - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "dictionarySchema.yaml"))) + using (var stream = Resources.GetStream(Path.Join(SampleFolderPath, "dictionarySchema.yaml"))) { var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); @@ -235,7 +237,7 @@ public void ParseSchemaWithOaiCompatibilityKeywordsShouldSucceed() [Fact] public void ParseBasicSchemaWithExampleShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicSchemaWithExample.yaml")); + using var stream = Resources.GetStream(Path.Join(SampleFolderPath, "basicSchemaWithExample.yaml")); var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); var yamlNode = yamlStream.Documents[0].RootNode; @@ -289,7 +291,7 @@ public void ParseBasicSchemaWithExampleShouldSucceed() public async Task ParseBasicSchemaWithReferenceShouldSucceed() { // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "basicSchemaWithReference.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "basicSchemaWithReference.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert var components = result.Document.Components; @@ -356,7 +358,7 @@ public async Task ParseBasicSchemaWithReferenceShouldSucceed() public async Task ParseAdvancedSchemaWithReferenceShouldSucceed() { // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "advancedSchemaWithReference.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "advancedSchemaWithReference.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var expectedComponents = new OpenApiComponents { @@ -442,8 +444,8 @@ public async Task ParseAdvancedSchemaWithReferenceShouldSucceed() }; // We serialize so that we can get rid of the schema BaseUri properties which show up as diffs - var actual = await result.Document.Components.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); - var expected = await expectedComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await result.Document.Components.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = await expectedComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); @@ -453,7 +455,7 @@ public async Task ParseAdvancedSchemaWithReferenceShouldSucceed() public async Task ParseExternalReferenceSchemaShouldSucceed() { // Act - var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalReferencesSchema.yaml"), SettingsFixture.ReaderSettings); + var result = await OpenApiDocument.LoadAsync(Path.Join(SampleFolderPath, "externalReferencesSchema.yaml"), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert var components = result.Document.Components; @@ -517,10 +519,10 @@ public async Task SerializeSchemaWithNullableShouldSucceed() var expected = @"type: string nullable: true"; - var path = Path.Combine(SampleFolderPath, "schemaWithNullable.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithNullable.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV3(new OpenApiYamlWriter(writer)); @@ -536,10 +538,10 @@ public async Task SerializeSchemaWithOnlyNullableShouldSucceed() // Arrange var expected = @"{ }"; - var path = Path.Combine(SampleFolderPath, "schemaWithOnlyNullable.yaml"); + var path = Path.Join(SampleFolderPath, "schemaWithOnlyNullable.yaml"); // Act - var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var schema = await OpenApiModelFactory.LoadAsync(path, OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); var writer = new StringWriter(); schema.SerializeAsV3(new OpenApiYamlWriter(writer)); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSecuritySchemeTests.cs index 46f0088b1..909e95811 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSecuritySchemeTests.cs @@ -17,7 +17,7 @@ public class OpenApiSecuritySchemeTests public async Task ParseHttpSecuritySchemeShouldSucceed() { // Act - var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "httpSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "httpSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -32,7 +32,7 @@ public async Task ParseHttpSecuritySchemeShouldSucceed() public async Task ParseApiKeySecuritySchemeShouldSucceed() { // Act - var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "apiKeySecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "apiKeySecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -48,7 +48,7 @@ public async Task ParseApiKeySecuritySchemeShouldSucceed() public async Task ParseBearerSecuritySchemeShouldSucceed() { // Act - var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "bearerSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "bearerSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -64,7 +64,7 @@ public async Task ParseBearerSecuritySchemeShouldSucceed() public async Task ParseOAuth2SecuritySchemeShouldSucceed() { // Act - var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "oauth2SecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "oauth2SecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( @@ -90,7 +90,7 @@ public async Task ParseOAuth2SecuritySchemeShouldSucceed() public async Task ParseOpenIdConnectSecuritySchemeShouldSucceed() { // Act - var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "openIdConnectSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings); + var securityScheme = await OpenApiModelFactory.LoadAsync(Path.Join(SampleFolderPath, "openIdConnectSecurityScheme.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs index 259400c90..7b1c67767 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs @@ -18,7 +18,7 @@ public class OpenApiXmlTests public async Task ParseBasicXmlShouldSucceed() { // Act - var xml = await OpenApiModelFactory.LoadAsync(Resources.GetStream(Path.Combine(SampleFolderPath, "basicXml.yaml")), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings); + var xml = await OpenApiModelFactory.LoadAsync(Resources.GetStream(Path.Join(SampleFolderPath, "basicXml.yaml")), OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/YamlConverterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/YamlConverterTests.cs index c246e0898..7bc094d48 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/YamlConverterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/YamlConverterTests.cs @@ -333,6 +333,99 @@ public void RoundTripEmptyStringsValues() Assert.Equal(yamlInput.MakeLineBreaksEnvironmentNeutral(), convertedBackOutput.MakeLineBreaksEnvironmentNeutral()); } + [Fact] + public void ExponentialAliasExpansionIsRejected() + { + // A "billion laughs" YAML bomb: each level references the previous one multiple times, + // so materializing the shared node graph into an independent JSON tree expands + // exponentially. The conversion must fail fast instead of exhausting memory. + var yamlBomb = + """ + a: &a ["x","x","x","x","x","x","x","x","x"] + b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] + c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] + d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] + e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] + f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] + g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] + h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] + i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] + """; + + Assert.Throws(() => ConvertYamlStringToJsonNode(yamlBomb)); + } + + [Fact] + public void ExcessiveNestingDepthIsRejected() + { + // Deeper than the conversion depth limit (mirrors the System.Text.Json default of 64), + // which protects the recursive converter from stack exhaustion. + const int depth = 70; + var deeplyNested = new string('[', depth) + new string(']', depth); + + Assert.Throws(() => ConvertYamlStringToJsonNode(deeplyNested)); + } + + [Fact] + public void LegitimateAliasesStillConvert() + { + var yamlInput = + """ + a: &val hello + b: *val + """; + + var jsonNode = Assert.IsType(ConvertYamlStringToJsonNode(yamlInput)); + + Assert.Equal("hello", jsonNode["a"]?.GetValue()); + Assert.Equal("hello", jsonNode["b"]?.GetValue()); + } + + [Fact] + public void ConversionLimitsDefaultToDocumentedValues() + { + Assert.Equal(64u, YamlConverter.DefaultMaxDepth); + Assert.Equal(5_000_000u, YamlConverter.DefaultMaxNodeCount); + Assert.Equal(YamlConverter.DefaultMaxDepth, YamlConverter.MaxDepth); + Assert.Equal(YamlConverter.DefaultMaxNodeCount, YamlConverter.MaxNodeCount); + } + + [Fact] + public void SettingMaxDepthToZeroThrows() + { + Assert.Throws(() => YamlConverter.MaxDepth = 0); + // The invalid assignment must not have changed the effective limit. + Assert.Equal(YamlConverter.DefaultMaxDepth, YamlConverter.MaxDepth); + } + + [Fact] + public void SettingMaxNodeCountToZeroThrows() + { + Assert.Throws(() => YamlConverter.MaxNodeCount = 0); + // The invalid assignment must not have changed the effective limit. + Assert.Equal(YamlConverter.DefaultMaxNodeCount, YamlConverter.MaxNodeCount); + } + + [Fact] + public void RaisingMaxDepthAllowsDocumentsDeeperThanTheDefault() + { + // A document nested deeper than the default depth limit (64) is rejected by default + // but can be permitted by a consumer that opts into a higher limit. + const int depth = 70; + var deeplyNested = new string('[', depth) + new string(']', depth); + + try + { + YamlConverter.MaxDepth = depth + 10; + var jsonNode = ConvertYamlStringToJsonNode(deeplyNested); + Assert.IsType(jsonNode); + } + finally + { + YamlConverter.MaxDepth = YamlConverter.DefaultMaxDepth; + } + } + private static JsonNode ConvertYamlStringToJsonNode(string yamlInput) { var yamlDocument = new YamlStream(); diff --git a/test/Microsoft.OpenApi.Tests/Extensions/OpenApiSerializableExtensionsTests.cs b/test/Microsoft.OpenApi.Tests/Extensions/OpenApiSerializableExtensionsTests.cs index a1e323ebf..470fb022b 100644 --- a/test/Microsoft.OpenApi.Tests/Extensions/OpenApiSerializableExtensionsTests.cs +++ b/test/Microsoft.OpenApi.Tests/Extensions/OpenApiSerializableExtensionsTests.cs @@ -27,11 +27,11 @@ public async Task UsesTheTerseOutputInformationFromSettingsTrue() }; using var stream = new MemoryStream(); - await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, settings); + await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, settings, TestContext.Current.CancellationToken); stream.Position = 0; using var reader = new StreamReader(stream); - var output = await reader.ReadToEndAsync(); + var output = await reader.ReadToEndAsync(TestContext.Current.CancellationToken); Assert.Equal("{\"name\":\"param1\",\"in\":\"query\",\"description\":\"A sample parameter\",\"schema\":{\"type\":\"string\"}}", output); } @@ -57,11 +57,11 @@ public async Task UsesTheTerseOutputInformationFromSettingsFalse() }; using var stream = new MemoryStream(); - await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, settings); + await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, settings, TestContext.Current.CancellationToken); stream.Position = 0; using var reader = new StreamReader(stream); - var output = await reader.ReadToEndAsync(); + var output = await reader.ReadToEndAsync(TestContext.Current.CancellationToken); Assert.Equal("{\n \"name\": \"param1\",\n \"in\": \"query\",\n \"description\": \"A sample parameter\",\n \"schema\": {\n \"type\": \"string\"\n }\n}", output); } @@ -82,11 +82,11 @@ public async Task UsesTheTerseOutputInformationFromSettingsNoSettings() }; using var stream = new MemoryStream(); - await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, null); + await parameter.SerializeAsync(stream, OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, null, TestContext.Current.CancellationToken); stream.Position = 0; using var reader = new StreamReader(stream); - var output = await reader.ReadToEndAsync(); + var output = await reader.ReadToEndAsync(TestContext.Current.CancellationToken); Assert.Equal("{\n \"name\": \"param1\",\n \"in\": \"query\",\n \"description\": \"A sample parameter\",\n \"schema\": {\n \"type\": \"string\"\n }\n}", output); } diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj index d2c73b955..cff07adde 100644 --- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj +++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs index e6cfa8007..57019906f 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs @@ -103,7 +103,7 @@ public async Task SerializeAdvancedCallbackAsV3JsonWorksAsync(bool produceTerseO // Act AdvancedCallback.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -120,7 +120,7 @@ public async Task SerializeReferencedCallbackAsV3JsonWorksAsync(bool produceTers // Act CallbackProxy.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -137,7 +137,7 @@ public async Task SerializeReferencedCallbackAsV3JsonWithoutReferenceWorksAsync( // Act ReferencedCallback.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiComponentsTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiComponentsTests.cs index 3a1b9fa30..cf5204581 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiComponentsTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiComponentsTests.cs @@ -267,7 +267,7 @@ public async Task SerializeBasicComponentsAsJsonWorks() var expected = @"{ }"; // Act - var actual = await BasicComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -282,7 +282,7 @@ public async Task SerializeBasicComponentsAsYamlWorks() var expected = @"{ }"; // Act - var actual = await BasicComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -334,7 +334,7 @@ public async Task SerializeAdvancedComponentsAsJsonV3Works() """; // Act - var actual = await AdvancedComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -392,7 +392,7 @@ public async Task SerializeAdvancedComponentsWithReferenceAsJsonV3Works() """; // Act - var actual = await AdvancedComponentsWithReference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedComponentsWithReference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -431,7 +431,7 @@ public async Task SerializeAdvancedComponentsAsYamlV3Works() """; // Act - var actual = await AdvancedComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -473,7 +473,7 @@ public async Task SerializeAdvancedComponentsWithReferenceAsYamlV3Works() """; // Act - var actual = await AdvancedComponentsWithReference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedComponentsWithReference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -510,7 +510,7 @@ public async Task SerializeBrokenComponentsAsJsonV3Works() """; // Act - var actual = await BrokenComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BrokenComponents.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -540,7 +540,7 @@ public async Task SerializeBrokenComponentsAsYamlV3Works() """; // Act - var actual = await BrokenComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BrokenComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -566,7 +566,7 @@ public async Task SerializeTopLevelReferencingComponentsAsYamlV3Works() """; // Act - var actual = await TopLevelReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await TopLevelReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -591,7 +591,7 @@ public async Task SerializeTopLevelSelfReferencingWithOtherPropertiesComponentsA type: string"; // Act - var actual = await TopLevelSelfReferencingComponentsWithOtherProperties.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await TopLevelSelfReferencingComponentsWithOtherProperties.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -646,7 +646,7 @@ public async Task SerializeComponentsWithPathItemsAsJsonWorks() } }"; // Act - var actual = await ComponentsWithPathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await ComponentsWithPathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -683,7 +683,7 @@ public async Task SerializeComponentsWithPathItemsAsYamlWorks() type: integer"; // Act - var actual = await ComponentsWithPathItem.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await ComponentsWithPathItem.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiContactTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiContactTests.cs index f699b2f40..81050fcb4 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiContactTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiContactTests.cs @@ -34,7 +34,7 @@ public async Task SerializeBasicContactWorks( string expected) { // Arrange & Act - var actual = await BasicContact.SerializeAsync(version, format); + var actual = await BasicContact.SerializeAsync(version, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -59,7 +59,7 @@ public async Task SerializeAdvanceContactAsJsonWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvanceContact.SerializeAsJsonAsync(version); + var actual = await AdvanceContact.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -82,7 +82,7 @@ public async Task SerializeAdvanceContactAsYamlWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvanceContact.SerializeAsYamlAsync(version); + var actual = await AdvanceContact.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorksAsync_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorksAsync_produceTerseOutput=True.verified.txt index b87f4acf5..479557a10 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorksAsync_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorksAsync_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"openapi":"3.0.4","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/add/{operand1}/{operand2}":{"get":{"operationId":"addByOperand1AndByOperand2","parameters":[{"name":"operand1","in":"path","description":"The first operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4},{"name":"operand2","in":"path","description":"The second operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}} +{"openapi":"3.0.4","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/add/{operand1}/{operand2}":{"get":{"operationId":"addByOperand1AndByOperand2","parameters":[{"name":"operand1","in":"path","description":"The first operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4},{"name":"operand2","in":"path","description":"The second operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs index b4cfe2543..1d6cedfb7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs @@ -1334,7 +1334,7 @@ public async Task SerializeAdvancedDocumentAsV3JsonWorksAsync(bool produceTerseO // Act AdvancedDocument.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1351,7 +1351,7 @@ public async Task SerializeAdvancedDocumentWithReferenceAsV3JsonWorksAsync(bool // Act AdvancedDocumentWithReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1368,7 +1368,7 @@ public async Task SerializeAdvancedDocumentWithServerVariableAsV2JsonWorksAsync( // Act AdvancedDocumentWithServerVariable.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1385,7 +1385,7 @@ public async Task SerializeAdvancedDocumentAsV2JsonWorksAsync(bool produceTerseO // Act AdvancedDocument.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1402,7 +1402,7 @@ public async Task SerializeDuplicateExtensionsAsV3JsonWorksAsync(bool produceTer // Act DuplicateExtensions.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1419,7 +1419,7 @@ public async Task SerializeDuplicateExtensionsAsV2JsonWorksAsync(bool produceTer // Act DuplicateExtensions.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1436,7 +1436,7 @@ public async Task SerializeAdvancedDocumentWithReferenceAsV2JsonWorksAsync(bool // Act AdvancedDocumentWithReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -1460,7 +1460,7 @@ public async Task SerializeSimpleDocumentWithTopLevelReferencingComponentsAsYaml type: string"; // Act - var actual = await SimpleDocumentWithTopLevelReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await SimpleDocumentWithTopLevelReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1479,7 +1479,7 @@ public async Task SerializeSimpleDocumentWithTopLevelSelfReferencingComponentsAs schema1: { }"; // Act - var actual = await SimpleDocumentWithTopLevelSelfReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await SimpleDocumentWithTopLevelSelfReferencingComponents.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1507,7 +1507,7 @@ public async Task SerializeSimpleDocumentWithTopLevelSelfReferencingWithOtherPro type: string"; // Act - var actual = await SimpleDocumentWithTopLevelSelfReferencingComponentsWithOtherProperties.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await SimpleDocumentWithTopLevelSelfReferencingComponentsWithOtherProperties.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1553,7 +1553,7 @@ public async Task SerializeDocumentWithReferenceButNoComponents() document.Paths["/"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema = new OpenApiSchemaReference("test", document); // Act - var actual = await document.SerializeAsync(OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Json); + var actual = await document.SerializeAsync(OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Json, TestContext.Current.CancellationToken); // Assert Assert.NotEmpty(actual); @@ -1581,7 +1581,7 @@ public async Task SerializeRelativePathAsV2JsonWorks() }; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1611,7 +1611,7 @@ public async Task SerializeRelativePathWithHostAsV2JsonWorks() }; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1640,7 +1640,7 @@ public async Task SerializeRelativeRootPathWithHostAsV2JsonWorks() }; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1653,18 +1653,18 @@ public async Task TestHashCodesForSimilarOpenApiDocuments() // Arrange var sampleFolderPath = "Models/Samples/"; - var doc1 = await ParseInputFileAsync(Path.Combine(sampleFolderPath, "sampleDocument.yaml")); - var doc2 = await ParseInputFileAsync(Path.Combine(sampleFolderPath, "sampleDocument.yaml")); - var doc3 = await ParseInputFileAsync(Path.Combine(sampleFolderPath, "sampleDocumentWithWhiteSpaces.yaml")); + var doc1 = await ParseInputFileAsync(Path.Join(sampleFolderPath, "sampleDocument.yaml")); + var doc2 = await ParseInputFileAsync(Path.Join(sampleFolderPath, "sampleDocument.yaml")); + var doc3 = await ParseInputFileAsync(Path.Join(sampleFolderPath, "sampleDocumentWithWhiteSpaces.yaml")); // Act && Assert /* Test whether reading in two similar documents yield the same hash code, And reading in similar documents(one has a whitespace) yields the same hash code as the result is terse */ - var doc1HashCode = await doc1.GetHashCodeAsync(); - var doc2HashCode = await doc2.GetHashCodeAsync(); - var doc3HashCode = await doc3.GetHashCodeAsync(); + var doc1HashCode = await doc1.GetHashCodeAsync(TestContext.Current.CancellationToken); + var doc2HashCode = await doc2.GetHashCodeAsync(TestContext.Current.CancellationToken); + var doc3HashCode = await doc3.GetHashCodeAsync(TestContext.Current.CancellationToken); Assert.NotNull(doc1HashCode); Assert.NotNull(doc2HashCode); Assert.NotNull(doc3HashCode); @@ -1725,7 +1725,7 @@ public async Task SerializeV2DocumentWithNonArraySchemaTypeDoesNotWriteOutCollec }; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1813,7 +1813,7 @@ public async Task SerializeV2DocumentWithStyleAsNullDoesNotWriteOutStyleValue() }; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1885,7 +1885,7 @@ public async Task SerializeDocumentWithWebhooksAsV3JsonWorks(bool produceTerseOu // Act DocumentWithWebhooks.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -1929,7 +1929,7 @@ public async Task SerializeDocumentWithWebhooksAsV3YamlWorks() description: Return a 200 status to indicate that the data was received successfully"; // Act - var actual = await DocumentWithWebhooks.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await DocumentWithWebhooks.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -1959,7 +1959,7 @@ public async Task SerializeDocumentWithRootJsonSchemaDialectPropertyWorks() paths: { }"; // Act - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); @@ -1980,7 +1980,7 @@ public async Task SerializeV31DocumentWithRefsInWebhooksWorks() items: type: object"; - var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithReusableWebhooks.yaml", SettingsFixture.ReaderSettings)).Document; + var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithReusableWebhooks.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var stringWriter = new StringWriter(); var writer = new OpenApiYamlWriter(stringWriter, new OpenApiWriterSettings { InlineLocalReferences = true }); @@ -2034,8 +2034,8 @@ public async Task SerializeDocWithDollarIdInDollarRefSucceeds() radius: type: number "; - var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithDollarId.yaml", SettingsFixture.ReaderSettings)).Document; - var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithDollarId.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; + var actual = await doc.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); } @@ -2089,7 +2089,7 @@ public async Task SerializeDocumentTagsWithMultipleExtensionsWorks() } }; - var actual = await doc.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await doc.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); } [Fact] @@ -2236,7 +2236,7 @@ public async Task SerializeAdvancedDocumentAsVersionJsonWorksAsync(OpenApiSpecVe // Act AdvancedDocument.SerializeAs(version, writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(version); @@ -2294,7 +2294,7 @@ public async Task SerializeDocWithSecuritySchemeWithInlineReferencesWorks() scopes: api://a2a7226d-e8d1-4ded-8c53-dd4c136ff456/repairs_read: Read repair records"; - var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithSecurityScheme.yaml", SettingsFixture.ReaderSettings)).Document; + var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithSecurityScheme.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var stringWriter = new StringWriter(); doc.SerializeAsV3(new OpenApiYamlWriter(stringWriter, new OpenApiWriterSettings { InlineLocalReferences = true })); var actual = stringWriter.ToString(); @@ -2326,7 +2326,7 @@ public async Task SerializeDocWithoutOperationSecurityWorks() type: object """; - var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithoutOperationSecurity.yaml", SettingsFixture.ReaderSettings)).Document; + var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithoutOperationSecurity.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var stringWriter = new StringWriter(); doc!.SerializeAsV3(new OpenApiYamlWriter(stringWriter, new OpenApiWriterSettings { InlineLocalReferences = true })); var actual = stringWriter.ToString(); @@ -2361,7 +2361,7 @@ public async Task SerializeDocWithEmptyOperationSecurityWorks() security: [ ] """; - var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithEmptyOperationSecurity.yaml", SettingsFixture.ReaderSettings)).Document; + var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithEmptyOperationSecurity.yaml", SettingsFixture.ReaderSettings, token: TestContext.Current.CancellationToken)).Document; var stringWriter = new StringWriter(); doc!.SerializeAsV3(new OpenApiYamlWriter(stringWriter, new OpenApiWriterSettings { InlineLocalReferences = true })); var actual = stringWriter.ToString(); @@ -2412,7 +2412,7 @@ public async Task SerializeDocumentWithSecurityRequirementAsJsonWorks(OpenApiSpe """; // Act - var actual = await doc.SerializeAsJsonAsync(openApiSpecVersion); + var actual = await doc.SerializeAsJsonAsync(openApiSpecVersion, TestContext.Current.CancellationToken); // Assert var actualSecurity = JsonNode.Parse(actual)?["security"]; diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiEncodingTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiEncodingTests.cs index 81d6426ad..f9dcbb8ea 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiEncodingTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiEncodingTests.cs @@ -25,7 +25,7 @@ public class OpenApiEncodingTests public async Task SerializeBasicEncodingAsV3Works(string format, string expected) { // Arrange & Act - var actual = await BasicEncoding.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format); + var actual = await BasicEncoding.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -48,7 +48,7 @@ public async Task SerializeAdvanceEncodingAsV3JsonWorks() """; // Act - var actual = await AdvanceEncoding.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceEncoding.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -69,7 +69,7 @@ public async Task SerializeAdvanceEncodingAsV3YamlWorks() """; // Act - var actual = await AdvanceEncoding.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceEncoding.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -119,7 +119,7 @@ public async Task WhenExplodeIsSetOutputShouldHaveExplode(bool? expectedExplode, } // Act - var actual = await parameter.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await parameter.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs index 3fb95d8c7..9b41ea090 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs @@ -104,7 +104,7 @@ public async Task SerializeAdvancedExampleAsV3JsonWorksAsync(bool produceTerseOu // Act AdvancedExample.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -121,7 +121,7 @@ public async Task SerializeReferencedExampleAsV3JsonWorksAsync(bool produceTerse // Act OpenApiExampleReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -138,7 +138,7 @@ public async Task SerializeReferencedExampleAsV3JsonWithoutReferenceWorksAsync(b // Act ReferencedExample.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiExternalDocsTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiExternalDocsTests.cs index 9a290d425..95bcde5d1 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiExternalDocsTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiExternalDocsTests.cs @@ -25,7 +25,7 @@ public class OpenApiExternalDocsTests public async Task SerializeBasicExternalDocsAsV3Works(string format, string expected) { // Arrange & Act - var actual = await BasicExDocs.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format); + var actual = await BasicExDocs.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -46,7 +46,7 @@ public async Task SerializeAdvanceExDocsAsV3JsonWorks() """; // Act - var actual = await AdvanceExDocs.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceExDocs.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -65,7 +65,7 @@ public async Task SerializeAdvanceExDocsAsV3YamlWorks() """; // Act - var actual = await AdvanceExDocs.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceExDocs.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs index 0f57503b3..a42fd1fb6 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs @@ -45,7 +45,7 @@ public async Task SerializeAdvancedHeaderAsV3JsonWorksAsync(bool produceTerseOut // Act AdvancedHeader.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -62,7 +62,7 @@ public async Task SerializeReferencedHeaderAsV3JsonWorksAsync(bool produceTerseO // Act OpenApiHeaderReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -79,7 +79,7 @@ public async Task SerializeReferencedHeaderAsV3JsonWithoutReferenceWorksAsync(bo // Act ReferencedHeader.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -96,7 +96,7 @@ public async Task SerializeAdvancedHeaderAsV2JsonWorksAsync(bool produceTerseOut // Act AdvancedHeader.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -113,7 +113,7 @@ public async Task SerializeReferencedHeaderAsV2JsonWorksAsync(bool produceTerseO // Act OpenApiHeaderReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -130,7 +130,7 @@ public async Task SerializeReferencedHeaderAsV2JsonWithoutReferenceWorksAsync(bo // Act ReferencedHeader.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs index 57c3e1c7e..eaded3a3f 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs @@ -61,7 +61,7 @@ public static IEnumerable BasicInfoJsonExpected() public async Task SerializeBasicInfoAsJsonWorks(OpenApiSpecVersion version, string expected) { // Arrange & Act - var actual = await BasicInfo.SerializeAsJsonAsync(version); + var actual = await BasicInfo.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -90,7 +90,7 @@ public static IEnumerable BasicInfoYamlExpected() public async Task SerializeBasicInfoAsYamlWorks(OpenApiSpecVersion version, string expected) { // Arrange & Act - var actual = await BasicInfo.SerializeAsYamlAsync(version); + var actual = await BasicInfo.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -135,7 +135,7 @@ public static IEnumerable AdvanceInfoJsonExpect() public async Task SerializeAdvanceInfoAsJsonWorks(OpenApiSpecVersion version, string expected) { // Arrange & Act - var actual = await AdvanceInfo.SerializeAsJsonAsync(version); + var actual = await AdvanceInfo.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -176,7 +176,7 @@ public static IEnumerable AdvanceInfoYamlExpect() public async Task SerializeAdvanceInfoAsYamlWorks(OpenApiSpecVersion version, string expected) { // Arrange & Act - var actual = await AdvanceInfo.SerializeAsYamlAsync(version); + var actual = await AdvanceInfo.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -201,7 +201,7 @@ public async Task InfoVersionShouldAcceptDateStyledAsVersions() """; // Act - var actual = await info.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml); + var actual = await info.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -219,7 +219,7 @@ public async Task SerializeInfoObjectWithSummaryAsV31YamlWorks() summary: This is a sample server for a pet store."; // Act - var actual = await InfoWithSummary.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await InfoWithSummary.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -239,7 +239,7 @@ public async Task SerializeInfoObjectWithSummaryAsV31JsonWorks() }"; // Act - var actual = await InfoWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await InfoWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiLicenseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiLicenseTests.cs index 58cdae2ce..0f9a99c18 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiLicenseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiLicenseTests.cs @@ -45,7 +45,7 @@ public async Task SerializeBasicLicenseAsJsonWorks(OpenApiSpecVersion version) """; // Act - var actual = await BasicLicense.SerializeAsJsonAsync(version); + var actual = await BasicLicense.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -62,7 +62,7 @@ public async Task SerializeBasicLicenseAsYamlWorks(OpenApiSpecVersion version) var expected = "name: Apache 2.0"; // Act - var actual = await BasicLicense.SerializeAsYamlAsync(version); + var actual = await BasicLicense.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -86,7 +86,7 @@ public async Task SerializeAdvanceLicenseAsJsonWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvanceLicense.SerializeAsJsonAsync(version); + var actual = await AdvanceLicense.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -108,7 +108,7 @@ public async Task SerializeAdvanceLicenseAsYamlWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvanceLicense.SerializeAsYamlAsync(version); + var actual = await AdvanceLicense.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -142,7 +142,26 @@ public async Task SerializeLicenseWithIdentifierAsJsonWorks() }"; // Act - var actual = await LicenseWithIdentifier.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await LicenseWithIdentifier.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); + + // Assert + Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); + } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + [InlineData(OpenApiSpecVersion.OpenApi2_0)] + public async Task SerializeLicenseWithIdentifierAsJsonWorksForV3AndV2(OpenApiSpecVersion version) + { + // Arrange + var expected = + @"{ + ""name"": ""Apache 2.0"", + ""x-oai-license-identifier"": ""Apache-2.0"" +}"; + + // Act + var actual = await LicenseWithIdentifier.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); @@ -156,7 +175,23 @@ public async Task SerializeLicenseWithIdentifierAsYamlWorks() identifier: Apache-2.0"; // Act - var actual = await LicenseWithIdentifier.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await LicenseWithIdentifier.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); + + // Assert + Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); + } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + [InlineData(OpenApiSpecVersion.OpenApi2_0)] + public async Task SerializeLicenseWithIdentifierAsYamlWorksForV3AndV2(OpenApiSpecVersion version) + { + // Arrange + var expected = @"name: Apache 2.0 +x-oai-license-identifier: Apache-2.0"; + + // Act + var actual = await LicenseWithIdentifier.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs index f67e82356..bf5e49b2e 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs @@ -74,7 +74,7 @@ public async Task SerializeAdvancedLinkAsV3JsonWorksAsync(bool produceTerseOutpu // Act AdvancedLink.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -91,7 +91,7 @@ public async Task SerializeReferencedLinkAsV3JsonWorksAsync(bool produceTerseOut // Act LinkReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -108,7 +108,7 @@ public async Task SerializeReferencedLinkAsV3JsonWithoutReferenceWorksAsync(bool // Act ReferencedLink.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiMediaTypeTests.cs index ff9c8badb..a272bbf63 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiMediaTypeTests.cs @@ -5,7 +5,6 @@ using System.Text.Json.Nodes; using System.Threading.Tasks; using Xunit; -using Xunit.Abstractions; namespace Microsoft.OpenApi.Tests.Models { @@ -133,7 +132,7 @@ public OpenApiMediaTypeTests(ITestOutputHelper output) public async Task SerializeBasicMediaTypeAsV3Works(string format, string expected) { // Arrange & Act - var actual = await BasicMediaType.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format); + var actual = await BasicMediaType.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -161,7 +160,7 @@ public async Task SerializeAdvanceMediaTypeAsV3JsonWorks() """; // Act - var actual = await AdvanceMediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceMediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -185,7 +184,7 @@ public async Task SerializeAdvanceMediaTypeAsV3YamlWorks() """; // Act - var actual = await AdvanceMediaType.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvanceMediaType.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -220,7 +219,7 @@ public async Task SerializeMediaTypeWithObjectExampleAsV3YamlWorks() """; // Act - var actual = await MediaTypeWithObjectExample.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithObjectExample.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -271,7 +270,7 @@ public async Task SerializeMediaTypeWithObjectExampleAsV3JsonWorks() """; // Act - var actual = await MediaTypeWithObjectExample.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithObjectExample.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -295,7 +294,7 @@ public async Task SerializeMediaTypeWithXmlExampleAsV3YamlWorks() """; // Act - var actual = await MediaTypeWithXmlExample.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithXmlExample.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -323,7 +322,7 @@ public async Task SerializeMediaTypeWithXmlExampleAsV3JsonWorks() """; // Act - var actual = await MediaTypeWithXmlExample.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithXmlExample.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -360,7 +359,7 @@ public async Task SerializeMediaTypeWithObjectExamplesAsV3YamlWorks() """; // Act - var actual = await MediaTypeWithObjectExamples.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithObjectExamples.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); _output.WriteLine(actual); // Assert @@ -416,7 +415,7 @@ public async Task SerializeMediaTypeWithObjectExamplesAsV3JsonWorks() """; // Act - var actual = await MediaTypeWithObjectExamples.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await MediaTypeWithObjectExamples.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); _output.WriteLine(actual); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowTests.cs index 16110f7a4..187b81546 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowTests.cs @@ -46,7 +46,7 @@ public async Task SerializeBasicOAuthFlowAsV3JsonWorks() """; // Act - var actual = await BasicOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -62,7 +62,7 @@ public async Task SerializeBasicOAuthFlowAsV3YamlWorks() @"scopes: { }"; // Act - var actual = await BasicOAuthFlow.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicOAuthFlow.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -86,7 +86,7 @@ public async Task SerializePartialOAuthFlowAsV3JsonWorks() """; // Act - var actual = await PartialOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await PartialOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -112,7 +112,7 @@ public async Task SerializeCompleteOAuthFlowAsV3JsonWorks() """; // Act - var actual = await CompleteOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await CompleteOAuthFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowsTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowsTests.cs index 2b423e48a..910841db8 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowsTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOAuthFlowsTests.cs @@ -56,7 +56,7 @@ public async Task SerializeBasicOAuthFlowsAsV3JsonWorks() @"{ }"; // Act - var actual = await BasicOAuthFlows.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicOAuthFlows.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -72,7 +72,7 @@ public async Task SerializeBasicOAuthFlowsAsV3YamlWorks() @"{ }"; // Act - var actual = await BasicOAuthFlows.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicOAuthFlows.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -98,7 +98,7 @@ public async Task SerializeOAuthFlowsWithSingleFlowAsV3JsonWorks() """; // Act - var actual = await OAuthFlowsWithSingleFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await OAuthFlowsWithSingleFlow.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -132,7 +132,7 @@ public async Task SerializeOAuthFlowsWithMultipleFlowsAsV3JsonWorks() """; // Act - var actual = await OAuthFlowsWithMultipleFlows.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await OAuthFlowsWithMultipleFlows.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs index cc0b485e1..6fb63c719 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs @@ -293,7 +293,7 @@ public async Task SerializeBasicOperationAsV3JsonWorks() """; // Act - var actual = await _basicOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await _basicOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -365,7 +365,7 @@ public async Task SerializeOperationWithBodyAsV3JsonWorks() """; // Act - var actual = await _operationWithBody.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await _operationWithBody.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -447,7 +447,7 @@ public async Task SerializeAdvancedOperationWithTagAndSecurityAsV3JsonWorks() """; // Act - var actual = await _advancedOperationWithTagsAndSecurity.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await _advancedOperationWithTagsAndSecurity.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -465,7 +465,7 @@ public async Task SerializeBasicOperationAsV2JsonWorks() """; // Act - var actual = await _basicOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await _basicOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -542,7 +542,7 @@ public async Task SerializeOperationWithFormDataAsV3JsonWorks() """; // Act - var actual = await _operationWithFormData.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await _operationWithFormData.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -596,7 +596,7 @@ public async Task SerializeOperationWithFormDataAsV2JsonWorks() """; // Act - var actual = await _operationWithFormData.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await _operationWithFormData.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -663,7 +663,7 @@ public async Task SerializeOperationWithBodyAsV2JsonWorks() """; // Act - var actual = await _operationWithBody.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await _operationWithBody.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -742,7 +742,7 @@ public async Task SerializeAdvancedOperationWithTagAndSecurityAsV2JsonWorks() """; // Act - var actual = await _advancedOperationWithTagsAndSecurity.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await _advancedOperationWithTagsAndSecurity.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -765,7 +765,7 @@ public async Task SerializeOperationWithNullCollectionAsV2JsonWorks() }; // Act - var actual = await operation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await operation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -826,9 +826,9 @@ public async Task EnsureOpenApiOperationCopyConstructor_SerializationResultsInSa foreach (var operation in operations) { // Act - var expected = await operation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = await operation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); var openApiOperation = new OpenApiOperation(operation); - var actual = await openApiOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await openApiOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs index 8bd30a7c9..1898aa6d9 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs @@ -171,7 +171,7 @@ public async Task WhenStyleAndInIsNullTheDefaultValueOfStyleShouldBeSimple(Param // Act & Assert parameter.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); Assert.Equal(expectedStyle, parameter.Style); } @@ -188,7 +188,7 @@ public async Task SerializeQueryParameterWithMissingStyleSucceeds() type: integer"; // Act - var actual = await QueryParameterWithMissingStyle.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await QueryParameterWithMissingStyle.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); @@ -207,7 +207,7 @@ public async Task SerializeBasicParameterAsV3JsonWorks() """; // Act - var actual = await BasicParameter.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicParameter.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -250,7 +250,7 @@ public async Task SerializeAdvancedParameterAsV3JsonWorks() """; // Act - var actual = await AdvancedPathParameterWithSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedPathParameterWithSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -280,7 +280,7 @@ public async Task SerializeAdvancedParameterAsV2JsonWorks() """; // Act - var actual = await AdvancedPathParameterWithSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await AdvancedPathParameterWithSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -299,7 +299,7 @@ public async Task SerializeReferencedParameterAsV3JsonWorksAsync(bool produceTer // Act OpenApiParameterReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -316,7 +316,7 @@ public async Task SerializeReferencedParameterAsV3JsonWithoutReferenceWorksAsync // Act ReferencedParameter.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -333,7 +333,7 @@ public async Task SerializeReferencedParameterAsV2JsonWorksAsync(bool produceTer // Act OpenApiParameterReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -350,7 +350,7 @@ public async Task SerializeReferencedParameterAsV2JsonWithoutReferenceWorksAsync // Act ReferencedParameter.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -367,7 +367,7 @@ public async Task SerializeParameterWithSchemaTypeObjectAsV2JsonWorksAsync(bool // Act AdvancedHeaderParameterWithSchemaTypeObject.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -384,7 +384,7 @@ public async Task SerializeParameterWithFormStyleAndExplodeFalseWorksAsync(bool // Act ParameterWithFormStyleAndExplodeFalse.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -401,7 +401,7 @@ public async Task SerializeParameterWithFormStyleAndExplodeTrueWorksAsync(bool p // Act ParameterWithFormStyleAndExplodeTrue.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiPathItemTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiPathItemTests.cs index 887d33893..6d09a545b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiPathItemTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiPathItemTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -130,7 +130,7 @@ public async Task SerializeAsV2JsonWorks() var parsedExpectedJson = JsonNode.Parse(expectedJson); // When - var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); var parsedActualJson = JsonNode.Parse(actualJson); // Then @@ -262,7 +262,7 @@ public async Task SerializeAsV3JsonWorks() var parsedExpectedJson = JsonNode.Parse(expectedJson); // When - var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); var parsedActualJson = JsonNode.Parse(actualJson); // Then @@ -394,7 +394,7 @@ public async Task SerializeAsV31JsonWorks() var parsedExpectedJson = JsonNode.Parse(expectedJson); // When - var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actualJson = await pathItem.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); var parsedActualJson = JsonNode.Parse(actualJson); // Then diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs index e2ad1f87c..a00963cfe 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs @@ -97,7 +97,7 @@ public async Task SerializeSchemaReferenceAsJsonV3Works() """; // Act - var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -121,7 +121,7 @@ public async Task SerializeHttpSchemaReferenceAsJsonV31Works(string id, string r """; // Act - var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -142,7 +142,7 @@ public async Task SerializeSchemaReferenceAsYamlV3Works() var expected = @"$ref: '#/components/schemas/Pet'"; // Act - var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); @@ -166,7 +166,7 @@ public async Task SerializeSchemaReferenceAsJsonV2Works() """.MakeLineBreaksEnvironmentNeutral(); // Act - var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual.MakeLineBreaksEnvironmentNeutral()); @@ -184,7 +184,7 @@ public async Task SerializeSchemaReferenceAsYamlV2Works() var expected = @"$ref: '#/definitions/Pet'"; // Act - var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); @@ -209,7 +209,7 @@ public async Task SerializeExternalReferenceAsJsonV2Works() """; // Act - var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -230,7 +230,7 @@ public async Task SerializeExternalReferenceAsYamlV2Works() var expected = @"$ref: main.json#/definitions/Pets"; // Act - var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); @@ -250,7 +250,7 @@ public async Task SerializeExternalReferenceAsJsonV3Works() """; // Act - var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await reference.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -266,7 +266,7 @@ public async Task SerializeExternalReferenceAsYamlV3Works() var expected = @"$ref: main.json#/components/schemas/Pets"; // Act - var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await reference.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected, actual); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs index 5da25b013..54734c83b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs @@ -57,7 +57,7 @@ public async Task SerializeAdvancedRequestBodyAsV3JsonWorksAsync(bool produceTer // Act AdvancedRequestBody.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -74,7 +74,7 @@ public async Task SerializeReferencedRequestBodyAsV3JsonWorksAsync(bool produceT // Act OpenApiRequestBodyReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -91,7 +91,7 @@ public async Task SerializeReferencedRequestBodyAsV3JsonWithoutReferenceWorksAsy // Act ReferencedRequestBody.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index a8902ef14..83e321975 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -181,7 +181,7 @@ public async Task SerializeBasicResponseWorks( }" : @"description: null"; // Act - var actual = await BasicResponse.SerializeAsync(version, format); + var actual = await BasicResponse.SerializeAsync(version, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -224,7 +224,7 @@ public async Task SerializeAdvancedResponseAsV3JsonWorks() }"; // Act - var actual = await AdvancedV3Response.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedV3Response.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -257,7 +257,7 @@ public async Task SerializeAdvancedResponseAsV3YamlWorks() myextension: myextensionvalue"; // Act - var actual = await AdvancedV3Response.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedV3Response.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -294,7 +294,7 @@ public async Task SerializeAdvancedResponseAsV2JsonWorks() }"; // Act - var actual = await AdvancedV2Response.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await AdvancedV2Response.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -324,7 +324,7 @@ public async Task SerializeAdvancedResponseAsV2YamlWorks() type: integer"; // Act - var actual = await AdvancedV2Response.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await AdvancedV2Response.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -343,7 +343,7 @@ public async Task SerializeReferencedResponseAsV3JsonWorksAsync(bool produceTers // Act V3OpenApiResponseReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -360,7 +360,7 @@ public async Task SerializeReferencedResponseAsV3JsonWithoutReferenceWorksAsync( // Act ReferencedV3Response.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -377,7 +377,7 @@ public async Task SerializeReferencedResponseAsV2JsonWorksAsync(bool produceTers // Act V2OpenApiResponseReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -394,7 +394,7 @@ public async Task SerializeReferencedResponseAsV2JsonWithoutReferenceWorksAsync( // Act ReferencedV2Response.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index 14ec467aa..a3cd6a2ed 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -11,6 +11,7 @@ using System.Text.Json.Serialization; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.OpenApi.Reader; using VerifyXunit; using Xunit; @@ -217,7 +218,7 @@ public async Task SerializeBasicSchemaAsJsonWorks(OpenApiSpecVersion version) var expected = @"{ }"; // Act - var actual = await BasicSchema.SerializeAsJsonAsync(version); + var actual = await BasicSchema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -247,7 +248,7 @@ public async Task SerializeAdvancedSchemaNumberAsV3JsonWorks() """; // Act - var actual = await AdvancedSchemaNumber.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedSchemaNumber.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -298,7 +299,7 @@ public async Task SerializeAdvancedSchemaObjectAsV3JsonWorks() """; // Act - var actual = await AdvancedSchemaObject.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedSchemaObject.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -353,7 +354,7 @@ public async Task SerializeAdvancedSchemaWithAllOfAsV3JsonWorks() """; // Act - var actual = await AdvancedSchemaWithAllOf.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedSchemaWithAllOf.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonObject.DeepEquals(JsonObject.Parse(expected), JsonObject.Parse(actual))); @@ -370,7 +371,7 @@ public async Task SerializeReferencedSchemaAsV3WithoutReferenceJsonWorksAsync(bo // Act ReferencedSchema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -387,7 +388,7 @@ public async Task SerializeReferencedSchemaAsV3JsonWorksAsync(bool produceTerseO // Act ReferencedSchema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -404,7 +405,7 @@ public async Task SerializeSchemaWRequiredPropertiesAsV2JsonWorksAsync(bool prod // Act AdvancedSchemaWithRequiredPropertiesObject.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -433,7 +434,7 @@ public async Task SerializeAsV2ShouldSetFormatPropertyInParentSchemaIfPresentInC // Act // Serialize as V2 schema.SerializeAsV2(openApiJsonWriter); - await openApiJsonWriter.FlushAsync(); + await openApiJsonWriter.FlushAsync(TestContext.Current.CancellationToken); var v2Schema = outputStringWriter.GetStringBuilder().ToString().MakeLineBreaksEnvironmentNeutral(); @@ -622,6 +623,7 @@ public static TheoryData SchemaExamples() [Theory] [MemberData(nameof(SchemaExamples))] +#pragma warning disable CS0618 public void CloningSchemaExamplesWorks(JsonNode example) { // Arrange @@ -638,6 +640,7 @@ public void CloningSchemaExamplesWorks(JsonNode example) .IgnoringCyclicReferences() .Excluding(x => x.Options)); } +#pragma warning restore CS0618 [Fact] public void CloningSchemaExtensionsWorks() @@ -725,7 +728,7 @@ public async Task SerializeSchemaWithUnrecognizedPropertiesWorks() }"; // Act - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Assert Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral()); @@ -747,7 +750,7 @@ public async Task WriteAsItemsPropertiesDoesNotWriteNull() // Act schema.WriteAsItemsProperties(writer); writer.WriteEndObject(); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert var actual = outputStringWriter.GetStringBuilder().ToString(); @@ -771,7 +774,7 @@ public async Task SerializeConstAsEnumV30() // Act - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert var v3Node = JsonNode.Parse(actual); @@ -791,7 +794,7 @@ public async Task SerializeConstAsEnumV20() }; // Act - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert var v2Node = JsonNode.Parse(actual); @@ -811,7 +814,7 @@ public async Task SerializeAdditionalPropertiesAsV2WithEmptySchemaEmits() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -829,7 +832,7 @@ public async Task SerializeAdditionalPropertiesAsV2WithRefSchemaEmits() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -846,7 +849,7 @@ public async Task SerializeAdditionalPropertiesAllowedAsV2DefaultDoesNotEmit() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -863,7 +866,7 @@ public async Task SerializeAdditionalPropertiesAllowedAsV2FalseEmits() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -882,7 +885,7 @@ public async Task SerializeAdditionalPropertiesAllowedAsV3PlusDefaultDoesNotEmit }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -901,7 +904,7 @@ public async Task SerializeAdditionalPropertiesAllowedAsV3PlusFalseEmits(OpenApi }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -920,7 +923,7 @@ public async Task SerializeAdditionalPropertiesAsV3PlusEmits(OpenApiSpecVersion }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -948,7 +951,7 @@ public async Task SerializeOneOfWithNullAsV3ShouldUseNullableAsync() // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -959,7 +962,8 @@ public async Task SerializeOneOfWithNullAsV3ShouldUseNullableAsync() { "enum": [ null - ] + ], + "nullable": true }, { "maxLength": 10, @@ -992,7 +996,7 @@ public async Task SerializeOneOfWithNullAndMultipleSchemasAsV3ShouldMarkItAsNull // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1003,7 +1007,8 @@ public async Task SerializeOneOfWithNullAndMultipleSchemasAsV3ShouldMarkItAsNull { "enum": [ null - ] + ], + "nullable": true }, { "type": "string" @@ -1044,7 +1049,7 @@ public async Task SerializeAnyOfWithNullAsV3ShouldUseNullableAsync() // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1055,7 +1060,8 @@ public async Task SerializeAnyOfWithNullAsV3ShouldUseNullableAsync() { "enum": [ null - ] + ], + "nullable": true }, { "type": "object", @@ -1091,7 +1097,7 @@ public async Task SerializeAnyOfWithNullAndMultipleSchemasAsV3ShouldApplyNullabl // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1102,7 +1108,8 @@ public async Task SerializeAnyOfWithNullAndMultipleSchemasAsV3ShouldApplyNullabl { "enum": [ null - ] + ], + "nullable": true }, { "minLength": 1, @@ -1136,7 +1143,7 @@ public async Task SerializeOneOfWithOnlyNullAsV3ShouldJustBeNullableAsync() // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1147,7 +1154,8 @@ public async Task SerializeOneOfWithOnlyNullAsV3ShouldJustBeNullableAsync() { "enum": [ null - ] + ], + "nullable": true } ] } @@ -1175,7 +1183,7 @@ public async Task SerializeOneOfWithNullAsV31ShouldNotChangeAsync() // Act schema.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v31Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1239,7 +1247,7 @@ public async Task SerializeOneOfWithNullAndRefAsV3ShouldUseNullableAsync() // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1250,7 +1258,8 @@ public async Task SerializeOneOfWithNullAndRefAsV3ShouldUseNullableAsync() { "enum": [ null - ] + ], + "nullable": true }, { "$ref": "#/components/schemas/Pet" @@ -1280,7 +1289,7 @@ public async Task SerializeContainsKeywordsAsV31Works() // Act schema.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v31Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1316,7 +1325,7 @@ public async Task SerializeContainsKeywordsAsV3EmitsCompatibilityExtensions() // Act schema.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var v3Schema = outputStringWriter.GetStringBuilder().ToString(); @@ -1345,7 +1354,7 @@ public async Task SerializeUnevaluatedPropertiesBooleanDefaultDoesNotEmit() var schema = new OpenApiSchema(); // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1362,7 +1371,7 @@ public async Task SerializeUnevaluatedPropertiesBooleanTrueDoesNotEmit() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1379,7 +1388,7 @@ public async Task SerializeUnevaluatedPropertiesBooleanFalseEmitsInV31() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1400,7 +1409,7 @@ public async Task SerializeUnevaluatedPropertiesSchemaEmits(OpenApiSpecVersion v }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1421,7 +1430,7 @@ public async Task SerializeUnevaluatedPropertiesSchemaTakesPrecedenceOverBoolean }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1438,7 +1447,7 @@ public async Task SerializeUnevaluatedPropertiesAsExtensionInEarlierVersions(Ope UnevaluatedProperties = false }; - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } @@ -1457,7 +1466,7 @@ public async Task SerializeUnevaluatedPropertiesSchemaAsExtensionInEarlierVersio } }; - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } @@ -1475,7 +1484,7 @@ public async Task SerializeUnevaluatedPropertiesTrueNotEmittedInEarlierVersions( }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1530,7 +1539,7 @@ public async Task SerializeMissingPropertiesEmitsJsonSchemaKeywordsInV31() Else = new OpenApiSchema { MaxProperties = 0 } }; - var actual = JsonNode.Parse(await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1)); + var actual = JsonNode.Parse(await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken)); Assert.True(JsonNode.DeepEquals(expected, actual)); } @@ -1592,7 +1601,7 @@ public async Task SerializeMissingPropertiesEmitsOaiExtensionsInV3() Else = new OpenApiSchema { MaxProperties = 0 } }; - var actual = JsonNode.Parse(await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0)); + var actual = JsonNode.Parse(await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken)); Assert.True(JsonNode.DeepEquals(expected, actual)); } @@ -1615,7 +1624,7 @@ public async Task SerializeUnevaluatedPropertiesFalseNotEmittedForNonObjectType( }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1639,7 +1648,7 @@ public async Task SerializeUnevaluatedPropertiesSchemaNotEmittedForNonObjectType }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1660,7 +1669,7 @@ public async Task SerializeUnevaluatedPropertiesNotEmittedAsExtensionForNonObjec }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then - should not contain unevaluatedProperties extension var parsed = JsonNode.Parse(actual)!.AsObject(); @@ -1679,7 +1688,7 @@ public async Task SerializeUnevaluatedPropertiesFalseStillEmittedForObjectType() }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1696,7 +1705,7 @@ public async Task SerializeUnevaluatedPropertiesFalseStillEmittedWhenTypeNotSet( }; // When - var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1718,7 +1727,7 @@ public async Task SerializePatternPropertiesAsKeywordInV31AndV32(OpenApiSpecVers }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1740,12 +1749,88 @@ public async Task SerializePatternPropertiesAsExtensionInEarlierVersions(OpenApi }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi2_0)] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + public async Task SerializeSingleExampleAsExampleInV2V3WhenExampleUnset(OpenApiSpecVersion version) + { + var expected = """ + { + "example": "example value" + } + """; + var schema = new OpenApiSchema + { + Examples = + [ + JsonValue.Create("example value")! + ] + }; + + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi2_0)] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + public async Task SerializeMultipleExamplesInV2V3WhenExampleUnset(OpenApiSpecVersion version) + { + var expected = """ + { + "example": "example value", + "x-jsonschema-examples": [ + 42 + ] + } + """; + var schema = new OpenApiSchema + { + Examples = + [ + JsonValue.Create("example value")!, + JsonValue.Create(42)! + ] + }; + + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi3_1)] + public async Task SerializeExamplesAsJsonSchemaKeywordInV31AndLater(OpenApiSpecVersion version) + { + var expected = """ + { + "examples": [ + "example value", + 42 + ] + } + """; + var schema = new OpenApiSchema + { + Examples = + [ + JsonValue.Create("example value")!, + JsonValue.Create(42)! + ] + }; + + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + } + [Theory] [InlineData(OpenApiSpecVersion.OpenApi2_0)] [InlineData(OpenApiSpecVersion.OpenApi3_0)] @@ -1759,7 +1844,7 @@ public async Task SerializeEmptyPatternPropertiesNotEmittedInEarlierVersions(Ope }; // When - var actual = await schema.SerializeAsJsonAsync(version); + var actual = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Then Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -1837,6 +1922,80 @@ public void DeserializePatternPropertiesExtensionInV3AssignsPatternPropertiesPro Assert.True(schema.Extensions is null || !schema.Extensions.ContainsKey("x-jsonschema-patternProperties")); } + [Fact] + public void DeserializeExamplesExtensionInV2AssignsExamplesProperty() + { + var jsonContent = """ + { + "swagger": "2.0", + "info": { "title": "Test", "version": "1.0" }, + "paths": {}, + "definitions": { + "TestSchema": { + "type": "string", + "example": "primary example", + "x-jsonschema-examples": [ + "secondary example", + 42 + ] + } + } + } + """; + + var readResult = OpenApiDocument.Parse(jsonContent, "json"); + + Assert.Empty(readResult.Diagnostic.Errors); + var schema = readResult.Document.Components.Schemas["TestSchema"]; +#pragma warning disable CS0618 // Type or member is obsolete + Assert.Equal("primary example", schema.Example?.GetValue()); +#pragma warning restore CS0618 // Type or member is obsolete + Assert.NotNull(schema.Examples); + Assert.Collection( + schema.Examples, + example => Assert.Equal("secondary example", example.GetValue()), + example => Assert.Equal(42, example.GetValue())); + Assert.True(schema.Extensions is null || !schema.Extensions.ContainsKey(OpenApiConstants.JsonSchemaExamplesExtension)); + } + + [Fact] + public void DeserializeExamplesExtensionInV3AssignsExamplesProperty() + { + var jsonContent = """ + { + "openapi": "3.0.0", + "info": { "title": "Test", "version": "1.0" }, + "paths": {}, + "components": { + "schemas": { + "TestSchema": { + "type": "string", + "example": "primary example", + "x-jsonschema-examples": [ + "secondary example", + 42 + ] + } + } + } + } + """; + + var readResult = OpenApiDocument.Parse(jsonContent, "json"); + + Assert.Empty(readResult.Diagnostic.Errors); + var schema = readResult.Document.Components.Schemas["TestSchema"]; +#pragma warning disable CS0618 // Type or member is obsolete + Assert.Equal("primary example", schema.Example?.GetValue()); +#pragma warning restore CS0618 // Type or member is obsolete + Assert.NotNull(schema.Examples); + Assert.Collection( + schema.Examples, + example => Assert.Equal("secondary example", example.GetValue()), + example => Assert.Equal(42, example.GetValue())); + Assert.True(schema.Extensions is null || !schema.Extensions.ContainsKey(OpenApiConstants.JsonSchemaExamplesExtension)); + } + [Fact] public void DeserializeContainsExtensionsInV3AssignsContainsProperties() { @@ -1884,14 +2043,15 @@ public async Task SerializeNullableEnumWith3_0() // Otherwise, validators will consider null as invalid even if nullable is set to true. // It's unclear if it's an issue of the validators or not, but it's safer to do it that way. var schema = CreateNullableEnumSchema(); - var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); var expected = """ { "oneOf": [ { "enum": [ null - ] + ], + "nullable": true }, { "enum": [ @@ -1911,7 +2071,7 @@ public async Task SerializeNullableEnumWith3_0() public async Task SerializeNullableEnumWith3_1_And_Later(OpenApiSpecVersion version) { var schema = CreateNullableEnumSchema(); - var result = await schema.SerializeAsJsonAsync(version); + var result = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); var expected = """ { "oneOf": [ @@ -1934,12 +2094,13 @@ public async Task SerializeNullableEnumWith3_1_And_Later(OpenApiSpecVersion vers public async Task SerializeNullableTypeWith3_0() { var schema = CreateTypeNullSchema(); - var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); var expected = """ { "enum": [ null - ] + ], + "nullable": true } """; @@ -1951,7 +2112,7 @@ public async Task SerializeNullableTypeWith3_0() public async Task SerializeNullableTypeWith3_1_And_Later(OpenApiSpecVersion version) { var schema = CreateTypeNullSchema(); - var result = await schema.SerializeAsJsonAsync(version); + var result = await schema.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); var expected = """ { "type": "null" @@ -1960,6 +2121,754 @@ public async Task SerializeNullableTypeWith3_1_And_Later(OpenApiSpecVersion vers Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); } + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "integer", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "integer", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "integer", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Null(deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "type": "string", + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "type": "string", + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ], + "nullable": true + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "integer", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ], + "nullable": true + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "integer", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + var expected = """ + { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ], + "nullable": true + } + ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "type": [ "null", "integer", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, cancellationToken: TestContext.Current.CancellationToken); + var expected = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Null(deserializedSchema.Type); + + var actual31 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, cancellationToken: TestContext.Current.CancellationToken); + var expected31 = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected31), JsonNode.Parse(actual31))); + } + private OpenApiSchema CreateNullableEnumSchema() { var schema = new OpenApiSchema(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs new file mode 100644 index 000000000..ae03dcfb2 --- /dev/null +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs @@ -0,0 +1,293 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.OpenApi.Tests.Models +{ + /// + /// Tests for the transformations applied when an that uses + /// JSON Schema DRAFT 2020-12 / OpenAPI 3.2 features is serialized down to OpenAPI 3.0 (which lacks those features), + /// and the corresponding behavior when such documents are deserialized back. + /// + [Collection("DefaultSettings")] + public class OpenApiSchemaV30CompatibilityTests + { + private static IOpenApiSchema ParseSchemaFromV30Document(string schemaJson) + { + var jsonContent = $$""" + { + "openapi": "3.0.0", + "info": { "title": "Test", "version": "1.0" }, + "paths": {}, + "components": { + "schemas": { + "TestSchema": {{schemaJson}} + } + } + } + """; + + var readResult = OpenApiDocument.Parse(jsonContent, "json"); + Assert.Empty(readResult.Diagnostic.Errors); + return readResult.Document.Components.Schemas["TestSchema"]; + } + + [Fact] + public async Task NullableEnumShouldRoundTripCorrectly() + { + var schema = new OpenApiSchema + { + Enum = + [ + JsonValue.Create(1), + JsonValue.Create(2), + JsonValue.Create(3), + JsonNullSentinel.JsonNull, + ] + }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = + """ + { + "enum": [ + 1, + 2, + 3, + null + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + + Assert.Equal(4, deserializedSchema.Enum.Count); + Assert.Equal(1, deserializedSchema.Enum[0].GetValue()); + Assert.Equal(2, deserializedSchema.Enum[1].GetValue()); + Assert.Equal(3, deserializedSchema.Enum[2].GetValue()); + Assert.True(deserializedSchema.Enum[3].IsJsonNullSentinel()); + } + + [Fact] + public async Task TypeNullAloneAsV3ShouldRoundTripCorrectly() + { + var schema = new OpenApiSchema { Type = JsonSchemaType.Null }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = + """ + { + "enum": [ + null + ], + "nullable": true + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + + Assert.Equal(JsonSchemaType.Null, deserializedSchema.Type); + Assert.Null(deserializedSchema.Enum); + } + + [Fact] + public async Task NullableTypeAsV3ShouldRoundTripCorrectly() + { + var schema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Null }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = + """ + { + "type": "string", + "nullable": true + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + Assert.Equal(JsonSchemaType.String | JsonSchemaType.Null, deserializedSchema.Type); + } + + [Fact] + public async Task SerializeMultipleNonNullTypesAsV3DoesNotOmitType() + { + var schema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Integer }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + Assert.Equal(schema.Type, deserializedSchema.Type); + } + + [Fact] + public async Task SerializeMultipleNonNullTypesWithNullAsV3DoesNotOmitType() + { + var schema = new OpenApiSchema + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null + }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ], + "nullable": true + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + Assert.Equal(schema.Type, deserializedSchema.Type); + } + + [Fact] + public void DeserializeAnyOfWithConstraintsAsV3PreservesConstraints() + { + var schemaJson = """ + { + "anyOf": [ + { + "type": "string", + "format": "email", + "maxLength": 10 + }, + { + "type": "integer", + "minimum": 0 + } + ] + } + """; + + var deserializedSchema = ParseSchemaFromV30Document(schemaJson); + + Assert.Null(deserializedSchema.Type); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Collection(deserializedSchema.AnyOf, + first => + { + Assert.Equal(JsonSchemaType.String, first.Type); + Assert.Equal("email", first.Format); + Assert.Equal(10, first.MaxLength); + }, + second => + { + Assert.Equal(JsonSchemaType.Integer, second.Type); + Assert.Equal("0", second.Minimum); + }); + } + + [Fact] + public async Task SerializeConstAsV3EmitsSingleValueEnum() + { + var schema = new OpenApiSchema { Type = JsonSchemaType.String, Const = "foo" }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var node = JsonNode.Parse(actual)!.AsObject(); + Assert.False(node.ContainsKey("const")); + Assert.True(node["enum"] is JsonArray enumArray + && enumArray.Count == 1 + && enumArray[0]!.ToString() == "foo"); + + var deserializedSchema = ParseSchemaFromV30Document(actual); + Assert.Null(deserializedSchema.Const); + Assert.NotNull(deserializedSchema.Enum); + Assert.Single(deserializedSchema.Enum); + Assert.Equal("foo", deserializedSchema.Enum[0]!.ToString()); + } + + [Fact] + public async Task SerializeExclusiveMaximumAsV3EmitsMaximumWithBooleanFlag() + { + var schema = new OpenApiSchema + { + Type = JsonSchemaType.Integer, + ExclusiveMaximum = "5" + }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = + """ + { + "type": "integer", + "maximum": 5, + "exclusiveMaximum": true + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = (OpenApiSchema)ParseSchemaFromV30Document(actual); + Assert.True(deserializedSchema.IsExclusiveMaximum); + Assert.Null(deserializedSchema.Maximum); + Assert.Equal("5", deserializedSchema.ExclusiveMaximum); + } + + [Fact] + public async Task SerializeExclusiveMinimumAsV3EmitsMinimumWithBooleanFlag() + { + var schema = new OpenApiSchema + { + Type = JsonSchemaType.Integer, + ExclusiveMinimum = "1" + }; + + var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); + + var expected = + """ + { + "type": "integer", + "minimum": 1, + "exclusiveMinimum": true + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + + var deserializedSchema = (OpenApiSchema)ParseSchemaFromV30Document(actual); + Assert.True(deserializedSchema.IsExclusiveMinimum); + Assert.Null(deserializedSchema.Minimum); + Assert.Equal("1", deserializedSchema.ExclusiveMinimum); + } + } +} diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs index 29f5af3c6..8022d1070 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs @@ -105,7 +105,7 @@ public async Task SerializeBasicSecurityRequirementAsV3JsonWorks() var expected = @"{ }"; // Act - var actual = await BasicSecurityRequirement.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicSecurityRequirement.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -124,7 +124,7 @@ public async Task SerializeSecurityRequirementAsV3JsonWorksAsync(bool produceTer // Act SecurityRequirementWithReferencedSecurityScheme.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -153,7 +153,7 @@ public async Task SerializeSecurityRequirementWithReferencedSecuritySchemeAsJson """; // Act - var actual = await SecurityRequirementWithReferencedSecurityScheme.SerializeAsJsonAsync(openApiSpecVersion); + var actual = await SecurityRequirementWithReferencedSecurityScheme.SerializeAsJsonAsync(openApiSpecVersion, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); @@ -178,7 +178,7 @@ public async Task SerializeSecurityRequirementWithUnreferencedSecuritySchemeAsJs """; // Act - var actual = await SecurityRequirementWithUnreferencedSecurityScheme.SerializeAsJsonAsync(openApiSpecVersion); + var actual = await SecurityRequirementWithUnreferencedSecurityScheme.SerializeAsJsonAsync(openApiSpecVersion, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs index 8c7300aba..75c572059 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs @@ -131,7 +131,7 @@ public async Task SerializeApiKeySecuritySchemeAsV3JsonWorks() """; // Act - var actual = await ApiKeySecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await ApiKeySecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -152,7 +152,7 @@ public async Task SerializeApiKeySecuritySchemeAsV3YamlWorks() """; // Act - var actual = await ApiKeySecurityScheme.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await ApiKeySecurityScheme.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -244,7 +244,7 @@ public async Task SerializeHttpSecuritySchemeWithoutSchemeAsV2DoesNotThrow() }; // Act - var actual = await securityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await securityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse("{}"), JsonNode.Parse(actual))); @@ -297,7 +297,7 @@ public async Task SerializeOpenIdConnectSecuritySchemeWithoutOpenIdConnectUrlAsV }; // Act - var actual = await securityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); + var actual = await securityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0, TestContext.Current.CancellationToken); // Assert Assert.True(JsonNode.DeepEquals(JsonNode.Parse("{}"), JsonNode.Parse(actual))); @@ -317,7 +317,7 @@ public async Task SerializeHttpBasicSecuritySchemeAsV3JsonWorks() """; // Act - var actual = await HttpBasicSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await HttpBasicSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -340,7 +340,7 @@ public async Task SerializeHttpBearerSecuritySchemeAsV3JsonWorks() """; // Act - var actual = await HttpBearerSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await HttpBearerSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -383,7 +383,7 @@ public async Task SerializeOAuthSingleFlowSecuritySchemeAsV3JsonWorks() """; // Act - var actual = await OAuth2SingleFlowSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await OAuth2SingleFlowSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -429,7 +429,7 @@ public async Task SerializeOAuthMultipleFlowSecuritySchemeAsV3JsonWorks() """; // Act - var actual = await OAuth2MultipleFlowSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await OAuth2MultipleFlowSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -451,7 +451,7 @@ public async Task SerializeOpenIdConnectSecuritySchemeAsV3JsonWorks() """; // Act - var actual = await OpenIdConnectSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await OpenIdConnectSecurityScheme.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -470,7 +470,7 @@ public async Task SerializeReferencedSecuritySchemeAsV3JsonWorksAsync(bool produ // Act OpenApiSecuritySchemeReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -487,7 +487,7 @@ public async Task SerializeReferencedSecuritySchemeAsV3JsonWithoutReferenceWorks // Act ReferencedSecurityScheme.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiServerTests.cs index 9e616a8d5..0ceb6b0af 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiServerTests.cs @@ -57,7 +57,7 @@ public async Task SerializeBasicServerAsV3JsonWorks() """; // Act - var actual = await BasicServer.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await BasicServer.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -95,7 +95,7 @@ public async Task SerializeAdvancedServerAsV3JsonWorks() """; // Act - var actual = await AdvancedServer.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedServer.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiServerVariableTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiServerVariableTests.cs index ee9a81826..4770d34d9 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiServerVariableTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiServerVariableTests.cs @@ -28,7 +28,7 @@ public class OpenApiServerVariableTests public async Task SerializeBasicServerVariableAsV3Works(string format, string expected) { // Arrange & Act - var actual = await BasicServerVariable.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format); + var actual = await BasicServerVariable.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -53,7 +53,7 @@ public async Task SerializeAdvancedServerVariableAsV3JsonWorks() """; // Act - var actual = await AdvancedServerVariable.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedServerVariable.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -75,7 +75,7 @@ public async Task SerializeAdvancedServerVariableAsV3YamlWorks() """; // Act - var actual = await AdvancedServerVariable.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); + var actual = await AdvancedServerVariable.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiTagTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiTagTests.cs index 16a486878..263638722 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiTagTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiTagTests.cs @@ -39,7 +39,7 @@ public async Task SerializeBasicTagAsV3JsonWithoutReferenceWorksAsync(bool produ // Act BasicTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -56,7 +56,7 @@ public async Task SerializeBasicTagAsV2JsonWithoutReferenceWorksAsync(bool produ // Act BasicTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -90,7 +90,7 @@ public async Task SerializeBasicTagAsV2YamlWithoutReferenceWorks() // Act BasicTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -117,7 +117,7 @@ public async Task SerializeAdvancedTagAsV3YamlWithoutReferenceWorks() // Act AdvancedTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -144,7 +144,7 @@ public async Task SerializeAdvancedTagAsV2YamlWithoutReferenceWorks() // Act AdvancedTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -164,7 +164,7 @@ public async Task SerializeAdvancedTagAsV3JsonWorksAsync(bool produceTerseOutput // Act AdvancedTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -181,7 +181,7 @@ public async Task SerializeAdvancedTagAsV2JsonWorksAsync(bool produceTerseOutput // Act AdvancedTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -203,7 +203,7 @@ public async Task SerializeAdvancedTagAsV3YamlWorks() // Act AdvancedTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -228,7 +228,7 @@ public async Task SerializeAdvancedTagAsV2YamlWorks() // Act AdvancedTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -248,7 +248,7 @@ public async Task SerializeReferencedTagAsV3JsonWorksAsync(bool produceTerseOutp // Act ReferencedTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -265,7 +265,7 @@ public async Task SerializeReferencedTagAsV2JsonWorksAsync(bool produceTerseOutp // Act ReferencedTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -282,7 +282,7 @@ public async Task SerializeReferencedTagAsV3YamlWorks() // Act ReferencedTag.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert @@ -302,7 +302,7 @@ public async Task SerializeReferencedTagAsV2YamlWorks() // Act ReferencedTag.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiXmlTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiXmlTests.cs index 5424e1eb9..b6142a911 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiXmlTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiXmlTests.cs @@ -35,7 +35,7 @@ public async Task SerializeBasicXmlWorks( string format) { // Act - var actual = await BasicXml.SerializeAsync(version, format); + var actual = await BasicXml.SerializeAsync(version, format, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -61,7 +61,7 @@ public async Task SerializeAdvancedXmlAsJsonWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvancedXml.SerializeAsJsonAsync(version); + var actual = await AdvancedXml.SerializeAsJsonAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); @@ -86,7 +86,7 @@ public async Task SerializeAdvancedXmlAsYamlWorks(OpenApiSpecVersion version) """; // Act - var actual = await AdvancedXml.SerializeAsYamlAsync(version); + var actual = await AdvancedXml.SerializeAsYamlAsync(version, TestContext.Current.CancellationToken); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs index c39db4c13..6c6f42665 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs @@ -166,7 +166,7 @@ public async Task SerializeCallbackReferenceAsV3JsonWorks(bool produceTerseOutpu // Act _externalCallbackReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -185,7 +185,7 @@ public async Task SerializeCallbackReferenceAsV31JsonWorks(bool produceTerseOutp // Act _externalCallbackReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs index bd40056a4..98f352da7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs @@ -156,7 +156,7 @@ public async Task SerializeExampleReferenceAsV3JsonWorks(bool produceTerseOutput // Act _localExampleReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -175,7 +175,7 @@ public async Task SerializeExampleReferenceAsV31JsonWorks(bool produceTerseOutpu // Act _localExampleReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs index 7a5e7fc9c..4556c1bff 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs @@ -116,7 +116,7 @@ public async Task SerializeHeaderReferenceAsV3JsonWorks(bool produceTerseOutput, // Act _localHeaderReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -135,7 +135,7 @@ public async Task SerializeHeaderReferenceAsV31JsonWorks(bool produceTerseOutput // Act _localHeaderReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -154,7 +154,7 @@ public async Task SerializeHeaderReferenceAsV2JsonWorksAsync(bool produceTerseOu // Act _localHeaderReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs index 33354a67c..f75dbb11b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs @@ -164,7 +164,7 @@ public async Task SerializeLinkReferenceAsV3JsonWorks(bool produceTerseOutput, b // Act _localLinkReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -183,7 +183,7 @@ public async Task SerializeLinkReferenceAsV31JsonWorks(bool produceTerseOutput, // Act _localLinkReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs index 89f96c990..f682b012f 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs @@ -117,7 +117,7 @@ public async Task SerializeParameterReferenceAsV3JsonWorks(bool produceTerseOutp // Act _localParameterReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -136,7 +136,7 @@ public async Task SerializeParameterReferenceAsV31JsonWorks(bool produceTerseOut // Act _localParameterReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -155,7 +155,7 @@ public async Task SerializeParameterReferenceAsV2JsonWorksAsync(bool produceTers // Act _localParameterReference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs index e4a98a0a1..5f74fb600 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs @@ -126,7 +126,7 @@ public async Task SerializePathItemReferenceAsV31JsonWorks(bool produceTerseOutp // Act _localPathItemReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs index e3219e021..5991237ba 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs @@ -130,7 +130,7 @@ public async Task SerializeRequestBodyReferenceAsV3JsonWorks(bool produceTerseOu // Act _localRequestBodyReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -149,7 +149,7 @@ public async Task SerializeRequestBodyReferenceAsV31JsonWorks(bool produceTerseO // Act _localRequestBodyReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs index b1e44a90d..63f272acc 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs @@ -112,7 +112,7 @@ public async Task SerializeResponseReferenceAsV3JsonWorks(bool produceTerseOutpu // Act _localResponseReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -131,7 +131,7 @@ public async Task SerializeResponseReferenceAsV31JsonWorks(bool produceTerseOutp // Act _localResponseReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt index ddb324ad6..0af262f8e 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt @@ -1,3 +1,3 @@ { "$ref": "#/definitions/Pet" -} +} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt index b36112c01..d4b02da13 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.SerializeSchemaReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"$ref":"#/definitions/Pet"} +{"$ref":"#/definitions/Pet"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.cs index 1a0031060..1954857ed 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSchemaReferenceTests.cs @@ -314,7 +314,7 @@ public async Task SerializeSchemaReferenceAsV31JsonWorks(bool produceTerseOutput // Act reference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -346,7 +346,7 @@ public async Task SerializeSchemaReferenceAsV3JsonWorks(bool produceTerseOutput) // Act reference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -378,7 +378,7 @@ public async Task SerializeSchemaReferenceAsV2JsonWorks(bool produceTerseOutput) // Act reference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -549,7 +549,7 @@ public async Task SchemaReferenceExtensionsNotWrittenInV30() // Act reference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var output = outputStringWriter.ToString(); // Assert: In v3.0, ONLY $ref should appear - no description, no extensions @@ -574,7 +574,7 @@ public async Task SchemaReferenceExtensionsNotWrittenInV2() // Act reference.SerializeAsV2(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var output = outputStringWriter.ToString(); // Assert: In v2, ONLY $ref should appear - no description, no extensions diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs index 767ea126f..1fb49794a 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs @@ -63,7 +63,7 @@ public async Task SerializeSecuritySchemeReferenceAsV3JsonWorks(bool produceTers // Act _openApiSecuritySchemeReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); @@ -82,7 +82,7 @@ public async Task SerializeSecuritySchemeReferenceAsV31JsonWorks(bool produceTer // Act _openApiSecuritySchemeReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput, inlineLocalReferences); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiTagReferenceTest.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiTagReferenceTest.cs index df008d516..a9734254f 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiTagReferenceTest.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiTagReferenceTest.cs @@ -95,7 +95,7 @@ public async Task SerializeTagReferenceAsV3JsonWorks(bool produceTerseOutput) // Act _openApiTagReference.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -112,7 +112,7 @@ public async Task SerializeTagReferenceAsV31JsonWorks(bool produceTerseOutput) // Act _openApiTagReference.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -129,7 +129,7 @@ public async Task SerializeTagAsV3JsonWorks(bool produceTerseOutput) // Act _openApiTagReference2.SerializeAsV3(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert Assert.Equal("\"users.user\"", outputStringWriter.ToString()); @@ -146,7 +146,7 @@ public async Task SerializeTagAsV31JsonWorks(bool produceTerseOutput) // Act _openApiTagReference2.SerializeAsV31(writer); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); // Assert Assert.Equal("\"users.user\"", outputStringWriter.ToString()); @@ -193,7 +193,7 @@ public async Task SerializesADescriptionWithNoMatchingTagDefinition(OpenApiSpecV document.SerializeAsV31(writer); break; } - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var expected = version switch { diff --git a/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs b/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs index 9a28fb126..206cc46c1 100644 --- a/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs +++ b/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs @@ -12,7 +12,7 @@ public class OpenApiModelFactoryTests [Fact] public async Task LoadDocumentWithCircularSchemaPropertyReferencesShouldSucceed() { - var filePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.json"); + var filePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.json"); await File.WriteAllTextAsync(filePath, """ { "openapi": "3.0.0", @@ -40,11 +40,11 @@ await File.WriteAllTextAsync(filePath, """ } } } -"""); +""", TestContext.Current.CancellationToken); try { - var result = await OpenApiDocument.LoadAsync(filePath); + var result = await OpenApiDocument.LoadAsync(filePath, token: TestContext.Current.CancellationToken); Assert.NotNull(result.Document); Assert.Empty(result.Diagnostic.Errors); @@ -62,7 +62,7 @@ await File.WriteAllTextAsync(filePath, """ [Fact] public async Task LoadDocumentWithCircularRootSchemaReferencesShouldReturnDiagnosticWarning() { - var filePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.json"); + var filePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.json"); await File.WriteAllTextAsync(filePath, """ { "openapi": "3.0.0", @@ -82,11 +82,11 @@ await File.WriteAllTextAsync(filePath, """ } } } -"""); +""", TestContext.Current.CancellationToken); try { - var result = await OpenApiDocument.LoadAsync(filePath); + var result = await OpenApiDocument.LoadAsync(filePath, token: TestContext.Current.CancellationToken); Assert.NotNull(result.Document); Assert.Empty(result.Diagnostic.Errors); @@ -102,7 +102,7 @@ await File.WriteAllTextAsync(filePath, """ [Fact] public async Task UsesSettingsBaseUrl() { - var tempFilePathReferee = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePathReferee = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePathReferee, """ { @@ -147,8 +147,8 @@ await File.WriteAllTextAsync(tempFilePathReferee, } } } -"""); - var tempFilePathReferrer = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); +""", TestContext.Current.CancellationToken); + var tempFilePathReferrer = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePathReferrer, $$$""" { @@ -193,18 +193,18 @@ await File.WriteAllTextAsync(tempFilePathReferrer, } } } -"""); +""", TestContext.Current.CancellationToken); // read referrer document to a memory stream using var stream = new MemoryStream(); using var reader = new StreamReader(tempFilePathReferrer); - await reader.BaseStream.CopyToAsync(stream); + await reader.BaseStream.CopyToAsync(stream, TestContext.Current.CancellationToken); stream.Position = 0; var baseUri = new Uri(tempFilePathReferrer); var settings = new OpenApiReaderSettings { BaseUrl = baseUri, }; - var readResult = await OpenApiDocument.LoadAsync(stream, settings: settings); + var readResult = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); Assert.Equal(OpenApiConstants.Json, readResult.Diagnostic.Format); Assert.NotNull(readResult.Document); Assert.NotNull(readResult.Document.Components); @@ -237,7 +237,7 @@ public async Task CanLoadANonSeekableStreamInJsonAndDetectFormat() using var nonSeekableStream = new NonSeekableStream(memoryStream); // When - var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream); + var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, cancellationToken: TestContext.Current.CancellationToken); // Then Assert.NotNull(document); @@ -254,7 +254,7 @@ public async Task CanLoadANonSeekableStreamInYamlAndDetectFormat() settings.AddYamlReader(); // When - var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, settings: settings); + var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); // Then Assert.NotNull(document); @@ -269,7 +269,7 @@ public async Task CanLoadAnAsyncOnlyStreamInJsonAndDetectFormat() await using var nonSeekableStream = new AsyncOnlyStream(memoryStream); // When - var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream); + var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, cancellationToken: TestContext.Current.CancellationToken); // Then Assert.NotNull(document); @@ -286,7 +286,7 @@ public async Task CanLoadAnAsyncOnlyStreamInYamlAndDetectFormat() settings.AddYamlReader(); // When - var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, settings: settings); + var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, settings: settings, cancellationToken: TestContext.Current.CancellationToken); // Then Assert.NotNull(document); @@ -301,7 +301,7 @@ public async Task CanLoadANonSeekableStreamInJsonAndDetectFormatWhenPrecededBySp using var nonSeekableStream = new NonSeekableStream(memoryStream); // When - var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream); + var (document, _) = await OpenApiDocument.LoadAsync(nonSeekableStream, cancellationToken: TestContext.Current.CancellationToken); // Then Assert.NotNull(document); diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs index 0cb229534..8a5751666 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs @@ -36,6 +36,7 @@ public void ValidateDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() } [Fact] +#pragma warning disable CS0618 public void ValidateExampleAndDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange @@ -58,6 +59,7 @@ public void ValidateExampleAndDefaultShouldNotHaveDataTypeMismatchForSimpleSchem // Assert Assert.True(result); } +#pragma warning restore CS0618 [Fact] public void ValidateEnumShouldNotHaveDataTypeMismatchForSimpleSchema() diff --git a/test/Microsoft.OpenApi.Tests/Writers/OpenApiJsonWriterTests.cs b/test/Microsoft.OpenApi.Tests/Writers/OpenApiJsonWriterTests.cs index fa3b0163d..8065c16b3 100644 --- a/test/Microsoft.OpenApi.Tests/Writers/OpenApiJsonWriterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Writers/OpenApiJsonWriterTests.cs @@ -58,7 +58,7 @@ public async Task WriteStringListAsJsonShouldMatchExpected(string[] stringValues } writer.WriteEndArray(); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var parsedObject = JsonSerializer.Deserialize>(outputString.GetStringBuilder().ToString()); var expectedObject = diff --git a/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterAnyExtensionsTests.cs b/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterAnyExtensionsTests.cs index fb315feff..fb537ce39 100644 --- a/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterAnyExtensionsTests.cs +++ b/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterAnyExtensionsTests.cs @@ -173,13 +173,10 @@ public async Task WriteOpenApiDateTimeAsJsonWorksAsync(string inputString, bool Assert.Equal(expectedJson, json); } - public static IEnumerable BooleanInputs - { - get => - from input in new[] { true, false } - from shouldBeTerse in shouldProduceTerseOutputValues - select new object[] { input, shouldBeTerse }; - } + public static IEnumerable BooleanInputs { get; } = + from input in new[] { true, false } + from shouldBeTerse in shouldProduceTerseOutputValues + select new object[] { input, shouldBeTerse }; [Theory] [MemberData(nameof(BooleanInputs))] diff --git a/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterSpecialCharacterTests.cs b/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterSpecialCharacterTests.cs index 66819367c..16a416080 100644 --- a/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterSpecialCharacterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterSpecialCharacterTests.cs @@ -14,23 +14,20 @@ public class OpenApiWriterSpecialCharacterTests { static bool[] shouldProduceTerseOutputValues = new[] { true, false }; - public static IEnumerable StringWithSpecialCharacters - { - get => - from inputExpected in new[] { - new[]{ "Test\bTest", "\"Test\\bTest\"" }, - new[]{ "Test\fTest", "\"Test\\fTest\""}, - new[]{ "Test\nTest", "\"Test\\nTest\""}, - new[]{ "Test\rTest", "\"Test\\rTest\""}, - new[]{ "Test\tTest", "\"Test\\tTest\""}, - new[]{ "Test\\Test", "\"Test\\\\Test\""}, - new[]{ "Test\"Test", "\"Test\\\"Test\""}, - new[]{ "StringsWith\"Quotes\"", "\"StringsWith\\\"Quotes\\\"\""}, - new[]{ "0x1234", "\"0x1234\""}, - } - from shouldBeTerse in shouldProduceTerseOutputValues - select new object[] { inputExpected[0], inputExpected[1], shouldBeTerse }; - } + public static IEnumerable StringWithSpecialCharacters { get; } = + from inputExpected in new[] { + new[]{ "Test\bTest", "\"Test\\bTest\"" }, + new[]{ "Test\fTest", "\"Test\\fTest\""}, + new[]{ "Test\nTest", "\"Test\\nTest\""}, + new[]{ "Test\rTest", "\"Test\\rTest\""}, + new[]{ "Test\tTest", "\"Test\\tTest\""}, + new[]{ "Test\\Test", "\"Test\\\\Test\""}, + new[]{ "Test\"Test", "\"Test\\\"Test\""}, + new[]{ "StringsWith\"Quotes\"", "\"StringsWith\\\"Quotes\\\"\""}, + new[]{ "0x1234", "\"0x1234\""}, + } + from shouldBeTerse in shouldProduceTerseOutputValues + select new object[] { inputExpected[0], inputExpected[1], shouldBeTerse }; [Theory] [MemberData(nameof(StringWithSpecialCharacters))] diff --git a/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs b/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs index 5f36e8d48..f9062d0bb 100644 --- a/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs @@ -70,7 +70,7 @@ public async Task WriteStringListAsYamlShouldMatchExpected(string[] stringValues } writer.WriteEndArray(); - await writer.FlushAsync(); + await writer.FlushAsync(TestContext.Current.CancellationToken); var actualYaml = outputString.GetStringBuilder() .ToString()