Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation articles by adding short abstracts to them. #1137

Merged
merged 2 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions Sources/Nimble/Nimble.docc/Guides/Concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 <doc:PollingExpectations>.
Note: Swift Concurrency support is different than the
``AsyncExpectation/toEventually(_:timeout:pollInterval:description:)-38brw``/``AsyncExpectation/toEventuallyNot(_:timeout:pollInterval:description:)-4ez1r``
feature described in <doc:PollingExpectations>.
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.
Expand Down
42 changes: 6 additions & 36 deletions Sources/Nimble/Nimble.docc/Guides/PollingExpectations.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,19 @@ 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
`toEventuallyNot`/`toNotEventually` | Until pass | to not match
`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
Expand Down Expand Up @@ -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:
Expand Down
31 changes: 0 additions & 31 deletions Sources/Nimble/Nimble.docc/Matchers/CollectionCount.md

This file was deleted.

47 changes: 0 additions & 47 deletions Sources/Nimble/Nimble.docc/Matchers/CollectionElements.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Comparisons.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Comparisons

Comparing the expression with other values.

```swift
// Swift

Expand Down
5 changes: 4 additions & 1 deletion Sources/Nimble/Nimble.docc/Matchers/CustomValidation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Custom Validation

Nimble allows you to perform custom validation.

```swift
// Swift

Expand All @@ -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.
2 changes: 2 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Equivalence.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Equivalence

Checking if a value is equal to another.

```swift
// Swift

Expand Down
4 changes: 3 additions & 1 deletion Sources/Nimble/Nimble.docc/Matchers/Exceptions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Exceptions

Check exceptions raised from Objective-C.

```swift
// Swift

Expand Down Expand Up @@ -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.
2 changes: 2 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/GroupsOfMatchers.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Matching a value to any of a group of matchers

Combining matchers into a single Expectation.

```swift
// Swift

Expand Down
5 changes: 5 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Identity.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Identity

Checking if an object is the same address as another.

```swift
// Swift

Expand Down Expand Up @@ -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.
2 changes: 2 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Map.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 3 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Notifications.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Notifications

Checking Notifications posted to `NotificationCenter` or a
`DistributedNotificationCenter`.

```swift
// Swift
let testNotification = Notification(name: Notification.Name("Foo"), object: nil)
Expand Down
5 changes: 4 additions & 1 deletion Sources/Nimble/Nimble.docc/Matchers/Result.md
Original file line number Diff line number Diff line change
@@ -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<String, Error> = .success("Hooray")
Expand Down Expand Up @@ -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.
7 changes: 7 additions & 0 deletions Sources/Nimble/Nimble.docc/Matchers/Strings.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Loading
Loading