Skip to content

Commit

Permalink
Update documentation in preparation for Nimble 12 (#1052)
Browse files Browse the repository at this point in the history
- Mention how to install via Swift Package Manager
- Directly mention that you need to await toEventually expectations in async contexts
- Rearrange the Polling Expectations section.
  • Loading branch information
younata authored Apr 14, 2023
1 parent 3e9397c commit 7a23396
Showing 1 changed file with 91 additions and 34 deletions.
125 changes: 91 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ whether the value it's processing was abtained async or not.

Async support is Swift-only, and it requires that you execute the test in an
async context. For XCTest, this is as simple as marking your test function with
`async`. If you use Quick, then you don't need to do anything because as of
Quick 6, all tests are executed in an async context.
`async`. If you use Quick, all tests in Quick 6 are executed in an async context.
In Quick 7 and later, only tests that are in an `AsyncSpec` subclass will be
executed in an async context.

To avoid a compiler errors when using synchronous `expect` in asynchronous contexts,
`expect` with async expressions does not support autoclosures. However, the `expecta`
Expand Down Expand Up @@ -376,7 +377,22 @@ 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.
`toEventaully` et. al. now also supports async expectations. For example, the following test is now supported:
### Using Polling Expectations in Async Tests
You can easily use `toEventually` or `toEventuallyNot` in async contexts as
well. You only need to add an `await` statement to the beginning of the line:
```swift
// Swift
DispatchQueue.main.async {
ocean.add("dolphins")
ocean.add("whales")
}
await expect(ocean).toEventually(contain("dolphens", "whiles"))
```

Starting in Numble 12, `toEventually` et. al. now also supports async
expectations. For example, the following test is now supported:

```swift
actor MyActor {
Expand All @@ -392,6 +408,8 @@ let subject = MyActor()
await expect { await subject.access() }.toEventually(equal(2))
```

### Verifying a Predicate will Never or Always Match

You can also test that a value always or never matches throughout the length of the timeout. Use `toNever` and `toAlways` for this:

```swift
Expand All @@ -408,25 +426,7 @@ expect(ocean).toAlways(contain(@"dolphins"))
expect(ocean).toNever(contain(@"hares"))
```
Sometimes it takes more than a second for a value to update. In those
cases, use the `timeout` parameter:
```swift
// Swift
// Waits three seconds for ocean to contain "starfish":
expect(ocean).toEventually(contain("starfish"), timeout: .seconds(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: .milliseconds(5500), pollInterval: .milliseconds(200))
```

```objc
// Objective-C

// Waits three seconds for ocean to contain "starfish":
expect(ocean).withTimeout(3).toEventually(contain(@"starfish"));
```
### Waiting for a Callback to be Called
You can also provide a callback by using the `waitUntil` function:
Expand Down Expand Up @@ -482,6 +482,28 @@ 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.
### Changing the Timeout and Polling Intervals
Sometimes it takes more than a second for a value to update. In those
cases, use the `timeout` parameter:
```swift
// Swift
// Waits three seconds for ocean to contain "starfish":
expect(ocean).toEventually(contain("starfish"), timeout: .seconds(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: .milliseconds(5500), pollInterval: .milliseconds(200))
```

```objc
// Objective-C

// Waits three seconds for ocean to contain "starfish":
expect(ocean).withTimeout(3).toEventually(contain(@"starfish"));
```
### Changing default Timeout and Poll Intervals
In some cases (e.g. when running on slower machines) it can be useful to modify
Expand Down Expand Up @@ -617,6 +639,7 @@ For the following matchers:
- `beFalsy`
- `haveCount`


If you would like to see more, [file an issue](https://github.com/Quick/Nimble/issues).

## Disabling Objective-C Shorthand
Expand Down Expand Up @@ -1766,17 +1789,6 @@ extension NMBPredicate {
}
```

## Migrating from the Old Matcher API

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

- `Matcher`
- `NonNilMatcherFunc`
- `MatcherFunc`

All of those types have been replaced by `Predicate`. The old API has been
removed completely in Nimble v10.

# Installing Nimble

> Nimble can be used on its own, or in conjunction with its sister
Expand Down Expand Up @@ -1804,7 +1816,7 @@ install just Nimble.

## Installing Nimble via CocoaPods

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

Expand All @@ -1823,6 +1835,51 @@ end

Finally run `pod install`.

## Installing Nimble via Swift Package Manager

### Xcode

To install Nimble via Xcode's Swift Package Manager Integration:
Select your project configuration, then the project tab, then the Package
Dependencies tab. Click on the "plus" button at the bottom of the list,
then follow the wizard to add Quick to your project. Specify
`https://github.com/Quick/Nimble.git` as the url, and be sure to add
Nimble as a dependency of your unit test target, not your app target.

### Package.Swift

To use Nimble with Swift Package Manager to test your applications, add Nimble
to your `Package.Swift` and link it with your test target:

```swift
// swift-tools-version:5.5

import PackageDescription

let package = Package(
name: "MyAwesomeLibrary",
products: [
// ...
],
dependencies: [
// ...
.package(url: "https://github.com/Quick/Nimble.git", from: "12.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "MyAwesomeLibrary",
dependencies: ...),
.testTarget(
name: "MyAwesomeLibraryTests",
dependencies: ["MyAwesomeLibrary", "Nimble"]),
]
)
```

Please note that if you install Nimble using Swift Package Manager, then `raiseException` is not available.

## Using Nimble without XCTest

Nimble is integrated with XCTest to allow it work well when used in Xcode test
Expand Down

0 comments on commit 7a23396

Please sign in to comment.