Skip to content

Commit 1c24f7f

Browse files
CopilotMrKWatkins
andcommitted
Add precision to floating-point comparison methods; expand async action tests with async throw variants
Co-authored-by: MrKWatkins <345796+MrKWatkins@users.noreply.github.com>
1 parent a375d38 commit 1c24f7f

File tree

3 files changed

+67
-51
lines changed

3 files changed

+67
-51
lines changed

src/MrKWatkins.Assertions.Tests/AsyncActionAssertionsTests.cs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,41 @@ public sealed class AsyncActionAssertionsTests
66
public async Task ThrowAsync()
77
{
88
Func<Task> doesNotThrow = () => Task.CompletedTask;
9+
Func<Task> doesNotThrowAsync = async () => await Task.Yield();
910

1011
var exception = new InvalidOperationException("Test");
1112
Func<Task> throws = () => throw exception;
13+
Func<Task> throwsAsync = async () => { await Task.Yield(); throw exception; };
1214

1315
Func<Task> throwsWrongException = () => throw new NotSupportedException("Wrong");
16+
Func<Task> throwsWrongExceptionAsync = async () => { await Task.Yield(); throw new NotSupportedException("Wrong"); };
1417

1518
await Assert.That(() => throws.Should().ThrowAsync<InvalidOperationException>()).ThrowsNothing();
19+
await Assert.That(() => throwsAsync.Should().ThrowAsync<InvalidOperationException>()).ThrowsNothing();
1620

1721
await Assert.That(() => doesNotThrow.Should().ThrowAsync<InvalidOperationException>())
1822
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException.");
23+
await Assert.That(() => doesNotThrowAsync.Should().ThrowAsync<InvalidOperationException>())
24+
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException.");
1925

2026
await Assert.That(() => throwsWrongException.Should().ThrowAsync<InvalidOperationException>())
2127
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException but threw a NotSupportedException with message \"Wrong\".");
28+
await Assert.That(() => throwsWrongExceptionAsync.Should().ThrowAsync<InvalidOperationException>())
29+
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException but threw a NotSupportedException with message \"Wrong\".");
2230
}
2331

2432
[Test]
2533
public async Task ThrowAsync_Chain()
2634
{
2735
var exception = new InvalidOperationException("Test");
2836
Func<Task> throws = () => throw exception;
37+
Func<Task> throwsAsync = async () => { await Task.Yield(); throw exception; };
2938

3039
var chain = await throws.Should().ThrowAsync<InvalidOperationException>().ConfigureAwait(false);
40+
await Assert.That(chain.Exception).IsSameReferenceAs(exception);
41+
await Assert.That(chain.That).IsSameReferenceAs(exception);
3142

43+
chain = await throwsAsync.Should().ThrowAsync<InvalidOperationException>().ConfigureAwait(false);
3244
await Assert.That(chain.Exception).IsSameReferenceAs(exception);
3345
await Assert.That(chain.That).IsSameReferenceAs(exception);
3446
}
@@ -37,32 +49,46 @@ public async Task ThrowAsync_Chain()
3749
public async Task ThrowAsync_String()
3850
{
3951
Func<Task> doesNotThrow = () => Task.CompletedTask;
52+
Func<Task> doesNotThrowAsync = async () => await Task.Yield();
4053

4154
var exception = new InvalidOperationException("Test");
4255
Func<Task> throws = () => throw exception;
56+
Func<Task> throwsAsync = async () => { await Task.Yield(); throw exception; };
4357

4458
Func<Task> throwsWrongException = () => throw new NotSupportedException("Wrong");
59+
Func<Task> throwsWrongExceptionAsync = async () => { await Task.Yield(); throw new NotSupportedException("Wrong"); };
4560

4661
await Assert.That(() => throws.Should().ThrowAsync<InvalidOperationException>("Test")).ThrowsNothing();
62+
await Assert.That(() => throwsAsync.Should().ThrowAsync<InvalidOperationException>("Test")).ThrowsNothing();
4763

4864
await Assert.That(() => throws.Should().ThrowAsync<InvalidOperationException>("Wrong Message"))
4965
.Throws<AssertionException>().WithMessage("Value should have Message \"Wrong Message\" but was \"Test\".");
66+
await Assert.That(() => throwsAsync.Should().ThrowAsync<InvalidOperationException>("Wrong Message"))
67+
.Throws<AssertionException>().WithMessage("Value should have Message \"Wrong Message\" but was \"Test\".");
5068

5169
await Assert.That(() => doesNotThrow.Should().ThrowAsync<InvalidOperationException>("Test"))
5270
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException.");
71+
await Assert.That(() => doesNotThrowAsync.Should().ThrowAsync<InvalidOperationException>("Test"))
72+
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException.");
5373

5474
await Assert.That(() => throwsWrongException.Should().ThrowAsync<InvalidOperationException>("Test"))
5575
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException but threw a NotSupportedException with message \"Wrong\".");
76+
await Assert.That(() => throwsWrongExceptionAsync.Should().ThrowAsync<InvalidOperationException>("Test"))
77+
.Throws<AssertionException>().WithMessage("Function should throw an InvalidOperationException but threw a NotSupportedException with message \"Wrong\".");
5678
}
5779

