tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81414 Definitions

⎇ bce89b1006f36ce35abfaf1f1c2b3dd95f3dffd3 bindings/swift/Example/Pods/Nimble/README.md Markdown · 1749 lines · 52.3 KB History raw

Basic swift / cocoapods project setup 409cdc4cd · Emil Sjölander ·

1# Nimble
2
3[![Build Status](https://travis-ci.org/Quick/Nimble.svg?branch=master)](https://travis-ci.org/Quick/Nimble)
4[![CocoaPods](https://img.shields.io/cocoapods/v/Nimble.svg)](https://cocoapods.org/pods/Nimble)
5[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
6[![Platforms](https://img.shields.io/cocoapods/p/Nimble.svg)](https://cocoapods.org/pods/Nimble)
7[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
8
9Use Nimble to express the expected outcomes of Swift
10or Objective-C expressions. Inspired by
11[Cedar](https://github.com/pivotal/cedar).
12
13```swift
14// Swift
15expect(1 + 1).to(equal(2))
16expect(1.2).to(beCloseTo(1.1, within: 0.1))
17expect(3) > 2
18expect("seahorse").to(contain("sea"))
19expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi"))
20expect(ocean.isClean).toEventually(beTruthy())
21```
22
23# How to Use Nimble
24
25<!-- START doctoc generated TOC please keep comment here to allow auto update -->
26<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
27**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
28
29- [Some Background: Expressing Outcomes Using Assertions in XCTest](#some-background-expressing-outcomes-using-assertions-in-xctest)
30- [Nimble: Expectations Using `expect(...).to`](#nimble-expectations-using-expectto)
31  - [Custom Failure Messages](#custom-failure-messages)
32  - [Type Safety](#type-safety)
33  - [Operator Overloads](#operator-overloads)
34  - [Lazily Computed Values](#lazily-computed-values)
35  - [C Primitives](#c-primitives)
36  - [Asynchronous Expectations](#asynchronous-expectations)
37  - [Objective-C Support](#objective-c-support)
38  - [Disabling Objective-C Shorthand](#disabling-objective-c-shorthand)
39- [Built-in Matcher Functions](#built-in-matcher-functions)
40  - [Type Checking](#type-checking)
41  - [Equivalence](#equivalence)
42  - [Identity](#identity)
43  - [Comparisons](#comparisons)
44  - [Types/Classes](#typesclasses)
45  - [Truthiness](#truthiness)
46  - [Swift Assertions](#swift-assertions)
47  - [Swift Error Handling](#swift-error-handling)
48  - [Exceptions](#exceptions)
49  - [Collection Membership](#collection-membership)
50  - [Strings](#strings)
51  - [Collection Elements](#collection-elements)
52  - [Collection Count](#collection-count)
53  - [Notifications](#notifications)
54  - [Matching a value to any of a group of matchers](#matching-a-value-to-any-of-a-group-of-matchers)
55  - [Custom Validation](#custom-validation)
56- [Writing Your Own Matchers](#writing-your-own-matchers)
57  - [PredicateResult](#predicateresult)
58  - [Lazy Evaluation](#lazy-evaluation)
59  - [Type Checking via Swift Generics](#type-checking-via-swift-generics)
60  - [Customizing Failure Messages](#customizing-failure-messages)
61    - [Basic Customization](#basic-customization)
62    - [Full Customization](#full-customization)
63  - [Supporting Objective-C](#supporting-objective-c)
64    - [Properly Handling `nil` in Objective-C Matchers](#properly-handling-nil-in-objective-c-matchers)
65  - [Migrating from the Old Matcher API](#migrating-from-the-old-matcher-api)
66    - [Minimal Step - Use `.predicate`](#minimal-step---use-predicate)
67    - [Convert to use `Predicate` Type with Old Matcher Constructor](#convert-to-use-predicate-type-with-old-matcher-constructor)
68    - [Convert to `Predicate` Type with Preferred Constructor](#convert-to-predicate-type-with-preferred-constructor)
69    - [Deprecation Roadmap](#deprecation-roadmap)
70- [Installing Nimble](#installing-nimble)
71  - [Installing Nimble as a Submodule](#installing-nimble-as-a-submodule)
72  - [Installing Nimble via CocoaPods](#installing-nimble-via-cocoapods)
73  - [Using Nimble without XCTest](#using-nimble-without-xctest)
74
75<!-- END doctoc generated TOC please keep comment here to allow auto update -->
76
77# Some Background: Expressing Outcomes Using Assertions in XCTest
78
79Apple's Xcode includes the XCTest framework, which provides
80assertion macros to test whether code behaves properly.
81For example, to assert that `1 + 1 = 2`, XCTest has you write:
82
83```swift
84// Swift
85
86XCTAssertEqual(1 + 1, 2, "expected one plus one to equal two")
87```
88
89Or, in Objective-C:
90
91```objc
92// Objective-C
93
94XCTAssertEqual(1 + 1, 2, @"expected one plus one to equal two");
95```
96
97XCTest assertions have a couple of drawbacks:
98
991. **Not enough macros.** There's no easy way to assert that a string
100   contains a particular substring, or that a number is less than or
101   equal to another.
1022. **It's hard to write asynchronous tests.** XCTest forces you to write
103   a lot of boilerplate code.
104
105Nimble addresses these concerns.
106
107# Nimble: Expectations Using `expect(...).to`
108
109Nimble allows you to express expectations using a natural,
110easily understood language:
111
112```swift
113// Swift
114
115import Nimble
116
117expect(seagull.squawk).to(equal("Squee!"))
118```
119
120```objc
121// Objective-C
122
123@import Nimble;
124
125expect(seagull.squawk).to(equal(@"Squee!"));
126```
127
128> The `expect` function autocompletes to include `file:` and `line:`,
129  but these parameters are optional. Use the default values to have
130  Xcode highlight the correct line when an expectation is not met.
131
132To perform the opposite expectation--to assert something is *not*
133equal--use `toNot` or `notTo`:
134
135```swift
136// Swift
137
138import Nimble
139
140expect(seagull.squawk).toNot(equal("Oh, hello there!"))
141expect(seagull.squawk).notTo(equal("Oh, hello there!"))
142```
143
144```objc
145// Objective-C
146
147@import Nimble;
148
149expect(seagull.squawk).toNot(equal(@"Oh, hello there!"));
150expect(seagull.squawk).notTo(equal(@"Oh, hello there!"));
151```
152
153## Custom Failure Messages
154
155Would you like to add more information to the test's failure messages? Use the `description` optional argument to add your own text:
156
157```swift
158// Swift
159
160expect(1 + 1).to(equal(3))
161// failed - expected to equal <3>, got <2>
162
163expect(1 + 1).to(equal(3), description: "Make sure libKindergartenMath is loaded")
164// failed - Make sure libKindergartenMath is loaded
165// expected to equal <3>, got <2>
166```
167
168Or the *WithDescription version in Objective-C:
169
170```objc
171// Objective-C
172
173@import Nimble;
174
175expect(@(1+1)).to(equal(@3));
176// failed - expected to equal <3.0000>, got <2.0000>
177
178expect(@(1+1)).toWithDescription(equal(@3), @"Make sure libKindergartenMath is loaded");
179// failed - Make sure libKindergartenMath is loaded
180// expected to equal <3.0000>, got <2.0000>
181```
182
183## Type Safety
184
185Nimble makes sure you don't compare two types that don't match:
186
187```swift
188// Swift
189
190// Does not compile:
191expect(1 + 1).to(equal("Squee!"))
192```
193
194> Nimble uses generics--only available in Swift--to ensure
195  type correctness. That means type checking is
196  not available when using Nimble in Objective-C. :sob:
197
198## Operator Overloads
199
200Tired of so much typing? With Nimble, you can use overloaded operators
201like `==` for equivalence, or `>` for comparisons:
202
203```swift
204// Swift
205
206// Passes if squawk does not equal "Hi!":
207expect(seagull.squawk) != "Hi!"
208
209// Passes if 10 is greater than 2:
210expect(10) > 2
211```
212
213> Operator overloads are only available in Swift, so you won't be able
214  to use this syntax in Objective-C. :broken_heart:
215
216## Lazily Computed Values
217
218The `expect` function doesn't evaluate the value it's given until it's
219time to match. So Nimble can test whether an expression raises an
220exception once evaluated:
221
222```swift
223// Swift
224
225// Note: Swift currently doesn't have exceptions.
226//       Only Objective-C code can raise exceptions
227//       that Nimble will catch.
228//       (see https://github.com/Quick/Nimble/issues/220#issuecomment-172667064)
229let exception = NSException(
230    name: NSInternalInconsistencyException,
231    reason: "Not enough fish in the sea.",
232    userInfo: ["something": "is fishy"])
233expect { exception.raise() }.to(raiseException())
234
235// Also, you can customize raiseException to be more specific
236expect { exception.raise() }.to(raiseException(named: NSInternalInconsistencyException))
237expect { exception.raise() }.to(raiseException(
238    named: NSInternalInconsistencyException,
239    reason: "Not enough fish in the sea"))
240expect { exception.raise() }.to(raiseException(
241    named: NSInternalInconsistencyException,
242    reason: "Not enough fish in the sea",
243    userInfo: ["something": "is fishy"]))
244```
245
246Objective-C works the same way, but you must use the `expectAction`
247macro when making an expectation on an expression that has no return
248value:
249
250```objc
251// Objective-C
252
253NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
254                                                 reason:@"Not enough fish in the sea."
255                                               userInfo:nil];
256expectAction(^{ [exception raise]; }).to(raiseException());
257
258// Use the property-block syntax to be more specific.
259expectAction(^{ [exception raise]; }).to(raiseException().named(NSInternalInconsistencyException));
260expectAction(^{ [exception raise]; }).to(raiseException().
261    named(NSInternalInconsistencyException).
262    reason("Not enough fish in the sea"));
263expectAction(^{ [exception raise]; }).to(raiseException().
264    named(NSInternalInconsistencyException).
265    reason("Not enough fish in the sea").
266    userInfo(@{@"something": @"is fishy"}));
267
268// You can also pass a block for custom matching of the raised exception
269expectAction(exception.raise()).to(raiseException().satisfyingBlock(^(NSException *exception) {
270    expect(exception.name).to(beginWith(NSInternalInconsistencyException));
271}));
272```
273
274## C Primitives
275
276Some testing frameworks make it hard to test primitive C values.
277In Nimble, it just works:
278
279```swift
280// Swift
281
282let actual: CInt = 1
283let expectedValue: CInt = 1
284expect(actual).to(equal(expectedValue))
285```
286
287In fact, Nimble uses type inference, so you can write the above
288without explicitly specifying both types:
289
290```swift
291// Swift
292
293expect(1 as CInt).to(equal(1))
294```
295
296> In Objective-C, Nimble only supports Objective-C objects. To
297  make expectations on primitive C values, wrap then in an object
298  literal:
299
300```objc
301expect(@(1 + 1)).to(equal(@2));
302```
303
304## Asynchronous Expectations
305
306In Nimble, it's easy to make expectations on values that are updated
307asynchronously. Just use `toEventually` or `toEventuallyNot`:
308
309```swift
310// Swift
311DispatchQueue.main.async {
312    ocean.add("dolphins")
313    ocean.add("whales")
314}
315expect(ocean).toEventually(contain("dolphins", "whales"))
316```
317
318
319```objc
320// Objective-C
321
322dispatch_async(dispatch_get_main_queue(), ^{
323    [ocean add:@"dolphins"];
324    [ocean add:@"whales"];
325});
326expect(ocean).toEventually(contain(@"dolphins", @"whales"));
327```
328
329Note: toEventually triggers its polls on the main thread. Blocking the main
330thread will cause Nimble to stop the run loop. This can cause test pollution
331for whatever incomplete code that was running on the main thread.  Blocking the
332main thread can be caused by blocking IO, calls to sleep(), deadlocks, and
333synchronous IPC.
334
335In the above example, `ocean` is constantly re-evaluated. If it ever
336contains dolphins and whales, the expectation passes. If `ocean` still
337doesn't contain them, even after being continuously re-evaluated for one
338whole second, the expectation fails.
339
340Sometimes it takes more than a second for a value to update. In those
341cases, use the `timeout` parameter:
342
343```swift
344// Swift
345
346// Waits three seconds for ocean to contain "starfish":
347expect(ocean).toEventually(contain("starfish"), timeout: 3)
348
349// Evaluate someValue every 0.2 seconds repeatedly until it equals 100, or fails if it timeouts after 5.5 seconds.
350expect(someValue).toEventually(equal(100), timeout: 5.5, pollInterval: 0.2)
351```
352
353```objc
354// Objective-C
355
356// Waits three seconds for ocean to contain "starfish":
357expect(ocean).withTimeout(3).toEventually(contain(@"starfish"));
358```
359
360You can also provide a callback by using the `waitUntil` function:
361
362```swift
363// Swift
364
365waitUntil { done in
366    ocean.goFish { success in
367        expect(success).to(beTrue())
368        done()
369    }
370}
371```
372
373```objc
374// Objective-C
375
376waitUntil(^(void (^done)(void)){
377    [ocean goFishWithHandler:^(BOOL success){
378        expect(success).to(beTrue());
379        done();
380    }];
381});
382```
383
384`waitUntil` also optionally takes a timeout parameter:
385
386```swift
387// Swift
388
389waitUntil(timeout: 10) { done in
390    ocean.goFish { success in
391        expect(success).to(beTrue())
392        done()
393    }
394}
395```
396
397```objc
398// Objective-C
399
400waitUntilTimeout(10, ^(void (^done)(void)){
401    [ocean goFishWithHandler:^(BOOL success){
402        expect(success).to(beTrue());
403        done();
404    }];
405});
406```
407
408Note: `waitUntil` triggers its timeout code on the main thread. Blocking the main
409thread will cause Nimble to stop the run loop to continue. This can cause test
410pollution for whatever incomplete code that was running on the main thread.
411Blocking the main thread can be caused by blocking IO, calls to sleep(),
412deadlocks, and synchronous IPC.
413
414In some cases (e.g. when running on slower machines) it can be useful to modify
415the default timeout and poll interval values. This can be done as follows:
416
417```swift
418// Swift
419
420// Increase the global timeout to 5 seconds:
421Nimble.AsyncDefaults.Timeout = 5
422
423// Slow the polling interval to 0.1 seconds:
424Nimble.AsyncDefaults.PollInterval = 0.1
425```
426
427## Objective-C Support
428
429Nimble has full support for Objective-C. However, there are two things
430to keep in mind when using Nimble in Objective-C:
431
4321. All parameters passed to the `expect` function, as well as matcher
433   functions like `equal`, must be Objective-C objects or can be converted into
434   an `NSObject` equivalent:
435
436   ```objc
437   // Objective-C
438
439   @import Nimble;
440
441   expect(@(1 + 1)).to(equal(@2));
442   expect(@"Hello world").to(contain(@"world"));
443
444   // Boxed as NSNumber *
445   expect(2).to(equal(2));
446   expect(1.2).to(beLessThan(2.0));
447   expect(true).to(beTruthy());
448
449   // Boxed as NSString *
450   expect("Hello world").to(equal("Hello world"));
451
452   // Boxed as NSRange
453   expect(NSMakeRange(1, 10)).to(equal(NSMakeRange(1, 10)));
454   ```
455
4562. To make an expectation on an expression that does not return a value,
457   such as `-[NSException raise]`, use `expectAction` instead of
458   `expect`:
459
460   ```objc
461   // Objective-C
462
463   expectAction(^{ [exception raise]; }).to(raiseException());
464   ```
465
466The following types are currently converted to an `NSObject` type:
467
468 - **C Numeric types** are converted to `NSNumber *`
469 - `NSRange` is converted to `NSValue *`
470 - `char *` is converted to `NSString *`
471
472For the following matchers:
473
474- `equal`
475- `beGreaterThan`
476- `beGreaterThanOrEqual`
477- `beLessThan`
478- `beLessThanOrEqual`
479- `beCloseTo`
480- `beTrue`
481- `beFalse`
482- `beTruthy`
483- `beFalsy`
484- `haveCount`
485
486If you would like to see more, [file an issue](https://github.com/Quick/Nimble/issues).
487
488## Disabling Objective-C Shorthand
489
490Nimble provides a shorthand for expressing expectations using the
491`expect` function. To disable this shorthand in Objective-C, define the
492`NIMBLE_DISABLE_SHORT_SYNTAX` macro somewhere in your code before
493importing Nimble:
494
495```objc
496#define NIMBLE_DISABLE_SHORT_SYNTAX 1
497
498@import Nimble;
499
500NMB_expect(^{ return seagull.squawk; }, __FILE__, __LINE__).to(NMB_equal(@"Squee!"));
501```
502
503> Disabling the shorthand is useful if you're testing functions with
504  names that conflict with Nimble functions, such as `expect` or
505  `equal`. If that's not the case, there's no point in disabling the
506  shorthand.
507
508# Built-in Matcher Functions
509
510Nimble includes a wide variety of matcher functions.
511
512## Type Checking
513
514Nimble supports checking the type membership of any kind of object, whether
515Objective-C conformant or not:
516
517```swift
518// Swift
519
520protocol SomeProtocol{}
521class SomeClassConformingToProtocol: SomeProtocol{}
522struct SomeStructConformingToProtocol: SomeProtocol{}
523
524// The following tests pass
525expect(1).to(beAKindOf(Int.self))
526expect("turtle").to(beAKindOf(String.self))
527
528let classObject = SomeClassConformingToProtocol()
529expect(classObject).to(beAKindOf(SomeProtocol.self))
530expect(classObject).to(beAKindOf(SomeClassConformingToProtocol.self))
531expect(classObject).toNot(beAKindOf(SomeStructConformingToProtocol.self))
532
533let structObject = SomeStructConformingToProtocol()
534expect(structObject).to(beAKindOf(SomeProtocol.self))
535expect(structObject).to(beAKindOf(SomeStructConformingToProtocol.self))
536expect(structObject).toNot(beAKindOf(SomeClassConformingToProtocol.self))
537```
538
539```objc
540// Objective-C
541
542// The following tests pass
543NSMutableArray *array = [NSMutableArray array];
544expect(array).to(beAKindOf([NSArray class]));
545expect(@1).toNot(beAKindOf([NSNull class]));
546```
547
548Objects can be tested for their exact types using the `beAnInstanceOf` matcher:
549
550```swift
551// Swift
552
553protocol SomeProtocol{}
554class SomeClassConformingToProtocol: SomeProtocol{}
555struct SomeStructConformingToProtocol: SomeProtocol{}
556
557// Unlike the 'beKindOf' matcher, the 'beAnInstanceOf' matcher only
558// passes if the object is the EXACT type requested. The following
559// tests pass -- note its behavior when working in an inheritance hierarchy.
560expect(1).to(beAnInstanceOf(Int.self))
561expect("turtle").to(beAnInstanceOf(String.self))
562
563let classObject = SomeClassConformingToProtocol()
564expect(classObject).toNot(beAnInstanceOf(SomeProtocol.self))
565expect(classObject).to(beAnInstanceOf(SomeClassConformingToProtocol.self))
566expect(classObject).toNot(beAnInstanceOf(SomeStructConformingToProtocol.self))
567
568let structObject = SomeStructConformingToProtocol()
569expect(structObject).toNot(beAnInstanceOf(SomeProtocol.self))
570expect(structObject).to(beAnInstanceOf(SomeStructConformingToProtocol.self))
571expect(structObject).toNot(beAnInstanceOf(SomeClassConformingToProtocol.self))
572```
573
574## Equivalence
575
576```swift
577// Swift
578
579// Passes if 'actual' is equivalent to 'expected':
580expect(actual).to(equal(expected))
581expect(actual) == expected
582
583// Passes if 'actual' is not equivalent to 'expected':
584expect(actual).toNot(equal(expected))
585expect(actual) != expected
586```
587
588```objc
589// Objective-C
590
591// Passes if 'actual' is equivalent to 'expected':
592expect(actual).to(equal(expected))
593
594// Passes if 'actual' is not equivalent to 'expected':
595expect(actual).toNot(equal(expected))
596```
597
598Values must be `Equatable`, `Comparable`, or subclasses of `NSObject`.
599`equal` will always fail when used to compare one or more `nil` values.
600
601## Identity
602
603```swift
604// Swift
605
606// Passes if 'actual' has the same pointer address as 'expected':
607expect(actual).to(beIdenticalTo(expected))
608expect(actual) === expected
609
610// Passes if 'actual' does not have the same pointer address as 'expected':
611expect(actual).toNot(beIdenticalTo(expected))
612expect(actual) !== expected
613```
614
615It is important to remember that `beIdenticalTo` only makes sense when comparing
616types with reference semantics, which have a notion of identity. In Swift, 
617that means types that are defined as a `class`. 
618
619This matcher will not work when comparing types with value semantics such as
620those defined as a `struct` or `enum`. If you need to compare two value types,
621consider what it means for instances of your type to be identical. This may mean
622comparing individual properties or, if it makes sense to do so, conforming your type 
623to `Equatable` and using Nimble's equivalence matchers instead.
624
625
626```objc
627// Objective-C
628
629// Passes if 'actual' has the same pointer address as 'expected':
630expect(actual).to(beIdenticalTo(expected));
631
632// Passes if 'actual' does not have the same pointer address as 'expected':
633expect(actual).toNot(beIdenticalTo(expected));
634```
635
636## Comparisons
637
638```swift
639// Swift
640
641expect(actual).to(beLessThan(expected))
642expect(actual) < expected
643
644expect(actual).to(beLessThanOrEqualTo(expected))
645expect(actual) <= expected
646
647expect(actual).to(beGreaterThan(expected))
648expect(actual) > expected
649
650expect(actual).to(beGreaterThanOrEqualTo(expected))
651expect(actual) >= expected
652```
653
654```objc
655// Objective-C
656
657expect(actual).to(beLessThan(expected));
658expect(actual).to(beLessThanOrEqualTo(expected));
659expect(actual).to(beGreaterThan(expected));
660expect(actual).to(beGreaterThanOrEqualTo(expected));
661```
662
663> Values given to the comparison matchers above must implement
664  `Comparable`.
665
666Because of how computers represent floating point numbers, assertions
667that two floating point numbers be equal will sometimes fail. To express
668that two numbers should be close to one another within a certain margin
669of error, use `beCloseTo`:
670
671```swift
672// Swift
673
674expect(actual).to(beCloseTo(expected, within: delta))
675```
676
677```objc
678// Objective-C
679
680expect(actual).to(beCloseTo(expected).within(delta));
681```
682
683For example, to assert that `10.01` is close to `10`, you can write:
684
685```swift
686// Swift
687
688expect(10.01).to(beCloseTo(10, within: 0.1))
689```
690
691```objc
692// Objective-C
693
694expect(@(10.01)).to(beCloseTo(@10).within(0.1));
695```
696
697There is also an operator shortcut available in Swift:
698
699```swift
700// Swift
701
702expect(actual) ≈ expected
703expect(actual) ≈ (expected, delta)
704
705```
706(Type <kbd>option</kbd>+<kbd>x</kbd> to get `≈` on a U.S. keyboard)
707
708The former version uses the default delta of 0.0001. Here is yet another way to do this:
709
710```swift
711// Swift
712
713expect(actual) ≈ expected ± delta
714expect(actual) == expected ± delta
715
716```
717(Type <kbd>option</kbd>+<kbd>shift</kbd>+<kbd>=</kbd> to get `±` on a U.S. keyboard)
718
719If you are comparing arrays of floating point numbers, you'll find the following useful:
720
721```swift
722// Swift
723
724expect([0.0, 2.0]) ≈ [0.0001, 2.0001]
725expect([0.0, 2.0]).to(beCloseTo([0.1, 2.1], within: 0.1))
726
727```
728
729> Values given to the `beCloseTo` matcher must be coercable into a
730  `Double`.
731
732## Types/Classes
733
734```swift
735// Swift
736
737// Passes if 'instance' is an instance of 'aClass':
738expect(instance).to(beAnInstanceOf(aClass))
739
740// Passes if 'instance' is an instance of 'aClass' or any of its subclasses:
741expect(instance).to(beAKindOf(aClass))
742```
743
744```objc
745// Objective-C
746
747// Passes if 'instance' is an instance of 'aClass':
748expect(instance).to(beAnInstanceOf(aClass));
749
750// Passes if 'instance' is an instance of 'aClass' or any of its subclasses:
751expect(instance).to(beAKindOf(aClass));
752```
753
754> Instances must be Objective-C objects: subclasses of `NSObject`,
755  or Swift objects bridged to Objective-C with the `@objc` prefix.
756
757For example, to assert that `dolphin` is a kind of `Mammal`:
758
759```swift
760// Swift
761
762expect(dolphin).to(beAKindOf(Mammal))
763```
764
765```objc
766// Objective-C
767
768expect(dolphin).to(beAKindOf([Mammal class]));
769```
770
771> `beAnInstanceOf` uses the `-[NSObject isMemberOfClass:]` method to
772  test membership. `beAKindOf` uses `-[NSObject isKindOfClass:]`.
773
774## Truthiness
775
776```swift
777// Passes if 'actual' is not nil, true, or an object with a boolean value of true:
778expect(actual).to(beTruthy())
779
780// Passes if 'actual' is only true (not nil or an object conforming to Boolean true):
781expect(actual).to(beTrue())
782
783// Passes if 'actual' is nil, false, or an object with a boolean value of false:
784expect(actual).to(beFalsy())
785
786// Passes if 'actual' is only false (not nil or an object conforming to Boolean false):
787expect(actual).to(beFalse())
788
789// Passes if 'actual' is nil:
790expect(actual).to(beNil())
791```
792
793```objc
794// Objective-C
795
796// Passes if 'actual' is not nil, true, or an object with a boolean value of true:
797expect(actual).to(beTruthy());
798
799// Passes if 'actual' is only true (not nil or an object conforming to Boolean true):
800expect(actual).to(beTrue());
801
802// Passes if 'actual' is nil, false, or an object with a boolean value of false:
803expect(actual).to(beFalsy());
804
805// Passes if 'actual' is only false (not nil or an object conforming to Boolean false):
806expect(actual).to(beFalse());
807
808// Passes if 'actual' is nil:
809expect(actual).to(beNil());
810```
811
812## Swift Assertions
813
814If you're using Swift, you can use the `throwAssertion` matcher to check if an assertion is thrown (e.g. `fatalError()`). This is made possible by [@mattgallagher](https://github.com/mattgallagher)'s [CwlPreconditionTesting](https://github.com/mattgallagher/CwlPreconditionTesting) library.
815
816```swift
817// Swift
818
819// Passes if 'somethingThatThrows()' throws an assertion, 
820// such as by calling 'fatalError()' or if a precondition fails:
821expect { try somethingThatThrows() }.to(throwAssertion())
822expect { () -> Void in fatalError() }.to(throwAssertion())
823expect { precondition(false) }.to(throwAssertion())
824
825// Passes if throwing an NSError is not equal to throwing an assertion:
826expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion())
827
828// Passes if the code after the precondition check is not run:
829var reachedPoint1 = false
830var reachedPoint2 = false
831expect {
832    reachedPoint1 = true
833    precondition(false, "condition message")
834    reachedPoint2 = true
835}.to(throwAssertion())
836
837expect(reachedPoint1) == true
838expect(reachedPoint2) == false
839```
840
841Notes:
842
843* This feature is only available in Swift.
844* It is only supported for `x86_64` binaries, meaning _you cannot run this matcher on iOS devices, only simulators_.
845* The tvOS simulator is supported, but using a different mechanism, requiring you to turn off the `Debug executable` scheme setting for your tvOS scheme's Test configuration.
846
847## Swift Error Handling
848
849You can use the `throwError` matcher to check if an error is thrown.
850
851```swift
852// Swift
853
854// Passes if 'somethingThatThrows()' throws an 'Error':
855expect { try somethingThatThrows() }.to(throwError())
856
857// Passes if 'somethingThatThrows()' throws an error within a particular domain:
858expect { try somethingThatThrows() }.to(throwError { (error: Error) in
859    expect(error._domain).to(equal(NSCocoaErrorDomain))
860})
861
862// Passes if 'somethingThatThrows()' throws a particular error enum case:
863expect { try somethingThatThrows() }.to(throwError(NSCocoaError.PropertyListReadCorruptError))
864
865// Passes if 'somethingThatThrows()' throws an error of a particular type:
866expect { try somethingThatThrows() }.to(throwError(errorType: NimbleError.self))
867```
868
869When working directly with `Error` values, using the `matchError` matcher
870allows you to perform certain checks on the error itself without having to
871explicitly cast the error.
872
873The `matchError` matcher allows you to check whether or not the error:
874
875- is the same _type_ of error you are expecting.
876- represents a particular error value that you are expecting.
877
878This can be useful when using `Result` or `Promise` types, for example.
879
880```swift
881// Swift
882
883let actual: Error = ...
884
885// Passes if 'actual' represents any error value from the NimbleErrorEnum type:
886expect(actual).to(matchError(NimbleErrorEnum.self))
887
888// Passes if 'actual' represents the case 'timeout' from the NimbleErrorEnum type:
889expect(actual).to(matchError(NimbleErrorEnum.timeout))
890
891// Passes if 'actual' contains an NSError equal to the one provided:
892expect(actual).to(matchError(NSError(domain: "err", code: 123, userInfo: nil)))
893```
894
895Note: This feature is only available in Swift.
896
897## Exceptions
898
899```swift
900// Swift
901
902// Passes if 'actual', when evaluated, raises an exception:
903expect(actual).to(raiseException())
904
905// Passes if 'actual' raises an exception with the given name:
906expect(actual).to(raiseException(named: name))
907
908// Passes if 'actual' raises an exception with the given name and reason:
909expect(actual).to(raiseException(named: name, reason: reason))
910
911// Passes if 'actual' raises an exception which passes expectations defined in the given closure:
912// (in this case, if the exception's name begins with "a r")
913expect { exception.raise() }.to(raiseException { (exception: NSException) in
914    expect(exception.name).to(beginWith("a r"))
915})
916```
917
918```objc
919// Objective-C
920
921// Passes if 'actual', when evaluated, raises an exception:
922expect(actual).to(raiseException())
923
924// Passes if 'actual' raises an exception with the given name
925expect(actual).to(raiseException().named(name))
926
927// Passes if 'actual' raises an exception with the given name and reason:
928expect(actual).to(raiseException().named(name).reason(reason))
929
930// Passes if 'actual' raises an exception and it passes expectations defined in the given block:
931// (in this case, if name begins with "a r")
932expect(actual).to(raiseException().satisfyingBlock(^(NSException *exception) {
933    expect(exception.name).to(beginWith(@"a r"));
934}));
935```
936
937Note: Swift currently doesn't have exceptions (see [#220](https://github.com/Quick/Nimble/issues/220#issuecomment-172667064)). 
938Only Objective-C code can raise exceptions that Nimble will catch.
939
940## Collection Membership
941
942```swift
943// Swift
944
945// Passes if all of the expected values are members of 'actual':
946expect(actual).to(contain(expected...))
947
948// Passes if 'actual' is empty (i.e. it contains no elements):
949expect(actual).to(beEmpty())
950```
951
952```objc
953// Objective-C
954
955// Passes if expected is a member of 'actual':
956expect(actual).to(contain(expected));
957
958// Passes if 'actual' is empty (i.e. it contains no elements):
959expect(actual).to(beEmpty());
960```
961
962> In Swift `contain` takes any number of arguments. The expectation
963  passes if all of them are members of the collection. In Objective-C,
964  `contain` only takes one argument [for now](https://github.com/Quick/Nimble/issues/27).
965
966For example, to assert that a list of sea creature names contains
967"dolphin" and "starfish":
968
969```swift
970// Swift
971
972expect(["whale", "dolphin", "starfish"]).to(contain("dolphin", "starfish"))
973```
974
975```objc
976// Objective-C
977
978expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"dolphin"));
979expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"starfish"));
980```
981
982> `contain` and `beEmpty` expect collections to be instances of
983  `NSArray`, `NSSet`, or a Swift collection composed of `Equatable` elements.
984
985To test whether a set of elements is present at the beginning or end of
986an ordered collection, use `beginWith` and `endWith`:
987
988```swift
989// Swift
990
991// Passes if the elements in expected appear at the beginning of 'actual':
992expect(actual).to(beginWith(expected...))
993
994// Passes if the the elements in expected come at the end of 'actual':
995expect(actual).to(endWith(expected...))
996```
997
998```objc
999// Objective-C
1000
1001// Passes if the elements in expected appear at the beginning of 'actual':
1002expect(actual).to(beginWith(expected));
1003
1004// Passes if the the elements in expected come at the end of 'actual':
1005expect(actual).to(endWith(expected));
1006```
1007
1008> `beginWith` and `endWith` expect collections to be instances of
1009  `NSArray`, or ordered Swift collections composed of `Equatable`
1010  elements.
1011
1012  Like `contain`, in Objective-C `beginWith` and `endWith` only support
1013  a single argument [for now](https://github.com/Quick/Nimble/issues/27).
1014
1015For code that returns collections of complex objects without a strict
1016ordering, there is the `containElementSatisfying` matcher:
1017
1018```swift
1019// Swift
1020
1021struct Turtle {
1022    let color: String
1023}
1024
1025let turtles: [Turtle] = functionThatReturnsSomeTurtlesInAnyOrder()
1026
1027// This set of matchers passes regardless of whether the array is 
1028// [{color: "blue"}, {color: "green"}] or [{color: "green"}, {color: "blue"}]:
1029
1030expect(turtles).to(containElementSatisfying({ turtle in
1031    return turtle.color == "green"
1032}))
1033expect(turtles).to(containElementSatisfying({ turtle in
1034    return turtle.color == "blue"
1035}, "that is a turtle with color 'blue'"))
1036
1037// The second matcher will incorporate the provided string in the error message
1038// should it fail
1039```
1040
1041```objc
1042// Objective-C
1043
1044@interface Turtle : NSObject
1045@property (nonatomic, readonly, nonnull) NSString *color;
1046@end
1047
1048@implementation Turtle 
1049@end
1050
1051NSArray<Turtle *> * __nonnull turtles = functionThatReturnsSomeTurtlesInAnyOrder();
1052
1053// This set of matchers passes regardless of whether the array is 
1054// [{color: "blue"}, {color: "green"}] or [{color: "green"}, {color: "blue"}]:
1055
1056expect(turtles).to(containElementSatisfying(^BOOL(id __nonnull object) {
1057    return [[turtle color] isEqualToString:@"green"];
1058}));
1059expect(turtles).to(containElementSatisfying(^BOOL(id __nonnull object) {
1060    return [[turtle color] isEqualToString:@"blue"];
1061}));
1062```
1063
1064## Strings
1065
1066```swift
1067// Swift
1068
1069// Passes if 'actual' contains 'substring':
1070expect(actual).to(contain(substring))
1071
1072// Passes if 'actual' begins with 'prefix':
1073expect(actual).to(beginWith(prefix))
1074
1075// Passes if 'actual' ends with 'suffix':
1076expect(actual).to(endWith(suffix))
1077
1078// Passes if 'actual' represents the empty string, "":
1079expect(actual).to(beEmpty())
1080
1081// Passes if 'actual' matches the regular expression defined in 'expected':
1082expect(actual).to(match(expected))
1083```
1084
1085```objc
1086// Objective-C
1087
1088// Passes if 'actual' contains 'substring':
1089expect(actual).to(contain(expected));
1090
1091// Passes if 'actual' begins with 'prefix':
1092expect(actual).to(beginWith(prefix));
1093
1094// Passes if 'actual' ends with 'suffix':
1095expect(actual).to(endWith(suffix));
1096
1097// Passes if 'actual' represents the empty string, "":
1098expect(actual).to(beEmpty());
1099
1100// Passes if 'actual' matches the regular expression defined in 'expected':
1101expect(actual).to(match(expected))
1102```
1103
1104## Collection Elements
1105
1106Nimble provides a means to check that all elements of a collection pass a given expectation.
1107
1108### Swift
1109
1110In Swift, the collection must be an instance of a type conforming to
1111`Sequence`.
1112
1113```swift
1114// Swift
1115
1116// Providing a custom function:
1117expect([1, 2, 3, 4]).to(allPass { $0! < 5 })
1118
1119// Composing the expectation with another matcher:
1120expect([1, 2, 3, 4]).to(allPass(beLessThan(5)))
1121```
1122
1123### Objective-C
1124
1125In Objective-C, the collection must be an instance of a type which implements
1126the `NSFastEnumeration` protocol, and whose elements are instances of a type
1127which subclasses `NSObject`.
1128
1129Additionally, unlike in Swift, there is no override to specify a custom
1130matcher function.
1131
1132```objc
1133// Objective-C
1134
1135expect(@[@1, @2, @3, @4]).to(allPass(beLessThan(@5)));
1136```
1137
1138## Collection Count
1139
1140```swift
1141// Swift
1142
1143// Passes if 'actual' contains the 'expected' number of elements:
1144expect(actual).to(haveCount(expected))
1145
1146// Passes if 'actual' does _not_ contain the 'expected' number of elements:
1147expect(actual).notTo(haveCount(expected))
1148```
1149
1150```objc
1151// Objective-C
1152
1153// Passes if 'actual' contains the 'expected' number of elements:
1154expect(actual).to(haveCount(expected))
1155
1156// Passes if 'actual' does _not_ contain the 'expected' number of elements:
1157expect(actual).notTo(haveCount(expected))
1158```
1159
1160For Swift, the actual value must be an instance of a type conforming to `Collection`.
1161For example, instances of `Array`, `Dictionary`, or `Set`.
1162
1163For Objective-C, the actual value must be one of the following classes, or their subclasses:
1164
1165 - `NSArray`,
1166 - `NSDictionary`,
1167 - `NSSet`, or
1168 - `NSHashTable`.
1169
1170## Notifications
1171
1172```swift
1173// Swift
1174let testNotification = Notification(name: "Foo", object: nil)
1175
1176// passes if the closure in expect { ... } posts a notification to the default
1177// notification center.
1178expect {
1179    NotificationCenter.default.postNotification(testNotification)
1180}.to(postNotifications(equal([testNotification]))
1181
1182// passes if the closure in expect { ... } posts a notification to a given
1183// notification center
1184let notificationCenter = NotificationCenter()
1185expect {
1186    notificationCenter.postNotification(testNotification)
1187}.to(postNotifications(equal([testNotification]), fromNotificationCenter: notificationCenter))
1188```
1189
1190> This matcher is only available in Swift.
1191
1192## Matching a value to any of a group of matchers
1193
1194```swift
1195// Swift
1196
1197// passes if actual is either less than 10 or greater than 20
1198expect(actual).to(satisfyAnyOf(beLessThan(10), beGreaterThan(20)))
1199
1200// can include any number of matchers -- the following will pass
1201// **be careful** -- too many matchers can be the sign of an unfocused test
1202expect(6).to(satisfyAnyOf(equal(2), equal(3), equal(4), equal(5), equal(6), equal(7)))
1203
1204// in Swift you also have the option to use the || operator to achieve a similar function
1205expect(82).to(beLessThan(50) || beGreaterThan(80))
1206```
1207
1208```objc
1209// Objective-C
1210
1211// passes if actual is either less than 10 or greater than 20
1212expect(actual).to(satisfyAnyOf(beLessThan(@10), beGreaterThan(@20)))
1213
1214// can include any number of matchers -- the following will pass
1215// **be careful** -- too many matchers can be the sign of an unfocused test
1216expect(@6).to(satisfyAnyOf(equal(@2), equal(@3), equal(@4), equal(@5), equal(@6), equal(@7)))
1217```
1218
1219Note: This matcher allows you to chain any number of matchers together. This provides flexibility,
1220      but if you find yourself chaining many matchers together in one test, consider whether you
1221      could instead refactor that single test into multiple, more precisely focused tests for
1222      better coverage.
1223
1224## Custom Validation
1225
1226```swift
1227// Swift
1228
1229// passes if .succeeded is returned from the closure
1230expect({
1231    guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else {
1232        return .failed(reason: "wrong enum case")
1233    }
1234
1235    return .succeeded
1236}).to(succeed())
1237
1238// passes if .failed is returned from the closure
1239expect({
1240    guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else {
1241        return .failed(reason: "wrong enum case")
1242    }
1243
1244    return .succeeded
1245}).notTo(succeed())
1246```
1247
1248The `String` provided with `.failed()` is shown when the test fails.
1249
1250When using `toEventually()` be careful not to make state changes or run process intensive code since this closure will be ran many times.
1251
1252# Writing Your Own Matchers
1253
1254In Nimble, matchers are Swift functions that take an expected
1255value and return a `Predicate` closure. Take `equal`, for example:
1256
1257```swift
1258// Swift
1259
1260public func equal<T: Equatable>(expectedValue: T?) -> Predicate<T> {
1261    // Can be shortened to:
1262    //   Predicate { actual in  ... }
1263    //
1264    // But shown with types here for clarity.
1265    return Predicate { (actualExpression: Expression<T>) throws -> PredicateResult in
1266        let msg = ExpectationMessage.expectedActualValueTo("equal <\(expectedValue)>")
1267        if let actualValue = try actualExpression.evaluate() {
1268            return PredicateResult(
1269                bool: actualValue == expectedValue!,
1270                message: msg
1271            )
1272        } else {
1273            return PredicateResult(
1274                status: .fail,
1275                message: msg.appendedBeNilHint()
1276            )
1277        }
1278    }
1279}
1280```
1281
1282The return value of a `Predicate` closure is a `PredicateResult` that indicates
1283whether the actual value matches the expectation and what error message to
1284display on failure.
1285
1286> The actual `equal` matcher function does not match when
1287  `expected` are nil; the example above has been edited for brevity.
1288
1289Since matchers are just Swift functions, you can define them anywhere:
1290at the top of your test file, in a file shared by all of your tests, or
1291in an Xcode project you distribute to others.
1292
1293> If you write a matcher you think everyone can use, consider adding it
1294  to Nimble's built-in set of matchers by sending a pull request! Or
1295  distribute it yourself via GitHub.
1296
1297For examples of how to write your own matchers, just check out the
1298[`Matchers` directory](https://github.com/Quick/Nimble/tree/master/Sources/Nimble/Matchers)
1299to see how Nimble's built-in set of matchers are implemented. You can
1300also check out the tips below.
1301
1302## PredicateResult
1303
1304`PredicateResult` is the return struct that `Predicate` return to indicate
1305success and failure. A `PredicateResult` is made up of two values:
1306`PredicateStatus` and `ExpectationMessage`.
1307
1308Instead of a boolean, `PredicateStatus` captures a trinary set of values:
1309
1310```swift
1311// Swift
1312
1313public enum PredicateStatus {
1314// The predicate "passes" with the given expression
1315// eg - expect(1).to(equal(1))
1316case matches
1317
1318// The predicate "fails" with the given expression
1319// eg - expect(1).toNot(equal(1))
1320case doesNotMatch
1321
1322// The predicate never "passes" with the given expression, even if negated
1323// eg - expect(nil as Int?).toNot(equal(1))
1324case fail
1325
1326// ...
1327}
1328```
1329
1330Meanwhile, `ExpectationMessage` provides messaging semantics for error reporting.
1331
1332```swift
1333// Swift
1334
1335public indirect enum ExpectationMessage {
1336// Emits standard error message:
1337// eg - "expected to <string>, got <actual>"
1338case expectedActualValueTo(/* message: */ String)
1339
1340// Allows any free-form message
1341// eg - "<string>"
1342case fail(/* message: */ String)
1343
1344// ...
1345}
1346```
1347
1348Predicates should usually depend on either `.expectedActualValueTo(..)` or
1349`.fail(..)` when reporting errors. Special cases can be used for the other enum
1350cases.
1351
1352Finally, if your Predicate utilizes other Predicates, you can utilize
1353`.appended(details:)` and `.appended(message:)` methods to annotate an existing
1354error with more details.
1355
1356A common message to append is failing on nils. For that, `.appendedBeNilHint()`
1357can be used.
1358
1359## Lazy Evaluation
1360
1361`actualExpression` is a lazy, memoized closure around the value provided to the
1362`expect` function. The expression can either be a closure or a value directly
1363passed to `expect(...)`. In order to determine whether that value matches,
1364custom matchers should call `actualExpression.evaluate()`:
1365
1366```swift
1367// Swift
1368
1369public func beNil<T>() -> Predicate<T> {
1370    // Predicate.simpleNilable(..) automatically generates ExpectationMessage for
1371    // us based on the string we provide to it. Also, the 'Nilable' postfix indicates
1372    // that this Predicate supports matching against nil actualExpressions, instead of
1373    // always resulting in a PredicateStatus.fail result -- which is true for
1374    // Predicate.simple(..)
1375    return Predicate.simpleNilable("be nil") { actualExpression in
1376        let actualValue = try actualExpression.evaluate()
1377        return PredicateStatus(bool: actualValue == nil)
1378    }
1379}
1380```
1381
1382In the above example, `actualExpression` is not `nil` -- it is a closure
1383that returns a value. The value it returns, which is accessed via the
1384`evaluate()` method, may be `nil`. If that value is `nil`, the `beNil`
1385matcher function returns `true`, indicating that the expectation passed.
1386
1387## Type Checking via Swift Generics
1388
1389Using Swift's generics, matchers can constrain the type of the actual value
1390passed to the `expect` function by modifying the return type.
1391
1392For example, the following matcher, `haveDescription`, only accepts actual
1393values that implement the `Printable` protocol. It checks their `description`
1394against the one provided to the matcher function, and passes if they are the same:
1395
1396```swift
1397// Swift
1398
1399public func haveDescription(description: String) -> Predicate<Printable?> {
1400    return Predicate.simple("have description") { actual in
1401        return PredicateStatus(bool: actual.evaluate().description == description)
1402    }
1403}
1404```
1405
1406## Customizing Failure Messages
1407
1408When using `Predicate.simple(..)` or `Predicate.simpleNilable(..)`, Nimble
1409outputs the following failure message when an expectation fails:
1410
1411```swift
1412// where `message` is the first string argument and
1413// `actual` is the actual value received in `expect(..)`
1414"expected to \(message), got <\(actual)>"
1415```
1416
1417You can customize this message by modifying the way you create a `Predicate`.
1418
1419### Basic Customization
1420
1421For slightly more complex error messaging, receive the created failure message
1422with `Predicate.define(..)`:
1423
1424```swift
1425// Swift
1426
1427public func equal<T: Equatable>(_ expectedValue: T?) -> Predicate<T> {
1428    return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in
1429        let actualValue = try actualExpression.evaluate()
1430        let matches = actualValue == expectedValue && expectedValue != nil
1431        if expectedValue == nil || actualValue == nil {
1432            if expectedValue == nil && actualValue != nil {
1433                return PredicateResult(
1434                    status: .fail,
1435                    message: msg.appendedBeNilHint()
1436                )
1437            }
1438            return PredicateResult(status: .fail, message: msg)
1439        }
1440        return PredicateResult(bool: matches, message: msg)
1441    }
1442}
1443```
1444
1445In the example above, `msg` is defined based on the string given to
1446`Predicate.define`. The code looks akin to:
1447
1448```swift
1449// Swift
1450
1451let msg = ExpectationMessage.expectedActualValueTo("equal <\(stringify(expectedValue))>")
1452```
1453
1454### Full Customization
1455
1456To fully customize the behavior of the Predicate, use the overload that expects
1457a `PredicateResult` to be returned.
1458
1459Along with `PredicateResult`, there are other `ExpectationMessage` enum values you can use:
1460
1461```swift
1462public indirect enum ExpectationMessage {
1463// Emits standard error message:
1464// eg - "expected to <message>, got <actual>"
1465case expectedActualValueTo(/* message: */ String)
1466
1467// Allows any free-form message
1468// eg - "<message>"
1469case fail(/* message: */ String)
1470
1471// Emits standard error message with a custom actual value instead of the default.
1472// eg - "expected to <message>, got <actual>"
1473case expectedCustomValueTo(/* message: */ String, /* actual: */ String)
1474
1475// Emits standard error message without mentioning the actual value
1476// eg - "expected to <message>"
1477case expectedTo(/* message: */ String)
1478
1479// ...
1480}
1481```
1482
1483For matchers that compose other matchers, there are a handful of helper
1484functions to annotate messages.
1485
1486`appended(message: String)` is used to append to the original failure message:
1487
1488```swift
1489// produces "expected to be true, got <actual> (use beFalse() for inverse)"
1490// appended message do show up inline in Xcode.
1491.expectedActualValueTo("be true").appended(message: " (use beFalse() for inverse)")
1492```
1493
1494For a more comprehensive message that spans multiple lines, use
1495`appended(details: String)` instead:
1496
1497```swift
1498// produces "expected to be true, got <actual>\n\nuse beFalse() for inverse\nor use beNil()"
1499// details do not show inline in Xcode, but do show up in test logs.
1500.expectedActualValueTo("be true").appended(details: "use beFalse() for inverse\nor use beNil()")
1501```
1502
1503## Supporting Objective-C
1504
1505To use a custom matcher written in Swift from Objective-C, you'll have
1506to extend the `NMBObjCMatcher` class, adding a new class method for your
1507custom matcher. The example below defines the class method
1508`+[NMBObjCMatcher beNilMatcher]`:
1509
1510```swift
1511// Swift
1512
1513extension NMBObjCMatcher {
1514    public class func beNilMatcher() -> NMBObjCMatcher {
1515        return NMBObjCMatcher { actualBlock, failureMessage, location in
1516            let block = ({ actualBlock() as NSObject? })
1517            let expr = Expression(expression: block, location: location)
1518            return beNil().matches(expr, failureMessage: failureMessage)
1519        }
1520    }
1521}
1522```
1523
1524The above allows you to use the matcher from Objective-C:
1525
1526```objc
1527// Objective-C
1528
1529expect(actual).to([NMBObjCMatcher beNilMatcher]());
1530```
1531
1532To make the syntax easier to use, define a C function that calls the
1533class method:
1534
1535```objc
1536// Objective-C
1537
1538FOUNDATION_EXPORT id<NMBMatcher> beNil() {
1539    return [NMBObjCMatcher beNilMatcher];
1540}
1541```
1542
1543### Properly Handling `nil` in Objective-C Matchers
1544
1545When supporting Objective-C, make sure you handle `nil` appropriately.
1546Like [Cedar](https://github.com/pivotal/cedar/issues/100),
1547**most matchers do not match with nil**. This is to bring prevent test
1548writers from being surprised by `nil` values where they did not expect
1549them.
1550
1551Nimble provides the `beNil` matcher function for test writer that want
1552to make expectations on `nil` objects:
1553
1554```objc
1555// Objective-C
1556
1557expect(nil).to(equal(nil)); // fails
1558expect(nil).to(beNil());    // passes
1559```
1560
1561If your matcher does not want to match with nil, you use `NonNilMatcherFunc`
1562and the `canMatchNil` constructor on `NMBObjCMatcher`. Using both types will
1563automatically generate expected value failure messages when they're nil.
1564
1565```swift
1566
1567public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> NonNilMatcherFunc<S> {
1568    return NonNilMatcherFunc { actualExpression, failureMessage in
1569        failureMessage.postfixMessage = "begin with <\(startingElement)>"
1570        if let actualValue = actualExpression.evaluate() {
1571            var actualGenerator = actualValue.makeIterator()
1572            return actualGenerator.next() == startingElement
1573        }
1574        return false
1575    }
1576}
1577
1578extension NMBObjCMatcher {
1579    public class func beginWithMatcher(expected: AnyObject) -> NMBObjCMatcher {
1580        return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in
1581            let actual = actualExpression.evaluate()
1582            let expr = actualExpression.cast { $0 as? NMBOrderedCollection }
1583            return beginWith(expected).matches(expr, failureMessage: failureMessage)
1584        }
1585    }
1586}
1587```
1588
1589## Migrating from the Old Matcher API
1590
1591Previously (`<7.0.0`), Nimble supported matchers via the following types:
1592
1593- `Matcher`
1594- `NonNilMatcherFunc`
1595- `MatcherFunc`
1596
1597All of those types have been replaced by `Predicate`. While migrating can be a
1598lot of work, Nimble currently provides several steps to aid migration of your
1599custom matchers:
1600
1601### Minimal Step - Use `.predicate`
1602
1603Nimble provides an extension to the old types that automatically naively
1604converts those types to the newer `Predicate`.
1605
1606```swift
1607// Swift
1608public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> Predicate<S> {
1609    return NonNilMatcherFunc { actualExpression, failureMessage in
1610        failureMessage.postfixMessage = "begin with <\(startingElement)>"
1611        if let actualValue = actualExpression.evaluate() {
1612            var actualGenerator = actualValue.makeIterator()
1613            return actualGenerator.next() == startingElement
1614        }
1615        return false
1616    }.predicate
1617}
1618```
1619
1620This is the simpliest way to externally support `Predicate` which allows easier
1621composition than the old Nimble matcher interface, with minimal effort to change.
1622
1623### Convert to use `Predicate` Type with Old Matcher Constructor
1624
1625The second most convenient step is to utilize special constructors that
1626`Predicate` supports that closely align to the constructors of the old Nimble
1627matcher types.
1628
1629```swift
1630// Swift
1631public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> Predicate<S> {
1632    return Predicate.fromDeprecatedClosure { actualExpression, failureMessage in
1633        failureMessage.postfixMessage = "begin with <\(startingElement)>"
1634        if let actualValue = actualExpression.evaluate() {
1635            var actualGenerator = actualValue.makeIterator()
1636            return actualGenerator.next() == startingElement
1637        }
1638        return false
1639    }
1640}
1641```
1642
1643This allows you to completely drop the old types from your code, although the
1644intended behavior may alter slightly to what is desired.
1645
1646### Convert to `Predicate` Type with Preferred Constructor
1647
1648Finally, you can convert to the native `Predicate` format using one of the
1649constructors not used to assist in the migration.
1650
1651### Deprecation Roadmap
1652
1653Nimble 7 introduces `Predicate` but will support the old types with warning
1654deprecations. A couple major releases of Nimble will remain backwards
1655compatible with the old matcher api, although new features may not be
1656backported.
1657
1658The deprecating plan is a 3 major versions removal. Which is as follows:
1659
1660 1. Introduce new `Predicate` API, deprecation warning for old matcher APIs.
1661    (Nimble `v7.x.x` and `v8.x.x`)
1662 2. Introduce warnings on migration-path features (`.predicate`,
1663    `Predicate`-constructors with similar arguments to old API). (Nimble
1664    `v9.x.x`)
1665 3. Remove old API. (Nimble `v10.x.x`)
1666
1667
1668# Installing Nimble
1669
1670> Nimble can be used on its own, or in conjunction with its sister
1671  project, [Quick](https://github.com/Quick/Quick). To install both
1672  Quick and Nimble, follow [the installation instructions in the Quick
1673  Documentation](https://github.com/Quick/Quick/blob/master/Documentation/en-us/InstallingQuick.md).
1674
1675Nimble can currently be installed in one of two ways: using CocoaPods, or with
1676git submodules.
1677
1678## Installing Nimble as a Submodule
1679
1680To use Nimble as a submodule to test your macOS, iOS or tvOS applications, follow
1681these 4 easy steps:
1682
16831. Clone the Nimble repository
16842. Add Nimble.xcodeproj to the Xcode workspace for your project
16853. Link Nimble.framework to your test target
16864. Start writing expectations!
1687
1688For more detailed instructions on each of these steps,
1689read [How to Install Quick](https://github.com/Quick/Quick#how-to-install-quick).
1690Ignore the steps involving adding Quick to your project in order to
1691install just Nimble.
1692
1693## Installing Nimble via CocoaPods
1694
1695To use Nimble in CocoaPods to test your macOS, iOS or tvOS applications, add
1696Nimble to your podfile and add the ```use_frameworks!``` line to enable Swift
1697support for CocoaPods.
1698
1699```ruby
1700platform :ios, '8.0'
1701
1702source 'https://github.com/CocoaPods/Specs.git'
1703
1704# Whatever pods you need for your app go here
1705
1706target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do
1707  use_frameworks!
1708  pod 'Nimble', '~> 6.0.0'
1709end
1710```
1711
1712Finally run `pod install`.
1713
1714## Using Nimble without XCTest
1715
1716Nimble is integrated with XCTest to allow it work well when used in Xcode test
1717bundles, however it can also be used in a standalone app. After installing
1718Nimble using one of the above methods, there are two additional steps required
1719to make this work.
1720
17211. Create a custom assertion handler and assign an instance of it to the
1722   global `NimbleAssertionHandler` variable. For example:
1723
1724```swift
1725class MyAssertionHandler : AssertionHandler {
1726    func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) {
1727        if (!assertion) {
1728            print("Expectation failed: \(message.stringValue)")
1729        }
1730    }
1731}
1732```
1733```swift
1734// Somewhere before you use any assertions
1735NimbleAssertionHandler = MyAssertionHandler()
1736```
1737
17382. Add a post-build action to fix an issue with the Swift XCTest support
1739   library being unnecessarily copied into your app
1740  * Edit your scheme in Xcode, and navigate to Build -> Post-actions
1741  * Click the "+" icon and select "New Run Script Action"
1742  * Open the "Provide build settings from" dropdown and select your target
1743  * Enter the following script contents:
1744```
1745rm "${SWIFT_STDLIB_TOOL_DESTINATION_DIR}/libswiftXCTest.dylib"
1746```
1747
1748You can now use Nimble assertions in your code and handle failures as you see
1749fit.

README.md

Nimble

Build Status CocoaPods Carthage Compatible Platforms Reviewed by Hound

Use Nimble to express the expected outcomes of Swift or Objective-C expressions. Inspired by Cedar.

// Swift
expect(1 + 1).to(equal(2))
expect(1.2).to(beCloseTo(1.1, within: 0.1))
expect(3) > 2
expect("seahorse").to(contain("sea"))
expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi"))
expect(ocean.isClean).toEventually(beTruthy())

How to Use Nimble

<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

Table of Contents generated with DocToc

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Some Background: Expressing Outcomes Using Assertions in XCTest

Apple's Xcode includes the XCTest framework, which provides assertion macros to test whether code behaves properly. For example, to assert that 1 + 1 = 2, XCTest has you write:

// Swift

XCTAssertEqual(1 + 1, 2, "expected one plus one to equal two")

Or, in Objective-C:

// Objective-C

XCTAssertEqual(1 + 1, 2, @"expected one plus one to equal two");

XCTest assertions have a couple of drawbacks:

  1. Not enough macros. There's no easy way to assert that a string contains a particular substring, or that a number is less than or equal to another.
  2. It's hard to write asynchronous tests. XCTest forces you to write a lot of boilerplate code.

Nimble addresses these concerns.

Nimble: Expectations Using expect(...).to

Nimble allows you to express expectations using a natural, easily understood language:

// Swift

import Nimble

expect(seagull.squawk).to(equal("Squee!"))
// Objective-C

@import Nimble;

expect(seagull.squawk).to(equal(@"Squee!"));

The expect function autocompletes to include file: and line:, but these parameters are optional. Use the default values to have Xcode highlight the correct line when an expectation is not met.

To perform the opposite expectation--to assert something is not equal--use toNot or notTo:

// Swift

import Nimble

expect(seagull.squawk).toNot(equal("Oh, hello there!"))
expect(seagull.squawk).notTo(equal("Oh, hello there!"))
// Objective-C

@import Nimble;

expect(seagull.squawk).toNot(equal(@"Oh, hello there!"));
expect(seagull.squawk).notTo(equal(@"Oh, hello there!"));

Custom Failure Messages

Would you like to add more information to the test's failure messages? Use the description optional argument to add your own text:

// Swift

expect(1 + 1).to(equal(3))
// failed - expected to equal <3>, got <2>

expect(1 + 1).to(equal(3), description: "Make sure libKindergartenMath is loaded")
// failed - Make sure libKindergartenMath is loaded
// expected to equal <3>, got <2>

Or the *WithDescription version in Objective-C:

// Objective-C

@import Nimble;

expect(@(1+1)).to(equal(@3));
// failed - expected to equal <3.0000>, got <2.0000>

expect(@(1+1)).toWithDescription(equal(@3), @"Make sure libKindergartenMath is loaded");
// failed - Make sure libKindergartenMath is loaded
// expected to equal <3.0000>, got <2.0000>

Type Safety

Nimble makes sure you don't compare two types that don't match:

// Swift

// Does not compile:
expect(1 + 1).to(equal("Squee!"))

Nimble uses generics--only available in Swift--to ensure type correctness. That means type checking is not available when using Nimble in Objective-C. :sob:

Operator Overloads

Tired of so much typing? With Nimble, you can use overloaded operators like == for equivalence, or > for comparisons:

// Swift

// Passes if squawk does not equal "Hi!":
expect(seagull.squawk) != "Hi!"

// Passes if 10 is greater than 2:
expect(10) > 2

Operator overloads are only available in Swift, so you won't be able to use this syntax in Objective-C. :broken_heart:

Lazily Computed Values

The expect function doesn't evaluate the value it's given until it's time to match. So Nimble can test whether an expression raises an exception once evaluated:

// Swift

// Note: Swift currently doesn't have exceptions.
//       Only Objective-C code can raise exceptions
//       that Nimble will catch.
//       (see https://github.com/Quick/Nimble/issues/220#issuecomment-172667064)
let exception = NSException(
    name: NSInternalInconsistencyException,
    reason: "Not enough fish in the sea.",
    userInfo: ["something": "is fishy"])
expect { exception.raise() }.to(raiseException())

// Also, you can customize raiseException to be more specific
expect { exception.raise() }.to(raiseException(named: NSInternalInconsistencyException))
expect { exception.raise() }.to(raiseException(
    named: NSInternalInconsistencyException,
    reason: "Not enough fish in the sea"))
expect { exception.raise() }.to(raiseException(
    named: NSInternalInconsistencyException,
    reason: "Not enough fish in the sea",
    userInfo: ["something": "is fishy"]))

Objective-C works the same way, but you must use the expectAction macro when making an expectation on an expression that has no return value:

// Objective-C

NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
                                                 reason:@"Not enough fish in the sea."
                                               userInfo:nil];
expectAction(^{ [exception raise]; }).to(raiseException());

// Use the property-block syntax to be more specific.
expectAction(^{ [exception raise]; }).to(raiseException().named(NSInternalInconsistencyException));
expectAction(^{ [exception raise]; }).to(raiseException().
    named(NSInternalInconsistencyException).
    reason("Not enough fish in the sea"));
expectAction(^{ [exception raise]; }).to(raiseException().
    named(NSInternalInconsistencyException).
    reason("Not enough fish in the sea").
    userInfo(@{@"something": @"is fishy"}));

// You can also pass a block for custom matching of the raised exception
expectAction(exception.raise()).to(raiseException().satisfyingBlock(^(NSException *exception) {
    expect(exception.name).to(beginWith(NSInternalInconsistencyException));
}));

C Primitives

Some testing frameworks make it hard to test primitive C values. In Nimble, it just works:

// Swift

let actual: CInt = 1
let expectedValue: CInt = 1
expect(actual).to(equal(expectedValue))

In fact, Nimble uses type inference, so you can write the above without explicitly specifying both types:

// Swift

expect(1 as CInt).to(equal(1))

In Objective-C, Nimble only supports Objective-C objects. To make expectations on primitive C values, wrap then in an object literal:

expect(@(1 + 1)).to(equal(@2));

Asynchronous Expectations

In Nimble, it's easy to make expectations on values that are updated asynchronously. Just use toEventually or toEventuallyNot:

// Swift
DispatchQueue.main.async {
    ocean.add("dolphins")
    ocean.add("whales")
}
expect(ocean).toEventually(contain("dolphins", "whales"))
// Objective-C

dispatch_async(dispatch_get_main_queue(), ^{
    [ocean add:@"dolphins"];
    [ocean add:@"whales"];
});
expect(ocean).toEventually(contain(@"dolphins", @"whales"));

Note: toEventually triggers its polls on the main thread. Blocking the main thread will cause Nimble to stop the run loop. This can cause test pollution for whatever incomplete code that was running on the main thread. Blocking the main thread can be caused by blocking IO, calls to sleep(), deadlocks, and synchronous IPC.

In the above example, ocean is constantly re-evaluated. If it ever contains dolphins and whales, the expectation passes. If ocean still doesn't contain them, even after being continuously re-evaluated for one whole second, the expectation fails.

Sometimes it takes more than a second for a value to update. In those cases, use the timeout parameter:

// Swift

// Waits three seconds for ocean to contain "starfish":
expect(ocean).toEventually(contain("starfish"), timeout: 3)

// Evaluate someValue every 0.2 seconds repeatedly until it equals 100, or fails if it timeouts after 5.5 seconds.
expect(someValue).toEventually(equal(100), timeout: 5.5, pollInterval: 0.2)
// Objective-C

// Waits three seconds for ocean to contain "starfish":
expect(ocean).withTimeout(3).toEventually(contain(@"starfish"));

You can also provide a callback by using the waitUntil function:

// Swift

waitUntil { done in
    ocean.goFish { success in
        expect(success).to(beTrue())
        done()
    }
}
// Objective-C

waitUntil(^(void (^done)(void)){
    [ocean goFishWithHandler:^(BOOL success){
        expect(success).to(beTrue());
        done();
    }];
});

waitUntil also optionally takes a timeout parameter:

// Swift

waitUntil(timeout: 10) { done in
    ocean.goFish { success in
        expect(success).to(beTrue())
        done()
    }
}
// Objective-C

waitUntilTimeout(10, ^(void (^done)(void)){
    [ocean goFishWithHandler:^(BOOL success){
        expect(success).to(beTrue());
        done();
    }];
});

Note: waitUntil triggers its timeout code on the main thread. Blocking the main thread will cause Nimble to stop the run loop to continue. This can cause test pollution for whatever incomplete code that was running on the main thread. Blocking the main thread can be caused by blocking IO, calls to sleep(), deadlocks, and synchronous IPC.

In some cases (e.g. when running on slower machines) it can be useful to modify the default timeout and poll interval values. This can be done as follows:

// Swift

// Increase the global timeout to 5 seconds:
Nimble.AsyncDefaults.Timeout = 5

// Slow the polling interval to 0.1 seconds:
Nimble.AsyncDefaults.PollInterval = 0.1

Objective-C Support

Nimble has full support for Objective-C. However, there are two things to keep in mind when using Nimble in Objective-C:

  1. All parameters passed to the expect function, as well as matcher functions like equal, must be Objective-C objects or can be converted into an NSObject equivalent:

    // Objective-C
    
    @import Nimble;
    
    expect(@(1 + 1)).to(equal(@2));
    expect(@"Hello world").to(contain(@"world"));
    
    // Boxed as NSNumber *
    expect(2).to(equal(2));
    expect(1.2).to(beLessThan(2.0));
    expect(true).to(beTruthy());
    
    // Boxed as NSString *
    expect("Hello world").to(equal("Hello world"));
    
    // Boxed as NSRange
    expect(NSMakeRange(1, 10)).to(equal(NSMakeRange(1, 10)));
    
  2. To make an expectation on an expression that does not return a value, such as -[NSException raise], use expectAction instead of expect:

    // Objective-C
    
    expectAction(^{ [exception raise]; }).to(raiseException());
    

The following types are currently converted to an NSObject type:

For the following matchers:

If you would like to see more, file an issue.

Disabling Objective-C Shorthand

Nimble provides a shorthand for expressing expectations using the expect function. To disable this shorthand in Objective-C, define the NIMBLE_DISABLE_SHORT_SYNTAX macro somewhere in your code before importing Nimble:

#define NIMBLE_DISABLE_SHORT_SYNTAX 1

@import Nimble;

NMB_expect(^{ return seagull.squawk; }, __FILE__, __LINE__).to(NMB_equal(@"Squee!"));

Disabling the shorthand is useful if you're testing functions with names that conflict with Nimble functions, such as expect or equal. If that's not the case, there's no point in disabling the shorthand.

Built-in Matcher Functions

Nimble includes a wide variety of matcher functions.

Type Checking

Nimble supports checking the type membership of any kind of object, whether Objective-C conformant or not:

// Swift

protocol SomeProtocol{}
class SomeClassConformingToProtocol: SomeProtocol{}
struct SomeStructConformingToProtocol: SomeProtocol{}

// The following tests pass
expect(1).to(beAKindOf(Int.self))
expect("turtle").to(beAKindOf(String.self))

let classObject = SomeClassConformingToProtocol()
expect(classObject).to(beAKindOf(SomeProtocol.self))
expect(classObject).to(beAKindOf(SomeClassConformingToProtocol.self))
expect(classObject).toNot(beAKindOf(SomeStructConformingToProtocol.self))

let structObject = SomeStructConformingToProtocol()
expect(structObject).to(beAKindOf(SomeProtocol.self))
expect(structObject).to(beAKindOf(SomeStructConformingToProtocol.self))
expect(structObject).toNot(beAKindOf(SomeClassConformingToProtocol.self))
// Objective-C

// The following tests pass
NSMutableArray *array = [NSMutableArray array];
expect(array).to(beAKindOf([NSArray class]));
expect(@1).toNot(beAKindOf([NSNull class]));

Objects can be tested for their exact types using the beAnInstanceOf matcher:

// Swift

protocol SomeProtocol{}
class SomeClassConformingToProtocol: SomeProtocol{}
struct SomeStructConformingToProtocol: SomeProtocol{}

// Unlike the 'beKindOf' matcher, the 'beAnInstanceOf' matcher only
// passes if the object is the EXACT type requested. The following
// tests pass -- note its behavior when working in an inheritance hierarchy.
expect(1).to(beAnInstanceOf(Int.self))
expect("turtle").to(beAnInstanceOf(String.self))

let classObject = SomeClassConformingToProtocol()
expect(classObject).toNot(beAnInstanceOf(SomeProtocol.self))
expect(classObject).to(beAnInstanceOf(SomeClassConformingToProtocol.self))
expect(classObject).toNot(beAnInstanceOf(SomeStructConformingToProtocol.self))

let structObject = SomeStructConformingToProtocol()
expect(structObject).toNot(beAnInstanceOf(SomeProtocol.self))
expect(structObject).to(beAnInstanceOf(SomeStructConformingToProtocol.self))
expect(structObject).toNot(beAnInstanceOf(SomeClassConformingToProtocol.self))

Equivalence

// Swift

// Passes if 'actual' is equivalent to 'expected':
expect(actual).to(equal(expected))
expect(actual) == expected

// Passes if 'actual' is not equivalent to 'expected':
expect(actual).toNot(equal(expected))
expect(actual) != expected
// Objective-C

// Passes if 'actual' is equivalent to 'expected':
expect(actual).to(equal(expected))

// Passes if 'actual' is not equivalent to 'expected':
expect(actual).toNot(equal(expected))

Values must be Equatable, Comparable, or subclasses of NSObject. equal will always fail when used to compare one or more nil values.

Identity

// Swift

// Passes if 'actual' has the same pointer address as 'expected':
expect(actual).to(beIdenticalTo(expected))
expect(actual) === expected

// Passes if 'actual' does not have the same pointer address as 'expected':
expect(actual).toNot(beIdenticalTo(expected))
expect(actual) !== expected

It is important to remember that beIdenticalTo only makes sense when comparing types with reference semantics, which have a notion of identity. In Swift, that means types that are defined as a class.

This matcher will not work when comparing types with value semantics such as those defined as a struct or enum. If you need to compare two value types, consider what it means for instances of your type to be identical. This may mean comparing individual properties or, if it makes sense to do so, conforming your type to Equatable and using Nimble's equivalence matchers instead.

// Objective-C

// Passes if 'actual' has the same pointer address as 'expected':
expect(actual).to(beIdenticalTo(expected));

// Passes if 'actual' does not have the same pointer address as 'expected':
expect(actual).toNot(beIdenticalTo(expected));

Comparisons

// Swift

expect(actual).to(beLessThan(expected))
expect(actual) < expected

expect(actual).to(beLessThanOrEqualTo(expected))
expect(actual) <= expected

expect(actual).to(beGreaterThan(expected))
expect(actual) > expected

expect(actual).to(beGreaterThanOrEqualTo(expected))
expect(actual) >= expected
// Objective-C

expect(actual).to(beLessThan(expected));
expect(actual).to(beLessThanOrEqualTo(expected));
expect(actual).to(beGreaterThan(expected));
expect(actual).to(beGreaterThanOrEqualTo(expected));

Values given to the comparison matchers above must implement Comparable.

Because of how computers represent floating point numbers, assertions that two floating point numbers be equal will sometimes fail. To express that two numbers should be close to one another within a certain margin of error, use beCloseTo:

// Swift

expect(actual).to(beCloseTo(expected, within: delta))
// Objective-C

expect(actual).to(beCloseTo(expected).within(delta));

For example, to assert that 10.01 is close to 10, you can write:

// Swift

expect(10.01).to(beCloseTo(10, within: 0.1))
// Objective-C

expect(@(10.01)).to(beCloseTo(@10).within(0.1));

There is also an operator shortcut available in Swift:

// Swift

expect(actual) ≈ expected
expect(actual) ≈ (expected, delta)

(Type <kbd>option</kbd>+<kbd>x</kbd> to get ≈ on a U.S. keyboard)

The former version uses the default delta of 0.0001. Here is yet another way to do this:

// Swift

expect(actual) ≈ expected ± delta
expect(actual) == expected ± delta

(Type <kbd>option</kbd>+<kbd>shift</kbd>+<kbd>=</kbd> to get ± on a U.S. keyboard)

If you are comparing arrays of floating point numbers, you'll find the following useful:

// Swift

expect([0.0, 2.0]) ≈ [0.0001, 2.0001]
expect([0.0, 2.0]).to(beCloseTo([0.1, 2.1], within: 0.1))

Values given to the beCloseTo matcher must be coercable into a Double.

Types/Classes

// Swift

// Passes if 'instance' is an instance of 'aClass':
expect(instance).to(beAnInstanceOf(aClass))

// Passes if 'instance' is an instance of 'aClass' or any of its subclasses:
expect(instance).to(beAKindOf(aClass))
// Objective-C

// Passes if 'instance' is an instance of 'aClass':
expect(instance).to(beAnInstanceOf(aClass));

// Passes if 'instance' is an instance of 'aClass' or any of its subclasses:
expect(instance).to(beAKindOf(aClass));

Instances must be Objective-C objects: subclasses of NSObject, or Swift objects bridged to Objective-C with the @objc prefix.

For example, to assert that dolphin is a kind of Mammal:

// Swift

expect(dolphin).to(beAKindOf(Mammal))
// Objective-C

expect(dolphin).to(beAKindOf([Mammal class]));

beAnInstanceOf uses the -[NSObject isMemberOfClass:] method to test membership. beAKindOf uses -[NSObject isKindOfClass:].

Truthiness

// Passes if 'actual' is not nil, true, or an object with a boolean value of true:
expect(actual).to(beTruthy())

// Passes if 'actual' is only true (not nil or an object conforming to Boolean true):
expect(actual).to(beTrue())

// Passes if 'actual' is nil, false, or an object with a boolean value of false:
expect(actual).to(beFalsy())

// Passes if 'actual' is only false (not nil or an object conforming to Boolean false):
expect(actual).to(beFalse())

// Passes if 'actual' is nil:
expect(actual).to(beNil())
// Objective-C

// Passes if 'actual' is not nil, true, or an object with a boolean value of true:
expect(actual).to(beTruthy());

// Passes if 'actual' is only true (not nil or an object conforming to Boolean true):
expect(actual).to(beTrue());

// Passes if 'actual' is nil, false, or an object with a boolean value of false:
expect(actual).to(beFalsy());

// Passes if 'actual' is only false (not nil or an object conforming to Boolean false):
expect(actual).to(beFalse());

// Passes if 'actual' is nil:
expect(actual).to(beNil());

Swift Assertions

If you're using Swift, you can use the throwAssertion matcher to check if an assertion is thrown (e.g. fatalError()). This is made possible by @mattgallagher's CwlPreconditionTesting library.

// Swift

// Passes if 'somethingThatThrows()' throws an assertion, 
// such as by calling 'fatalError()' or if a precondition fails:
expect { try somethingThatThrows() }.to(throwAssertion())
expect { () -> Void in fatalError() }.to(throwAssertion())
expect { precondition(false) }.to(throwAssertion())

// Passes if throwing an NSError is not equal to throwing an assertion:
expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion())

// Passes if the code after the precondition check is not run:
var reachedPoint1 = false
var reachedPoint2 = false
expect {
    reachedPoint1 = true
    precondition(false, "condition message")
    reachedPoint2 = true
}.to(throwAssertion())

expect(reachedPoint1) == true
expect(reachedPoint2) == false

Notes:

Swift Error Handling

You can use the throwError matcher to check if an error is thrown.

// Swift

// Passes if 'somethingThatThrows()' throws an 'Error':
expect { try somethingThatThrows() }.to(throwError())

// Passes if 'somethingThatThrows()' throws an error within a particular domain:
expect { try somethingThatThrows() }.to(throwError { (error: Error) in
    expect(error._domain).to(equal(NSCocoaErrorDomain))
})

// Passes if 'somethingThatThrows()' throws a particular error enum case:
expect { try somethingThatThrows() }.to(throwError(NSCocoaError.PropertyListReadCorruptError))

// Passes if 'somethingThatThrows()' throws an error of a particular type:
expect { try somethingThatThrows() }.to(throwError(errorType: NimbleError.self))

When working directly with Error values, using the matchError matcher allows you to perform certain checks on the error itself without having to explicitly cast the error.

The matchError matcher allows you to check whether or not the error:

This can be useful when using Result or Promise types, for example.

// Swift

let actual: Error = ...

// Passes if 'actual' represents any error value from the NimbleErrorEnum type:
expect(actual).to(matchError(NimbleErrorEnum.self))

// Passes if 'actual' represents the case 'timeout' from the NimbleErrorEnum type:
expect(actual).to(matchError(NimbleErrorEnum.timeout))

// Passes if 'actual' contains an NSError equal to the one provided:
expect(actual).to(matchError(NSError(domain: "err", code: 123, userInfo: nil)))

Note: This feature is only available in Swift.

Exceptions

// Swift

// Passes if 'actual', when evaluated, raises an exception:
expect(actual).to(raiseException())

// Passes if 'actual' raises an exception with the given name:
expect(actual).to(raiseException(named: name))

// Passes if 'actual' raises an exception with the given name and reason:
expect(actual).to(raiseException(named: name, reason: reason))

// Passes if 'actual' raises an exception which passes expectations defined in the given closure:
// (in this case, if the exception's name begins with "a r")
expect { exception.raise() }.to(raiseException { (exception: NSException) in
    expect(exception.name).to(beginWith("a r"))
})
// Objective-C

// Passes if 'actual', when evaluated, raises an exception:
expect(actual).to(raiseException())

// Passes if 'actual' raises an exception with the given name
expect(actual).to(raiseException().named(name))

// Passes if 'actual' raises an exception with the given name and reason:
expect(actual).to(raiseException().named(name).reason(reason))

// Passes if 'actual' raises an exception and it passes expectations defined in the given block:
// (in this case, if name begins with "a r")
expect(actual).to(raiseException().satisfyingBlock(^(NSException *exception) {
    expect(exception.name).to(beginWith(@"a r"));
}));

Note: Swift currently doesn't have exceptions (see #220). Only Objective-C code can raise exceptions that Nimble will catch.

Collection Membership

// Swift

// Passes if all of the expected values are members of 'actual':
expect(actual).to(contain(expected...))

// Passes if 'actual' is empty (i.e. it contains no elements):
expect(actual).to(beEmpty())
// Objective-C

// Passes if expected is a member of 'actual':
expect(actual).to(contain(expected));

// Passes if 'actual' is empty (i.e. it contains no elements):
expect(actual).to(beEmpty());

In Swift contain takes any number of arguments. The expectation passes if all of them are members of the collection. In Objective-C, contain only takes one argument for now.

For example, to assert that a list of sea creature names contains "dolphin" and "starfish":

// Swift

expect(["whale", "dolphin", "starfish"]).to(contain("dolphin", "starfish"))
// Objective-C

expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"dolphin"));
expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"starfish"));

contain and beEmpty expect collections to be instances of NSArray, NSSet, or a Swift collection composed of Equatable elements.

To test whether a set of elements is present at the beginning or end of an ordered collection, use beginWith and endWith:

// Swift

// Passes if the elements in expected appear at the beginning of 'actual':
expect(actual).to(beginWith(expected...))

// Passes if the the elements in expected come at the end of 'actual':
expect(actual).to(endWith(expected...))
// Objective-C

// Passes if the elements in expected appear at the beginning of 'actual':
expect(actual).to(beginWith(expected));

// Passes if the the elements in expected come at the end of 'actual':
expect(actual).to(endWith(expected));

beginWith and endWith expect collections to be instances of NSArray, or ordered Swift collections composed of Equatable elements.

Like contain, in Objective-C beginWith and endWith only support a single argument for now.

For code that returns collections of complex objects without a strict ordering, there is the containElementSatisfying matcher:

// Swift

struct Turtle {
    let color: String
}

let turtles: [Turtle] = functionThatReturnsSomeTurtlesInAnyOrder()

// This set of matchers passes regardless of whether the array is 
// [{color: "blue"}, {color: "green"}] or [{color: "green"}, {color: "blue"}]:

expect(turtles).to(containElementSatisfying({ turtle in
    return turtle.color == "green"
}))
expect(turtles).to(containElementSatisfying({ turtle in
    return turtle.color == "blue"
}, "that is a turtle with color 'blue'"))

// The second matcher will incorporate the provided string in the error message
// should it fail
// Objective-C

@interface Turtle : NSObject
@property (nonatomic, readonly, nonnull) NSString *color;
@end

@implementation Turtle 
@end

NSArray<Turtle *> * __nonnull turtles = functionThatReturnsSomeTurtlesInAnyOrder();

// This set of matchers passes regardless of whether the array is 
// [{color: "blue"}, {color: "green"}] or [{color: "green"}, {color: "blue"}]:

expect(turtles).to(containElementSatisfying(^BOOL(id __nonnull object) {
    return [[turtle color] isEqualToString:@"green"];
}));
expect(turtles).to(containElementSatisfying(^BOOL(id __nonnull object) {
    return [[turtle color] isEqualToString:@"blue"];
}));

Strings

// Swift

// Passes if 'actual' contains 'substring':
expect(actual).to(contain(substring))

// Passes if 'actual' begins with 'prefix':
expect(actual).to(beginWith(prefix))

// Passes if 'actual' ends with 'suffix':
expect(actual).to(endWith(suffix))

// Passes if 'actual' represents the empty string, "":
expect(actual).to(beEmpty())

// Passes if 'actual' matches the regular expression defined in 'expected':
expect(actual).to(match(expected))
// Objective-C

// Passes if 'actual' contains 'substring':
expect(actual).to(contain(expected));

// Passes if 'actual' begins with 'prefix':
expect(actual).to(beginWith(prefix));

// Passes if 'actual' ends with 'suffix':
expect(actual).to(endWith(suffix));

// Passes if 'actual' represents the empty string, "":
expect(actual).to(beEmpty());

// Passes if 'actual' matches the regular expression defined in 'expected':
expect(actual).to(match(expected))

Collection Elements

Nimble provides a means to check that all elements of a collection pass a given expectation.

Swift

In Swift, the collection must be an instance of a type conforming to Sequence.

// Swift

// Providing a custom function:
expect([1, 2, 3, 4]).to(allPass { $0! < 5 })

// Composing the expectation with another matcher:
expect([1, 2, 3, 4]).to(allPass(beLessThan(5)))

Objective-C

In Objective-C, the collection must be an instance of a type which implements the NSFastEnumeration protocol, and whose elements are instances of a type which subclasses NSObject.

Additionally, unlike in Swift, there is no override to specify a custom matcher function.

// Objective-C

expect(@[@1, @2, @3, @4]).to(allPass(beLessThan(@5)));

Collection Count

// Swift

// Passes if 'actual' contains the 'expected' number of elements:
expect(actual).to(haveCount(expected))

// Passes if 'actual' does _not_ contain the 'expected' number of elements:
expect(actual).notTo(haveCount(expected))
// Objective-C

// Passes if 'actual' contains the 'expected' number of elements:
expect(actual).to(haveCount(expected))

// Passes if 'actual' does _not_ contain the 'expected' number of elements:
expect(actual).notTo(haveCount(expected))

For Swift, the actual value must be an instance of a type conforming to Collection. For example, instances of Array, Dictionary, or Set.

For Objective-C, the actual value must be one of the following classes, or their subclasses:

Notifications

// Swift
let testNotification = Notification(name: "Foo", object: nil)

// passes if the closure in expect { ... } posts a notification to the default
// notification center.
expect {
    NotificationCenter.default.postNotification(testNotification)
}.to(postNotifications(equal([testNotification]))

// passes if the closure in expect { ... } posts a notification to a given
// notification center
let notificationCenter = NotificationCenter()
expect {
    notificationCenter.postNotification(testNotification)
}.to(postNotifications(equal([testNotification]), fromNotificationCenter: notificationCenter))

This matcher is only available in Swift.

Matching a value to any of a group of matchers

// Swift

// passes if actual is either less than 10 or greater than 20
expect(actual).to(satisfyAnyOf(beLessThan(10), beGreaterThan(20)))

// can include any number of matchers -- the following will pass
// **be careful** -- too many matchers can be the sign of an unfocused test
expect(6).to(satisfyAnyOf(equal(2), equal(3), equal(4), equal(5), equal(6), equal(7)))

// in Swift you also have the option to use the || operator to achieve a similar function
expect(82).to(beLessThan(50) || beGreaterThan(80))
// Objective-C

// passes if actual is either less than 10 or greater than 20
expect(actual).to(satisfyAnyOf(beLessThan(@10), beGreaterThan(@20)))

// can include any number of matchers -- the following will pass
// **be careful** -- too many matchers can be the sign of an unfocused test
expect(@6).to(satisfyAnyOf(equal(@2), equal(@3), equal(@4), equal(@5), equal(@6), equal(@7)))

Note: This matcher allows you to chain any number of matchers together. This provides flexibility, but if you find yourself chaining many matchers together in one test, consider whether you could instead refactor that single test into multiple, more precisely focused tests for better coverage.

Custom Validation

// Swift

// passes if .succeeded is returned from the closure
expect({
    guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else {
        return .failed(reason: "wrong enum case")
    }

    return .succeeded
}).to(succeed())

// passes if .failed is returned from the closure
expect({
    guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else {
        return .failed(reason: "wrong enum case")
    }

    return .succeeded
}).notTo(succeed())

The String provided with .failed() is shown when the test fails.

When using toEventually() be careful not to make state changes or run process intensive code since this closure will be ran many times.

Writing Your Own Matchers

In Nimble, matchers are Swift functions that take an expected value and return a Predicate closure. Take equal, for example:

// Swift

public func equal<T: Equatable>(expectedValue: T?) -> Predicate<T> {
    // Can be shortened to:
    //   Predicate { actual in  ... }
    //
    // But shown with types here for clarity.
    return Predicate { (actualExpression: Expression<T>) throws -> PredicateResult in
        let msg = ExpectationMessage.expectedActualValueTo("equal <\(expectedValue)>")
        if let actualValue = try actualExpression.evaluate() {
            return PredicateResult(
                bool: actualValue == expectedValue!,
                message: msg
            )
        } else {
            return PredicateResult(
                status: .fail,
                message: msg.appendedBeNilHint()
            )
        }
    }
}

The return value of a Predicate closure is a PredicateResult that indicates whether the actual value matches the expectation and what error message to display on failure.

The actual equal matcher function does not match when expected are nil; the example above has been edited for brevity.

Since matchers are just Swift functions, you can define them anywhere: at the top of your test file, in a file shared by all of your tests, or in an Xcode project you distribute to others.

If you write a matcher you think everyone can use, consider adding it to Nimble's built-in set of matchers by sending a pull request! Or distribute it yourself via GitHub.

For examples of how to write your own matchers, just check out the Matchers directory to see how Nimble's built-in set of matchers are implemented. You can also check out the tips below.

PredicateResult

PredicateResult is the return struct that Predicate return to indicate success and failure. A PredicateResult is made up of two values: PredicateStatus and ExpectationMessage.

Instead of a boolean, PredicateStatus captures a trinary set of values:

// Swift

public enum PredicateStatus {
// The predicate "passes" with the given expression
// eg - expect(1).to(equal(1))
case matches

// The predicate "fails" with the given expression
// eg - expect(1).toNot(equal(1))
case doesNotMatch

// The predicate never "passes" with the given expression, even if negated
// eg - expect(nil as Int?).toNot(equal(1))
case fail

// ...
}

Meanwhile, ExpectationMessage provides messaging semantics for error reporting.

// Swift

public indirect enum ExpectationMessage {
// Emits standard error message:
// eg - "expected to <string>, got <actual>"
case expectedActualValueTo(/* message: */ String)

// Allows any free-form message
// eg - "<string>"
case fail(/* message: */ String)

// ...
}

Predicates should usually depend on either .expectedActualValueTo(..) or .fail(..) when reporting errors. Special cases can be used for the other enum cases.

Finally, if your Predicate utilizes other Predicates, you can utilize .appended(details:) and .appended(message:) methods to annotate an existing error with more details.

A common message to append is failing on nils. For that, .appendedBeNilHint() can be used.

Lazy Evaluation

actualExpression is a lazy, memoized closure around the value provided to the expect function. The expression can either be a closure or a value directly passed to expect(...). In order to determine whether that value matches, custom matchers should call actualExpression.evaluate():

// Swift

public func beNil<T>() -> Predicate<T> {
    // Predicate.simpleNilable(..) automatically generates ExpectationMessage for
    // us based on the string we provide to it. Also, the 'Nilable' postfix indicates
    // that this Predicate supports matching against nil actualExpressions, instead of
    // always resulting in a PredicateStatus.fail result -- which is true for
    // Predicate.simple(..)
    return Predicate.simpleNilable("be nil") { actualExpression in
        let actualValue = try actualExpression.evaluate()
        return PredicateStatus(bool: actualValue == nil)
    }
}

In the above example, actualExpression is not nil -- it is a closure that returns a value. The value it returns, which is accessed via the evaluate() method, may be nil. If that value is nil, the beNil matcher function returns true, indicating that the expectation passed.

Type Checking via Swift Generics

Using Swift's generics, matchers can constrain the type of the actual value passed to the expect function by modifying the return type.

For example, the following matcher, haveDescription, only accepts actual values that implement the Printable protocol. It checks their description against the one provided to the matcher function, and passes if they are the same:

// Swift

public func haveDescription(description: String) -> Predicate<Printable?> {
    return Predicate.simple("have description") { actual in
        return PredicateStatus(bool: actual.evaluate().description == description)
    }
}

Customizing Failure Messages

When using Predicate.simple(..) or Predicate.simpleNilable(..), Nimble outputs the following failure message when an expectation fails:

// where `message` is the first string argument and
// `actual` is the actual value received in `expect(..)`
"expected to \(message), got <\(actual)>"

You can customize this message by modifying the way you create a Predicate.

Basic Customization

For slightly more complex error messaging, receive the created failure message with Predicate.define(..):

// Swift

public func equal<T: Equatable>(_ expectedValue: T?) -> Predicate<T> {
    return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in
        let actualValue = try actualExpression.evaluate()
        let matches = actualValue == expectedValue && expectedValue != nil
        if expectedValue == nil || actualValue == nil {
            if expectedValue == nil && actualValue != nil {
                return PredicateResult(
                    status: .fail,
                    message: msg.appendedBeNilHint()
                )
            }
            return PredicateResult(status: .fail, message: msg)
        }
        return PredicateResult(bool: matches, message: msg)
    }
}

In the example above, msg is defined based on the string given to Predicate.define. The code looks akin to:

// Swift

let msg = ExpectationMessage.expectedActualValueTo("equal <\(stringify(expectedValue))>")

Full Customization

To fully customize the behavior of the Predicate, use the overload that expects a PredicateResult to be returned.

Along with PredicateResult, there are other ExpectationMessage enum values you can use:

public indirect enum ExpectationMessage {
// Emits standard error message:
// eg - "expected to <message>, got <actual>"
case expectedActualValueTo(/* message: */ String)

// Allows any free-form message
// eg - "<message>"
case fail(/* message: */ String)

// Emits standard error message with a custom actual value instead of the default.
// eg - "expected to <message>, got <actual>"
case expectedCustomValueTo(/* message: */ String, /* actual: */ String)

// Emits standard error message without mentioning the actual value
// eg - "expected to <message>"
case expectedTo(/* message: */ String)

// ...
}

For matchers that compose other matchers, there are a handful of helper functions to annotate messages.

appended(message: String) is used to append to the original failure message:

// produces "expected to be true, got <actual> (use beFalse() for inverse)"
// appended message do show up inline in Xcode.
.expectedActualValueTo("be true").appended(message: " (use beFalse() for inverse)")

For a more comprehensive message that spans multiple lines, use appended(details: String) instead:

// produces "expected to be true, got <actual>\n\nuse beFalse() for inverse\nor use beNil()"
// details do not show inline in Xcode, but do show up in test logs.
.expectedActualValueTo("be true").appended(details: "use beFalse() for inverse\nor use beNil()")

Supporting Objective-C

To use a custom matcher written in Swift from Objective-C, you'll have to extend the NMBObjCMatcher class, adding a new class method for your custom matcher. The example below defines the class method +[NMBObjCMatcher beNilMatcher]:

// Swift

extension NMBObjCMatcher {
    public class func beNilMatcher() -> NMBObjCMatcher {
        return NMBObjCMatcher { actualBlock, failureMessage, location in
            let block = ({ actualBlock() as NSObject? })
            let expr = Expression(expression: block, location: location)
            return beNil().matches(expr, failureMessage: failureMessage)
        }
    }
}

The above allows you to use the matcher from Objective-C:

// Objective-C

expect(actual).to([NMBObjCMatcher beNilMatcher]());

To make the syntax easier to use, define a C function that calls the class method:

// Objective-C

FOUNDATION_EXPORT id<NMBMatcher> beNil() {
    return [NMBObjCMatcher beNilMatcher];
}

Properly Handling nil in Objective-C Matchers

When supporting Objective-C, make sure you handle nil appropriately. Like Cedar, most matchers do not match with nil. This is to bring prevent test writers from being surprised by nil values where they did not expect them.

Nimble provides the beNil matcher function for test writer that want to make expectations on nil objects:

// Objective-C

expect(nil).to(equal(nil)); // fails
expect(nil).to(beNil());    // passes

If your matcher does not want to match with nil, you use NonNilMatcherFunc and the canMatchNil constructor on NMBObjCMatcher. Using both types will automatically generate expected value failure messages when they're nil.


public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> NonNilMatcherFunc<S> {
    return NonNilMatcherFunc { actualExpression, failureMessage in
        failureMessage.postfixMessage = "begin with <\(startingElement)>"
        if let actualValue = actualExpression.evaluate() {
            var actualGenerator = actualValue.makeIterator()
            return actualGenerator.next() == startingElement
        }
        return false
    }
}

extension NMBObjCMatcher {
    public class func beginWithMatcher(expected: AnyObject) -> NMBObjCMatcher {
        return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in
            let actual = actualExpression.evaluate()
            let expr = actualExpression.cast { $0 as? NMBOrderedCollection }
            return beginWith(expected).matches(expr, failureMessage: failureMessage)
        }
    }
}

Migrating from the Old Matcher API

Previously (<7.0.0), Nimble supported matchers via the following types:

All of those types have been replaced by Predicate. While migrating can be a lot of work, Nimble currently provides several steps to aid migration of your custom matchers:

Minimal Step - Use .predicate

Nimble provides an extension to the old types that automatically naively converts those types to the newer Predicate.

// Swift
public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> Predicate<S> {
    return NonNilMatcherFunc { actualExpression, failureMessage in
        failureMessage.postfixMessage = "begin with <\(startingElement)>"
        if let actualValue = actualExpression.evaluate() {
            var actualGenerator = actualValue.makeIterator()
            return actualGenerator.next() == startingElement
        }
        return false
    }.predicate
}

This is the simpliest way to externally support Predicate which allows easier composition than the old Nimble matcher interface, with minimal effort to change.

Convert to use Predicate Type with Old Matcher Constructor

The second most convenient step is to utilize special constructors that Predicate supports that closely align to the constructors of the old Nimble matcher types.

// Swift
public func beginWith<S: Sequence, T: Equatable where S.Iterator.Element == T>(startingElement: T) -> Predicate<S> {
    return Predicate.fromDeprecatedClosure { actualExpression, failureMessage in
        failureMessage.postfixMessage = "begin with <\(startingElement)>"
        if let actualValue = actualExpression.evaluate() {
            var actualGenerator = actualValue.makeIterator()
            return actualGenerator.next() == startingElement
        }
        return false
    }
}

This allows you to completely drop the old types from your code, although the intended behavior may alter slightly to what is desired.

Convert to Predicate Type with Preferred Constructor

Finally, you can convert to the native Predicate format using one of the constructors not used to assist in the migration.

Deprecation Roadmap

Nimble 7 introduces Predicate but will support the old types with warning deprecations. A couple major releases of Nimble will remain backwards compatible with the old matcher api, although new features may not be backported.

The deprecating plan is a 3 major versions removal. Which is as follows:

  1. Introduce new Predicate API, deprecation warning for old matcher APIs. (Nimble v7.x.x and v8.x.x)
  2. Introduce warnings on migration-path features (.predicate, Predicate-constructors with similar arguments to old API). (Nimble v9.x.x)
  3. Remove old API. (Nimble v10.x.x)

Installing Nimble

Nimble can be used on its own, or in conjunction with its sister project, Quick. To install both Quick and Nimble, follow the installation instructions in the Quick Documentation.

Nimble can currently be installed in one of two ways: using CocoaPods, or with git submodules.

Installing Nimble as a Submodule

To use Nimble as a submodule to test your macOS, iOS or tvOS applications, follow these 4 easy steps:

  1. Clone the Nimble repository
  2. Add Nimble.xcodeproj to the Xcode workspace for your project
  3. Link Nimble.framework to your test target
  4. Start writing expectations!

For more detailed instructions on each of these steps, read How to Install Quick. Ignore the steps involving adding Quick to your project in order to install just Nimble.

Installing Nimble via CocoaPods

To use Nimble in CocoaPods to test your macOS, iOS or tvOS applications, add Nimble to your podfile and add the use_frameworks! line to enable Swift support for CocoaPods.

platform :ios, '8.0'

source 'https://github.com/CocoaPods/Specs.git'

# Whatever pods you need for your app go here

target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do
  use_frameworks!
  pod 'Nimble', '~> 6.0.0'
end

Finally run pod install.

Using Nimble without XCTest

Nimble is integrated with XCTest to allow it work well when used in Xcode test bundles, however it can also be used in a standalone app. After installing Nimble using one of the above methods, there are two additional steps required to make this work.

  1. Create a custom assertion handler and assign an instance of it to the global NimbleAssertionHandler variable. For example:
class MyAssertionHandler : AssertionHandler {
    func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) {
        if (!assertion) {
            print("Expectation failed: \(message.stringValue)")
        }
    }
}
// Somewhere before you use any assertions
NimbleAssertionHandler = MyAssertionHandler()
  1. Add a post-build action to fix an issue with the Swift XCTest support library being unnecessarily copied into your app
rm "${SWIFT_STDLIB_TOOL_DESTINATION_DIR}/libswiftXCTest.dylib"

You can now use Nimble assertions in your code and handle failures as you see fit.