Skip to content

Commit

Permalink
Merge pull request #695 from Quick/elementsequal-predicate-closure
Browse files Browse the repository at this point in the history
Add `elementsEqual(_:by:)` matcher using a predicate closure
  • Loading branch information
ikesyo authored Sep 18, 2019
2 parents d9d6799 + 33c9e5c commit ad5e995
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
28 changes: 26 additions & 2 deletions Sources/Nimble/Matchers/ElementsEqual.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/// A Nimble matcher that succeeds when the actual sequence contain the same elements in the same order to the exepected sequence.
/// A Nimble matcher that succeeds when the actual sequence and the exepected sequence contain the same elements in
/// the same order.
///
/// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2854213-elementsequal
public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(_ expectedValue: Seq2?)
-> Predicate<Seq1> where Seq1.Element: Equatable, Seq1.Element == Seq2.Element
{ //swiftlint:disable:this opening_brace
// A matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2949668-elementsequal
return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in
let actualValue = try actualExpression.evaluate()
switch (expectedValue, actualValue) {
Expand All @@ -16,3 +18,25 @@ public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(_ expectedValue: Seq2?
}
}
}

/// A Nimble matcher that succeeds when the actual sequence and the exepected sequence contain equivalent elements in
/// the same order, using the given predicate as the equivalence test.
///
/// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2949668-elementsequal
public func elementsEqual<Seq1: Sequence, Seq2: Sequence>(
_ expectedValue: Seq2?,
by areEquivalent: @escaping (Seq1.Element, Seq2.Element) -> Bool
) -> Predicate<Seq1> {
return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in
let actualValue = try actualExpression.evaluate()
switch (expectedValue, actualValue) {
case (nil, _?):
return PredicateResult(status: .fail, message: msg.appendedBeNilHint())
case (nil, nil), (_, nil):
return PredicateResult(status: .fail, message: msg)
case (let expected?, let actual?):
let matches = actual.elementsEqual(expected, by: areEquivalent)
return PredicateResult(bool: matches, message: msg)
}
}
}
24 changes: 24 additions & 0 deletions Tests/NimbleTests/Matchers/ElementsEqualTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,33 @@ final class ElementsEqualTest: XCTestCase {
expect(sequence1).to(elementsEqual([1, 2, 3]))
}

func testSequenceElementsEqualityUsingPredicateClosure() {
failsWithErrorMessageForNil("expected to elementsEqual <nil>, got <nil>") {
expect(nil as [Int]?).to(elementsEqual(nil as [Int]?, by: { $0 == $1 }))
}
let sequence = [1, 2]
failsWithErrorMessageForNil("expected to elementsEqual <[1, 2]>, got <nil>") {
expect(nil as [Int]?).to(elementsEqual(sequence, by: { $0 == $1 }))
}

failsWithErrorMessageForNil("expected to elementsEqual <nil>, got <[1, 2]>") {
expect(sequence).to(elementsEqual(nil as [Int]?, by: { $0 == $1 }))
}

let sequence1 = [1, 2, 3]
let sequence2 = [1, 2, 3, 4, 5]
expect(sequence1).toNot(elementsEqual(sequence2, by: { $0 == $1 }))
expect(sequence1).toNot(elementsEqual([3, 2, 1], by: { $0 == $1 }))
expect(sequence1).to(elementsEqual([1, 2, 3], by: { $0 == $1 }))
}

func testElementsEqualDifferentSequenceTypes() {
expect(1...3).to(elementsEqual([1, 2, 3]))
expect(1...3).toNot(elementsEqual([1, 2, 3, 4, 5]))
expect(1...3).toNot(elementsEqual([3, 2, 1]))

expect(1...3).to(elementsEqual([1, 2, 3], by: { $0 == $1 }))
expect(1...3).toNot(elementsEqual([1, 2, 3, 4, 5], by: { $0 == $1 }))
expect(1...3).toNot(elementsEqual([3, 2, 1], by: { $0 == $1 }))
}
}
1 change: 1 addition & 0 deletions Tests/NimbleTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ extension ElementsEqualTest {
static let __allTests__ElementsEqualTest = [
("testElementsEqualDifferentSequenceTypes", testElementsEqualDifferentSequenceTypes),
("testSequenceElementsEquality", testSequenceElementsEquality),
("testSequenceElementsEqualityUsingPredicateClosure", testSequenceElementsEqualityUsingPredicateClosure),
]
}

Expand Down

0 comments on commit ad5e995

Please sign in to comment.