Crate smoothy

Crate smoothy 

Source
Expand description

Write smooth assertions in a fluent and human-readable way.

  1. Overview
  2. Basic value assertions
  3. String-likes
  4. Result
  5. Option
  6. Iterables
  7. Filesystem / Path Assertions
  8. File Handle Assertions
  9. Json
  10. Accessors

§Overview

Start asserting by calling assert_that on a value. Then chain assertions based on the type you are asserting.

§Basic value assertions

There are several assertions available for all types:

§Equality

There are two ways to assert equality:

  • is compares the value with something of the same type.
  • equals compares the value with something that can be converted into the same type. This is done by using the Into trait.

All equality assertions

assert_that(1).equals(1);
assert_that(String::from("Hello")).equals("Hello");
assert_that(1).not_equals(2);
assert_that(String::from("Hello")).not_equals("Hello There");

Same for try_into_equals and try_into_not_equals but here the trait TryInto is used.

assert_that(1u8).try_into_equals(1i8);
assert_that(1u8).try_into_not_equals(2i8);

When one wants to assert a value while assuring the same type without any conversions is used is can be used.

assert_that(1).is(1);
assert_that(1).is_not(2);

§Booleans

There are convenience methods for asserting booleans:

assert_that(true).is_true();
assert_that(false).is_false();

Or one can assert with equality:

assert_that(true).is(true);

§String-likes

String-likes can be asserted by calling contains, starts_with or by calling matches.

All string assertions

assert_that("Hello World")
    .contains("Hello")
    .and()
    .contains("World");
assert_that("Hello World").starts_with("Hello");
assert_that("Hello World").matches(&Regex::new(r"\bHello\b").unwrap());

§Result

Results can be asserted by calling is_err or is_ok. Furthermore, their actual content can be asserted as well.

All result assertions

§Ok

Basic assertion that the result is Ok:

let result: Result<u8, ()> = Ok(1);
assert_that(result).is_ok();

Asserting the Ok-value:

let result: Result<u8, ()> = Ok(1);
assert_that(result).is_ok().and_value().equals(1);

§Err

Basic assertion that the result is Err:

let result: Result<(), String> = Err(String::from("Oh no!"));
assert_that(result).is_err();

Asserting the Err-value:

#[derive(Debug, PartialEq)]
struct CustomError(String);

let result: Result<(), CustomError> = Err(CustomError(String::from("Oh no!")));
assert_that(result)
    .is_err()
    .and_error()
    .equals(CustomError(String::from("Oh no!")));

Alternatively one can assert the error message (given the error implements Display):

#[derive(Debug)]
struct CustomError(String);

let result: Result<(), CustomError> = Err(CustomError(String::from("Oh no!")));
assert_that(result)
    .is_err()
    .and_error()
    .to_string()
    .equals("Oh no!");

§Option

Options can be asserted by calling is_none or is_some. Instances of Some can be further asserted with and_value.

All option assertions

§None

let option: Option<()> = None;

assert_that(option).is_none();

§Some

let option: Option<u8> = Some(1);
let asserter: BasicAsserter<u8> = assert_that(option).is_some().and_value();
// further assertions
asserter.equals(1);

§Iterables

Anything that implements IntoIterator can be asserted in content and size.

All iterable assertions

let vec: Vec<u8> = vec![];
assert_that(vec).is_empty();
let vec: Vec<u8> = vec![1, 2, 3];
assert_that(vec).is_not_empty();
let vec: Vec<u8> = vec![1, 2, 3];
assert_that(vec).size().is(3);
assert_that([1, 2, 3]).first().is(1);
assert_that([1, 2, 3]).second().is(2);
assert_that([1, 2, 3]).third().is(3);
assert_that([1, 2, 3]).nth(0).is(1);

§Content assertions

The content of iterables can be asserted in different ways depending on the invariants one wants to assert

  • Ordered The order of expected items must match the order of the actual items.
  • In Sequence The expected items must be in the same order as the actual items without any items in between.
  • Exclusive Only the expected items should exist in the iterable and all the expected items should be present in the iterable.
