Skip to content

Commit 494cf56

Browse files
xzerorikesyo
authored andcommitted
Adds matchers for Swift 5 Result type
1 parent 39d4d6d commit 494cf56

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

Nimble.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
0477153523B740AD00402D4E /* DispatchTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0477153423B740AD00402D4E /* DispatchTimeInterval.swift */; };
2525
0477153623B740B700402D4E /* DispatchTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0477153423B740AD00402D4E /* DispatchTimeInterval.swift */; };
2626
0477153723B740B800402D4E /* DispatchTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0477153423B740AD00402D4E /* DispatchTimeInterval.swift */; };
27+
106112BD2251DFE7000A5848 /* BeResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112BC2251DFE7000A5848 /* BeResult.swift */; };
28+
106112C02251E0FA000A5848 /* BeResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112BC2251DFE7000A5848 /* BeResult.swift */; };
29+
106112C22251E0FD000A5848 /* BeResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112BC2251DFE7000A5848 /* BeResult.swift */; };
30+
106112C52251E13B000A5848 /* BeResultTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112C42251E13B000A5848 /* BeResultTest.swift */; };
31+
106112C62251E13B000A5848 /* BeResultTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112C42251E13B000A5848 /* BeResultTest.swift */; };
32+
106112C72251E13B000A5848 /* BeResultTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106112C42251E13B000A5848 /* BeResultTest.swift */; };
2733
1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */; };
2834
1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */; };
2935
1F0648D41963AAB2001F9C46 /* SynchronousTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648D31963AAB2001F9C46 /* SynchronousTest.swift */; };
@@ -504,6 +510,8 @@
504510

