Imported Upstream version 5.8.0.22

Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-10-19 20:04:20 +00:00
parent 5f4a27cc8a
commit 7d05485754
5020 changed files with 114082 additions and 186061 deletions

View File

@@ -10,7 +10,7 @@
<SupportedFramework>net45;netcore45;netcoreapp1.0;wp8;wpa81;$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
<InboxOnTargetFramework Include="netcoreapp2.0" />
<InboxOnTargetFramework Include="uap10.1" />
<InboxOnTargetFramework Include="$(UAPvNextTFM)" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -37,6 +37,8 @@
<Compile Include="System\Collections\Immutable\IImmutableQueue.cs" />
<Compile Include="System\Collections\Immutable\IImmutableSet.cs" />
<Compile Include="System\Collections\Immutable\IImmutableStack.cs" />
<Compile Include="System\Collections\Immutable\ImmutableHashSet_1.HashBucketByValueEqualityComparer.cs" />
<Compile Include="System\Collections\Immutable\ImmutableHashSet_1.HashBucketByRefEqualityComparer.cs" />
<Compile Include="System\Collections\Immutable\IStrongEnumerable_2.cs" />
<Compile Include="System\Collections\Immutable\IStrongEnumerator_1.cs" />
<Compile Include="System\Collections\Immutable\IOrderedCollection.cs" />

View File

