assertor 0.0.2

Fluent assertion library with readable failure messages.
Documentation
How to extend
=============

## 1. Write your own Assertion trait.
- S: Subject type (e.g. HashSet<T>)
- R: Return type of assertion
  - For `assert_that!` macro, `R` is `()` (or panic when the assertion fails).
  - For `check_that!` macro, `R` is `CheckThatResult`.

```rust
trait SetAssertion<S, T, R> {
    fn contains<B: Borrow<T>>(&self, expected: B) -> R;
    fn is_equal_to<B: Borrow<S>>(&self, expected: S) -> R;
}
```

## 2. Write implementation for `Subject<S, (), R>`.

```rust
impl<T, R> SetAssertion<HashSet<T>, T, R> for Subject<HashSet<T>, (), R> {
    fn contains<B: Borrow<T>>(&self, expected: B) -> R {
        if (self.actual().contains(expected)) {
            self.new_result().do_ok()
        } else {
            self.new_result()
                .add_fact("expected to contain", "XXX")
                .add_fact(...)
                .do_fail()
        }
    }
}
```

## 3. Write tests.

```rust
#[cfg(test)]
mod tests {
    use std::iter::FromIterator;

    use crate::*;

    use super::*;

    #[test]
    fn contains() {
        assert_that!(HashSet::from_iter(vec![1, 2, 3].iter())).contains(&3);

        // Failures
        let result = check_that!(HashSet::from_iter(vec![1, 2, 3].iter())).contains(&10);
        assert_that!(result).facts_are_at_least(vec![
            Fact::new("expected to contain", "10"),
            Fact::new_simple_fact("but did not"),
        ]);
        assert_that!(result)
            .fact_keys()
            .contains(&"though it did contain".to_string());
        // Skip test for value because key order is not stable.
    }
}
```

Do and Dont
===========

DONT: Method chain of multiple independent assertions
-----------------------------------------------------

```rust
assert_that!(3).is_less_than(10).is_larger_than(1);
assert_that!(vec![1,2,3]).contains_exactly(3, 2, 1).in_order(); // Java Truth like 
```

### DO:

##### Recommended: Independent assertions.

```rust
assert_that!(3).is_less_than(10);
assert_that!(3).is_larger_than(1);
```

##### Ok: Define one assertion method to check both.

```rust
assert_that!(3).is_in(1, 10);
assert_that!(vec![1,2,3]).contains_exactly_in_order(3, 2, 1);
```

### Why?

- Readability
    - One `assert_that!()` should check one assertion for readability.
- Design complication
    - Return type of `assert_that!(3).is_less_than(10)` will be complicated like `Result<Subject<..>, R>`.

DO: Derived subjects
--------------------

```rust
assert_that!(hash_map).key_set().contains( & "foo");
assert_that!(hash_map).key_set().contains_exactly( & "foo", & "bar");
```

It is one option not to use derived subject when the assertion method is expected to be used frequently and when the api
of derived subject is hard to use (`&` in argument in previous example).

##### Ok

```rust
assert_that!(hash_map).contains_key("foo");
assert_that!(hash_map).contains_key("bar");
```

### Why?

- API simplicity
    - To avoid having many method having `key_set` prefix (
      ex. `assert_that!(..).key_set_contains(), assert_that!(..).key_set_contains_exactly()`)
- Code duplication
    - Derived subject enables to reuse the existing implementation easily.

### What is `derived subject`?

A feature to create a new subject whose type is different from the original subject type.

- `Subject.new_subject(..)`
- `Subject.new_owned_subject(..)`

```rust

impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
    where
        AssertionResult: ReturnStrategy<R>,
{
    fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { // <- Returns new subject whose type is Keys<> from HashMap<>
        self.new_owned_subject(
            self.actual().keys(),
            Some(format!("{}.keys()", self.description_or_expr())),
            (),
        )
    }
}
```