public void TestTryGetValue() { ImmutableTreeSet <string?> .Builder set = ImmutableTreeSet.CreateBuilder(StringComparer.OrdinalIgnoreCase); Assert.True(set.Add("a")); Assert.False(set.Add("A")); Assert.True(set.TryGetValue("a", out string?value)); Assert.Equal("a", value); Assert.True(set.TryGetValue("A", out value)); Assert.Equal("a", value); Assert.False(set.TryGetValue("b", out value)); Assert.Null(value); }
public void TestIEnumeratorT() { ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); IEnumerator <int> enumerator = set.GetEnumerator(); Assert.Equal(0, enumerator.Current); Assert.False(enumerator.MoveNext()); Assert.Equal(0, enumerator.Current); // Adding an item to the list invalidates it, but Current is still unchecked CollectionAssert.EnumeratorInvalidated(set, () => set.Add(1)); Assert.Throws <InvalidOperationException>(() => enumerator.MoveNext()); Assert.Throws <InvalidOperationException>(() => enumerator.Reset()); Assert.Equal(0, enumerator.Current); enumerator = set.GetEnumerator(); Assert.Equal(0, enumerator.Current); Assert.True(enumerator.MoveNext()); Assert.Equal(1, enumerator.Current); Assert.False(enumerator.MoveNext()); Assert.Equal(1, enumerator.Current); enumerator.Reset(); Assert.Equal(0, enumerator.Current); Assert.True(enumerator.MoveNext()); Assert.Equal(1, enumerator.Current); enumerator.Reset(); Assert.Equal(0, enumerator.Current); Assert.True(enumerator.MoveNext()); Assert.Equal(1, enumerator.Current); Assert.False(enumerator.MoveNext()); Assert.Equal(1, enumerator.Current); }
public void TestTrimExcess() { var random = new Random(); ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); var reference = new SortedSet <int>(); for (int i = 0; i < 2 * 4 * 4; i++) { int value = random.Next(set.Count + 1); set.Add(i); reference.Add(i); } set.Validate(ValidationRules.None); // In the first call to TrimExcess, items will move set.TrimExcess(); set.Validate(ValidationRules.RequirePacked); Assert.Equal(reference, set); // In the second call, the list is already packed so nothing will move set.TrimExcess(); set.Validate(ValidationRules.RequirePacked); Assert.Equal(reference, set); ImmutableTreeSet <int> .Builder empty = ImmutableTreeSet.CreateBuilder <int>(); empty.Validate(ValidationRules.RequirePacked); empty.TrimExcess(); empty.Validate(ValidationRules.RequirePacked); var single = ImmutableTreeSet.CreateRange <int>(Enumerable.Range(0, 1)).ToBuilder(); single.Validate(ValidationRules.RequirePacked); single.TrimExcess(); single.Validate(ValidationRules.RequirePacked); // Construct a poorly-packed list with several levels ImmutableTreeSet <int> .Builder binary = ImmutableTreeSet.CreateBuilder <int>(); for (int i = 99; i >= 0; i--) { binary.Add(i); } binary.TrimExcess(); binary.Validate(ValidationRules.RequirePacked); // Construct a poorly-packed list with several levels var ternary = ImmutableTreeSet.CreateRange <int>(equalityComparer: null, Enumerable.Range(0, 100)).ToBuilder(); for (int i = 99; i >= 0; i--) { ternary.Add(i); } ternary.TrimExcess(); ternary.Validate(ValidationRules.RequirePacked); }
public void TestAddStaysPacked() { ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); for (int i = 0; i < 4 * 8 * 8; i++) { // This test assumes items are being added are already ordered by hash code Assert.Equal(i, i.GetHashCode()); set.Add(i); set.Validate(ValidationRules.RequirePacked); } }
public void TestAdd() { int value = Generator.GetInt32(); ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); Assert.Empty(set); set.Add(value); Assert.Single(set); Assert.Equal(value, set.First()); int[] expected = { value }; int[] actual = set.ToArray(); Assert.Equal(expected, actual); }
public void TestAddMany() { int[] expected = { 600, 601, 602, 603, 700, 701, 702, 703, 800, 801, 802, 803 }; ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); foreach (var item in expected) { set.Add(item); } Assert.Equal(expected.Length, set.Count); int[] actual = set.ToArray(); Assert.Equal(expected, actual); }
public void TestContains() { ImmutableTreeSet <int> .Builder set = ImmutableTreeSet.CreateBuilder <int>(); for (int i = 0; i < 4 * 8 * 8; i++) { int value = Generator.GetInt32(set.Count + 1); set.Add(i); // Use set.Contains(i) since this is a targeted collection API test #pragma warning disable xUnit2017 // Do not use Contains() to check if a value exists in a collection Assert.True(set.Contains(i)); #pragma warning restore xUnit2017 // Do not use Contains() to check if a value exists in a collection } set.Validate(ValidationRules.None); }
public void TestTryGetValueWithCollidingHashCodes() { ImmutableTreeSet <string?> .Builder set = ImmutableTreeSet.CreateBuilder(new ZeroHashCodeEqualityComparer <string?>(StringComparer.OrdinalIgnoreCase)); Assert.True(set.Add("a")); Assert.False(set.Add("A")); Assert.True(set.TryGetValue("a", out string?value)); Assert.Equal("a", value); Assert.True(set.TryGetValue("A", out value)); Assert.Equal("a", value); Assert.False(set.TryGetValue("b", out value)); Assert.Null(value); // The test below forces coverage of an edge case. We don't know if the hash code for 'aa' or 'bb' comes // first, so write the test in a way that either will cover the early-exit branch in TryGetValue. set = ImmutableTreeSet.CreateBuilder(new SubsetHashCodeEqualityComparer <string?>(StringComparer.Ordinal, StringComparer.OrdinalIgnoreCase)); Assert.True(set.Add("aa")); Assert.True(set.Add("Aa")); Assert.True(set.Add("bb")); Assert.True(set.Add("Bb")); Assert.True(set.TryGetValue("aa", out value)); Assert.Equal("aa", value); Assert.True(set.TryGetValue("Aa", out value)); Assert.Equal("Aa", value); Assert.False(set.TryGetValue("AA", out value)); Assert.Null(value); Assert.True(set.TryGetValue("bb", out value)); Assert.Equal("bb", value); Assert.True(set.TryGetValue("Bb", out value)); Assert.Equal("Bb", value); Assert.False(set.TryGetValue("BB", out value)); Assert.Null(value); }