Skip to content

Commit

Permalink
Merge pull request #820 from stakx/times-default
Browse files Browse the repository at this point in the history
Adjust `default(Times)` to `Times.AtLeastOnce()`
  • Loading branch information
stakx committed Apr 27, 2019
2 parents 5d65d46 + 4dc244d commit 64638ae
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
44 changes: 38 additions & 6 deletions src/Moq/Times.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System;
using System.Diagnostics;
using System.Globalization;

using Moq.Properties;
Expand All @@ -22,6 +23,28 @@ private Times(Kind kind, int from, int to)
this.kind = kind;
}

private void Deconstruct(out int from, out int to)
{
if (this.kind == default)
{
// This branch makes `default(Times)` equivalent to `Times.AtLeastOnce()`,
// which is the implicit default across Moq's API for overloads that don't
// accept a `Times` instance. While user code shouldn't use `default(Times)`
// (but instead either specify `Times` explicitly or not at all), it is
// easy enough to correct:

Debug.Assert(this.kind == Kind.AtLeastOnce);

from = 1;
to = int.MaxValue;
}
else
{
from = this.from;
to = this.to;
}
}

/// <include file='Times.xdoc' path='docs/doc[@for="Times.AtLeast"]/*'/>
public static Times AtLeast(int callCount)
{
Expand Down Expand Up @@ -115,7 +138,9 @@ public static Times Once()
/// </returns>
public bool Equals(Times other)
{
return this.from == other.from && this.to == other.to;
var (from, to) = this;
var (otherFrom, otherTo) = other;
return from == otherFrom && to == otherTo;
}

/// <include file='Times.xdoc' path='docs/doc[@for="Times.Equals"]/*'/>
Expand All @@ -127,7 +152,8 @@ public override bool Equals(object obj)
/// <include file='Times.xdoc' path='docs/doc[@for="Times.GetHashCode"]/*'/>
public override int GetHashCode()
{
return this.from.GetHashCode() ^ this.to.GetHashCode();
var (from, to) = this;
return from.GetHashCode() ^ to.GetHashCode();
}

/// <include file='Times.xdoc' path='docs/doc[@for="Times.op_Equality"]/*'/>
Expand All @@ -144,8 +170,13 @@ public override int GetHashCode()

internal string GetExceptionMessage(int callCount)
{
var from = this.kind == Kind.BetweenExclusive ? this.from - 1 : this.from;
var to = this.kind == Kind.BetweenExclusive ? this.to + 1 : this.to;
var (from, to) = this;

if (this.kind == Kind.BetweenExclusive)
{
--from;
++to;
}

string message = null;
switch (this.kind)
Expand All @@ -166,13 +197,14 @@ internal string GetExceptionMessage(int callCount)

internal bool Verify(int callCount)
{
return this.from <= callCount && callCount <= this.to;
var (from, to) = this;
return from <= callCount && callCount <= to;
}

private enum Kind
{
AtLeast,
AtLeastOnce,
AtLeast,
AtMost,
AtMostOnce,
BetweenExclusive,
Expand Down
23 changes: 23 additions & 0 deletions tests/Moq.Tests/TimesFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ namespace Moq.Tests
{
public class TimesFixture
{
[Theory]
[InlineData(0, false)]
[InlineData(1, true)]
[InlineData(int.MaxValue, true)]
public void default_ranges_between_one_and_MaxValue(int count, bool verifies)
{
Assert.Equal(verifies, default(Times).Verify(count));
}

[Fact]
public void AtLeastOnceRangesBetweenOneAndMaxValue()
{
Expand Down Expand Up @@ -174,6 +183,20 @@ public void OnceChecksOneTime()

public class Equality
{
#pragma warning disable xUnit2000 // Constants and literals should be the expected argument
[Fact]
public void default_Equals_AtLeastOnce()
{
Assert.Equal(Times.AtLeastOnce(), default(Times));
}
#pragma warning restore xUnit2000

[Fact]
public void default_GetHashCode_equals_AtLeastOnce_GetHashCode()
{
Assert.Equal(Times.AtLeastOnce().GetHashCode(), default(Times).GetHashCode());
}

[Fact]
public void AtMostOnce_equals_Between_0_1_inclusive()
{
Expand Down

0 comments on commit 64638ae

Please sign in to comment.