diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index 69597d978..b3c482215 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -10,7 +10,7 @@ Microsoft Microsoft.OpenApi.Readers Microsoft.OpenApi.Readers - 1.6.4-preview2 + 1.6.4-preview3 OpenAPI.NET Readers for JSON and YAML documents © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs index 02e868412..fa3aa7224 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs @@ -139,6 +139,12 @@ private static void MakeServers(IList servers, ParsingContext con var schemes = context.GetFromTempStorage>("schemes"); Uri defaultUrl = rootNode.Context.BaseUrl; + // so we don't default to the document path when a host is provided + if (string.IsNullOrEmpty(basePath) && !string.IsNullOrEmpty(host)) + { + basePath = "/"; + } + // If nothing is provided, don't create a server if (host == null && basePath == null && schemes == null) { diff --git a/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj b/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj index c7ab75af4..88f12fcb9 100644 --- a/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj +++ b/src/Microsoft.OpenApi.Workbench/Microsoft.OpenApi.Workbench.csproj @@ -1,4 +1,4 @@ - + net7.0-windows WinExe @@ -10,7 +10,7 @@ all - + diff --git a/src/Microsoft.OpenApi/Helpers/DictionaryCloneHelper.cs b/src/Microsoft.OpenApi/Helpers/DictionaryCloneHelper.cs index 279e4639d..1af7bc8c4 100644 --- a/src/Microsoft.OpenApi/Helpers/DictionaryCloneHelper.cs +++ b/src/Microsoft.OpenApi/Helpers/DictionaryCloneHelper.cs @@ -9,7 +9,7 @@ namespace Microsoft.OpenApi.Helpers /// /// Helper class for deep cloning dictionaries. /// - internal class DictionaryCloneHelper + internal static class DictionaryCloneHelper { /// /// Deep clone key value pairs in a dictionary. @@ -21,14 +21,26 @@ internal class DictionaryCloneHelper internal static Dictionary Clone(IDictionary dictionary) { if (dictionary is null) return null; + var clonedDictionary = new Dictionary(dictionary.Keys.Count); + var clonedObjects = new Dictionary(); - foreach (var kvp in dictionary) + foreach (var keyValuePair in dictionary) { - // Create instance of the specified type using the constructor matching the specified parameter types. - clonedDictionary[kvp.Key] = (U)Activator.CreateInstance(kvp.Value.GetType(), kvp.Value); - } - + // If the object has already been cloned, use the cloned object instead of cloning it again + if (clonedObjects.TryGetValue(keyValuePair.Value, out var clonedValue)) + { + clonedDictionary[keyValuePair.Key] = (U)clonedValue; + } + else + { + // Create instance of the specified type using the constructor matching the specified parameter types. + clonedDictionary[keyValuePair.Key] = (U)Activator.CreateInstance(keyValuePair.Value.GetType(), keyValuePair.Value); + + // Add the cloned object to the dictionary of cloned objects + clonedObjects.Add(keyValuePair.Value, clonedDictionary[keyValuePair.Key]); + } + } return clonedDictionary; } diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index c996acbaf..4a291f120 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -11,7 +11,7 @@ Microsoft Microsoft.OpenApi Microsoft.OpenApi - 1.6.4-preview2 + 1.6.4-preview3 .NET models with JSON and YAML writers for OpenAPI specification © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs index c87b491ab..1b917fde7 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs @@ -74,6 +74,31 @@ public void JustHostNoDefault() Assert.Equal("//www.foo.com", server.Url); } + [Fact] + public void NoBasePath() + { + var input = @" +swagger: 2.0 +info: + title: test + version: 1.0.0 +host: www.foo.com +schemes: + - http +paths: {} +"; + var reader = new OpenApiStringReader(new OpenApiReaderSettings() + { + BaseUrl = new Uri("https://www.foo.com/spec.yaml") + }); + + var doc = reader.Read(input, out var diagnostic); + + var server = doc.Servers.First(); + Assert.Equal(1, doc.Servers.Count); + Assert.Equal("http://www.foo.com", server.Url); + } + [Fact] public void JustBasePathNoDefault() { @@ -203,14 +228,14 @@ public void JustHostWithCustomHostWithApi() "; var reader = new OpenApiStringReader(new OpenApiReaderSettings() { - BaseUrl = new Uri("https://dev.bing.com/api") + BaseUrl = new Uri("https://dev.bing.com/api/description.yaml") }); var doc = reader.Read(input, out var diagnostic); var server = doc.Servers.First(); Assert.Equal(1, doc.Servers.Count); - Assert.Equal("https://prod.bing.com/api", server.Url); + Assert.Equal("https://prod.bing.com", server.Url); } [Fact]