Skip to content

Commit ad5e995

Browse files
authored
Merge pull request Quick#695 from Quick/elementsequal-predicate-closure
Add `elementsEqual(_:by:)` matcher using a predicate closure
2 parents d9d6799 + 33c9e5c commit ad5e995

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

Sources/Nimble/Matchers/ElementsEqual.swift

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
/// A Nimble matcher that succeeds when the actual sequence contain the same elements in the same order to the exepected sequence.
1+
/// A Nimble matcher that succeeds when the actual sequence and the exepected sequence contain the same elements in
2+
/// the same order.
3+
///
4+
/// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2854213-elementsequal
25
public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(_ expectedValue: Seq2?)
36
-> Predicate<Seq1> where Seq1.Element: Equatable, Seq1.Element == Seq2.Element
47
{ //swiftlint:disable:this opening_brace
5-
// A matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2949668-elementsequal
68
return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in
79
let actualValue = try actualExpression.evaluate()
810
switch (expectedValue, actualValue) {
@@ -16,3 +18,25 @@ public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(_ expectedValue: Seq2?
1618
}
1719
}
1820
}
21+
22+
/// A Nimble matcher that succeeds when the actual sequence and the exepected sequence contain equivalent elements in
23+
/// the same order, using the given predicate as the equivalence test.
24+
///
25+
/// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2949668-elementsequal
26+
public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(
27+
_ expectedValue: Seq2?,
28+
by areEquivalent: @escaping (Seq1.Element, Seq2.Element) -> Bool
29+
) -> Predicate<Seq1> {
30+
return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in
31+
let actualValue = try actualExpression.evaluate()
32+
switch (expectedValue, actualValue) {
33+
case (nil, _?):
34+
return PredicateResult(status: .fail, message: msg.appendedBeNilHint())
35+
case (nil, nil), (_, nil):
36+
return PredicateResult(status: .fail, message: msg)
37+
case (let expected?, let actual?):
38+
let matches = actual.elementsEqual(expected, by: areEquivalent)
39+
return PredicateResult(bool: matches, message: msg)
40+
}
41+
}
42+
}

Tests/NimbleTests/Matchers/ElementsEqualTest.swift

+24
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,33 @@ final class ElementsEqualTest: XCTestCase {
2424
expect(sequence1).to(elementsEqual([1, 2, 3]))
2525
}
2626

27+
func testSequenceElementsEqualityUsingPredicateClosure() {
28+
failsWithErrorMessageForNil("expected to elementsEqual <nil>, got <nil>") {
29+
expect(nil as [Int]?).to(elementsEqual(nil as [Int]?, by: { $0 == $1 }))
30+
}
31+
let sequence = [1, 2]
32+
failsWithErrorMessageForNil("expected to elementsEqual <[1, 2]>, got <nil>") {
33+
expect(nil as [Int]?).to(elementsEqual(sequence, by: { $0 == $1 }))
34+
}
35+
36+
failsWithErrorMessageForNil("expected to elementsEqual <nil>, got <[1, 2]>") {
37+
expect(sequence).to(elementsEqual(nil as [Int]?, by: { $0 == $1 }))
38+
}
39+
40+
let sequence1 = [1, 2, 3]
41+
let sequence2 = [1, 2, 3, 4, 5]
42+
expect(sequence1).toNot(elementsEqual(sequence2, by: { $0 == $1 }))
43+
expect(sequence1).toNot(elementsEqual([3, 2, 1], by: { $0 == $1 }))
44+
expect(sequence1).to(elementsEqual([1, 2, 3], by: { $0 == $1 }))
45+
}
46+
2747
func testElementsEqualDifferentSequenceTypes() {
2848
expect(1...3).to(elementsEqual([1, 2, 3]))
2949
expect(1...3).toNot(elementsEqual([1, 2, 3, 4, 5]))
3050
expect(1...3).toNot(elementsEqual([3, 2, 1]))
51+
52+
expect(1...3).to(elementsEqual([1, 2, 3], by: { $0 == $1 }))
53+
expect(1...3).toNot(elementsEqual([1, 2, 3, 4, 5], by: { $0 == $1 }))
54+
expect(1...3).toNot(elementsEqual([3, 2, 1], by: { $0 == $1 }))
3155
}
3256
}

Tests/NimbleTests/XCTestManifests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ extension ElementsEqualTest {
283283
static let __allTests__ElementsEqualTest = [
284284
("testElementsEqualDifferentSequenceTypes", testElementsEqualDifferentSequenceTypes),
285285
("testSequenceElementsEquality", testSequenceElementsEquality),
286+
("testSequenceElementsEqualityUsingPredicateClosure", testSequenceElementsEqualityUsingPredicateClosure),
286287
]
287288
}
288289

0 commit comments

Comments
 (0)