@@ -15,7 +15,7 @@ namespace System.Collections.Immutable
/// <summary>
/// Contains all the key/values in the collection that hash to the same value.
/// </summary>
internal struct HashBucket : IEnumerable<KeyValuePair<TKey, TValue>>, IEquatable<HashBucket>
internal struct HashBucket : IEnumerable<KeyValuePair<TKey, TValue>>
{
/// <summary>
/// One of the values in this bucket.
@@ -110,12 +110,21 @@ namespace System.Collections.Immutable
/// <summary>
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
/// </summary>
bool IEquatable<HashBucket>.Equals(HashBucket other)
public override bool Equals(object obj)
{
// This should never be called, as hash buckets don't know how to equate themselves.
throw new NotSupportedException();
}
/// <summary>
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
/// </summary>
public override int GetHashCode()
{
// This should never be called, as hash buckets don't know how to hash themselves.
throw new NotSupportedException();
}
/// <summary>
/// Adds the specified key.
/// </summary>

View File

@@ -16,6 +16,21 @@ namespace System.Collections.Immutable
/// </summary>
internal static partial class ImmutableExtensions
{
internal static bool IsValueType<T>()
{
if (default(T) != null)
{
return true;
}
Type t = typeof(T);
if (t.IsConstructedGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return true;
}
return false;
}
#if EqualsStructurally

View File

@@ -43,6 +43,11 @@ namespace System.Collections.Immutable
/// </summary>
private IEqualityComparer<T> _equalityComparer;
/// <summary>
/// The equality comparer to use when balancing the tree of hash buckets.
/// </summary>
private IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
/// <summary>
/// The number of elements in this collection.
/// </summary>
@@ -69,6 +74,7 @@ namespace System.Collections.Immutable
_root = set._root;
_count = set._count;
_equalityComparer = set._equalityComparer;
_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
_immutable = set;
}
@@ -113,7 +119,7 @@ namespace System.Collections.Immutable
if (value != _equalityComparer)
{
var result = Union(this, new MutationInput(SortedInt32KeyNode<HashBucket>.EmptyNode, value, 0));
var result = Union(this, new MutationInput(SortedInt32KeyNode<HashBucket>.EmptyNode, value, _hashBucketEqualityComparer, 0));
_immutable = null;
_equalityComparer = value;
@@ -136,7 +142,7 @@ namespace System.Collections.Immutable
/// </summary>
private MutationInput Origin
{
get { return new MutationInput(this.Root, _equalityComparer, _count); }
get { return new MutationInput(this.Root, _equalityComparer, _hashBucketEqualityComparer, _count); }
}
/// <summary>
@@ -259,7 +265,7 @@ namespace System.Collections.Immutable
/// <param name="other">The collection of items to remove from the set.</param>
public void ExceptWith(IEnumerable<T> other)
{
var result = ImmutableHashSet<T>.Except(other, _equalityComparer, _root);
var result = ImmutableHashSet<T>.Except(other, _equalityComparer, _hashBucketEqualityComparer, _root);
this.Apply(result);
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Collections.Immutable
{
@@ -76,6 +77,49 @@ namespace System.Collections.Immutable
return new Enumerator(this);
}
/// <summary>
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
/// </summary>
public override bool Equals(object obj)
{
// This should never be called, as hash buckets don't know how to equate themselves.
throw new NotSupportedException();
}
/// <summary>
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
/// </summary>
public override int GetHashCode()
{
// This should never be called, as hash buckets don't know how to hash themselves.
throw new NotSupportedException();
}
/// <summary>
/// Checks whether this <see cref="HashBucket"/> is exactly like another one,
/// comparing by reference. For use when type parameter T is an object.
/// </summary>
/// <param name="other">The other bucket.</param>
/// <returns><c>true</c> if the two <see cref="HashBucket"/> structs have precisely the same values.</returns>
internal bool EqualsByRef(HashBucket other)
{
return object.ReferenceEquals(_firstValue, other._firstValue)
&& object.ReferenceEquals(_additionalElements, other._additionalElements);
}
/// <summary>
/// Checks whether this <see cref="HashBucket"/> is exactly like another one,
/// comparing by value. For use when type parameter T is a struct.
/// </summary>
/// <param name="other">The other bucket.</param>
/// <param name="valueComparer">The comparer to use for the first value in the bucket.</param>
/// <returns><c>true</c> if the two <see cref="HashBucket"/> structs have precisely the same values.</returns>
internal bool EqualsByValue(HashBucket other, IEqualityComparer<T> valueComparer)
{
return valueComparer.Equals(_firstValue, other._firstValue)
&& object.ReferenceEquals(_additionalElements, other._additionalElements);
}
/// <summary>
/// Adds the specified value.
/// </summary>

View File

@@ -0,0 +1,44 @@
// 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.
using System.Collections.Generic;
namespace System.Collections.Immutable
{
/// <content>
/// Contains the inner <see cref="ImmutableHashSet{T}.HashBucketByRefEqualityComparer"/> class.
/// </content>
public sealed partial class ImmutableHashSet<T> : IImmutableSet<T>, IHashKeyCollection<T>, IReadOnlyCollection<T>, ICollection<T>, ISet<T>, ICollection, IStrongEnumerable<T, ImmutableHashSet<T>.Enumerator>
{
/// <summary>
/// Compares equality between two <see cref="HashBucket"/> instances
/// by reference.
/// </summary>
private class HashBucketByRefEqualityComparer : IEqualityComparer<HashBucket>
{
/// <summary>
/// The singleton instance.
/// </summary>
private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByRefEqualityComparer();
/// <summary>
/// Gets the singleton instance to use.
/// </summary>
internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;
/// <summary>
/// Prevents a default instance of the <see cref="HashBucketByRefEqualityComparer"/> class from being created.
/// </summary>
private HashBucketByRefEqualityComparer()
{
}
/// <inheritdoc />
public bool Equals(HashBucket x, HashBucket y) => x.EqualsByRef(y);
/// <inheritdoc />
public int GetHashCode(HashBucket obj) => throw new NotSupportedException();
}
}
}

View File

@@ -0,0 +1,53 @@
// 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.
using System.Collections.Generic;
namespace System.Collections.Immutable
{
/// <content>
/// Contains the inner <see cref="ImmutableHashSet{T}.HashBucketByValueEqualityComparer"/> class.
/// </content>
public sealed partial class ImmutableHashSet<T> : IImmutableSet<T>, IHashKeyCollection<T>, IReadOnlyCollection<T>, ICollection<T>, ISet<T>, ICollection, IStrongEnumerable<T, ImmutableHashSet<T>.Enumerator>
{
/// <summary>
/// Compares equality between two <see cref="HashBucket"/> instances
/// by value.
/// </summary>
private class HashBucketByValueEqualityComparer : IEqualityComparer<HashBucket>
{
/// <summary>
/// The instance to use when the value comparer is <see cref="EqualityComparer{T}.Default"/>.
/// </summary>
private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByValueEqualityComparer(EqualityComparer<T>.Default);
/// <summary>
/// Gets the instance to use when the value comparer is
/// <see cref="EqualityComparer{T}.Default"/>.
/// </summary>
internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;
/// <summary>
/// The value comparer to use when comparing two T instances.
/// </summary>
private readonly IEqualityComparer<T> _valueComparer;
/// <summary>
/// Initializes a new instance of the <see cref="HashBucketByValueEqualityComparer"/> class.
/// </summary>
/// <param name="valueComparer">The value comparer for T.</param>
internal HashBucketByValueEqualityComparer(IEqualityComparer<T> valueComparer)
{
Requires.NotNull(valueComparer, nameof(valueComparer));
_valueComparer = valueComparer;
}
/// <inheritdoc />
public bool Equals(HashBucket x, HashBucket y) => x.EqualsByValue(y, _valueComparer);
/// <inheritdoc />
public int GetHashCode(HashBucket obj) => throw new NotSupportedException();
}
}
}

View File

@@ -32,6 +32,11 @@ namespace System.Collections.Immutable
/// </summary>
private readonly int _count;
/// <summary>
/// The equality comparer to use when checking for <see cref="HashBucket"/> equality.
/// </summary>
private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableHashSet{T}.MutationInput"/> struct.
/// </summary>
@@ -42,6 +47,7 @@ namespace System.Collections.Immutable
_root = set._root;
_equalityComparer = set._equalityComparer;
_count = set._count;
_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
}
/// <summary>
@@ -49,15 +55,19 @@ namespace System.Collections.Immutable
/// </summary>
/// <param name="root">The root.</param>
/// <param name="equalityComparer">The equality comparer.</param>
/// <param name="hashBucketEqualityComparer">The equality comparer to use when checking for <see cref="HashBucket"/> equality.</param>
/// <param name="count">The count.</param>
internal MutationInput(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, int count)
internal MutationInput(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, int count)
{
Requires.NotNull(root, nameof(root));
Requires.NotNull(equalityComparer, nameof(equalityComparer));
Requires.Range(count >= 0, nameof(count));
Requires.NotNull(hashBucketEqualityComparer, nameof(hashBucketEqualityComparer));
_root = root;
_equalityComparer = equalityComparer;
_count = count;
_hashBucketEqualityComparer = hashBucketEqualityComparer;
}
/// <summary>
@@ -83,6 +93,11 @@ namespace System.Collections.Immutable
{
get { return _count; }
}
/// <summary>
/// Gets the equality comparer to use when checking for <see cref="HashBucket"/> equality.
/// </summary>
internal IEqualityComparer<HashBucket> HashBucketEqualityComparer => _hashBucketEqualityComparer;
}
}
}

