Skip to content
Merged
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
64 changes: 64 additions & 0 deletions TUnit.Assertions.Tests/SatisfiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,70 @@ await Assert.That(models).All().Satisfy(model => model!.Value, item => item.Cont
""");
}

[Test]
public async Task Satisfies_With_Member_As_Final_Statement()
{
var list = new List<MyModelWithId>
{
new() { Id = 1, Name = "First" }
};

await Assert.That(list).Satisfies(
l => l.First(),
item => item.Member(i => i.Id, v => v.EqualTo(1)));
}

[Test]
public async Task Satisfies_With_Member_After_Chaining()
{
var list = new List<MyModelWithId>
{
new() { Id = 1, Name = "First" }
};

await Assert.That(list).Satisfies(
l => l.First(),
item => item.IsNotNull()
.And.Member(i => i.Id, v => v.EqualTo(1)));
}

[Test]
public async Task Satisfies_With_Member_Before_Other_Assertions()
{
var list = new List<MyModelWithId>
{
new() { Id = 1, Name = "First" }
};

await Assert.That(list).Satisfies(
l => l.First(),
item => item.Member(i => i.Id, v => v.EqualTo(1))
.And.IsNotNull());
}

[Test]
public async Task Satisfies_With_Member_Fails_Correctly()
{
var list = new List<MyModelWithId>
{
new() { Id = 2, Name = "First" }
};

await Assert.That(async () =>
await Assert.That(list).Satisfies(
l => l.First(),
item => item.IsNotNull()
.And.Member(i => i.Id, v => v.EqualTo(1)))
).Throws<AssertionException>().WithMessageMatching("""
*to satisfy*
""");
}

public class MyModelWithId
{
public int Id { get; init; }
public string? Name { get; init; }
}

public class MyModel
{
Expand Down
16 changes: 16 additions & 0 deletions TUnit.Assertions/Conditions/MemberAssertion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ public OrContinuation<TObject> Or
return ExecuteAsync().GetAwaiter();
}

/// <summary>
/// Implicit conversion to Assertion&lt;TObject&gt; to allow Member() to be used as the final statement
/// in contexts that expect an Assertion, such as Satisfies() lambdas.
/// </summary>
public static implicit operator Assertion<TObject>(MemberAssertionResult<TObject> result)
{
return new MemberExecutionWrapper<TObject>(result._parentContext, result._memberAssertion);
}

private async Task<TObject?> ExecuteAsync()
{
// Execute the member assertion
Expand Down Expand Up @@ -88,6 +97,13 @@ public MemberExecutionWrapper(AssertionContext<TObject> parentContext, Assertion
return parentValue;
}

protected override async Task<AssertionResult> CheckAsync(EvaluationMetadata<TObject> metadata)
{
// Execute the member assertion
await _memberAssertion.AssertAsync();
return AssertionResult.Passed;
}

protected override string GetExpectation() => _memberAssertion.InternalGetExpectation();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ namespace .Conditions
public .<TObject> And { get; }
public .<TObject> Or { get; }
public .<TObject?> GetAwaiter() { }
public static .<TObject> op_Implicit(.<TObject> result) { }
}
[.("IsNotEqualTo")]
public class NotEqualsAssertion<TValue> : .<TValue>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ namespace .Conditions
public .<TObject> And { get; }
public .<TObject> Or { get; }
public .<TObject?> GetAwaiter() { }
public static .<TObject> op_Implicit(.<TObject> result) { }
}
[.("IsNotEqualTo")]
public class NotEqualsAssertion<TValue> : .<TValue>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ namespace .Conditions
public .<TObject> And { get; }
public .<TObject> Or { get; }
public .<TObject?> GetAwaiter() { }
public static .<TObject> op_Implicit(.<TObject> result) { }
}
[.("IsNotEqualTo")]
public class NotEqualsAssertion<TValue> : .<TValue>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ namespace .Conditions
public .<TObject> And { get; }
public .<TObject> Or { get; }
public .<TObject?> GetAwaiter() { }
public static .<TObject> op_Implicit(.<TObject> result) { }
}
[.("IsNotEqualTo")]
public class NotEqualsAssertion<TValue> : .<TValue>
Expand Down
Loading