AssertionOrderedIn SequenceExclusiveNote
contains / contains_allfalsefalsefalse
contains_onlyfalsefalsetrue
-falsetruefalseDoes not make sense
-falsetruetrueDoes not make sense
contains_in_order (WIP)truefalsefalse
-truefalsetrueCould be useful, but is it needed?
contains_in_sequence (WIP)truetruefalse
is / equalstruetruetrue
assert_that([1, 2, 3]).is([1, 2, 3]);
assert_that([1, 2, 3]).contains(1);
assert_that([1, 2, 3]).contains_all([2, 1]);
assert_that([1, 2, 3, 2]).contains_only([3, 1, 2, 2]);

§Predicate-based assertions

Predicate-based assertions can be used to validate the contents of an iterable.

// Assert that all elements match a condition
let numbers = vec![2, 4, 6, 8];
assert_that(numbers).all_match(|x| x % 2 == 0);
let numbers = vec![1, 2, 3];
assert_that(numbers).any_match(|x| x % 2 == 0);
let numbers = vec![1, 3, 5];
assert_that(numbers).none_match(|x| x % 2 == 0);

§Filesystem / Path Assertions

Path assertions work with any type implementing AsRef<Path> such as str, String, &Path, and PathBuf.

All path assertions

§Existence checks

let temp_file = NamedTempFile::new().unwrap();

assert_that(temp_file.path()).exists();
assert_that("/path/that/does/not/exist").not_exists();

§Type checks

Check if a path points to a regular file:

let temp_file = NamedTempFile::new().unwrap();

assert_that(temp_file.path()).is_file();

Check if a path points to a directory:

let temp_dir = TempDir::new().unwrap();

assert_that(temp_dir.path()).is_directory();

Check if a path is a symlink (without following it):

let temp_dir = TempDir::new().unwrap();
let target = temp_dir.path().join("target");
let link = temp_dir.path().join("link");
std::fs::write(&target, "content").unwrap();
symlink(&target, &link).unwrap();

assert_that(&link).is_symlink();

§File Handle Assertions

File handle assertions work with File handles and types that implement Borrow<File>. These assertions check the metadata of the file handle itself.

All file assertions

Check if a file handle points to a regular file:

let file = tempfile().unwrap();

assert_that(file).is_file();

Check if a file handle points to a directory:

let temp_dir = TempDir::new().unwrap();
let dir = File::open(temp_dir.path()).unwrap();

assert_that(dir).is_directory();

§JSON

JSON values as used by serde_json can be asserted about JSON types and values.

use serde_json::json;
let json = json!({"test": 42});

assert_that(json)
    .is_object()
    .and()
    .get("test")
    .is_number()
    .and()
    .equals(42);
use serde_json::json;
let json = json!("test");

assert_that(json).is_string().and().equals("test");

§Accessors

Sometimes one wants to assert only one specific value of a struct. To do so one can use the extract method.

struct Struct(pub String);

assert_that(Struct("hello".to_string()))
    .extract(|s| s.0.clone())
    .equals("hello");

Modules§

prelude
The prelude for smoothy. Contains the most important structs, traits and functions but not all

Structs§

AssertionConnector
Basic Connector between two assertions on the same value
BasicAsserter
Main struct with various assertions on AssertedType
ErrAsserter
Enables various assertions on Err-values
OkAsserter
Enables various assertions on Ok-values
SomeAsserter
Enables various assertions on Some-values

Traits§

BooleanAssertion
Specifies various assertions on values that can be converted to a boolean. Implemented on BasicAsserter
EqualityAssertion
Specifies various equality assertions. Implemented on BasicAsserter
FileAssertion
Specifies various assertions on file handles. Implemented on BasicAsserter
IteratorAssertion
Specifies various assertions on IntoIterator. Implemented on BasicAsserter
JsonObjectAssertionjson
Specifies various assertions on Map<String, Value>. Implemented on BasicAsserter
JsonValueAssertionjson
Specifies various assertions on Value. Implemented on BasicAsserter
OptionAssertion
Specifies various assertions on Option. Implemented on BasicAsserter
PathAssertion
Specifies various assertions on file system paths. Implemented on BasicAsserter
ResultAssertion
Specifies various assertions on Result. Implemented on BasicAsserter
StringAssertion
Specifies various assertions on String. Implemented on BasicAsserter

Functions§

assert_that
Entrypoint for all assertions