Skip to content

.All().Satisfy() loses specialised assertion source for collection item #5705

@thomhurst

Description

@thomhurst

Related: #5703, #5704 (same pattern — generic source drops specialised type).

Problem

.All().Satisfy(item => ...) and .All().Satisfy(mapper, assert => ...) expose a generic IAssertionSource<TItem> / IAssertionSource<TMapped> inside the lambda. When the item (or mapped value) is itself a string, collection, dictionary, or set, specialised assertions on that element are unreachable.

Repro

// IEnumerable<string>
await Assert.That(items).All().Satisfy(s => s.Contains(\"x\")); // fails: string-specific .Contains not on IAssertionSource<string>

// IEnumerable<List<int>>
await Assert.That(listOfLists).All().Satisfy(l => l.HasCount(3)); // fails

// Mapped to a collection
await Assert.That(models).All().Satisfy(m => m.Tags, tags => tags.Contains(\"x\")); // fails

Affected signatures

TUnit.Assertions/Conditions/CollectionAssertions.cs:

  • :361 Satisfy<TAssertion>(Func<IAssertionSource<TItem>, TAssertion?> assertion, ...)
  • :374 Satisfy<TMapped, TAssertion>(Func<TItem, TMapped> mapper, Func<IAssertionSource<TMapped>, TAssertion?> assertion, ...)

Proposed fix

Add specialised Satisfy overloads keyed on TItem (and TMapped) being string, IEnumerable<>, IDictionary<>, ISet<>, etc., passing the matching specialised source into the lambda. Use OverloadResolutionPriority to steer the compiler (same approach already used for .Member string/collection overloads).

Acceptance

  • .All().Satisfy(item => ...) lambda exposes specialised surface when TItem is string/collection/dict/set.
  • Mapped variant likewise for TMapped.
  • Tests cover each specialised element shape for both variants.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions