Skip to content

Commit 008576c

Browse files
authored
Merge pull request #2679 from spanglerco/issue2678
fix: Support custom tag ordering
2 parents 748b3d2 + 7610d07 commit 008576c

File tree

2 files changed

+88
-3
lines changed

2 files changed

+88
-3
lines changed

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
using System;
55
using System.Collections.Generic;
6+
#if NET
7+
using System.Collections.Immutable;
8+
#endif
69
using System.IO;
710
using System.Linq;
811
using System.Security.Cryptography;
@@ -83,9 +86,15 @@ public ISet<OpenApiTag>? Tags
8386
{
8487
return;
8588
}
86-
_tags = value is HashSet<OpenApiTag> tags && tags.Comparer is OpenApiTagComparer ?
87-
tags :
88-
new HashSet<OpenApiTag>(value, OpenApiTagComparer.Instance);
89+
_tags = value switch
90+
{
91+
HashSet<OpenApiTag> tags when tags.Comparer != EqualityComparer<OpenApiTag>.Default => value,
92+
SortedSet<OpenApiTag> => value,
93+
#if NET
94+
ImmutableSortedSet<OpenApiTag> => value,
95+
#endif
96+
_ => new HashSet<OpenApiTag>(value, OpenApiTagComparer.Instance),
97+
};
8998
}
9099
}
91100

test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Collections.Immutable;
7+
using System.Diagnostics.CodeAnalysis;
68
using System.Globalization;
79
using System.IO;
10+
using System.Linq;
811
using System.Net.Http;
912
using System.Threading.Tasks;
1013
using VerifyXunit;
@@ -2126,6 +2129,79 @@ public void DeduplicatesTags()
21262129
Assert.Contains(document.Tags, t => t.Name == "tag2");
21272130
}
21282131

2132+
[Fact]
2133+
public void TagsSupportsCustomComparer()
2134+
{
2135+
var document = new OpenApiDocument
2136+
{
2137+
Tags = new HashSet<OpenApiTag>(new CaseInsensitiveOpenApiTagEqualityComparer()),
2138+
};
2139+
2140+
Assert.True(document.Tags.Add(new OpenApiTag { Name = "Tag1" }));
2141+
Assert.False(document.Tags.Add(new OpenApiTag { Name = "tag1" }));
2142+
Assert.True(document.Tags.Add(new OpenApiTag { Name = "tag2" }));
2143+
Assert.False(document.Tags.Add(new OpenApiTag { Name = "TAG1" }));
2144+
Assert.Equal(2, document.Tags.Count);
2145+
}
2146+
2147+
private sealed class CaseInsensitiveOpenApiTagEqualityComparer : IEqualityComparer<OpenApiTag>
2148+
{
2149+
public bool Equals(OpenApiTag x, OpenApiTag y)
2150+
{
2151+
return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
2152+
}
2153+
2154+
public int GetHashCode([DisallowNull] OpenApiTag obj)
2155+
{
2156+
return obj.Name.GetHashCode(StringComparison.OrdinalIgnoreCase);
2157+
}
2158+
}
2159+
2160+
[Fact]
2161+
public void TagsSupportsSortedSets()
2162+
{
2163+
var document = new OpenApiDocument
2164+
{
2165+
Tags = new SortedSet<OpenApiTag>(new DescendingOpenApiTagComparer())
2166+
{
2167+
new OpenApiTag { Name = "tagB" },
2168+
new OpenApiTag { Name = "tagA" },
2169+
new OpenApiTag { Name = "tagC" },
2170+
}
2171+
};
2172+
2173+
var names = document.Tags.Select(t => t.Name);
2174+
Assert.Equal(["tagC", "tagB", "tagA"], names);
2175+
Assert.IsType<SortedSet<OpenApiTag>>(document.Tags);
2176+
}
2177+
2178+
private sealed class DescendingOpenApiTagComparer : IComparer<OpenApiTag>
2179+
{
2180+
public int Compare(OpenApiTag x, OpenApiTag y)
2181+
{
2182+
return string.Compare(y?.Name, x?.Name, StringComparison.Ordinal);
2183+
}
2184+
}
2185+
2186+
[Fact]
2187+
public void TagsSupportsImmutableSortedSets()
2188+
{
2189+
var document = new OpenApiDocument
2190+
{
2191+
Tags = ImmutableSortedSet.Create(
2192+
new DescendingOpenApiTagComparer(),
2193+
[
2194+
new OpenApiTag { Name = "tagB" },
2195+
new OpenApiTag { Name = "tagA" },
2196+
new OpenApiTag { Name = "tagC" },
2197+
]),
2198+
};
2199+
2200+
var names = document.Tags.Select(t => t.Name);
2201+
Assert.Equal(["tagC", "tagB", "tagA"], names);
2202+
Assert.IsType<ImmutableSortedSet<OpenApiTag>>(document.Tags);
2203+
}
2204+
21292205
public static TheoryData<OpenApiSpecVersion> OpenApiSpecVersions()
21302206
{
21312207
var values = new TheoryData<OpenApiSpecVersion>();

0 commit comments

Comments
 (0)