Skip to content

Commit

Permalink
Merge pull request #884 from Quick/9.x-tuple-equal
Browse files Browse the repository at this point in the history
[9.x] Add support for tuples of up to 6 elements to `equal` matcher, as with the standard library
  • Loading branch information
ikesyo authored May 9, 2021
2 parents 01e3b79 + 4a36072 commit 7ef3e4e
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 7 deletions.
8 changes: 8 additions & 0 deletions Nimble.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@
CDD80B831F2030790002CD65 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */; };
CDD80B841F20307A0002CD65 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */; };
CDD80B851F20307B0002CD65 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */; };
CDF5C57B2647B89B0036532C /* Equal+Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF5C57A2647B89B0036532C /* Equal+Tuple.swift */; };
CDF5C57C2647B89B0036532C /* Equal+Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF5C57A2647B89B0036532C /* Equal+Tuple.swift */; };
CDF5C57D2647B89B0036532C /* Equal+Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF5C57A2647B89B0036532C /* Equal+Tuple.swift */; };
CDFB6A231F7E07C700AD8CC7 /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFB6A1E1F7E07C600AD8CC7 /* CwlCatchException.swift */; };
CDFB6A241F7E07C700AD8CC7 /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFB6A1E1F7E07C600AD8CC7 /* CwlCatchException.swift */; };
CDFB6A251F7E07C700AD8CC7 /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = CDFB6A201F7E07C600AD8CC7 /* CwlCatchException.m */; };
Expand Down Expand Up @@ -637,6 +640,7 @@
CD4C8F082464365300A7BDE0 /* SynchronousDeprecatedTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousDeprecatedTest.swift; sourceTree = "<group>"; };
CDBC39B82462EA7D00069677 /* PredicateTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PredicateTest.swift; sourceTree = "<group>"; };
CDC157902511957100EAA480 /* DSLTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSLTest.swift; sourceTree = "<group>"; };
CDF5C57A2647B89B0036532C /* Equal+Tuple.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Equal+Tuple.swift"; sourceTree = "<group>"; };
CDFB6A1E1F7E07C600AD8CC7 /* CwlCatchException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CwlCatchException.swift; sourceTree = "<group>"; };
CDFB6A201F7E07C600AD8CC7 /* CwlCatchException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CwlCatchException.m; sourceTree = "<group>"; };
CDFB6A221F7E07C600AD8CC7 /* CwlCatchException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CwlCatchException.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -890,6 +894,7 @@
B20058C020E92C7500C1264D /* ElementsEqual.swift */,
1FD8CD1B1968AB07008ED995 /* EndWith.swift */,
1FD8CD1C1968AB07008ED995 /* Equal.swift */,
CDF5C57A2647B89B0036532C /* Equal+Tuple.swift */,
472FD1341B9E085700C7B8DA /* HaveCount.swift */,
DDB4D5EC19FE43C200E9D9FE /* Match.swift */,
1F1871E51CA89FCD00A34BF2 /* MatcherFunc.swift */,
Expand Down Expand Up @@ -1365,6 +1370,7 @@
29EA59661B551EE6002D767E /* ThrowError.swift in Sources */,
62FB326323B78BF90047BED9 /* BeginWithPrefix.swift in Sources */,
1FD8CD5A1968AB07008ED995 /* Equal.swift in Sources */,
CDF5C57C2647B89B0036532C /* Equal+Tuple.swift in Sources */,
1FD8CD4C1968AB07008ED995 /* BeLessThan.swift in Sources */,
1F1871CC1CA89EDB00A34BF2 /* NMBObjCMatcher.swift in Sources */,
1FD8CD461968AB07008ED995 /* BeGreaterThan.swift in Sources */,
Expand Down Expand Up @@ -1486,6 +1492,7 @@
buildActionMask = 2147483647;
files = (
1F5DF1791BDCA0F500C3A531 /* BeCloseTo.swift in Sources */,
CDF5C57D2647B89B0036532C /* Equal+Tuple.swift in Sources */,
1F5DF16C1BDCA0F500C3A531 /* AssertionRecorder.swift in Sources */,
1F1871D71CA89EEF00A34BF2 /* NMBExceptionCapture.m in Sources */,
1F5DF16E1BDCA0F500C3A531 /* NimbleXCTestHandler.swift in Sources */,
Expand Down Expand Up @@ -1654,6 +1661,7 @@
29EA59671B551EE6002D767E /* ThrowError.swift in Sources */,
62FB326223B78BF90047BED9 /* BeginWithPrefix.swift in Sources */,
1FD8CD5B1968AB07008ED995 /* Equal.swift in Sources */,
CDF5C57B2647B89B0036532C /* Equal+Tuple.swift in Sources */,
1FD8CD4D1968AB07008ED995 /* BeLessThan.swift in Sources */,
1FD8CD471968AB07008ED995 /* BeGreaterThan.swift in Sources */,
F8A1BE301CB3710900031679 /* XCTestObservationCenter+Register.m in Sources */,
Expand Down
127 changes: 127 additions & 0 deletions Sources/Nimble/Matchers/Equal+Tuple.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// swiftlint:disable large_tuple vertical_whitespace

// MARK: Tuple2

/// A Nimble matcher that succeeds when the actual tuple is equal to the expected tuple.
/// Values can support equal by supporting the Equatable protocol.
public func equal<T1: Equatable, T2: Equatable>(
_ expectedValue: (T1, T2)?
) -> Predicate<(T1, T2)> {
equal(expectedValue, by: ==)
}

public func ==<T1: Equatable, T2: Equatable>(
lhs: Expectation<(T1, T2)>,
rhs: (T1, T2)?
) {
lhs.to(equal(rhs))
}

public func !=<T1: Equatable, T2: Equatable>(
lhs: Expectation<(T1, T2)>,
rhs: (T1, T2)?
) {
lhs.toNot(equal(rhs))
}


// MARK: Tuple3

/// A Nimble matcher that succeeds when the actual tuple is equal to the expected tuple.
/// Values can support equal by supporting the Equatable protocol.
public func equal<T1: Equatable, T2: Equatable, T3: Equatable>(
_ expectedValue: (T1, T2, T3)?
) -> Predicate<(T1, T2, T3)> {
equal(expectedValue, by: ==)
}

public func ==<T1: Equatable, T2: Equatable, T3: Equatable>(
lhs: Expectation<(T1, T2, T3)>,
rhs: (T1, T2, T3)?
) {
lhs.to(equal(rhs))
}

public func !=<T1: Equatable, T2: Equatable, T3: Equatable>(
lhs: Expectation<(T1, T2, T3)>,
rhs: (T1, T2, T3)?
) {
lhs.toNot(equal(rhs))
}


// MARK: Tuple4

/// A Nimble matcher that succeeds when the actual tuple is equal to the expected tuple.
/// Values can support equal by supporting the Equatable protocol.
public func equal<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable>(
_ expectedValue: (T1, T2, T3, T4)?
) -> Predicate<(T1, T2, T3, T4)> {
equal(expectedValue, by: ==)
}

public func ==<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable>(
lhs: Expectation<(T1, T2, T3, T4)>,
rhs: (T1, T2, T3, T4)?
) {
lhs.to(equal(rhs))
}

public func !=<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable>(
lhs: Expectation<(T1, T2, T3, T4)>,
rhs: (T1, T2, T3, T4)?
) {
lhs.toNot(equal(rhs))
}


// MARK: Tuple5

/// A Nimble matcher that succeeds when the actual tuple is equal to the expected tuple.
/// Values can support equal by supporting the Equatable protocol.
public func equal<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable>(
_ expectedValue: (T1, T2, T3, T4, T5)?
) -> Predicate<(T1, T2, T3, T4, T5)> {
equal(expectedValue, by: ==)
}

public func ==<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable>(
lhs: Expectation<(T1, T2, T3, T4, T5)>,
rhs: (T1, T2, T3, T4, T5)?
) {
lhs.to(equal(rhs))
}

public func !=<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable>(
lhs: Expectation<(T1, T2, T3, T4, T5)>,
rhs: (T1, T2, T3, T4, T5)?
) {
lhs.toNot(equal(rhs))
}


// MARK: Tuple6

/// A Nimble matcher that succeeds when the actual tuple is equal to the expected tuple.
/// Values can support equal by supporting the Equatable protocol.
public func equal<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable>(
_ expectedValue: (T1, T2, T3, T4, T5, T6)?
) -> Predicate<(T1, T2, T3, T4, T5, T6)> {
equal(expectedValue, by: ==)
}

public func ==<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable>(
lhs: Expectation<(T1, T2, T3, T4, T5, T6)>,
rhs: (T1, T2, T3, T4, T5, T6)?
) {
lhs.to(equal(rhs))
}

public func !=<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable>(
lhs: Expectation<(T1, T2, T3, T4, T5, T6)>,
rhs: (T1, T2, T3, T4, T5, T6)?
) {
lhs.toNot(equal(rhs))
}

// swiftlint:enable large_tuple vertical_whitespace
21 changes: 14 additions & 7 deletions Sources/Nimble/Matchers/Equal.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
/// A Nimble matcher that succeeds when the actual value is equal to the expected value.
/// Values can support equal by supporting the Equatable protocol.
///
/// @see beCloseTo if you want to match imprecise types (eg - floats, doubles).
public func equal<T: Equatable>(_ expectedValue: T?) -> Predicate<T> {
internal func equal<T>(
_ expectedValue: T?,
by areEquivalent: @escaping (T, T) -> Bool
) -> Predicate<T> {
return Predicate.define("equal <\(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):
case (_, nil):
return PredicateResult(status: .fail, message: msg)
case (let expected?, let actual?):
let matches = expected == actual
let matches = areEquivalent(expected, actual)
return PredicateResult(bool: matches, message: msg)
}
}
}

/// A Nimble matcher that succeeds when the actual value is equal to the expected value.
/// Values can support equal by supporting the Equatable protocol.
///
/// @see beCloseTo if you want to match imprecise types (eg - floats, doubles).
public func equal<T: Equatable>(_ expectedValue: T?) -> Predicate<T> {
equal(expectedValue, by: ==)
}

/// A Nimble matcher allowing comparison of collection with optional type
public func equal<T: Equatable>(_ expectedValue: [T?]) -> Predicate<[T?]> {
return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in
Expand Down
8 changes: 8 additions & 0 deletions Tests/NimbleTests/Matchers/EqualTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,12 @@ final class EqualTest: XCTestCase {

expect(result).to(equal(storyCount))
}

func testTuple() {
expect((1, "2")).to(equal((1, "2")))
expect((1, "2", 3)).to(equal((1, "2", 3)))
expect((1, "2", 3, four: "4")).to(equal((1, "2", 3, "4")))
expect((1, "2", 3, four: "4", 5)).to(equal((1, "2", 3, "4", five: 5)))
expect((1, "2", 3, four: "4", 5, "6")).to(equal((1, "2", 3, "4", five: 5, "6")))
}
}

0 comments on commit 7ef3e4e

Please sign in to comment.