505511
/* Begin PBXFileReference section */
506512
0477153423B740AD00402D4E /* DispatchTimeInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DispatchTimeInterval.swift; sourceTree = "<group>"; };
513+
106112BC2251DFE7000A5848 /* BeResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeResult.swift; sourceTree = "<group>"; };
514+
106112C42251E13B000A5848 /* BeResultTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeResultTest.swift; sourceTree = "<group>"; };
507515
1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectWithLazyProperty.swift; sourceTree = "<group>"; };
508516
1F0648D31963AAB2001F9C46 /* SynchronousTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousTest.swift; sourceTree = "<group>"; };
509517
1F14FB63194180C5009F2A08 /* utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = utils.swift; sourceTree = "<group>"; };
@@ -830,6 +838,7 @@
830838
1F925F0A195C18E100ED456B /* BeLessThanTest.swift */,
831839
1F925EEE195C136500ED456B /* BeLogicalTest.swift */,
832840
1F925EF8195C175000ED456B /* BeNilTest.swift */,
841+
106112C42251E13B000A5848 /* BeResultTest.swift */,
833842
1F91DD2C1C74BF36002C309F /* BeVoidTest.swift */,
834843
857D184D2536123F00D8693A /* BeWithinTest.swift */,
835844
7B13BA091DD360DE00C9098C /* ContainElementSatisfyingTest.swift */,
@@ -883,6 +892,7 @@
883892
1FD8CD161968AB07008ED995 /* BeLessThanOrEqual.swift */,
884893
1FD8CD171968AB07008ED995 /* BeLogical.swift */,
885894
1FD8CD181968AB07008ED995 /* BeNil.swift */,
895+
106112BC2251DFE7000A5848 /* BeResult.swift */,
886896
1F91DD301C74BF61002C309F /* BeVoid.swift */,
887897
857D1848253610A900D8693A /* BeWithin.swift */,
888898
1FD8CD1A1968AB07008ED995 /* Contain.swift */,
@@ -1341,6 +1351,7 @@
13411351
CDFB6A401F7E082500AD8CC7 /* CwlDarwinDefinitions.swift in Sources */,
13421352
1FD8CD401968AB07008ED995 /* BeCloseTo.swift in Sources */,
13431353
1F1871C81CA89EDB00A34BF2 /* NMBExceptionCapture.m in Sources */,
1354+
106112C02251E0FA000A5848 /* BeResult.swift in Sources */,
13441355
1FD8CD361968AB07008ED995 /* Expectation.swift in Sources */,
13451356
1FD8CD321968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */,
13461357
1F43728F1A1B344000EB80F8 /* Stringers.swift in Sources */,
@@ -1453,6 +1464,7 @@
14531464
1F299EAB19627B2D002641AF /* BeEmptyTest.swift in Sources */,
14541465
7B13BA111DD361EB00C9098C /* ObjCContainElementSatisfyingTest.m in Sources */,
14551466
1F925EF6195C147800ED456B /* BeCloseToTest.swift in Sources */,
1467+
106112C62251E13B000A5848 /* BeResultTest.swift in Sources */,
14561468
1F4A56791A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m in Sources */,
14571469
A8A3B6F6207329DD00E25A08 /* SatisfyAllOfTest.swift in Sources */,
14581470
AE7ADE491C80C00D00B94CD3 /* MatchErrorTest.swift in Sources */,
@@ -1530,6 +1542,7 @@
15301542
1F5DF17A1BDCA0F500C3A531 /* BeEmpty.swift in Sources */,
15311543
1F5DF18C1BDCA0F500C3A531 /* Await.swift in Sources */,
15321544
1F1871D81CA89EEF00A34BF2 /* NMBStringify.m in Sources */,
1545+
106112C22251E0FD000A5848 /* BeResult.swift in Sources */,
15331546
1F5DF1821BDCA0F500C3A531 /* BeNil.swift in Sources */,
15341547
1F5DF16F1BDCA0F500C3A531 /* AssertionDispatcher.swift in Sources */,
15351548
964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */,
@@ -1595,6 +1608,7 @@
15951608
1F5DF1A61BDCA10200C3A531 /* EndWithTest.swift in Sources */,
15961609
CD79C9A31D2CC841004B6F9A /* ObjCBeFalseTest.m in Sources */,
15971610
1F5DF1A71BDCA10200C3A531 /* EqualTest.swift in Sources */,
1611+
106112C72251E13B000A5848 /* BeResultTest.swift in Sources */,
15981612
CD79C9AA1D2CC848004B6F9A /* ObjCBeLessThanOrEqualToTest.m in Sources */,
15991613
1F5DF1931BDCA10200C3A531 /* SynchronousTest.swift in Sources */,
16001614
CD79C9A11D2CC83B004B6F9A /* ObjCBeCloseToTest.m in Sources */,
@@ -1630,6 +1644,7 @@
16301644
CDFB6A3F1F7E082500AD8CC7 /* CwlDarwinDefinitions.swift in Sources */,
16311645
1FD8CD411968AB07008ED995 /* BeCloseTo.swift in Sources */,
16321646
1F1871D31CA89EEE00A34BF2 /* NMBExceptionCapture.m in Sources */,
1647+
106112BD2251DFE7000A5848 /* BeResult.swift in Sources */,
16331648
1FD8CD371968AB07008ED995 /* Expectation.swift in Sources */,
16341649
1FD8CD331968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */,
16351650
1F43728E1A1B343F00EB80F8 /* Stringers.swift in Sources */,
@@ -1751,6 +1766,7 @@
17511766
857D184F2536124400D8693A /* BeWithinTest.swift in Sources */,
17521767
1F925EE7195C121200ED456B /* AsynchronousTest.swift in Sources */,
17531768
1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */,
1769+
106112C52251E13B000A5848 /* BeResultTest.swift in Sources */,
17541770
1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */,
17551771
DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */,
17561772
1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */,

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expect(ocean.isClean).toEventually(beTruthy())
5151
- [Collection Elements](#collection-elements)
5252
- [Collection Count](#collection-count)
5353
- [Notifications](#notifications)
54+
- [Result](#result)
5455
- [Matching a value to any of a group of matchers](#matching-a-value-to-any-of-a-group-of-matchers)
5556
- [Custom Validation](#custom-validation)
5657
- [Writing Your Own Matchers](#writing-your-own-matchers)
@@ -1197,6 +1198,35 @@ expect {
11971198

11981199
> This matcher is only available in Swift.
11991200
1201+
## Result
1202+
1203+
```swift
1204+
// Swift
1205+
let aResult: Result<String, Error> = .success("Hooray")
1206+
1207+
// passes if result is .success
1208+
expect(aResult).to(beSuccess())
1209+
1210+
// passes if result value is .success and validates Success value
1211+
expect(aResult).to(beSuccess { value in
1212+
expect(value).to(equal("Hooray"))
1213+
})
1214+
1215+
1216+
enum AnError: Error {
1217+
case somethingHappened
1218+
}
1219+
let otherResult: Result<String, Error> = .failure(AnError.somethingHappened)
1220+
1221+
// passes if result is .failure
1222+
expect(otherResult).to(beFailure())
1223+
1224+
// passes if result value is .failure and validates error
1225+
expect(otherResult).to(beFailure { error in
1226+
expect(error).to(matchError(AnError.somethingHappened))
1227+
})
1228+
```
1229+
12001230
## Matching a value to any of a group of matchers
12011231

12021232
```swift
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Foundation
2+
3+
///
4+
/// A Nimble matcher for Result that succeeds when the actual value is success
5+
///
6+
/// You can pass a closure to do any arbitrary custom matching
7+
/// to the value inside result. The closure only gets called when result is success.
8+
public func beSuccess<T>(test: ((T) -> Void)? = nil) -> Predicate<Result<T, Error>> {
9+
return Predicate.define("be <success>") { expression, message in
10+
guard case let .success(value)? = try expression.evaluate()
11+
else {
12+
return PredicateResult(status: .doesNotMatch, message: message)
13+
}
14+
test?(value)
15+
return PredicateResult(status: .matches, message: message)
16+
}
17+
}
18+
19+
///
20+
/// A Nimble matcher for Result that succeeds when the actual value is failure
21+
///
22+
/// You can pass a closure to do custom matching for the error inside result.
23+
/// The closure only gets called when result is failure.
24+
public func beFailure<T>(test: ((Error) -> Void)? = nil) -> Predicate<Result<T, Error>> {
25+
return Predicate.define("be <failure>") { expression, message in
26+
guard case let .failure(error)? = try expression.evaluate()
27+
else {
28+
return PredicateResult(status: .doesNotMatch, message: message)
29+
}
30+
test?(error)
31+
return PredicateResult(status: .matches, message: message)
32+
}
33+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import XCTest
2+
import Nimble
3+
4+
private struct StubError: Error, CustomDebugStringConvertible {
5+
let debugDescription = "StubError"
6+
}
7+
8+
final class BeSuccessTest: XCTestCase {
9+
func testPositiveMatch() {
10+
let successfulResult: Result<Int, Error> = .success(1)
11+
expect(successfulResult).to(beSuccess())
12+
}
13+
14+
func testPositiveMatchWithValueTesting() {
15+
let stubValue = 1
16+
let successfulResult: Result<Int, Error> = .success(stubValue)
17+
expect(successfulResult).to(beSuccess { value in
18+
expect(value).to(equal(stubValue))
19+
})
20+
}
21+
22+
func testNegativeMatch() {
23+
let failureResult: Result<Int, Error> = .failure(StubError())
24+
expect(failureResult).toNot(beSuccess())
25+
}
26+
27+
func testExpectationFailureMessage() {
28+
let failureResult: Result<Int, Error> = .failure(StubError())
29+
failsWithErrorMessage("expected to be <success>, got <failure(StubError)>") {
30+
expect(failureResult).to(beSuccess())
31+
}
32+
}
33+
}
34+
35+
final class BeFailureTest: XCTestCase {
36+
func testPositiveMatch() {
37+
let failureResult: Result<Int, Error> = .failure(StubError())
38+
expect(failureResult).to(beFailure())
39+
}
40+
41+
func testPositiveMatchWithValueTesting() {
42+
let failureResult: Result<Int, Error> = .failure(StubError())
43+
expect(failureResult).to(beFailure { value in
44+
expect(value).to(matchError(StubError.self))
45+
})
46+
}
47+
48+
func testNegativeMatch() {
49+
let successfulResult: Result<Int, Error> = .success(1)
50+
expect(successfulResult).toNot(beFailure())
51+
}
52+
53+
func testExpectationFailureMessage() {
54+
let successfulResult: Result<Int, Error> = .success(1)
55+
failsWithErrorMessage("expected to be <failure>, got <success(1)>") {
56+
expect(successfulResult).to(beFailure())
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)