View File

@@ -44,6 +44,11 @@ namespace System.Collections.Immutable
/// </summary>
private readonly SortedInt32KeyNode<HashBucket> _root;
/// <summary>
/// The equality comparer to use when balancing the tree of hash buckets.
/// </summary>
private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableHashSet{T}"/> class.
/// </summary>
@@ -68,6 +73,7 @@ namespace System.Collections.Immutable
_root = root;
_count = count;
_equalityComparer = equalityComparer;
_hashBucketEqualityComparer = GetHashBucketEqualityComparer(equalityComparer);
}
/// <summary>
@@ -213,7 +219,7 @@ namespace System.Collections.Immutable
/// <param name="actualValue">The value from the set that the search found, or the original value if the search yielded no match.</param>
/// <returns>A value indicating whether the search was successful.</returns>
/// <remarks>
/// This can be useful when you want to reuse a previously stored reference instead of
/// This can be useful when you want to reuse a previously stored reference instead of
/// a newly constructed one (so that more sharing of references can occur) or to look up
/// a value that has more complete data than the value you currently have, although their
/// comparer functions indicate they are equal.
@@ -264,7 +270,7 @@ namespace System.Collections.Immutable
{
Requires.NotNull(other, nameof(other));
var result = Except(other, _equalityComparer, _root);
var result = Except(other, _equalityComparer, _hashBucketEqualityComparer, _root);
return result.Finalize(this);
}
@@ -648,7 +654,7 @@ namespace System.Collections.Immutable
return new MutationResult(origin.Root, 0);
}
var newRoot = UpdateRoot(origin.Root, hashCode, newBucket);
var newRoot = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
Debug.Assert(result == OperationResult.SizeChanged);
return new MutationResult(newRoot, 1 /*result == OperationResult.SizeChanged ? 1 : 0*/);
}
@@ -670,7 +676,7 @@ namespace System.Collections.Immutable
return new MutationResult(origin.Root, 0);
}
newRoot = UpdateRoot(origin.Root, hashCode, newBucket);
newRoot = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
}
return new MutationResult(newRoot, result == OperationResult.SizeChanged ? -1 : 0);
@@ -708,7 +714,7 @@ namespace System.Collections.Immutable
var newBucket = bucket.Add(item, origin.EqualityComparer, out result);
if (result == OperationResult.SizeChanged)
{
newRoot = UpdateRoot(newRoot, hashCode, newBucket);
newRoot = UpdateRoot(newRoot, hashCode, origin.HashBucketEqualityComparer, newBucket);
count++;
}
}
@@ -769,7 +775,7 @@ namespace System.Collections.Immutable
/// <summary>
/// Performs the set operation on a given data structure.
/// </summary>
private static SortedInt32KeyNode<HashBucket> UpdateRoot(SortedInt32KeyNode<HashBucket> root, int hashCode, HashBucket newBucket)
private static SortedInt32KeyNode<HashBucket> UpdateRoot(SortedInt32KeyNode<HashBucket> root, int hashCode, IEqualityComparer<HashBucket> hashBucketEqualityComparer, HashBucket newBucket)
{
bool mutated;
if (newBucket.IsEmpty)
@@ -778,8 +784,7 @@ namespace System.Collections.Immutable
}
else
{
bool replacedExistingValue;
return root.SetItem(hashCode, newBucket, EqualityComparer<HashBucket>.Default, out replacedExistingValue, out mutated);
return root.SetItem(hashCode, newBucket, hashBucketEqualityComparer, out bool replacedExistingValue, out mutated);
}
}
@@ -796,7 +801,7 @@ namespace System.Collections.Immutable
{
if (Contains(item, origin))
{
var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, count));
var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
newSet = result.Root;
count += result.Count;
}
@@ -808,7 +813,7 @@ namespace System.Collections.Immutable
/// <summary>
/// Performs the set operation on a given data structure.
/// </summary>
private static MutationResult Except(IEnumerable<T> other, IEqualityComparer<T> equalityComparer, SortedInt32KeyNode<HashBucket> root)
private static MutationResult Except(IEnumerable<T> other, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, SortedInt32KeyNode<HashBucket> root)
{
Requires.NotNull(other, nameof(other));
Requires.NotNull(equalityComparer, nameof(equalityComparer));
@@ -827,7 +832,7 @@ namespace System.Collections.Immutable
if (result == OperationResult.SizeChanged)
{
count--;
newRoot = UpdateRoot(newRoot, hashCode, newBucket);
newRoot = UpdateRoot(newRoot, hashCode, hashBucketEqualityComparer, newBucket);
}
}
}
@@ -851,7 +856,7 @@ namespace System.Collections.Immutable
{
if (!otherAsSet.Contains(item))
{
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, count));
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
result = mutationResult.Root;
count += mutationResult.Count;
}
@@ -861,7 +866,7 @@ namespace System.Collections.Immutable
{
if (!Contains(item, origin))
{
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, count));
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
result = mutationResult.Root;
count += mutationResult.Count;
}
@@ -993,6 +998,27 @@ namespace System.Collections.Immutable
return new ImmutableHashSet<T>(root, equalityComparer, count);
}
/// <summary>
/// Gets the <see cref="IEqualityComparer{HashBucket}"/> to use.
/// </summary>
/// <param name="valueComparer">The value comparer for T.</param>
/// <returns>The equality comparer to use.</returns>
private static IEqualityComparer<HashBucket> GetHashBucketEqualityComparer(IEqualityComparer<T> valueComparer)
{
if (!ImmutableExtensions.IsValueType<T>())
{
return HashBucketByRefEqualityComparer.DefaultInstance;
}
else if (valueComparer == EqualityComparer<T>.Default)
{
return HashBucketByValueEqualityComparer.DefaultInstance;
}
else
{
return new HashBucketByValueEqualityComparer(valueComparer);
}
}
/// <summary>
/// Wraps the specified data structure with an immutable collection wrapper.
/// </summary>

