/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/Collections/ImmutableSegmentedDictionaryTest.cs
394 строки
17 KB
Tomáš Matoušek
Refactoring of synthesized types tracking across EnC generations (#69782)
15 сен 2023, 18:57
Не верифицирован
15 сен 2023, 18:57
8501bd1
Код
Авторство
О чём код?
// 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.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.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Reflection; using Microsoft.CodeAnalysis.Collections; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.Collections { public partial class ImmutableSegmentedDictionaryTest : ImmutableDictionaryTestBase { [Fact] public void AddExistingKeySameValueTest() { AddExistingKeySameValueTestHelper(Empty<string, string>(StringComparer.Ordinal), "Company", "Microsoft", "Microsoft"); } [Fact] public void AddExistingKeyDifferentValueTest() { AddExistingKeyDifferentValueTestHelper(Empty<string, string>(StringComparer.Ordinal), "Company", "Microsoft", "MICROSOFT"); } [Fact] public void UnorderedChangeTest() { var map = Empty<string, string>(StringComparer.Ordinal) .Add("Johnny", "Appleseed") .Add("JOHNNY", "Appleseed"); Assert.Equal(2, map.Count); Assert.True(map.ContainsKey("Johnny")); Assert.False(map.ContainsKey("johnny")); var newMap = map.WithComparer(StringComparer.OrdinalIgnoreCase); Assert.Equal(1, newMap.Count); Assert.True(newMap.ContainsKey("Johnny")); Assert.True(newMap.ContainsKey("johnny")); // because it's case insensitive } [Fact] public void ToSortedTest() { var map = Empty<string, string>(StringComparer.Ordinal) .Add("Johnny", "Appleseed") .Add("JOHNNY", "Appleseed"); var sortedMap = map.ToImmutableSortedDictionary(StringComparer.Ordinal); Assert.Equal(sortedMap.Count, map.Count); CollectionAssertAreEquivalent<KeyValuePair<string, string>>(sortedMap.ToList(), map.ToList()); } [Fact] public void SetItemUpdateEqualKeyTest() { var map = Empty<string, int>().WithComparer(StringComparer.OrdinalIgnoreCase) .SetItem("A", 1); map = map.SetItem("a", 2); Assert.Equal("A", map.Keys.Single()); } [Fact] public void ContainsValueTest() { ContainsValueTestHelper(ImmutableSegmentedDictionary<int, GenericParameterHelper>.Empty, 1, new GenericParameterHelper()); } [Fact] public void ContainsValue_NoSuchValue_ReturnsFalse() { ImmutableSegmentedDictionary<int, string?> dictionary = new Dictionary<int, string?> { { 1, "a" }, { 2, "b" } }.ToImmutableSegmentedDictionary(); Assert.False(dictionary.ContainsValue("c")); Assert.False(dictionary.ContainsValue(null)); } [Fact] public void Create() { IEnumerable<KeyValuePair<string, string>> pairs = new Dictionary<string, string> { { "a", "b" } }; var keyComparer = StringComparer.OrdinalIgnoreCase; var dictionary = ImmutableSegmentedDictionary.Create<string, string>(); Assert.Equal(0, dictionary.Count); Assert.Same(EqualityComparer<string>.Default, dictionary.KeyComparer); dictionary = ImmutableSegmentedDictionary.Create<string, string>(keyComparer); Assert.Equal(0, dictionary.Count); Assert.Same(keyComparer, dictionary.KeyComparer); dictionary = ImmutableSegmentedDictionary.CreateRange(pairs); Assert.Equal(1, dictionary.Count); Assert.Same(EqualityComparer<string>.Default, dictionary.KeyComparer); dictionary = ImmutableSegmentedDictionary.CreateRange(keyComparer, pairs); Assert.Equal(1, dictionary.Count); Assert.Same(keyComparer, dictionary.KeyComparer); } [Fact] public void ToImmutableDictionary() { IEnumerable<KeyValuePair<string, string>> pairs = new Dictionary<string, string> { { "a", "B" } }; var keyComparer = StringComparer.OrdinalIgnoreCase; ImmutableSegmentedDictionary<string, string> dictionary = pairs.ToImmutableSegmentedDictionary(); Assert.Equal(1, dictionary.Count); Assert.Same(EqualityComparer<string>.Default, dictionary.KeyComparer); dictionary = pairs.ToImmutableSegmentedDictionary(keyComparer); Assert.Equal(1, dictionary.Count); Assert.Same(keyComparer, dictionary.KeyComparer); dictionary = pairs.ToImmutableSegmentedDictionary(p => p.Key.ToUpperInvariant(), p => p.Value.ToLowerInvariant()); Assert.Equal(1, dictionary.Count); Assert.Equal("A", dictionary.Keys.Single()); Assert.Equal("b", dictionary.Values.Single()); Assert.Same(EqualityComparer<string>.Default, dictionary.KeyComparer); dictionary = pairs.ToImmutableSegmentedDictionary(p => p.Key.ToUpperInvariant(), p => p.Value.ToLowerInvariant(), keyComparer); Assert.Equal(1, dictionary.Count); Assert.Equal("A", dictionary.Keys.Single()); Assert.Equal("b", dictionary.Values.Single()); Assert.Same(keyComparer, dictionary.KeyComparer); var list = new int[] { 1, 2 }; var intDictionary = list.ToImmutableSegmentedDictionary(n => (double)n); Assert.Equal(1, intDictionary[1.0]); Assert.Equal(2, intDictionary[2.0]); Assert.Equal(2, intDictionary.Count); var stringIntDictionary = list.ToImmutableSegmentedDictionary(n => n.ToString(), StringComparer.OrdinalIgnoreCase); Assert.Same(StringComparer.OrdinalIgnoreCase, stringIntDictionary.KeyComparer); Assert.Equal(1, stringIntDictionary["1"]); Assert.Equal(2, stringIntDictionary["2"]); Assert.Equal(2, intDictionary.Count); Assert.Throws<ArgumentNullException>("keySelector", () => list.ToImmutableSegmentedDictionary<int, int>(null!)); Assert.Throws<ArgumentNullException>("keySelector", () => list.ToImmutableSegmentedDictionary<int, int, int>(null!, v => v)); Assert.Throws<ArgumentNullException>("elementSelector", () => list.ToImmutableSegmentedDictionary<int, int, int>(k => k, null!)); list.ToDictionary(k => k, v => v, null); // verifies BCL behavior is to not throw. list.ToImmutableSegmentedDictionary(k => k, v => v, null); } [Fact] public void ToImmutableDictionaryOptimized() { var dictionary = ImmutableSegmentedDictionary.Create<string, string>(); var result = dictionary.ToImmutableSegmentedDictionary(); Assert.True(IsSame(dictionary, result)); var cultureComparer = StringComparer.CurrentCulture; result = dictionary.WithComparer(cultureComparer); Assert.Same(cultureComparer, result.KeyComparer); } [Fact] public void WithComparer() { var map = ImmutableSegmentedDictionary.Create<string, string>().Add("a", "1").Add("B", "1"); Assert.Same(EqualityComparer<string>.Default, map.KeyComparer); Assert.True(map.ContainsKey("a")); Assert.False(map.ContainsKey("A")); map = map.WithComparer(StringComparer.OrdinalIgnoreCase); Assert.Same(StringComparer.OrdinalIgnoreCase, map.KeyComparer); Assert.Equal(2, map.Count); Assert.True(map.ContainsKey("a")); Assert.True(map.ContainsKey("A")); Assert.True(map.ContainsKey("b")); } [Fact] public void WithComparerCollisions() { // First check where collisions have matching values. var map = ImmutableSegmentedDictionary.Create<string, string>() .Add("a", "1").Add("A", "1"); map = map.WithComparer(StringComparer.OrdinalIgnoreCase); Assert.Same(StringComparer.OrdinalIgnoreCase, map.KeyComparer); Assert.Equal(1, map.Count); Assert.True(map.ContainsKey("a")); Assert.Equal("1", map["a"]); // Now check where collisions have conflicting values. map = ImmutableSegmentedDictionary.Create<string, string>() .Add("a", "1").Add("A", "2").Add("b", "3"); Assert.Throws<ArgumentException>(null, () => map.WithComparer(StringComparer.OrdinalIgnoreCase)); } [Fact] public void CollisionExceptionMessageContainsKey() { var map = ImmutableSegmentedDictionary.Create<string, string>() .Add("firstKey", "1").Add("secondKey", "2"); var exception = Assert.Throws<ArgumentException>(null, () => map.Add("firstKey", "3")); Assert.Contains("firstKey", exception.Message); } [Fact] public void WithComparerEmptyCollection() { var map = ImmutableSegmentedDictionary.Create<string, string>(); Assert.Same(EqualityComparer<string>.Default, map.KeyComparer); map = map.WithComparer(StringComparer.OrdinalIgnoreCase); Assert.Same(StringComparer.OrdinalIgnoreCase, map.KeyComparer); } [Fact] public void GetValueOrDefaultOfIImmutableDictionary() { IImmutableDictionary<string, int> empty = ImmutableSegmentedDictionary.Create<string, int>(); IImmutableDictionary<string, int> populated = ImmutableSegmentedDictionary.Create<string, int>().Add("a", 5); Assert.Equal(0, empty.GetValueOrDefault("a")); Assert.Equal(1, empty.GetValueOrDefault("a", 1)); Assert.Equal(5, populated.GetValueOrDefault("a")); Assert.Equal(5, populated.GetValueOrDefault("a", 1)); } [Fact] public void GetValueOrDefaultOfConcreteType() { var empty = ImmutableSegmentedDictionary.Create<string, int>(); var populated = ImmutableSegmentedDictionary.Create<string, int>().Add("a", 5); Assert.Equal(0, empty.GetValueOrDefault("a")); Assert.Equal(1, empty.GetValueOrDefault("a", 1)); Assert.Equal(5, populated.GetValueOrDefault("a")); Assert.Equal(5, populated.GetValueOrDefault("a", 1)); } [Fact(Skip = "Not implemented: https://github.com/dotnet/roslyn/issues/50657")] public void DebuggerAttributesValid() { DebuggerAttributes.ValidateDebuggerDisplayReferences(ImmutableSegmentedDictionary.Create<int, int>()); ImmutableSegmentedDictionary<string, int> dict = ImmutableSegmentedDictionary.Create<string, int>().Add("One", 1).Add("Two", 2); DebuggerAttributeInfo info = DebuggerAttributes.ValidateDebuggerTypeProxyProperties(dict); object rootNode = DebuggerAttributes.GetFieldValue(ImmutableSegmentedDictionary.Create<string, string>(), "_root") ?? throw new InvalidOperationException(); DebuggerAttributes.ValidateDebuggerDisplayReferences(rootNode); PropertyInfo itemProperty = info.Properties.Single(pr => pr.GetCustomAttribute<DebuggerBrowsableAttribute>()!.State == DebuggerBrowsableState.RootHidden); KeyValuePair<string, int>[]? items = itemProperty.GetValue(info.Instance) as KeyValuePair<string, int>[]; Assert.Equal(dict, items); } [Fact(Skip = "Not implemented: https://github.com/dotnet/roslyn/issues/50657")] public static void TestDebuggerAttributes_Null() { Type proxyType = DebuggerAttributes.GetProxyType(ImmutableSegmentedDictionary.Create<string, int>()); TargetInvocationException tie = Assert.Throws<TargetInvocationException>(() => Activator.CreateInstance(proxyType, (object?)null)); Assert.IsType<ArgumentNullException>(tie.InnerException); } [Fact] public void Clear_NoComparer_ReturnsEmptyWithoutComparer() { ImmutableSegmentedDictionary<string, int> dictionary = new Dictionary<string, int> { { "a", 1 } }.ToImmutableSegmentedDictionary(); Assert.True(IsSame(ImmutableSegmentedDictionary<string, int>.Empty, dictionary.Clear())); Assert.NotEmpty(dictionary); } [Fact] public void Clear_HasComparer_ReturnsEmptyWithOriginalComparer() { ImmutableSegmentedDictionary<string, int> dictionary = new Dictionary<string, int> { { "a", 1 } }.ToImmutableSegmentedDictionary(StringComparer.OrdinalIgnoreCase); ImmutableSegmentedDictionary<string, int> clearedDictionary = dictionary.Clear(); Assert.False(IsSame(ImmutableSegmentedDictionary<string, int>.Empty, clearedDictionary.Clear())); Assert.NotEmpty(dictionary); clearedDictionary = clearedDictionary.Add("a", 1); Assert.True(clearedDictionary.ContainsKey("A")); } [Fact] public void Indexer_KeyNotFoundException_ContainsKeyInMessage() { var map = ImmutableSegmentedDictionary.Create<string, string>() .Add("a", "1").Add("b", "2"); var missingKey = "__ThisKeyDoesNotExist__"; var exception = Assert.Throws<KeyNotFoundException>(() => map[missingKey]); Assert.Contains(missingKey, exception.Message); } [Fact] public void Keys_All() { var map = ImmutableSegmentedDictionary.Create<string, string>() .Add("a", "1") .Add("b", "2"); Assert.False(map.Keys.All((key, arg) => key == arg, "a")); Assert.True(map.Keys.All((key, arg) => key.Length == arg, 1)); Assert.True(ImmutableSegmentedDictionary<int, int>.Empty.Keys.All((_, _) => false, 0)); } [Fact] public void Values_All() { var map = ImmutableSegmentedDictionary.Create<string, string>() .Add("a", "1") .Add("b", "2"); Assert.False(map.Values.All((key, arg) => key == arg, "1")); Assert.True(map.Values.All((key, arg) => key.Length == arg, 1)); Assert.True(ImmutableSegmentedDictionary<int, int>.Empty.Values.All((_, _) => false, 0)); } protected override IImmutableDictionary<TKey, TValue> Empty<TKey, TValue>() { return ImmutableSegmentedDictionaryTest.Empty<TKey, TValue>(); } protected override IImmutableDictionary<string, TValue> Empty<TValue>(StringComparer comparer) { return ImmutableSegmentedDictionary.Create<string, TValue>(comparer); } protected override IEqualityComparer<TValue> GetValueComparer<TKey, TValue>(IImmutableDictionary<TKey, TValue> dictionary) { return EqualityComparer<TValue>.Default; } private protected static void ContainsValueTestHelper<TKey, TValue>(ImmutableSegmentedDictionary<TKey, TValue> map, TKey key, TValue value) where TKey : notnull { Assert.False(map.ContainsValue(value)); Assert.True(map.Add(key, value).ContainsValue(value)); } private static ImmutableSegmentedDictionary<TKey, TValue> Empty<TKey, TValue>(IEqualityComparer<TKey>? keyComparer = null) where TKey : notnull { return ImmutableSegmentedDictionary<TKey, TValue>.Empty.WithComparer(keyComparer); } /// <summary> /// An ordinal comparer for case-insensitive strings. /// </summary> private class MyStringOrdinalComparer : EqualityComparer<CaseInsensitiveString?> { public override bool Equals(CaseInsensitiveString? x, CaseInsensitiveString? y) { return StringComparer.Ordinal.Equals(x!.Value, y!.Value); } public override int GetHashCode(CaseInsensitiveString obj) { return StringComparer.Ordinal.GetHashCode(obj.Value); } } /// <summary> /// A string-wrapper that considers equality based on case insensitivity. /// </summary> private class CaseInsensitiveString { public CaseInsensitiveString(string value) { Value = value; } public string Value { get; private set; } public override int GetHashCode() { return StringComparer.OrdinalIgnoreCase.GetHashCode(this.Value); } public override bool Equals(object? obj) { return StringComparer.OrdinalIgnoreCase.Equals(this.Value, ((CaseInsensitiveString?)obj)!.Value); } } } }