diff --git a/Sources/Nimble/Nimble.docc/Guides/Concurrency.md b/Sources/Nimble/Nimble.docc/Guides/Concurrency.md index 6f241b287..debdb97f3 100644 --- a/Sources/Nimble/Nimble.docc/Guides/Concurrency.md +++ b/Sources/Nimble/Nimble.docc/Guides/Concurrency.md @@ -2,7 +2,7 @@ Nimble makes it easy to await for an async function to complete. -Simply pass the async function in to `expect`: +Simply pass the async function in to ``expecta(file:line:_:)-4z5rl``: ```swift // Swift @@ -29,7 +29,7 @@ await expecta(await aFunctionReturning1()).to(equal(1))) ``` Similarly, if you're ever in a situation where you want to force the compiler to -produce a `SyncExpectation`, you can use the `expects` (expect sync) function to +produce a ``SyncExpectation``, you can use the ``expects(file:line:_:)-1ojb4`` (expect sync) function to produce a `SyncExpectation`. Like so: ```swift @@ -43,19 +43,21 @@ expects(await someAsyncFunction()).to(equal(1)) // Compiler error: 'async' call In addition to asserting on async functions prior to passing them to a synchronous matcher, you can also write matchers that directly take in an -async value. These are called `AsyncMatcher`s. This is most obviously useful +async value. These are called ``AsyncMatcher``s. This is most obviously useful when directly asserting against an actor. In addition to writing your own async matchers, Nimble currently ships with async versions of the following matchers: -- ``allPass`` -- ``containElementSatisfying`` -- ``satisfyAllOf`` and the ``&&`` operator overload accept both `AsyncMatcher` and +- ``allPass(_:)-5avdc`` +- ``containElementSatisfying(_:_:)-8omf3`` +- ``satisfyAllOf(_:)-99ble`` and the ``&&(left:right:)`` operator overload accept both ``AsyncMatcher`` and synchronous ``Matcher``s. -- ``satisfyAnyOf`` and the ``||`` operator overload accept both ``AsyncMatcher`` and +- ``satisfyAnyOf(_:)-8groo`` and the ``||(left:right:)`` operator overload accept both ``AsyncMatcher`` and synchronous ``Matcher``s. -Note: Swift Concurrency support is different than the `toEventually`/`toEventuallyNot` feature described in . +Note: Swift Concurrency support is different than the +``AsyncExpectation/toEventually(_:timeout:pollInterval:description:)-38brw``/``AsyncExpectation/toEventuallyNot(_:timeout:pollInterval:description:)-4ez1r`` +feature described in . Polling Expectations works by continuously polling the `Expectation` until it passes. As described here, Nimble's Swift Concurrency support is about waiting for an expression to finish. diff --git a/Sources/Nimble/Nimble.docc/Guides/PollingExpectations.md b/Sources/Nimble/Nimble.docc/Guides/PollingExpectations.md index 53cb624a9..ee36ad5f8 100644 --- a/Sources/Nimble/Nimble.docc/Guides/PollingExpectations.md +++ b/Sources/Nimble/Nimble.docc/Guides/PollingExpectations.md @@ -14,15 +14,6 @@ until they stop polling. For example, `toEventually` will run until the Matcher matches, while `toNever` will run so long as the Matcher doesn't match. This makes them opposites. -> Warning: It is a very common mistake to assume that `toEventuallyNot` is the -opposite of `toEventually`. For example, if you're using a [Swift Fakes Spy](https://github.com/Quick/swift-fakes/blob/main/Sources/Fakes/Spy.swift), -you might be used to checking that it is called on a background thread by using -`expect(spy).toEventually(beCalled())`. If you want to check that a spy is not -called during some background behavior, you might be tempted to use `expect(spy).toEventuallyNot(beCalled())`. -All this will do is verify that, by the time the Expectation first runs, the spy -has not been called. At which point, that background behavior might not even have -run. The correct thing is to use `toNever`, as in `expect(spy).toNever(beCalled())`. - Polling form | Pass Duration | Expected Matcher Result ------------------------------------|---------------|------------------------ `toEventually` | Until pass | to match @@ -30,6 +21,12 @@ Polling form | Pass Duration | Expected Matcher Result `toAlways`/`alwaysTo` | Until fail | to match `toNever`/`neverTo` | Until fail | to not match +> Warning: It is a very common mistake to conflate `toEventuallyNot` with `toNever`. +`toEventuallyNot` runs intil the first time the matcher doesn't match. `toNever` +continously polls so long as the matcher doesn't match. Be mindful of the +behavior you expect to observe, and be sure to check that your Polling +Expectation is not falsely matching. + ### Verifying a Matcher will Eventually Match or stop Matching To verify that a value eventually matches or stops matching through the length @@ -77,33 +74,6 @@ expect(ocean).toAlways(contain(@"dolphins")) expect(ocean).toNever(contain(@"hares")) ``` -### Behaviors of different forms of Polling - -Fundamentally, the behaviors of the different types of polling (`toEventually`, -`toEventuallyNot`, `toAlways`, `toNever`) are about the duration of the polling, -and what they're looking for with regard to the Expectation. - -For example, `toEventually` will run until the Expectation matches, while `toNever` -will run so long as the Expectation dosen't match. This effectively makes them -opposites. - -> Warning: It is a very common mistake to assume that `toEventuallyNot` is the -opposite of `toEventually`. For example, if you're using a [Swift Fakes Spy](https://github.com/Quick/swift-fakes/blob/main/Sources/Fakes/Spy.swift), -you might be used to checking that it is called on a background thread by using -`expect(spy).toEventually(beCalled())`. If you want to check that a spy is not -called during some background behavior, you might be tempted to use `expect(spy).toEventuallyNot(beCalled())`. -All this will do is verify that, by the time the Expectation first runs, the spy -has not been called. At which point, that background behavior might not even have -run. The correct thing is to use `toNever`, as in `expect(spy).toNever(beCalled())`. - -Polling form | Pass Duration | Expected Matcher Result -------------------------------------|---------------|------------------------ -`toEventually` | Until pass | to match -`toEventuallyNot`/`toNotEventually` | Until pass | to not match -`toAlways`/`alwaysTo` | Until fail | to match -`toNever`/`neverTo` | Until fail | to not match - - ### Waiting for a Callback to be Called You can also provide a callback by using the `waitUntil` function: diff --git a/Sources/Nimble/Nimble.docc/Matchers/CollectionCount.md b/Sources/Nimble/Nimble.docc/Matchers/CollectionCount.md deleted file mode 100644 index e611c8328..000000000 --- a/Sources/Nimble/Nimble.docc/Matchers/CollectionCount.md +++ /dev/null @@ -1,31 +0,0 @@ -# Collection Count - -```swift -// 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)) -``` - -```objc -// 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: - - - `NSArray`, - - `NSDictionary`, - - `NSSet`, or - - `NSHashTable`. diff --git a/Sources/Nimble/Nimble.docc/Matchers/CollectionElements.md b/Sources/Nimble/Nimble.docc/Matchers/CollectionElements.md deleted file mode 100644 index df113a440..000000000 --- a/Sources/Nimble/Nimble.docc/Matchers/CollectionElements.md +++ /dev/null @@ -1,47 +0,0 @@ -# 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 -// 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))) -``` - -There are also variants of `allPass` that check against async matchers, and -that take in async functions: - -```swift -// Swift - -// Providing a custom function: -expect([1, 2, 3, 4]).to(allPass { await asyncFunctionReturningBool($0) }) - -// Composing the expectation with another matcher: -expect([1, 2, 3, 4]).to(allPass(someAsyncMatcher())) -``` - -## 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. - -```objc -// Objective-C - -expect(@[@1, @2, @3, @4]).to(allPass(beLessThan(@5))); -``` - diff --git a/Sources/Nimble/Nimble.docc/Matchers/CollectionMembership.md b/Sources/Nimble/Nimble.docc/Matchers/Collections.md similarity index 66% rename from Sources/Nimble/Nimble.docc/Matchers/CollectionMembership.md rename to Sources/Nimble/Nimble.docc/Matchers/Collections.md index 739a3667a..5eeac6270 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/CollectionMembership.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Collections.md @@ -1,4 +1,85 @@ -# Collection Membership +# Collection + +Nimble allows you to easily check `Collection`s. + +## Collection Count + +```swift +// 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)) +``` + +```objc +// 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: + + - `NSArray`, + - `NSDictionary`, + - `NSSet`, or + - `NSHashTable`. + +## Collection Elements + +### Swift + +In Swift, the collection must be an instance of a type conforming to +`Sequence`. + +```swift +// 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))) +``` + +There are also variants of `allPass` that check against async matchers, and +that take in async functions: + +```swift +// Swift + +// Providing a custom function: +expect([1, 2, 3, 4]).to(allPass { await asyncFunctionReturningBool($0) }) + +// Composing the expectation with another matcher: +expect([1, 2, 3, 4]).to(allPass(someAsyncMatcher())) +``` + +### 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. + +```objc +// Objective-C + +expect(@[@1, @2, @3, @4]).to(allPass(beLessThan(@5))); +``` + +## Collection Membership ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/Comparisons.md b/Sources/Nimble/Nimble.docc/Matchers/Comparisons.md index 9c26a7004..c47a4962f 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Comparisons.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Comparisons.md @@ -1,5 +1,7 @@ # Comparisons +Comparing the expression with other values. + ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/CustomValidation.md b/Sources/Nimble/Nimble.docc/Matchers/CustomValidation.md index 828c2f670..a8abe30c8 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/CustomValidation.md +++ b/Sources/Nimble/Nimble.docc/Matchers/CustomValidation.md @@ -1,5 +1,7 @@ # Custom Validation +Nimble allows you to perform custom validation. + ```swift // Swift @@ -24,4 +26,5 @@ expect { The `String` provided with `.failed()` is shown when the test fails. -> Warning: When using Polling Expectations be careful not to make state changes or run process intensive code since this closure will be ran many times. +> Warning: When using Polling Expectations be careful not to make state changes +or run process intensive code since this closure will be ran many times. diff --git a/Sources/Nimble/Nimble.docc/Matchers/Equivalence.md b/Sources/Nimble/Nimble.docc/Matchers/Equivalence.md index f45493258..3376afd03 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Equivalence.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Equivalence.md @@ -1,5 +1,7 @@ # Equivalence +Checking if a value is equal to another. + ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/Exceptions.md b/Sources/Nimble/Nimble.docc/Matchers/Exceptions.md index a29ec73eb..1d39369df 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Exceptions.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Exceptions.md @@ -1,5 +1,7 @@ # Exceptions +Check exceptions raised from Objective-C. + ```swift // Swift @@ -41,5 +43,5 @@ expect(actual).to(raiseException().satisfyingBlock(^(NSException *exception) { > Note: Swift currently doesn't have exceptions (see [#220](https://github.com/Quick/Nimble/issues/220#issuecomment-172667064)). Only Objective-C code can raise exceptions that Nimble will catch. -> Note: ``raiseException()`` is currentl unavailable when Nimble is installed +> Note: ``raiseException()`` is currently unavailable when Nimble is installed through Swift Package Manager. diff --git a/Sources/Nimble/Nimble.docc/Matchers/GroupsOfMatchers.md b/Sources/Nimble/Nimble.docc/Matchers/GroupsOfMatchers.md index 4a0b429ee..38d00b494 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/GroupsOfMatchers.md +++ b/Sources/Nimble/Nimble.docc/Matchers/GroupsOfMatchers.md @@ -1,5 +1,7 @@ # Matching a value to any of a group of matchers +Combining matchers into a single Expectation. + ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/Identity.md b/Sources/Nimble/Nimble.docc/Matchers/Identity.md index b822a672f..07096996e 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Identity.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Identity.md @@ -1,5 +1,7 @@ # Identity +Checking if an object is the same address as another. + ```swift // Swift @@ -32,3 +34,6 @@ expect(actual).to(beIdenticalTo(expected)); // Passes if 'actual' does not have the same pointer address as 'expected': expect(actual).toNot(beIdenticalTo(expected)); ``` + +> Warning: `beIdenticalTo` checks the pointer addresses. It does not use the +`Identifiable` protocol to check for identity. diff --git a/Sources/Nimble/Nimble.docc/Matchers/Map.md b/Sources/Nimble/Nimble.docc/Matchers/Map.md index 4790df6ea..b84bbe98f 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Map.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Map.md @@ -1,5 +1,7 @@ # Mapping a Value to Another Value +Mapping a value to another value in the matcher. + Sometimes, you only want to match against a property or group of properties. For example, if you wanted to check that only one or a few properties of a value are equal to something else. For this, use the ``map`` matcher to convert a value diff --git a/Sources/Nimble/Nimble.docc/Matchers/Notifications.md b/Sources/Nimble/Nimble.docc/Matchers/Notifications.md index 5cc93aa40..79085de0c 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Notifications.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Notifications.md @@ -1,5 +1,8 @@ # Notifications +Checking Notifications posted to `NotificationCenter` or a +`DistributedNotificationCenter`. + ```swift // Swift let testNotification = Notification(name: Notification.Name("Foo"), object: nil) diff --git a/Sources/Nimble/Nimble.docc/Matchers/Result.md b/Sources/Nimble/Nimble.docc/Matchers/Result.md index 071765690..838a6b8e5 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Result.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Result.md @@ -1,5 +1,8 @@ # Result +You can check the contents of a `Result` type using the `beSuccess` or +`beFailure` matchers. + ```swift // Swift let aResult: Result = .success("Hooray") @@ -39,4 +42,4 @@ expect(otherResult).to(beFailure { error in expect(otherResult).to(beFailure(matchError(AnError.somethingHappened))) ``` -> This matcher is only available in Swift. +> Note: This matcher is only available in Swift. diff --git a/Sources/Nimble/Nimble.docc/Matchers/Strings.md b/Sources/Nimble/Nimble.docc/Matchers/Strings.md index 3360941f6..bcbad3ef0 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Strings.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Strings.md @@ -1,5 +1,12 @@ # Strings +You can check strings using the `contain`, `beginWith`, `endWith`, `beEmpty`, +and `match` matchers. + +The `contain`, `beginWith`, `endWith`, and `beEmpty` operate using substrings, +while the `match` matcher checks if the string matches the given regular +expression. + ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/SwiftAssertions.md b/Sources/Nimble/Nimble.docc/Matchers/SwiftAssertions.md index 676f39b70..4a7e7c450 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/SwiftAssertions.md +++ b/Sources/Nimble/Nimble.docc/Matchers/SwiftAssertions.md @@ -1,6 +1,10 @@ # 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](https://github.com/mattgallagher)'s [CwlPreconditionTesting](https://github.com/mattgallagher/CwlPreconditionTesting) library. +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](https://github.com/mattgallagher)'s +[CwlPreconditionTesting](https://github.com/mattgallagher/CwlPreconditionTesting) library. ```swift // Swift @@ -27,7 +31,7 @@ expect(reachedPoint1) == true expect(reachedPoint2) == false ``` -Notes: - -* This feature is only available in Swift. -* 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. +> Note: This feature is only available in Swift. +> Note: 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. diff --git a/Sources/Nimble/Nimble.docc/Matchers/SwiftErrors.md b/Sources/Nimble/Nimble.docc/Matchers/SwiftErrors.md index 019e0562b..7507b653b 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/SwiftErrors.md +++ b/Sources/Nimble/Nimble.docc/Matchers/SwiftErrors.md @@ -1,6 +1,9 @@ # Swift Error Handling -You can use the `throwError` matcher to check if an error is thrown. +You can use the ``throwError()`` matcher to check if an error is thrown, and the +``matchError(_:)-8o974`` to check already-captured errors. + +`throwError` operates on errors that expressions throw using `try`. ```swift // Swift diff --git a/Sources/Nimble/Nimble.docc/Matchers/Truthiness.md b/Sources/Nimble/Nimble.docc/Matchers/Truthiness.md index 57ef26ed0..33e99716e 100644 --- a/Sources/Nimble/Nimble.docc/Matchers/Truthiness.md +++ b/Sources/Nimble/Nimble.docc/Matchers/Truthiness.md @@ -1,5 +1,19 @@ # Truthiness +Checking whether an expression is true, false, or nil. + +The ``beTrue()`` matcher matches only if the expression evaluates to `true`, while +the ``beTruthy()`` matcher will also match if the expression also evaluates to a +non-`nil` value, or an object with a boolean value of `true`. + +Similarly, the ``beFalse()`` matcher matches only if the expression evaluates to +`false`, while the ``beFalsy()`` also accepts `nil`, or objects with a boolean +value of `false`. + +Finally, the ``beNil())`` matcher matches only if the expression evaluates to +`nil`. + + ```swift // Passes if 'actual' is not nil, true, or an object with a boolean value of true: expect(actual).to(beTruthy()) diff --git a/Sources/Nimble/Nimble.docc/Nimble.md b/Sources/Nimble/Nimble.docc/Nimble.md index fdde2480f..6d0e331e7 100644 --- a/Sources/Nimble/Nimble.docc/Nimble.md +++ b/Sources/Nimble/Nimble.docc/Nimble.md @@ -4,13 +4,28 @@ ## Overview -Nimbel provides 3 things: +Nimbel provides 4 things: - A way to verify expressions using a natural, easily understood language. -- **Matchers**, or functions to check the outcome of an expression. -- Means of requiring an **Expectation** - an expression-matcher combination to pass before continuing. +- **Matchers**, or functions to check the Behavior of an expression. +- Means of requiring an **Expectation** - an expression-matcher combination - to pass before continuing. - A way to check expressions that change over time. +## Terms + +- term Expression: A Swift or Objective-C bit of code. For example `1 + 1`. +- term Behavior: A result or side effect of an expression. For example +`print("hello")` has a behavior of writing "hello\n" to standard output, while +`1 + 1` has a behavior of returning 2. +- term Matcher: A function from Nimble which checks an Expression's Behavior. +- term Expectation: An Expression combined with an Expression. For example, +`expect(1 + 1).to(equal(2))` is an Expectation. +- term Polling Expectation: An expectation that is continuously polled until it +finishes. +- term Requirement: An Expectation that must pass before continuing. These are +usually defined using `require` instead of `expect`, though there are shortcuts +such as ``unwrap(file:line:customError:_:)-5q9f3`` and ``pollUnwrap(file:line:_:)-4ddnp``. + ## Topics ### Guides @@ -41,9 +56,4 @@ Nimble includes a wide variety of matcher functions. - - - - -#### Collections - -- -- -- +- diff --git a/script/build_docs b/script/build_docs index d3ec254bb..218e35500 100755 --- a/script/build_docs +++ b/script/build_docs @@ -1,5 +1,7 @@ #!/usr/bin/env sh +set -e + export DOCC_JSON_PRETTYPRINT="YES" mkdir -p docs