Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions TUnit.Assertions.Tests/AssertConditions/BecauseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public async Task Include_Because_Reason_In_Message()
await Assert.That(variable).IsFalse().Because(because);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(because);
}

Expand All @@ -30,7 +30,7 @@ public async Task Prefix_Because_Message(string because, string expectedWithPref
await Assert.That(variable).IsFalse().Because(because);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(expectedWithPrefix);
}

Expand All @@ -45,7 +45,7 @@ public async Task Honor_Already_Present_Because_Prefix()
await Assert.That(variable).IsFalse().Because(because);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(because)
.And.DoesNotContain("because because");
}
Expand All @@ -65,7 +65,7 @@ At Assert.That(variable).IsFalse()
await Assert.That(variable).IsFalse();
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).IsEqualTo(expectedMessage);
}

Expand All @@ -87,7 +87,7 @@ await Assert.That(variable).IsTrue().Because(because)
.And.IsFalse();
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).IsEqualTo(expectedMessage);
}

Expand All @@ -104,7 +104,7 @@ await Assert.That(variable).IsTrue().Because(because1)
.And.IsFalse().Because(because2);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(because1);
}

Expand All @@ -121,7 +121,7 @@ await Assert.That(variable).IsTrue().Because(because1)
.And.IsFalse().Because(because2);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(because2);
}

Expand All @@ -138,7 +138,7 @@ await Assert.That(variable).IsFalse().Because(because1)
.Or.IsFalse().Because(because2);
};

var exception = await Assert.ThrowsAsync<AssertionException>(action);
var exception = await Assert.That(action).Throws<AssertionException>();
await Assert.That(exception.Message).Contains(because1).And.Contains(because2);
}
}
10 changes: 5 additions & 5 deletions TUnit.Assertions.UnitTests/AsyncTaskTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,30 @@ public async Task Task_Is_Callable()
[Test]
public async Task Func_Throws_Task_Is_Callable()
{
await TUnitAssert.ThrowsAsync(() => Task.FromException(new DivideByZeroException()));
await TUnitAssert.That(() => Task.FromException(new DivideByZeroException())).ThrowsException();
}

[Test]
public async Task Func_Throws_Awaited_Task_Is_Callable()
{
await TUnitAssert.ThrowsAsync(async () => await Task.FromException(new DivideByZeroException()));
await TUnitAssert.That(async () => await Task.FromException(new DivideByZeroException())).ThrowsException();
}

[Test]
public async Task Func_Throws_Awaited_ValueTask_Is_Callable()
{
await TUnitAssert.ThrowsAsync(async () => await ValueTask.FromException(new DivideByZeroException()));
await TUnitAssert.That(async () => await ValueTask.FromException(new DivideByZeroException())).ThrowsException();
}

[Test]
public async Task Throws_Task_Is_Callable()
{
await TUnitAssert.ThrowsAsync(Task.FromException(new DivideByZeroException()));
await TUnitAssert.That(Task.FromException(new DivideByZeroException())).ThrowsException();
}

[Test]
public async Task Throws_ValueTask_Is_Callable()
{
await TUnitAssert.ThrowsAsync(ValueTask.FromException(new DivideByZeroException()));
await TUnitAssert.That(ValueTask.FromException(new DivideByZeroException())).ThrowsException();
}
}
70 changes: 0 additions & 70 deletions TUnit.Assertions/Assert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Runtime.CompilerServices;
using TUnit.Assertions.AssertionBuilders;
using TUnit.Assertions.Exceptions;
using TUnit.Assertions.Extensions;

namespace TUnit.Assertions;

Expand Down Expand Up @@ -63,73 +62,4 @@ public static void Fail(string reason)
{
throw new AssertionException(reason);
}

public static Task<Exception> ThrowsAsync(Func<Task> @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null)
=> ThrowsAsync<Exception>(@delegate, doNotPopulateThisValue);

public static Task<Exception> ThrowsAsync(Task @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null)
=> ThrowsAsync(async () => await @delegate, doNotPopulateThisValue);

public static Task<Exception> ThrowsAsync(ValueTask @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null)
=> ThrowsAsync(async () => await @delegate, doNotPopulateThisValue);

