Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.406"
Comment thread
baywet marked this conversation as resolved.
"version": "8.0.115"
}
}
43 changes: 1 addition & 42 deletions src/Microsoft.OpenApi/Extensions/CollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,9 @@
using System;
Comment thread
baywet marked this conversation as resolved.
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.OpenApi
namespace Microsoft.OpenApi
{
/// <summary>
/// Dictionary extension methods
/// </summary>
internal static class CollectionExtensions
{
/// <summary>
/// Returns a new dictionary with entries sorted by key using a custom comparer.
/// </summary>
internal static IDictionary<TKey, TValue> Sort<TKey, TValue>(
this IDictionary<TKey, TValue> source,
IComparer<TKey> comparer)
where TKey : notnull
{
#if NET7_0_OR_GREATER
ArgumentNullException.ThrowIfNull(nameof(source));
ArgumentNullException.ThrowIfNull(nameof(comparer));
#else
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
#endif
return source.OrderBy(kvp => kvp.Key, comparer)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

/// <summary>
/// Sorts any IEnumerable<T> using the specified comparer and returns a List</T>.
/// </summary>
internal static List<T> Sort<T>(this IEnumerable<T> source, IComparer<T> comparer)
{
#if NET7_0_OR_GREATER
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(comparer);
#else
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
#endif
return source.OrderBy(item => item, comparer).ToList();
}
}
}
13 changes: 0 additions & 13 deletions src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,6 @@ private static void WriteCollectionInternal<T>(
writer.WriteStartArray();
if (elements != null)
{
var settings = writer.GetSettings();

if (settings?.KeyComparer is IComparer<T> typedComparer)
{
elements = elements.Sort(typedComparer);
}

foreach (var item in elements)
{
if (item != null)
Expand Down Expand Up @@ -464,12 +457,6 @@ private static void WriteMapInternal<T>(

if (elements != null)
{
var settings = writer.GetSettings();
if (settings?.KeyComparer != null)
{
elements = elements.Sort(settings.KeyComparer); // sort using custom comparer
}

foreach (var item in elements)
{
writer.WritePropertyName(item.Key);
Expand Down
9 changes: 1 addition & 8 deletions src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace Microsoft.OpenApi
namespace Microsoft.OpenApi
{
/// <summary>
/// Configuration settings to control how OpenAPI documents are written
Expand All @@ -23,10 +21,5 @@ internal bool ShouldInlineReference(OpenApiReference reference)
return (reference.IsLocal && InlineLocalReferences)
|| (reference.IsExternal && InlineExternalReferences);
}

/// <summary>
/// Specifies a comparer used to sort string-based collection keys, such as components or tags.
/// </summary>
public IComparer<string>? KeyComparer { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,74 +132,6 @@ public class CollectionExtensionsTests
}
};

[Theory]
Comment thread
baywet marked this conversation as resolved.
[MemberData(nameof(OpenApiSpecVersions))]
public async Task SortOpenApiDocumentUsingCustomComparerSucceeds(OpenApiSpecVersion version)
{
// Arrange
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
var settings = new OpenApiWriterSettings
{
KeyComparer = StringComparer.OrdinalIgnoreCase
};
var writer = new OpenApiYamlWriter(outputStringWriter, settings);

// Act
Document.SerializeAs(version, writer);
await writer.FlushAsync();

// Assert
await Verifier.Verify(outputStringWriter).UseParameters(version);
}

[Fact]
public async Task SortHashSetsWorks()
{
// Arrange
var expected = @"required:
- id
- name
- tag";
var schema = new OpenApiSchema
{
Required = new HashSet<string> { "tag", "id", "name" },
};

var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
var settings = new OpenApiWriterSettings
{
KeyComparer = StringComparer.OrdinalIgnoreCase
};
var writer = new OpenApiYamlWriter(outputStringWriter, settings);

// Act
schema.SerializeAsV3(writer);
await writer.FlushAsync();
var sortedString = outputStringWriter.ToString();

// Assert
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), sortedString.MakeLineBreaksEnvironmentNeutral());
}

[Fact]
public void SortTagsByNameUsingComparerWorks()
{
// Arrange
var tags = new HashSet<OpenApiTag>
{
new() { Name = "three" },
new() { Name = "two" },
new() { Name = "one" }
};

// Act
var sortedTags = tags.Sort(new OpenApiTagNameComparer());

// Assert
Assert.Equal(3, sortedTags.Count);
Assert.True(sortedTags[0].Name == "one");
}

public static TheoryData<OpenApiSpecVersion> OpenApiSpecVersions()
{
var values = new TheoryData<OpenApiSpecVersion>();
Expand All @@ -210,12 +142,4 @@ public static TheoryData<OpenApiSpecVersion> OpenApiSpecVersions()
return values;
}
}

public class OpenApiTagNameComparer : IComparer<OpenApiTag>
{
public int Compare(OpenApiTag tag1, OpenApiTag tag2)
{
return string.Compare(tag1.Name, tag2.Name, StringComparison.OrdinalIgnoreCase);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,6 @@ namespace Microsoft.OpenApi
public OpenApiWriterSettings() { }
public bool InlineExternalReferences { get; set; }
public bool InlineLocalReferences { get; set; }
public System.Collections.Generic.IComparer<string>? KeyComparer { get; set; }
}
public class OpenApiXml : Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiSerializable
{
Expand Down
Loading