View File

@@ -212,7 +212,7 @@ namespace System.Collections.Immutable.Tests
// Now check where collisions have conflicting values.
builder = ImmutableDictionary.Create<string, string>()
.Add("a", "1").Add("A", "2").Add("b", "3").ToBuilder();
Assert.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
AssertExtensions.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
// Force all values to be considered equal.
builder.ValueComparer = EverythingEqual<string>.Default;

View File

@@ -43,7 +43,7 @@ namespace System.Collections.Immutable.Tests
{
var builder = this.GetBuilder<string, int>();
builder.Add("five", 5);
Assert.Throws<ArgumentException>(null, () => builder.Add("five", 6));
AssertExtensions.Throws<ArgumentException>(null, () => builder.Add("five", 6));
}
[Fact]

View File

@@ -263,7 +263,7 @@ namespace System.Collections.Immutable.Tests
// Now check where collisions have conflicting values.
map = ImmutableDictionary.Create<string, string>()
.Add("a", "1").Add("A", "2").Add("b", "3");
Assert.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
AssertExtensions.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
// Force all values to be considered equal.
map = map.WithComparers(StringComparer.OrdinalIgnoreCase, EverythingEqual<string>.Default);
@@ -279,7 +279,7 @@ namespace System.Collections.Immutable.Tests
{
var map = ImmutableDictionary.Create<string, string>()
.Add("firstKey", "1").Add("secondKey", "2");
var exception = Assert.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
var exception = AssertExtensions.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
if (!PlatformDetection.IsNetNative) //.Net Native toolchain removes exception messages.
{

View File

@@ -466,8 +466,8 @@ namespace System.Collections.Immutable.Tests
var map1 = map.Add(key, value1);
var map2 = map.Add(key, value2);
Assert.Throws<ArgumentException>(null, () => map1.Add(key, value2));
Assert.Throws<ArgumentException>(null, () => map2.Add(key, value1));
AssertExtensions.Throws<ArgumentException>(null, () => map1.Add(key, value2));
AssertExtensions.Throws<ArgumentException>(null, () => map2.Add(key, value1));
}
protected void ContainsKeyTestHelper<TKey, TValue>(IImmutableDictionary<TKey, TValue> map, TKey key, TValue value)

View File

@@ -64,13 +64,19 @@ namespace System.Collections.Immutable.Tests
}
[Fact]
[ActiveIssue("https://github.com/dotnet/corefx/issues/19044 - HashBucket.Equals() always returning true", TargetFrameworkMonikers.UapAot)]
public void EnumeratorWithHashCollisionsTest()
{
var emptySet = this.EmptyTyped<int>().WithComparer(new BadHasher<int>());
this.EnumeratorTestHelper(emptySet, null, 3, 1, 5);
}
[Fact]
public void EnumeratorWithHashCollisionsTest_RefType()
{
var emptySet = this.EmptyTyped<string>().WithComparer(new BadHasher<string>());
this.EnumeratorTestHelper(emptySet, null, "c", "a", "e");
}
[Fact]
public void EnumeratorRecyclingMisuse()
{
@@ -148,7 +154,6 @@ namespace System.Collections.Immutable.Tests
/// that *is* in the set.
/// </summary>
[Fact]
[ActiveIssue("https://github.com/dotnet/corefx/issues/19044 - HashBucket.Equals() always returning true", TargetFrameworkMonikers.UapAot)]
public void RemoveValuesFromCollidedHashCode()
{
var set = ImmutableHashSet.Create<int>(new BadHasher<int>(), 5, 6);
@@ -158,6 +163,21 @@ namespace System.Collections.Immutable.Tests
Assert.Equal(new[] { 6 }, setAfterRemovingFive);
}
/// <summary>
/// Verifies the non-removal of an item that does not belong to the set,
/// but which happens to have a colliding hash code with another value
/// that *is* in the set.
/// </summary>
[Fact]
public void RemoveValuesFromCollidedHashCode_RefType()
{
var set = ImmutableHashSet.Create<string>(new BadHasher<string>(), "a", "b");
Assert.Same(set, set.Remove("c"));
var setAfterRemovingA = set.Remove("a");
Assert.Equal(1, setAfterRemovingA.Count);
Assert.Equal(new[] { "b" }, setAfterRemovingA);
}
[Fact]
public void TryGetValueTest()
{
@@ -176,7 +196,7 @@ namespace System.Collections.Immutable.Tests
public void SymmetricExceptWithComparerTests()
{
var set = ImmutableHashSet.Create<string>("a").WithComparer(StringComparer.OrdinalIgnoreCase);
var otherCollection = new[] {"A"};
var otherCollection = new[] { "A" };
var expectedSet = new HashSet<string>(set, set.KeyComparer);
expectedSet.SymmetricExceptWith(otherCollection);

View File

@@ -220,7 +220,7 @@ namespace System.Collections.Immutable.Tests
// Now check where collisions have conflicting values.
builder = ImmutableSortedDictionary.Create<string, string>()
.Add("a", "1").Add("A", "2").Add("b", "3").ToBuilder();
Assert.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
AssertExtensions.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
// Force all values to be considered equal.
builder.ValueComparer = EverythingEqual<string>.Default;

View File

@@ -169,7 +169,7 @@ namespace System.Collections.Immutable.Tests
};
var map = Empty<string, string>(StringComparer.Ordinal, StringComparer.Ordinal);
Assert.Throws<ArgumentException>(null, () => map.AddRange(uniqueEntries));
AssertExtensions.Throws<ArgumentException>(null, () => map.AddRange(uniqueEntries));
}
[Fact]
@@ -294,7 +294,7 @@ namespace System.Collections.Immutable.Tests
// Now check where collisions have conflicting values.
map = ImmutableSortedDictionary.Create<string, string>()
.Add("a", "1").Add("A", "2").Add("b", "3");
Assert.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
AssertExtensions.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
// Force all values to be considered equal.
map = map.WithComparers(StringComparer.OrdinalIgnoreCase, EverythingEqual<string>.Default);
@@ -310,7 +310,7 @@ namespace System.Collections.Immutable.Tests
{
var map = ImmutableSortedDictionary.Create<string, string>()
.Add("firstKey", "1").Add("secondKey", "2");
var exception = Assert.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
var exception = AssertExtensions.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
if (!PlatformDetection.IsNetNative) //.Net Native toolchain removes exception messages.
{
Assert.Contains("firstKey", exception.Message);

View File

@@ -13,7 +13,7 @@ namespace System.Collections.Immutable.Tests
{
Requires.Argument(true);
Requires.Argument(true, "parameterName", "message");
Assert.Throws<ArgumentException>(null, () => Requires.Argument(false));
AssertExtensions.Throws<ArgumentException>(null, () => Requires.Argument(false));
AssertExtensions.Throws<ArgumentException>("parameterName", () => Requires.Argument(false, "parameterName", "message"));
}

View File

@@ -1,7 +1,10 @@
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library>
<!-- Needed because of objects in [Theory] data which causes xunit to reflect on its ToString() -->
<Type Name="System.Collections.Generic.ComparisonComparer&lt;T&gt;" Dynamic="Required Public" />
<Type Name="System.Collections.Generic.ComparisonComparer`1" Dynamic="Required Public" />
<Type Name="System.Collections.Generic.GenericComparer`1" Dynamic="Required Public" />
<Type Name="System.Collections.Generic.GenericEqualityComparer`1" Dynamic="Required Public" />
<Type Name="System.Collections.Generic.ObjectComparer`1" Dynamic="Required Public" />
</Library>
</Directives>

View File

@@ -48,9 +48,6 @@
<Compile Include="RequiresTests.cs" />
<Compile Include="SimpleElementImmutablesTestBase.cs" />
<Compile Include="TestExtensionsMethods.cs" />
<Compile Include="$(CommonTestPath)\System\AssertExtensions.cs">
<Link>Common\System\AssertExtensions.cs</Link>
</Compile>
<Compile Include="$(CommonTestPath)\System\Diagnostics\DebuggerAttributes.cs">
<Link>Common\System\Diagnostics\DebuggerAttributes.cs</Link>
</Compile>