5880
[Test]
5981
public async Task ThrowAsync_String_Chain()
6082
{
6183
var exception = new InvalidOperationException("Test");
6284
Func<Task> throws = () => throw exception;
85+
Func<Task> throwsAsync = async () => { await Task.Yield(); throw exception; };
6386

6487
var chain = await throws.Should().ThrowAsync<InvalidOperationException>("Test").ConfigureAwait(false);
88+
await Assert.That(chain.Exception).IsSameReferenceAs(exception);
89+
await Assert.That(chain.That).IsSameReferenceAs(exception);
6590

91+
chain = await throwsAsync.Should().ThrowAsync<InvalidOperationException>("Test").ConfigureAwait(false);
6692
await Assert.That(chain.Exception).IsSameReferenceAs(exception);
6793
await Assert.That(chain.That).IsSameReferenceAs(exception);
6894
}
@@ -71,38 +97,24 @@ public async Task ThrowAsync_String_Chain()
7197
public async Task NotThrowAsync()
7298
{
7399
Func<Task> doesNotThrow = () => Task.CompletedTask;
100+
Func<Task> doesNotThrowAsync = async () => await Task.Yield();
74101

75102
var exception = new InvalidOperationException("Test");
76103
Func<Task> throws = () => throw exception;
104+
Func<Task> throwsAsync = async () => { await Task.Yield(); throw exception; };
77105

78106
await Assert.That(() => doesNotThrow.Should().NotThrowAsync()).ThrowsNothing();
107+
await Assert.That(() => doesNotThrowAsync.Should().NotThrowAsync()).ThrowsNothing();
79108

80109
var actualException = await Assert.That(() => throws.Should().NotThrowAsync())
81110
.Throws<AssertionException>()
82111
.WithMessage("Function should not throw but threw an InvalidOperationException with message \"Test\".");
83112
await Assert.That(actualException!.InnerException).IsSameReferenceAs(exception);
84-
}
85-
86-
[Test]
87-
public async Task ThrowAsync_ActuallyAsync()
88-
{
89-
var exception = new InvalidOperationException("AsyncTest");
90-
Func<Task> throwsAsync = async () =>
91-
{
92-
await Task.Yield();
93-
throw exception;
94-
};
95-
96-
var chain = await throwsAsync.Should().ThrowAsync<InvalidOperationException>("AsyncTest").ConfigureAwait(false);
97-
await Assert.That(chain.Exception).IsSameReferenceAs(exception);
98-
}
99113

100-
[Test]
101-
public async Task NotThrowAsync_ActuallyAsync()
102-
{
103-
Func<Task> doesNotThrow = async () => await Task.Yield();
104-
105-
await Assert.That(() => doesNotThrow.Should().NotThrowAsync()).ThrowsNothing();
114+
actualException = await Assert.That(() => throwsAsync.Should().NotThrowAsync())
115+
.Throws<AssertionException>()
116+
.WithMessage("Function should not throw but threw an InvalidOperationException with message \"Test\".");
117+
await Assert.That(actualException!.InnerException).IsSameReferenceAs(exception);
106118
}
107119

108120
[Test]

src/MrKWatkins.Assertions.Tests/FloatingPointAssertionsTests.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ public async Task BeLessThan()
4040
{
4141
const double value = 5.0;
4242

43-
await Assert.That(() => value.Should().BeLessThan(10.0)).ThrowsNothing();
44-
await Assert.That(() => value.Should().BeLessThan(5.0)).Throws<AssertionException>()
45-
.WithMessage("Value should be less than 5 but was 5.");
46-
await Assert.That(() => value.Should().BeLessThan(1.0)).Throws<AssertionException>()
47-
.WithMessage("Value should be less than 1 but was 5.");
43+
await Assert.That(() => value.Should().BeLessThan(10.0, 0.001)).ThrowsNothing();
44+
await Assert.That(() => value.Should().BeLessThan(5.0, 0.001)).Throws<AssertionException>()
45+
.WithMessage("Value should be less than 5 (±0.001) but was 5.");
46+
await Assert.That(() => value.Should().BeLessThan(1.0, 0.001)).Throws<AssertionException>()
47+
.WithMessage("Value should be less than 1 (±0.001) but was 5.");
4848
}
4949

