Initial implementation of package:checks (#1693)

Implements the core mechanics for defining and using expectations, along
with some basic expectations for core types. Many more expectation
extensions will be added, including `deepEquals` which is already called
out in the docs as necessary to replace the behavior of `equals` from
Matcher.

High level design:

A `Check` is the target for extension methods. It may hold a value (if
it came from `checkThat`) or it may be a placeholder for a value that
could be checked (if it came from `describe`). In test code only the
extensions are visible. To write an expectation a second import exposes
a `context` field on the check which gives access to defining the
expectations.

Each expectation is synchronous or asynchronous, and may be a simple
clause on the value, or may extract a property from the value for
further checking. These are `expect/Async`, and `nest/Async`
respectively.

`expect` and `expectAsync` will add a clause to the list of clause:

```
Expected: a value that:
  some clause from `expect` or `expectAsync`
  another clause from `expect` or `expectAsync`
```

`nest` and `nestAsync` will create a nested context which can have it's
own clauses

```
Expected: a value that:
  has some property extracted by a `nest` or `nestAsync` callback that:
    some clause from an expectation on the nested Check
```

When a failure happens, the clause that failed is replace by the
"Actual" description from the `Rejection`

```
Expected: a value that:
  some clause that will pass
  some clause that will fail
Actual: a value that:
  some clause that will pass
  Actual: The description of the failing value
```

Expectation extensions are written as small as possible, with the
intention that they can be put together in interesting ways. For
instance instead of a `hasLength(int length)` expectation, the `length`
is extracted and a `.equals` expectation can be used on the extracted
value.

```dart
// BAD
checkThat(someList).hasLength(10);
// GOOD
checkThat(someList).length.equals(10);
```

Whenever possible, a name that matches an API on the class is used to
correspond to exactly that behavior. For instance
`Check<Iterable>.contains` use `Iterable.contains` in the
implementation. `Check<Iterable>.any` takes a callback to
match with the Checks library, since the corresponding API on Iterable
which takes a callback that returns a boolean is less useful in a test.
12 files changed