diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs index 20ce8bf53..d2de19612 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs @@ -139,7 +139,15 @@ public OpenApiOperation() { } public OpenApiOperation(OpenApiOperation operation) { Utils.CheckArgumentNull(operation); - Tags = operation.Tags != null ? new HashSet(operation.Tags) : null; + Tags = operation.Tags switch + { + HashSet tags when !ReferenceEquals(tags.Comparer, EqualityComparer.Default) => new HashSet(tags, tags.Comparer), + SortedSet sorted => new SortedSet(sorted, sorted.Comparer), +#if NET + ImmutableSortedSet => operation.Tags, +#endif + _ => operation.Tags != null ? new HashSet(operation.Tags, OpenApiTagComparer.Instance) : null, + }; Summary = operation.Summary ?? Summary; Description = operation.Description ?? Description; ExternalDocs = operation.ExternalDocs != null ? new(operation.ExternalDocs) : null; diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs index 46e25c183..b43ef7b53 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs @@ -939,5 +939,61 @@ public void TagsSupportsImmutableSortedSets() Assert.Equal(["tagC", "tagB", "tagA"], names); Assert.IsType>(operation.Tags); } + + [Fact] + public void OpenApiOperationCopyConstructorPreservesCustomComparer() + { + var operation = new OpenApiOperation + { + Tags = new HashSet(new CaseInsensitiveOpenApiTagReferenceEqualityComparer()) + { + new("Tag1") + } + }; + + var copy = new OpenApiOperation(operation); + Assert.NotNull(copy.Tags); + Assert.False(copy.Tags.Add(new OpenApiTagReference("tag1"))); + Assert.Single(copy.Tags); + } + + [Fact] + public void OpenApiOperationCopyConstructorPreservesSortedSet() + { + var operation = new OpenApiOperation + { + Tags = new SortedSet(new DescendingOpenApiTagReferenceComparer()) + { + new("tagB"), + new("tagA"), + new("tagC"), + } + }; + + var copy = new OpenApiOperation(operation); + Assert.IsType>(copy.Tags); + var copyNames = copy.Tags.Select(t => t.Name); + Assert.Equal(["tagC", "tagB", "tagA"], copyNames); + } + + [Fact] + public void OpenApiOperationCopyConstructorPreservesImmutableSortedSet() + { + var operation = new OpenApiOperation + { + Tags = ImmutableSortedSet.Create( + new DescendingOpenApiTagReferenceComparer(), + [ + new OpenApiTagReference("tagB"), + new OpenApiTagReference("tagA"), + new OpenApiTagReference("tagC"), + ]), + }; + + var copy = new OpenApiOperation(operation); + Assert.IsType>(copy.Tags); + var copyNames = copy.Tags.Select(t => t.Name); + Assert.Equal(["tagC", "tagB", "tagA"], copyNames); + } } }