5050
[Test]
5151
public async Task BeLessThan_Chain()
5252
{
5353
const double value = 5.0;
5454

55-
var chain = value.Should().BeLessThan(10.0);
55+
var chain = value.Should().BeLessThan(10.0, 0.001);
5656
await Assert.That(chain.Value).IsEqualTo(value);
5757
await Assert.That(chain.And.Value).IsEqualTo(value);
5858
}
@@ -62,18 +62,18 @@ public async Task BeLessThanOrEqualTo()
6262
{
6363
const double value = 5.0;
6464

65-
await Assert.That(() => value.Should().BeLessThanOrEqualTo(10.0)).ThrowsNothing();
66-
await Assert.That(() => value.Should().BeLessThanOrEqualTo(5.0)).ThrowsNothing();
67-
await Assert.That(() => value.Should().BeLessThanOrEqualTo(1.0)).Throws<AssertionException>()
68-
.WithMessage("Value should be less than or equal to 1 but was 5.");
65+
await Assert.That(() => value.Should().BeLessThanOrEqualTo(10.0, 0.001)).ThrowsNothing();
66+
await Assert.That(() => value.Should().BeLessThanOrEqualTo(5.0, 0.001)).ThrowsNothing();
67+
await Assert.That(() => value.Should().BeLessThanOrEqualTo(1.0, 0.001)).Throws<AssertionException>()
68+
.WithMessage("Value should be less than or equal to 1 (±0.001) but was 5.");
6969
}
7070

7171
[Test]
7272
public async Task BeLessThanOrEqualTo_Chain()
7373
{
7474
const double value = 5.0;
7575

76-
var chain = value.Should().BeLessThanOrEqualTo(5.0);
76+
var chain = value.Should().BeLessThanOrEqualTo(5.0, 0.001);
7777
await Assert.That(chain.Value).IsEqualTo(value);
7878
await Assert.That(chain.And.Value).IsEqualTo(value);
7979
}
@@ -83,19 +83,19 @@ public async Task BeGreaterThan()
8383
{
8484
const double value = 5.0;
8585

86-
await Assert.That(() => value.Should().BeGreaterThan(1.0)).ThrowsNothing();
87-
await Assert.That(() => value.Should().BeGreaterThan(5.0)).Throws<AssertionException>()
88-
.WithMessage("Value should be greater than 5 but was 5.");
89-
await Assert.That(() => value.Should().BeGreaterThan(10.0)).Throws<AssertionException>()
90-
.WithMessage("Value should be greater than 10 but was 5.");
86+
await Assert.That(() => value.Should().BeGreaterThan(1.0, 0.001)).ThrowsNothing();
87+
await Assert.That(() => value.Should().BeGreaterThan(5.0, 0.001)).Throws<AssertionException>()
88+
.WithMessage("Value should be greater than 5 (±0.001) but was 5.");
89+
await Assert.That(() => value.Should().BeGreaterThan(10.0, 0.001)).Throws<AssertionException>()
90+
.WithMessage("Value should be greater than 10 (±0.001) but was 5.");
9191
}
9292

9393
[Test]
9494
public async Task BeGreaterThan_Chain()
9595
{
9696
const double value = 5.0;
9797

98-
var chain = value.Should().BeGreaterThan(1.0);
98+
var chain = value.Should().BeGreaterThan(1.0, 0.001);
9999
await Assert.That(chain.Value).IsEqualTo(value);
100100
await Assert.That(chain.And.Value).IsEqualTo(value);
101101
}
@@ -105,18 +105,18 @@ public async Task BeGreaterThanOrEqualTo()
105105
{
106106
const double value = 5.0;
107107

108-
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(1.0)).ThrowsNothing();
109-
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(5.0)).ThrowsNothing();
110-
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(10.0)).Throws<AssertionException>()
111-
.WithMessage("Value should be greater than or equal to 10 but was 5.");
108+
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(1.0, 0.001)).ThrowsNothing();
109+
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(5.0, 0.001)).ThrowsNothing();
110+
await Assert.That(() => value.Should().BeGreaterThanOrEqualTo(10.0, 0.001)).Throws<AssertionException>()
111+
.WithMessage("Value should be greater than or equal to 10 (±0.001) but was 5.");
112112
}
113113

