diff --git a/Src/Idioms/EqualityComparerAssertion.cs b/Src/Idioms/EqualityComparerAssertion.cs
new file mode 100644
index 000000000..16538d200
--- /dev/null
+++ b/Src/Idioms/EqualityComparerAssertion.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly.
+ ///
+ public class EqualityComparerAssertion : CompositeIdiomaticAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerAssertion(ISpecimenBuilder builder)
+ : base(CreateChildAssertions(builder))
+ {
+ }
+
+ private static IEnumerable CreateChildAssertions(ISpecimenBuilder builder)
+ {
+ yield return new EqualityComparerEqualsSelfAssertion(builder);
+ yield return new EqualityComparerEqualsSymmetricAssertion(builder);
+ yield return new EqualityComparerEqualsTransitiveAssertion(builder);
+ yield return new EqualityComparerGetHashCodeAssertion(builder);
+ yield return new EqualityComparerEqualsNullAssertion(builder);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsAssertion.cs b/Src/Idioms/EqualityComparerEqualsAssertion.cs
new file mode 100644
index 000000000..089f65cc8
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsAssertion.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// A base class for building classes that encapsulate a unit test that verifies that a type implementing implements it correctly.
+ ///
+ public abstract class EqualityComparerEqualsAssertion : IdiomaticAssertion
+ {
+ ///
+ /// Gets the builder supplied by the constructor.
+ ///
+ public ISpecimenBuilder Builder { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ protected EqualityComparerEqualsAssertion(ISpecimenBuilder builder)
+ {
+ this.Builder = builder ?? throw new ArgumentNullException(nameof(builder));
+ }
+
+ ///
+ /// Forwards the call to if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ public override void Verify(MethodInfo methodInfo)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (!IsEqualityComparerEqualsMethod(methodInfo)) return;
+
+ this.VerifyEquals(methodInfo, methodInfo.GetParameters()[0].ParameterType);
+ }
+
+ ///
+ /// Abstract method used to verify if the method implements correctly .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected abstract void VerifyEquals(MethodInfo methodInfo, Type argumentType);
+
+ private static bool IsEqualityComparerEqualsMethod(MethodInfo methodInfo)
+ {
+ return methodInfo is { Name: nameof(IEqualityComparer.Equals), ReflectedType: { } type }
+ && methodInfo.GetParameters().Length == 2
+ && type.ImplementsGenericInterfaceDefinition(typeof(IEqualityComparer<>))
+ && type.ImplementsGenericInterface(
+ typeof(IEqualityComparer<>),
+ methodInfo.GetParameters()[0].ParameterType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsNullAssertion.cs b/Src/Idioms/EqualityComparerEqualsNullAssertion.cs
new file mode 100644
index 000000000..994843f4f
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsNullAssertion.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling Equals(x, null) should return false.
+ ///
+ public class EqualityComparerEqualsNullAssertion : EqualityComparerEqualsAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerEqualsNullAssertion(ISpecimenBuilder builder)
+ : base(builder)
+ {
+ }
+
+ ///
+ /// Verifies that `calling Equals(x, null) should return false`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected override void VerifyEquals(MethodInfo methodInfo, Type argumentType)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (argumentType == null) throw new ArgumentNullException(nameof(argumentType));
+ if (methodInfo.ReflectedType!.IsValueType) return;
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+ var testSubject = this.Builder.CreateAnonymous(argumentType);
+
+ var result = (bool)methodInfo.Invoke(comparer, new[] { testSubject, null });
+
+ if (result)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling Equals(x, null) should return false.",
+ methodInfo.ReflectedType!.FullName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsNullNullAssertion.cs b/Src/Idioms/EqualityComparerEqualsNullNullAssertion.cs
new file mode 100644
index 000000000..8bc9265fa
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsNullNullAssertion.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling Equals(null, null) should return true.
+ ///
+ public class EqualityComparerEqualsNullNullAssertion : EqualityComparerEqualsAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerEqualsNullNullAssertion(ISpecimenBuilder builder)
+ : base(builder)
+ {
+ }
+
+ ///
+ /// Verifies that `calling Equals(null, null) should return true`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected override void VerifyEquals(MethodInfo methodInfo, Type argumentType)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (argumentType == null) throw new ArgumentNullException(nameof(argumentType));
+ if (methodInfo.ReflectedType!.IsValueType) return;
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+
+ var result = (bool)methodInfo.Invoke(comparer, new object[] { null, null });
+
+ if (!result)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling Equals(null, null) should return true.",
+ methodInfo.ReflectedType!.FullName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsSelfAssertion.cs b/Src/Idioms/EqualityComparerEqualsSelfAssertion.cs
new file mode 100644
index 000000000..7811c584d
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsSelfAssertion.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling Equals(x, x) should return true.
+ ///
+ public class EqualityComparerEqualsSelfAssertion : EqualityComparerEqualsAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerEqualsSelfAssertion(ISpecimenBuilder builder)
+ : base(builder)
+ {
+ }
+
+ ///
+ /// Verifies that `calling Equals(x, x) should return true`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected override void VerifyEquals(MethodInfo methodInfo, Type argumentType)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (argumentType == null) throw new ArgumentNullException(nameof(argumentType));
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+ var testSubject = this.Builder.CreateAnonymous(argumentType);
+
+ var result = (bool)methodInfo.Invoke(comparer, new[] { testSubject, testSubject });
+
+ if (!result)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling Equals(x, x) should return true.",
+ methodInfo.ReflectedType!.FullName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsSymmetricAssertion.cs b/Src/Idioms/EqualityComparerEqualsSymmetricAssertion.cs
new file mode 100644
index 000000000..822b5b80a
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsSymmetricAssertion.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling Equals(x, y) should return same as Equals(y, x).
+ ///
+ public class EqualityComparerEqualsSymmetricAssertion : EqualityComparerEqualsAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerEqualsSymmetricAssertion(ISpecimenBuilder builder)
+ : base(builder)
+ {
+ }
+
+ ///
+ /// Verifies that `calling Equals(x, y) should return same as Equals(y, x)`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected override void VerifyEquals(MethodInfo methodInfo, Type argumentType)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (argumentType == null) throw new ArgumentNullException(nameof(argumentType));
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+ var firstTestSubject = this.Builder.CreateAnonymous(argumentType);
+ var secondTestSubject = this.Builder.CreateAnonymous(argumentType);
+
+ var directResult = (bool)methodInfo.Invoke(comparer, new[] { firstTestSubject, secondTestSubject });
+ var invertedResult = (bool)methodInfo.Invoke(comparer, new[] { secondTestSubject, firstTestSubject });
+
+ if (directResult != invertedResult)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling Equals(x, y) should return same as Equals(y, x).",
+ methodInfo.ReflectedType!.FullName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerEqualsTransitiveAssertion.cs b/Src/Idioms/EqualityComparerEqualsTransitiveAssertion.cs
new file mode 100644
index 000000000..6e4bc3b16
--- /dev/null
+++ b/Src/Idioms/EqualityComparerEqualsTransitiveAssertion.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling Equals(x, z) should return same as Equals(x, y) and Equals(y, z).
+ ///
+ public class EqualityComparerEqualsTransitiveAssertion : EqualityComparerEqualsAssertion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerEqualsTransitiveAssertion(ISpecimenBuilder builder)
+ : base(builder)
+ {
+ }
+
+ ///
+ /// Verifies that `calling Equals(x, z) should return same as Equals(x, y) and Equals(y, z)`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ /// The argument type of .
+ protected override void VerifyEquals(MethodInfo methodInfo, Type argumentType)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (argumentType == null) throw new ArgumentNullException(nameof(argumentType));
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+ var firstTestSubject = this.Builder.CreateAnonymous(argumentType);
+ var secondTestSubject = this.Builder.CreateAnonymous(argumentType);
+ var thirdTestSubject = this.Builder.CreateAnonymous(argumentType);
+
+ var firstToSecond = (bool)methodInfo.Invoke(comparer, new[] { firstTestSubject, secondTestSubject });
+ var secondToThird = (bool)methodInfo.Invoke(comparer, new[] { secondTestSubject, thirdTestSubject });
+ var firstToThird = (bool)methodInfo.Invoke(comparer, new[] { firstTestSubject, thirdTestSubject });
+
+ if ((firstToSecond && secondToThird) != firstToThird)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling Equals(x, z) should return same as Equals(x, y) and Equals(y, z).",
+ methodInfo.ReflectedType!.FullName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerGetHashCodeAssertion.cs b/Src/Idioms/EqualityComparerGetHashCodeAssertion.cs
new file mode 100644
index 000000000..dd4ce18a8
--- /dev/null
+++ b/Src/Idioms/EqualityComparerGetHashCodeAssertion.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using AutoFixture.Kernel;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Encapsulates a unit test that verifies that a type implementing implements it correctly
+ /// with respect of the rule: calling GetHashCode(x) should always return same value.
+ ///
+ public class EqualityComparerGetHashCodeAssertion : IdiomaticAssertion
+ {
+ ///
+ /// Gets the builder supplied by the constructor.
+ ///
+ public ISpecimenBuilder Builder { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A composer which can create instances required to implement the idiomatic unit test,
+ /// such as the owner of the property, as well as the value to be assigned and read from
+ /// the member.
+ ///
+ ///
+ ///
+ /// will typically be a instance.
+ ///
+ ///
+ public EqualityComparerGetHashCodeAssertion(ISpecimenBuilder builder)
+ {
+ this.Builder = builder ?? throw new ArgumentNullException(nameof(builder));
+ }
+
+ ///
+ /// Verifies that `calling GetHashCode(x) should always return same value`
+ /// if the supplied method is an implementation of .
+ ///
+ /// The method to verify.
+ public override void Verify(MethodInfo methodInfo)
+ {
+ if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo));
+ if (!IsEqualityComparerGetHashCode(methodInfo)) return;
+
+ var comparer = this.Builder.CreateAnonymous(methodInfo.ReflectedType);
+ var testSubject = this.Builder.CreateAnonymous(methodInfo.GetParameters()[0].ParameterType);
+
+ var firstHashCode = (int)methodInfo.Invoke(comparer, new[] { testSubject });
+ var secondHashCode = (int)methodInfo.Invoke(comparer, new[] { testSubject });
+
+ if (firstHashCode != secondHashCode)
+ {
+ throw new EqualityComparerImplementationException(string.Format(CultureInfo.CurrentCulture,
+ "The type '{0}' implements the `IEqualityComparer` interface incorrectly: " +
+ "calling GetHashCode(x) should always return same value.",
+ methodInfo.ReflectedType?.FullName));
+ }
+ }
+
+ private static bool IsEqualityComparerGetHashCode(MethodInfo methodInfo)
+ {
+ return methodInfo is { Name: nameof(IEqualityComparer.GetHashCode), ReflectedType: { } type }
+ && methodInfo.GetParameters().Length == 1
+ && type.ImplementsGenericInterfaceDefinition(typeof(IEqualityComparer<>))
+ && type.ImplementsGenericInterface(
+ typeof(IEqualityComparer<>),
+ methodInfo.GetParameters()[0].ParameterType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/EqualityComparerImplementationException.cs b/Src/Idioms/EqualityComparerImplementationException.cs
new file mode 100644
index 000000000..61d3d7dac
--- /dev/null
+++ b/Src/Idioms/EqualityComparerImplementationException.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace AutoFixture.Idioms
+{
+ ///
+ /// Represents an error about an ill-behaved implementation of the interface.
+ ///
+ [Serializable]
+ public class EqualityComparerImplementationException : Exception
+ {
+ ///
+ /// Initializes a new instance of teh class.
+ ///
+ public EqualityComparerImplementationException()
+ : base("The implementation of IEqualityComparer is ill-behaved.")
+ {
+ }
+
+ ///
+ /// Initializes a new instance of teh class.
+ ///
+ /// The error message that explains the reason for the exception.
+ public EqualityComparerImplementationException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of teh class.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception.
+ public EqualityComparerImplementationException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of teh class.
+ ///
+ ///
+ /// The that holds the
+ /// serialized object data about the exception being thrown.
+ ///
+ ///
+ /// The that contains
+ /// contextual information about the source or destination.
+ ///
+ protected EqualityComparerImplementationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Idioms/TypeExtensions.cs b/Src/Idioms/TypeExtensions.cs
new file mode 100644
index 000000000..1d931b83f
--- /dev/null
+++ b/Src/Idioms/TypeExtensions.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Linq;
+
+namespace AutoFixture.Idioms
+{
+ internal static class TypeExtensions
+ {
+ public static bool ImplementsGenericInterfaceDefinition(this Type type, Type interfaceType) => type.GetInterfaces().Any(i => i.GetGenericTypeDefinition().IsAssignableFrom(interfaceType));
+
+ public static bool ImplementsGenericInterface(this Type type, Type interfaceType, params Type[] argumentTypes) => type.GetInterfaces().Any(i => i.IsAssignableFrom(interfaceType.MakeGenericType(argumentTypes)));
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerAssertionTest.cs
new file mode 100644
index 000000000..f54a125b8
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerAssertionTest.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedNullEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedNullEqualityComparer)));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedSelfEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedSelfEqualityComparer)));
+ }
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedNullEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (x == null && y == null)
+ return false;
+
+ if (x == null ^ y == null)
+ return true;
+
+ return false;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+
+ private class IllBehavedSelfEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return false;
+
+ return true;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerEqualsNullAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerEqualsNullAssertionTest.cs
new file mode 100644
index 000000000..9c395dd98
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerEqualsNullAssertionTest.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerEqualsNullAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerEqualsNullAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerEqualsNullAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (x == null ^ y == null)
+ return true;
+
+ return false;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerEqualsNullNullAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerEqualsNullNullAssertionTest.cs
new file mode 100644
index 000000000..e35267bc6
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerEqualsNullNullAssertionTest.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerEqualsNullNullAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerEqualsNullNullAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullNullAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerEqualsNullNullAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsNullNullAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (x == null && y == null)
+ return false;
+
+ return true;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerEqualsSelfAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerEqualsSelfAssertionTest.cs
new file mode 100644
index 000000000..8730c8ab9
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerEqualsSelfAssertionTest.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerEqualsSelfAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerEqualsSelfAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSelfAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerEqualsSelfAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSelfAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSelfAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSelfAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSelfAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return false;
+
+ return true;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerEqualsSymmetricAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerEqualsSymmetricAssertionTest.cs
new file mode 100644
index 000000000..51a9575fb
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerEqualsSymmetricAssertionTest.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerEqualsSymmetricAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerEqualsSymmetricAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSymmetricAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerEqualsSymmetricAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSymmetricAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSymmetricAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSymmetricAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsSymmetricAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ private static bool flag = false;
+
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ flag = !flag;
+
+ return flag;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerEqualsTransitiveAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerEqualsTransitiveAssertionTest.cs
new file mode 100644
index 000000000..fdc478ef2
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerEqualsTransitiveAssertionTest.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerEqualsTransitiveAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerEqualsTransitiveAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerEqualsTransitiveAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerEqualsTransitiveAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsTransitiveAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsTransitiveAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsTransitiveAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerEqualsTransitiveAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (ReferenceEquals(x, null))
+ return false;
+
+ if (ReferenceEquals(y, null))
+ return false;
+
+ if (x.GetType() != y.GetType())
+ return false;
+
+ return x.Property == y.Property;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ private static bool flag = false;
+
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ flag = !flag;
+
+ return flag;
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ throw new Exception();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/IdiomsUnitTest/EqualityComparerGetHashCodeAssertionTest.cs b/Src/IdiomsUnitTest/EqualityComparerGetHashCodeAssertionTest.cs
new file mode 100644
index 000000000..192d5bdeb
--- /dev/null
+++ b/Src/IdiomsUnitTest/EqualityComparerGetHashCodeAssertionTest.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AutoFixture.Idioms;
+using AutoFixture.Kernel;
+using TestTypeFoundation;
+using Xunit;
+
+namespace AutoFixture.IdiomsUnitTest
+{
+ public class EqualityComparerGetHashCodeAssertionTest
+ {
+ [Fact]
+ public void SutIsIdiomaticAssertion()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ // Act
+ var sut = new EqualityComparerGetHashCodeAssertion(dummyComposer);
+ // Assert
+ Assert.IsAssignableFrom(sut);
+ }
+
+ [Fact]
+ public void ComposerIsCorrect()
+ {
+ // Arrange
+ var expectedComposer = new Fixture();
+ var sut = new EqualityComparerGetHashCodeAssertion(expectedComposer);
+ // Act
+ ISpecimenBuilder result = sut.Builder;
+ // Assert
+ Assert.Equal(expectedComposer, result);
+ }
+
+ [Fact]
+ public void ConstructWithNullComposerThrows()
+ {
+ // Arrange
+ // Act & Assert
+ Assert.Throws(() =>
+ new EqualityComparerGetHashCodeAssertion(null));
+ }
+
+ [Fact]
+ public void VerifyNullMethodThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerGetHashCodeAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify((MethodInfo)null));
+ }
+
+ [Fact]
+ public void VerifyNonEqualityComparerDoesNothing()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerGetHashCodeAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(NonEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyWellBehavedEqualityComparerDoesNotThrow()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerGetHashCodeAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Null(Record.Exception(() =>
+ sut.Verify(typeof(WellBehavedEqualityComparer))));
+ }
+
+ [Fact]
+ public void VerifyIllBehavedEqualityComparerThrows()
+ {
+ // Arrange
+ var dummyComposer = new Fixture();
+ var sut = new EqualityComparerGetHashCodeAssertion(dummyComposer);
+ // Act & Assert
+ Assert.Throws(() =>
+ sut.Verify(typeof(IllBehavedEqualityComparer)));
+ }
+
+#pragma warning disable 659
+ private class WellBehavedEqualityComparer : IEqualityComparer>
+ {
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ throw new Exception();
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return obj.Property;
+ }
+ }
+
+ private class IllBehavedEqualityComparer : IEqualityComparer>
+ {
+ private static readonly Random HashCodeGenerator = new Random();
+
+ public bool Equals(PropertyHolder x, PropertyHolder y)
+ {
+ throw new Exception();
+ }
+
+ public int GetHashCode(PropertyHolder obj)
+ {
+ return HashCodeGenerator.Next();
+ }
+ }
+#pragma warning restore 659
+
+ private class NonEqualityComparer
+ {
+ }
+ }
+}
\ No newline at end of file