11/// `map` works by transforming the expression to a value that the given matcher uses.
22///
33/// For example, you might only care that a particular property on a method equals some other value.
4- /// So, you could write `expect(myObject).to(lens (\.someIntValue, equal(3))`.
4+ /// So, you could write `expect(myObject).to(map (\.someIntValue, equal(3))`.
55/// This is also useful in conjunction with ``satisfyAllOf`` to do a partial equality of an object.
66public func map< T, U> ( _ transform: @escaping ( T ) throws -> U , _ matcher: Matcher < U > ) -> Matcher < T > {
77 Matcher { ( received: Expression < T > ) in
@@ -15,7 +15,7 @@ public func map<T, U>(_ transform: @escaping (T) throws -> U, _ matcher: Matcher
1515/// `map` works by transforming the expression to a value that the given matcher uses.
1616///
1717/// For example, you might only care that a particular property on a method equals some other value.
18- /// So, you could write `expect(myObject).to(lens (\.someIntValue, equal(3))`.
18+ /// So, you could write `expect(myObject).to(map (\.someIntValue, equal(3))`.
1919/// This is also useful in conjunction with ``satisfyAllOf`` to do a partial equality of an object.
2020public func map< T, U> ( _ transform: @escaping ( T ) async throws -> U , _ matcher: some AsyncableMatcher < U > ) -> AsyncMatcher < T > {
2121 AsyncMatcher { ( received: AsyncExpression < T > ) in
@@ -25,3 +25,45 @@ public func map<T, U>(_ transform: @escaping (T) async throws -> U, _ matcher: s
2525 } )
2626 }
2727}
28+
29+ /// `map` works by transforming the expression to a value that the given matcher uses.
30+ ///
31+ /// For example, you might only care that a particular property on a method equals some other value.
32+ /// So, you could write `expect(myObject).to(compactMap({ $0 as? Int }, equal(3))`.
33+ /// This is also useful in conjunction with ``satisfyAllOf`` to match against a converted type.
34+ public func map< T, U> ( _ transform: @escaping ( T ) throws -> U ? , _ matcher: Matcher < U > ) -> Matcher < T > {
35+ Matcher { ( received: Expression < T > ) in
36+ let message = ExpectationMessage . expectedTo ( " Map from \( T . self) to \( U . self) " )
37+
38+ guard let value = try received. evaluate ( ) else {
39+ return MatcherResult ( status: . fail, message: message. appendedBeNilHint ( ) )
40+ }
41+
42+ guard let transformedValue = try transform ( value) else {
43+ return MatcherResult ( status: . fail, message: message)
44+ }
45+
46+ return try matcher. satisfies ( Expression ( expression: { transformedValue } , location: received. location) )
47+ }
48+ }
49+
50+ /// `map` works by transforming the expression to a value that the given matcher uses.
51+ ///
52+ /// For example, you might only care that a particular property on a method equals some other value.
53+ /// So, you could write `expect(myObject).to(compactMap({ $0 as? Int }, equal(3))`.
54+ /// This is also useful in conjunction with ``satisfyAllOf`` to match against a converted type.
55+ public func map< T, U> ( _ transform: @escaping ( T ) async throws -> U ? , _ matcher: some AsyncableMatcher < U > ) -> AsyncMatcher < T > {
56+ AsyncMatcher { ( received: AsyncExpression < T > ) in
57+ let message = ExpectationMessage . expectedTo ( " Map from \( T . self) to \( U . self) " )
58+
59+ guard let value = try await received. evaluate ( ) else {
60+ return MatcherResult ( status: . fail, message: message. appendedBeNilHint ( ) )
61+ }
62+
63+ guard let transformedValue = try await transform ( value) else {
64+ return MatcherResult ( status: . fail, message: message)
65+ }
66+
67+ return try await matcher. satisfies ( AsyncExpression ( expression: { transformedValue } , location: received. location) )
68+ }
69+ }
0 commit comments