114114
[Test]
115115
public async Task BeGreaterThanOrEqualTo_Chain()
116116
{
117117
const double value = 5.0;
118118

119-
var chain = value.Should().BeGreaterThanOrEqualTo(5.0);
119+
var chain = value.Should().BeGreaterThanOrEqualTo(5.0, 0.001);
120120
await Assert.That(chain.Value).IsEqualTo(value);
121121
await Assert.That(chain.And.Value).IsEqualTo(value);
122122
}

src/MrKWatkins.Assertions/FloatingPointAssertions.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ public FloatingPointAssertionsChain<T> BeApproximately(T expected, T precision)
2727
/// Asserts that the floating-point value is less than the expected value.
2828
/// </summary>
2929
/// <param name="expected">The value the floating-point number should be less than.</param>
30+
/// <param name="precision">The precision to use for the comparison.</param>
3031
/// <returns>A <see cref="FloatingPointAssertionsChain{T}" /> for chaining further assertions.</returns>
31-
public FloatingPointAssertionsChain<T> BeLessThan(T expected)
32+
public FloatingPointAssertionsChain<T> BeLessThan(T expected, T precision)
3233
{
33-
Verify.That(Value < expected, $"Value should be less than {expected} but was {Value}.");
34+
Verify.That(Value < expected - precision, $"Value should be less than {expected}{precision}) but was {Value}.");
3435

3536
return new FloatingPointAssertionsChain<T>(this);
3637
}
@@ -39,10 +40,11 @@ public FloatingPointAssertionsChain<T> BeLessThan(T expected)
3940
/// Asserts that the floating-point value is less than or equal to the expected value.
4041
/// </summary>
4142
/// <param name="expected">The value the floating-point number should be less than or equal to.</param>
43+
/// <param name="precision">The precision to use for the comparison.</param>
4244
/// <returns>A <see cref="FloatingPointAssertionsChain{T}" /> for chaining further assertions.</returns>
43-
public FloatingPointAssertionsChain<T> BeLessThanOrEqualTo(T expected)
45+
public FloatingPointAssertionsChain<T> BeLessThanOrEqualTo(T expected, T precision)
4446
{
45-
Verify.That(Value <= expected, $"Value should be less than or equal to {expected} but was {Value}.");
47+
Verify.That(Value <= expected + precision, $"Value should be less than or equal to {expected}{precision}) but was {Value}.");
4648

4749
return new FloatingPointAssertionsChain<T>(this);
4850
}
@@ -51,10 +53,11 @@ public FloatingPointAssertionsChain<T> BeLessThanOrEqualTo(T expected)
5153
/// Asserts that the floating-point value is greater than the expected value.
5254
/// </summary>
5355
/// <param name="expected">The value the floating-point number should be greater than.</param>
56+
/// <param name="precision">The precision to use for the comparison.</param>
5457
/// <returns>A <see cref="FloatingPointAssertionsChain{T}" /> for chaining further assertions.</returns>
55-
public FloatingPointAssertionsChain<T> BeGreaterThan(T expected)
58+
public FloatingPointAssertionsChain<T> BeGreaterThan(T expected, T precision)
5659
{
57-
Verify.That(Value > expected, $"Value should be greater than {expected} but was {Value}.");
60+
Verify.That(Value > expected + precision, $"Value should be greater than {expected}{precision}) but was {Value}.");
5861

5962
return new FloatingPointAssertionsChain<T>(this);
6063
}
@@ -63,10 +66,11 @@ public FloatingPointAssertionsChain<T> BeGreaterThan(T expected)
6366
/// Asserts that the floating-point value is greater than or equal to the expected value.
6467
/// </summary>
6568
/// <param name="expected">The value the floating-point number should be greater than or equal to.</param>
69+
/// <param name="precision">The precision to use for the comparison.</param>
6670
/// <returns>A <see cref="FloatingPointAssertionsChain{T}" /> for chaining further assertions.</returns>
67-
public FloatingPointAssertionsChain<T> BeGreaterThanOrEqualTo(T expected)
71+
public FloatingPointAssertionsChain<T> BeGreaterThanOrEqualTo(T expected, T precision)
6872
{
69-
Verify.That(Value >= expected, $"Value should be greater than or equal to {expected} but was {Value}.");
73+
Verify.That(Value >= expected - precision, $"Value should be greater than or equal to {expected}{precision}) but was {Value}.");
7074

7175
return new FloatingPointAssertionsChain<T>(this);
7276
}

0 commit comments

Comments
 (0)