public static async Task<TException> ThrowsAsync<TException>(Func<Task> @delegate, [CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null) where TException : Exception
{
try
{
await @delegate();
Fail($"No exception was thrown by {doNotPopulateThisValue.GetStringOr("the delegate")}");
}
catch (Exception e) when(e is not AssertionException)
{
if (e is TException exception)
{
return exception;
}

Fail($"Exception is of type {e.GetType().Name} instead of {typeof(TException).Name} for {doNotPopulateThisValue.GetStringOr("the delegate")}");
}
catch (TException e)
{
// In case we want to assert to catch an AssertionException
return e;
}

return null!;
}

public static Task<TException> ThrowsAsync<TException>(Task @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null) where TException : Exception
=> ThrowsAsync<TException>(async () => await @delegate, doNotPopulateThisValue);

public static Task<TException> ThrowsAsync<TException>(ValueTask @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null) where TException : Exception
=> ThrowsAsync<TException>(async () => await @delegate, doNotPopulateThisValue);

public static Exception Throws(Action @delegate,
[CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null)
=> Throws<Exception>(@delegate, doNotPopulateThisValue);

public static TException Throws<TException>(Action @delegate, [CallerArgumentExpression("delegate")] string? doNotPopulateThisValue = null) where TException : Exception
{
try
{
@delegate();
Fail($"No exception was thrown by {doNotPopulateThisValue.GetStringOr("the delegate")}");
}
catch (Exception e) when(e is not AssertionException)
{
if (e is TException exception)
{
return exception;
}

Fail($"Exception is of type {e.GetType().Name} instead of {typeof(TException).Name} for {doNotPopulateThisValue.GetStringOr("the delegate")}");
}

return null!;
}
}
26 changes: 11 additions & 15 deletions TUnit.Assertions/AssertConditions/Throws/ThrowsException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,35 @@ namespace TUnit.Assertions.AssertConditions.Throws;
public class ThrowsException<TActual, TException>(
InvokableDelegateAssertionBuilder<TActual> delegateAssertionBuilder,
IDelegateSource<TActual> delegateSource,
Func<Exception?, Exception?> exceptionSelector,
[CallerMemberName] string callerMemberName = "")
Func<Exception?, Exception?> exceptionSelector)
where TException : Exception
{
private readonly IDelegateSource<TActual> _delegateSource = delegateSource;
private readonly Func<Exception?, Exception?> _exceptionSelector = exceptionSelector;
private IDelegateSource<TActual> delegateSource;
private Func<Exception?, TException?> exceptionSelector;

public ThrowsException<TActual, TException> WithMessageMatching(StringMatcher match, [CallerArgumentExpression("match")] string doNotPopulateThisValue = "")
{
_delegateSource.RegisterAssertion(new ThrowsWithMessageMatchingAssertCondition<TActual, TException>(match, _exceptionSelector)
, [doNotPopulateThisValue]);
delegateSource.RegisterAssertion(
new ThrowsWithMessageMatchingAssertCondition<TActual, TException>(match, exceptionSelector),
[doNotPopulateThisValue]);
return this;
}

public ThrowsException<TActual, TException> WithMessage(string expected, [CallerArgumentExpression("expected")] string doNotPopulateThisValue = "")
{
_delegateSource.RegisterAssertion(new ThrowsWithMessageAssertCondition<TActual, TException>(expected, StringComparison.Ordinal, _exceptionSelector)
, [doNotPopulateThisValue]);
delegateSource.RegisterAssertion(
new ThrowsWithMessageAssertCondition<TActual, TException>(expected, StringComparison.Ordinal, exceptionSelector),
[doNotPopulateThisValue]);
return this;
}

public ThrowsException<TActual, Exception> WithInnerException()
{
_delegateSource.AssertionBuilder.AppendExpression($"{nameof(WithInnerException)}()");
return new(delegateAssertionBuilder, _delegateSource, e => _exceptionSelector(e)?.InnerException);
delegateSource.AssertionBuilder.AppendExpression($"{nameof(WithInnerException)}()");
return new(delegateAssertionBuilder, delegateSource, e => exceptionSelector(e)?.InnerException);
}

public TaskAwaiter<TException?> GetAwaiter()
public TaskAwaiter<TException> GetAwaiter()
{
var task = delegateAssertionBuilder.ProcessAssertionsAsync(
d => d.Exception as TException);
return task.GetAwaiter();
return task.GetAwaiter()!;
}
}