[![pub package](https://img.shields.io/pub/v/checks.svg)](https://pub.dev/packages/checks)
[![package publisher](https://img.shields.io/pub/publisher/checks.svg)](https://pub.dev/packages/checks/publisher)

`package:checks` is a library for expressing test expectations and it features
a literate API.

## package:checks (experimental)

`package:checks` is still experimental. For production use cases, please use
`package:test` and `package:matcher`.

For packages in the `labs.dart.dev` publisher we generally plan to either
graduate the package into a supported publisher (`dart.dev`, `tools.dart.dev`)
after a period of feedback and iteration, or discontinue the package. These
packages have a much higher expected rate of API and breaking changes.

To provide feedback on the API, please file [an issue][] with questions,
suggestions, feature requests, or general feedback.

For documentation about converting your usage of `package:matcher` to `checks`,
see the [migration guide][].

[an issue]:https://github.com/dart-lang/test/issues/new?labels=package%3Achecks&template=03_checks_feedback.md
[migration guide]:https://github.com/dart-lang/test/blob/master/pkgs/checks/doc/migrating_from_matcher.md

## Quickstart

1. Add a `dev_dependency` on `checks` (`dart pub add dev:checks`).

1. Add an import for `package:checks/checks.dart`.

1. Use `checks` in your test code:

```dart
void main() {
  test('sample test', () {
    // test code here
    ...

    check(actual).equals(expected);
    check(someList).isNotEmpty();
    check(someObject).isA<Map>();
    check(someString)..startsWith('a')..endsWith('z')..contains('lmno');
  });
}
```

## Checking expectations with `checks`

Expectations start with `check`. This utility returns a `Subject`, and
expectations can be checked against the subject. Expectations are defined as
extension methods, and different expectations will be available for subjects
with different value types.

```dart
check(someValue).equals(expectedValue);
check(someList).deepEquals(expectedList);
check(someString).contains('expected pattern');
```

If a failure may not have enough context about the actual or expected values
from the expectation calls alone, add a "Reason" in the failure message by
passing a `because:` argument to `check()`.

```dart
check(
  because: 'log lines must start with the severity',
  logLines,
).every((l) => l
  ..anyOf([
    (l) => l.startsWith('ERROR'),
    (l) => l.startsWith('WARNING'),
    (l) => l.startsWith('INFO'),
  ]));
```


### Composing expectations


Multiple expectations can be checked against the same value using cascade
syntax. When multiple expectations are checked against a single value, a failure
will included descriptions of the expectations that already passed.

```dart
check(someString)
  ..startsWith('a')
  ..endsWith('z')
  ..contains('lmno');
```

Some nested checks may be not be possible to write with cascade syntax.
There is a `which` utility for this use case which takes a `Condition`.

```dart
check(someString)
  ..startsWith('a')
  // A cascade would not be possible on `length`
  ..length.which((l) => l
    ..isGreatherThan(10)
    ..isLessThan(100));
```


Some expectations return a `Subject` for another value derived from the original
value, such as the `length` extension.

```dart
check(someString).length.equals(expectedLength);
```

Fields or derived values can be extracted from objects for checking further
properties with the `has` utility.

```dart
check(someValue)
  .has((value) => value.property, 'property')
  .equals(expectedPropertyValue);
```

### Passing a set of expectations as an argument

Some expectations take arguments which are themselves expectations to apply to
other values. These expectations take `Condition` arguments which have the
signature `void Function(Subject)`. The conditions check expectations when they
are called with a `Subject` argument.

```dart
check(someList).any((e) => e.isGreaterThan(0));
```

### Checking asynchronous expectations

Expectation extension methods checking asynchronous behavior return a `Future`.
The future should typically be awaited within the test body, however
asynchronous expectations will also ensure that the test is not considered
complete before the expectation is complete.
Expectations with no concrete end conditions, such as any expectation that a
future never completes, cannot be awaited and may cause a failure after the test
has already appeared to complete.

Asynchronous expectations do not return a `Subject`. When an expectation
extracts a derived value further expectations can be checked by passing a
`Condition`.

```dart
await check(someFuture).completes((r) => r.isGreaterThan(0));
```

Subjects for `Stream` instances must first be wrapped into a `StreamQueue` to
allow multiple expectations to test against the stream from the same state.
The `withQueue` extension can be used when a given stream instance only needs to
be checked once, or if it is a broadcast stream, but if single subscription
stream needs to have multiple expectations checked separately it should be
wrapped with a `StreamQueue`.

```dart
await check(someStream).withQueue.inOrder([
  (s) => s.emits((e) => e.equals(1)),
  (s) => s.emits((e) => e.equals(2)),
  (s) => s.emits((e) => e.equals(3)),
  (s) => s.isDone(),
]);

var someQueue = StreamQueue(someOtherStream);
await check(someQueue).emits((e) => e.equals(1));
// do something
await check(someQueue).emits((e) => e.equals(2));
// do something
```


## Writing custom expectations

Expectations are written as extensions on `Subject` with specific generics. The
library `package:checks/context.dart` gives access to a `context` getter on
`Subject` which offers capabilities for defining expectations on the subject's
value.

The `Context` allows checking an expectation with `expect`, `expectAsync` and
`expectUnawaited`, or extracting a derived value for performing other checks
with `nest` and `nestAsync`. Failures are reported by returning a `Rejection`,
or an `Extracted.rejection`, extensions should avoid throwing exceptions.

Descriptions of the clause checked by an expectations are passed through a
separate callback from the predicate which checks the value. Nesting calls are
made with a label directly. When there are no failures the clause callbacks are
not called. When a condition callback is described, the clause callbacks are
called, but the predicate callbacks are not called. Conditions can be checked
against values without throwing an exception using `softCheck` or
`softCheckAsync`.

```dart
extension CustomChecks on Subject<CustomType> {
  void someExpectation() {
    context.expect(() => ['meets this expectation'], (actual) {
      if (_expectationIsMet(actual)) return null;
      return Rejection(which: ['does not meet this expectation']);
    });
  }

  Subject<Foo> get someDerivedValue =>
      context.nest(() => ['has someDerivedValue'], (actual) {
        if (_cannotReadDerivedValue(actual)) {
          return Extracted.rejection(which: ['cannot read someDerivedValue']);
        }
        return Extracted.value(_readDerivedValue(actual));
      });

  // for field reads that will not get rejected, use `has`
  Subject<Bar> get someField => has((a) => a.someField, 'someField');
}
```

Extensions may also compose existing expectations under a single name. When
such expectations fail, the test output will refer to the individual
expectations that were called.

```dart
extension ComposedChecks on Subject<Iterable> {
  void hasLengthInRange(int min, int max) {
    length
      ..isGreaterThan(min)
      ..isLessThan(max);
  }
}
```
