# Smoothy Write smooth assertions in a fluent and readable way. [![check](https://github.com/open-schnick/Smoothy/actions/workflows/check.yml/badge.svg)](https://github.com/open-schnick/Smoothy/actions/workflows/check.yml) [![test](https://github.com/open-schnick/Smoothy/actions/workflows/test.yml/badge.svg)](https://github.com/open-schnick/Smoothy/actions/workflows/test.yml) [![License](https://img.shields.io/crates/l/smoothy)](https://github.com/open-schnick/Smoothy/blob/master/LICENSE) [![Crates.io](https://img.shields.io/crates/v/smoothy)](https://crates.io/crates/smoothy) ## Features The crate is heavily inspired by [AssertJ](https://assertj.github.io/doc/) - simple and readable syntax - assertions based on the type of the asserted value - assertion values use type conversion traits to make assertions readable ## Examples All asserted are stared by calling `assert_that` on a value. After that various assertions based on the type of the asserted value can be made. ```rust use smoothy::assert_that; assert_that(42).equals(42); ``` ```rust use smoothy::assert_that; assert_that(1u8).try_into_equals(1i8); ``` ```rust use smoothy::assert_that; assert_that(String::from("Hello")).equals("Hello"); ``` ```rust use smoothy::assert_that; assert_that("Hello World").contains("Hello").and().contains("World"); ``` ```rust use smoothy::assert_that; let result: Result = Ok(42); assert_that(result) .is_ok() .and_value() .equals(42); ``` ```rust use smoothy::assert_that; let result: Result<(), String> = Err(String::from("ups!")); assert_that(result) .is_err() .and_error() .to_string() .equals("ups!"); ``` ```rust use smoothy::assert_that; let option: Option<()> = None; assert_that(option).is_none(); ``` ```rust use smoothy::assert_that; let option: Option = Some(1); assert_that(option) .is_some() .and_value() .equals(1); ``` ```rust use smoothy::assert_that; let iterable: Vec = vec![]; assert_that(iterable).is_empty(); ``` ```rust use smoothy::assert_that; assert_that(vec![1, 2, 3]).is_not_empty(); ``` ```rust use smoothy::assert_that; assert_that([1, 2, 3]).first().is(1); ``` ```rust use smoothy::assert_that; assert_that([1, 2, 3]).nth(1).is(2); ``` ## Assertion Structure Diagram ```mermaid stateDiagram-v2 [*] --> BasicAsserter<Assertable> : assert_that BasicAsserter<Assertable> --> Anything state "Assertable is any type" as Anything { [*] --> AssertionConnector<Assertable> : is [*] --> AssertionConnector<Assertable> : is_not [*] --> AssertionConnector<Assertable> : equals [*] --> AssertionConnector<Assertable> : not_equals [*] --> AssertionConnector<Assertable> : try_into_equals [*] --> AssertionConnector<Assertable> : try_into_not_equqls AssertionConnector<Assertable> --> [*] : and } BasicAsserter<Assertable> --> Result state "Assertable is Result<Ok, Err>" as Result { [*] --> OkAsserter<Ok> : is_ok OkAsserter<Ok> --> BasicAsserter<Ok> : and_value [*] --> ErrAsserter<Err> : is_err ErrAsserter<Err> --> BasicAsserter<Err> : and_error } BasicAsserter<Assertable> --> Option state "Assertable is Option<Some>" as Option { [*] --> [*] : is_none [*] --> SomeAsserter<Some> : is_some SomeAsserter<Some> --> BasicAsserter<Some> : and_value } BasicAsserter<Assertable> --> ImplString state "Assertable implements ToString" as ImplString { [*] --> BasicAsserter<String> : to_string } BasicAsserter<Assertable> --> ImplAsRefStr state "Assertable implements AsRef<str>" as ImplAsRefStr { [*] --> AssertionConnector<AsRef<str>> : contains [*] --> AssertionConnector<AsRef<str>> : is_matching AssertionConnector<AsRef<str>> --> [*] : and } BasicAsserter<Assertable> --> ImplIntoIter state "Assertable implements IntoIter<Item>" as ImplIntoIter { [*] --> [*] : is_empty [*] --> [*] : is_not_empty [*] --> BasicAsserter<Item>: first [*] --> BasicAsserter<Item>: second [*] --> BasicAsserter<Item>: third [*] --> BasicAsserter<Item>: nth } ```