Skip to content

Commit

Permalink
Test ExpressionKey.Equals against bad hashcodes
Browse files Browse the repository at this point in the history
Issue 328 revealed that ExpressionKey did not perform equality check-
ing correctly for objects with the same hash code. This commit adds
tests for that specific scenario.
  • Loading branch information
stakx committed Jun 7, 2017
1 parent c7b7dfd commit 4a2c2ac
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions UnitTests/Regressions/IssueReportsFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,93 @@ public void strict_mock_differenciates_multiple_setups_with_same_arguments_in_di

#endregion // #135

#region 328

public class Issue328
{
public struct BadlyHashed<T> : IEquatable<BadlyHashed<T>>
{
public static implicit operator BadlyHashed<T>(T value)
{
return new BadlyHashed<T>(value);
}

private T value;

public BadlyHashed(T value)
{
this.value = value;
}

public bool Equals(BadlyHashed<T> other)
{
return this.value.Equals(other.value);
}

public override bool Equals(object obj)
{
return obj is BadlyHashed<T> other && this.Equals(other);
}

public override int GetHashCode()
{
// This is legal: Equal objects must have equal hashcodes,
// but objects with equal hashcodes are not necessarily equal.
// We are essentially rendering GetHashCode useless for equality
// comparison, so whoever compares instances of this type will
// (or should!) end up using the more precise Equals.
return 0;
}
}

[Fact]
public void Two_BadlyHashed_instances_with_equal_values_are_equal()
{
BadlyHashed<string> a1 = "a", a2 = "a";
Assert.Equal(a1, a2);
Assert.Equal(a2, a1);
}

[Fact]
public void Two_BadlyHashed_instances_with_nonequal_values_are_not_equal()
{
BadlyHashed<string> a = "a", b = "b";
Assert.NotEqual(a, b);
Assert.NotEqual(b, a);
}

public interface IMockableService
{
void Use(BadlyHashed<string> wrappedString);
}

[Fact]
public void Strict_mock_expecting_calls_with_nonequal_BadlyHashed_values_should_verify_when_called_properly()
{
// The above test has already established that `a` and `b` are not equal.
BadlyHashed<string> a = "a", b = "b";

// We are setting up two calls in Strict mode, i.e. both calls must happen.
var mock = new Mock<IMockableService>(MockBehavior.Strict);
{
mock.Setup(service => service.Use(a));
mock.Setup(service => service.Use(b));
}

// And they do happen!
{
var service = mock.Object;
service.Use(a);
service.Use(b);
}

// So the following verification should succeed.
mock.VerifyAll();
}
}

#endregion // #328

// Old @ Google Code

#region #47
Expand Down

0 comments on commit 4a2c2ac

Please sign in to comment.