/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/Collections/ImmutableSegmentedHashSetBuilderTest.cs
368 строк
14 KB
Sam Harwell
Update implementation of ImmutableSegmentedHashSet<T> to pass tests
09 июл 2021, 23:38
09 июл 2021, 23:38
a2023ec
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // NOTE: This code is derived from an implementation originally in dotnet/runtime: // https://github.com/dotnet/runtime/blob/v5.0.2/src/libraries/System.Collections.Immutable/tests/ImmutableDictionaryTest.nonnetstandard.cs // // See the commentary in https://github.com/dotnet/roslyn/pull/50156 for notes on incorporating changes made to the // reference implementation. using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.Collections; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.Collections { public class ImmutableSegmentedHashSetBuilderTest : ImmutablesTestBase { [Fact] public void CreateBuilder() { var builder = ImmutableSegmentedHashSet.CreateBuilder<string>(); Assert.Same(EqualityComparer<string>.Default, builder.KeyComparer); builder = ImmutableSegmentedHashSet.CreateBuilder<string>(StringComparer.OrdinalIgnoreCase); Assert.Same(StringComparer.OrdinalIgnoreCase, builder.KeyComparer); } [Fact] public void ToBuilder() { var builder = ImmutableSegmentedHashSet<int>.Empty.ToBuilder(); Assert.True(builder.Add(3)); Assert.True(builder.Add(5)); Assert.False(builder.Add(5)); Assert.Equal(2, builder.Count); Assert.True(builder.Contains(3)); Assert.True(builder.Contains(5)); Assert.False(builder.Contains(7)); var set = builder.ToImmutable(); Assert.Equal(builder.Count, set.Count); Assert.True(builder.Add(8)); Assert.Equal(3, builder.Count); Assert.Equal(2, set.Count); Assert.True(builder.Contains(8)); Assert.False(set.Contains(8)); } [Fact] public void BuilderFromSet() { var set = ImmutableSegmentedHashSet<int>.Empty.Add(1); var builder = set.ToBuilder(); Assert.True(builder.Contains(1)); Assert.True(builder.Add(3)); Assert.True(builder.Add(5)); Assert.False(builder.Add(5)); Assert.Equal(3, builder.Count); Assert.True(builder.Contains(3)); Assert.True(builder.Contains(5)); Assert.False(builder.Contains(7)); var set2 = builder.ToImmutable(); Assert.Equal(builder.Count, set2.Count); Assert.True(set2.Contains(1)); Assert.True(builder.Add(8)); Assert.Equal(4, builder.Count); Assert.Equal(3, set2.Count); Assert.True(builder.Contains(8)); Assert.False(set.Contains(8)); Assert.False(set2.Contains(8)); } [Fact] public void EnumerateBuilderWhileMutating() { var builder = ImmutableSegmentedHashSet<int>.Empty.Union(Enumerable.Range(1, 10)).ToBuilder(); CollectionAssertAreEquivalent(Enumerable.Range(1, 10).ToArray(), builder.ToArray()); var enumerator = builder.GetEnumerator(); Assert.True(enumerator.MoveNext()); builder.Add(11); // Verify that a new enumerator will succeed. CollectionAssertAreEquivalent(Enumerable.Range(1, 11).ToArray(), builder.ToArray()); // Try enumerating further with the previous enumerable now that we've changed the collection. Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext()); enumerator.Reset(); enumerator.MoveNext(); // resetting should fix the problem. // Verify that by obtaining a new enumerator, we can enumerate all the contents. CollectionAssertAreEquivalent(Enumerable.Range(1, 11).ToArray(), builder.ToArray()); } [Fact] public void BuilderReusesUnchangedImmutableInstances() { var collection = ImmutableSegmentedHashSet<int>.Empty.Add(1); var builder = collection.ToBuilder(); Assert.True(IsSame(collection, builder.ToImmutable())); // no changes at all. builder.Add(2); var newImmutable = builder.ToImmutable(); Assert.False(IsSame(collection, newImmutable)); // first ToImmutable with changes should be a new instance. Assert.True(IsSame(newImmutable, builder.ToImmutable())); // second ToImmutable without changes should be the same instance. } [Fact] public void EnumeratorTest() { var builder = ImmutableSegmentedHashSet.Create(1).ToBuilder(); ManuallyEnumerateTest(new[] { 1 }, ((IEnumerable<int>)builder).GetEnumerator()); } [Fact] public void Clear() { var set = ImmutableSegmentedHashSet.Create(1); var builder = set.ToBuilder(); builder.Clear(); Assert.Equal(0, builder.Count); } [Fact] public void KeyComparer() { var builder = ImmutableSegmentedHashSet.Create("a", "B").ToBuilder(); Assert.Same(EqualityComparer<string>.Default, builder.KeyComparer); Assert.True(builder.Contains("a")); Assert.False(builder.Contains("A")); builder.KeyComparer = StringComparer.OrdinalIgnoreCase; Assert.Same(StringComparer.OrdinalIgnoreCase, builder.KeyComparer); Assert.Equal(2, builder.Count); Assert.True(builder.Contains("a")); Assert.True(builder.Contains("A")); var set = builder.ToImmutable(); Assert.Same(StringComparer.OrdinalIgnoreCase, set.KeyComparer); } [Fact] public void KeyComparerCollisions() { var builder = ImmutableSegmentedHashSet.Create("a", "A").ToBuilder(); builder.KeyComparer = StringComparer.OrdinalIgnoreCase; Assert.Equal(1, builder.Count); Assert.True(builder.Contains("a")); var set = builder.ToImmutable(); Assert.Same(StringComparer.OrdinalIgnoreCase, set.KeyComparer); Assert.Equal(1, set.Count); Assert.True(set.Contains("a")); } [Fact] public void KeyComparerEmptyCollection() { var builder = ImmutableSegmentedHashSet.Create<string>().ToBuilder(); Assert.Same(EqualityComparer<string>.Default, builder.KeyComparer); builder.KeyComparer = StringComparer.OrdinalIgnoreCase; Assert.Same(StringComparer.OrdinalIgnoreCase, builder.KeyComparer); var set = builder.ToImmutable(); Assert.Same(StringComparer.OrdinalIgnoreCase, set.KeyComparer); } [Fact] public void UnionWith() { var builder = ImmutableSegmentedHashSet.Create(1, 2, 3).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.UnionWith(null!)); builder.UnionWith(new[] { 2, 3, 4 }); Assert.Equal(new[] { 1, 2, 3, 4 }, builder); } [Fact] public void ExceptWith() { var builder = ImmutableSegmentedHashSet.Create(1, 2, 3).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.ExceptWith(null!)); builder.ExceptWith(new[] { 2, 3, 4 }); Assert.Equal(new[] { 1 }, builder); } [Fact] public void SymmetricExceptWith() { var builder = ImmutableSegmentedHashSet.Create(1, 2, 3).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.SymmetricExceptWith(null!)); builder.SymmetricExceptWith(new[] { 2, 3, 4 }); Assert.Equal(new[] { 1, 4 }, builder); } [Fact] public void IntersectWith() { var builder = ImmutableSegmentedHashSet.Create(1, 2, 3).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.IntersectWith(null!)); builder.IntersectWith(new[] { 2, 3, 4 }); Assert.Equal(new[] { 2, 3 }, builder); } [Fact] public void IsProperSubsetOf() { var builder = ImmutableSegmentedHashSet.CreateRange(Enumerable.Range(1, 3)).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.IsProperSubsetOf(null!)); Assert.False(builder.IsProperSubsetOf(Enumerable.Range(1, 3))); Assert.True(builder.IsProperSubsetOf(Enumerable.Range(1, 5))); } [Fact] public void IsProperSupersetOf() { var builder = ImmutableSegmentedHashSet.CreateRange(Enumerable.Range(1, 3)).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.IsProperSupersetOf(null!)); Assert.False(builder.IsProperSupersetOf(Enumerable.Range(1, 3))); Assert.True(builder.IsProperSupersetOf(Enumerable.Range(1, 2))); } [Fact] public void IsSubsetOf() { var builder = ImmutableSegmentedHashSet.CreateRange(Enumerable.Range(1, 3)).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.IsSubsetOf(null!)); Assert.False(builder.IsSubsetOf(Enumerable.Range(1, 2))); Assert.True(builder.IsSubsetOf(Enumerable.Range(1, 3))); Assert.True(builder.IsSubsetOf(Enumerable.Range(1, 5))); } [Fact] public void IsSupersetOf() { var builder = ImmutableSegmentedHashSet.CreateRange(Enumerable.Range(1, 3)).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.IsSupersetOf(null!)); Assert.False(builder.IsSupersetOf(Enumerable.Range(1, 4))); Assert.True(builder.IsSupersetOf(Enumerable.Range(1, 3))); Assert.True(builder.IsSupersetOf(Enumerable.Range(1, 2))); } [Fact] public void Overlaps() { var builder = ImmutableSegmentedHashSet.CreateRange(Enumerable.Range(1, 3)).ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.Overlaps(null!)); Assert.True(builder.Overlaps(Enumerable.Range(3, 2))); Assert.False(builder.Overlaps(Enumerable.Range(4, 3))); } [Fact] public void Remove() { var builder = ImmutableSegmentedHashSet.Create("a").ToBuilder(); Assert.False(builder.Remove("b")); Assert.True(builder.Remove("a")); } [Fact] public void SetEquals() { var builder = ImmutableSegmentedHashSet.Create("a").ToBuilder(); Assert.Throws<ArgumentNullException>("other", () => builder.SetEquals(null!)); Assert.False(builder.SetEquals(new[] { "b" })); Assert.True(builder.SetEquals(new[] { "a" })); Assert.True(builder.SetEquals(builder)); } [Fact] public void ICollectionOfTMethods() { ICollection<string> builder = ImmutableSegmentedHashSet.Create("a").ToBuilder(); builder.Add("b"); Assert.True(builder.Contains("b")); var array = new string[3]; builder.CopyTo(array, 1); Assert.Null(array[0]); CollectionAssertAreEquivalent(new[] { null, "a", "b" }, array); Assert.False(builder.IsReadOnly); CollectionAssertAreEquivalent(new[] { "a", "b" }, builder.ToArray()); // tests enumerator } [Fact] public void NullHandling() { var builder = ImmutableSegmentedHashSet<string?>.Empty.ToBuilder(); Assert.True(builder.Add(null)); Assert.False(builder.Add(null)); Assert.True(builder.Contains(null)); Assert.True(builder.Remove(null)); builder.UnionWith(new[] { null, "a" }); Assert.True(builder.IsSupersetOf(new[] { null, "a" })); Assert.True(builder.IsSubsetOf(new[] { null, "a" })); Assert.True(builder.IsProperSupersetOf(new[] { (string?)null })); Assert.True(builder.IsProperSubsetOf(new[] { null, "a", "b" })); builder.IntersectWith(new[] { (string?)null }); Assert.Equal(1, builder.Count); builder.ExceptWith(new[] { (string?)null }); Assert.False(builder.Remove(null)); } [Fact(Skip = "https://github.com/dotnet/roslyn/issues/54716")] public void DebuggerAttributesValid() { DebuggerAttributes.ValidateDebuggerDisplayReferences(ImmutableSegmentedHashSet.CreateBuilder<int>()); } [Fact] public void ToImmutableHashSet() { ImmutableSegmentedHashSet<int>.Builder builder = ImmutableSegmentedHashSet.CreateBuilder<int>(); builder.Add(1); builder.Add(2); builder.Add(3); var set = System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(builder); Assert.True(builder.Contains(1)); Assert.True(builder.Contains(2)); Assert.True(builder.Contains(3)); builder.Remove(3); Assert.False(builder.Contains(3)); Assert.True(set.Contains(3)); builder.Clear(); Assert.True(builder.ToImmutableSegmentedHashSet().IsEmpty); Assert.False(set.IsEmpty); ImmutableSegmentedHashSet<int>.Builder? nullBuilder = null; Assert.Throws<ArgumentNullException>("builder", () => nullBuilder!.ToImmutableSegmentedHashSet()); } [Fact] public void TryGetValue() { var builder = ImmutableSegmentedHashSet.Create(1, 2, 3).ToBuilder(); Assert.True(builder.TryGetValue(2, out _)); builder = ImmutableSegmentedHashSet.Create(CustomEqualityComparer.Instance, 1, 2, 3, 4).ToBuilder(); var existing = 0; Assert.True(builder.TryGetValue(5, out existing)); Assert.Equal(4, existing); } private class CustomEqualityComparer : IEqualityComparer<int> { private CustomEqualityComparer() { } public static CustomEqualityComparer Instance { get; } = new CustomEqualityComparer(); public bool Equals(int x, int y) => x >> 1 == y >> 1; public int GetHashCode(int obj) => (obj >> 1).GetHashCode(); } } }