Field-by-field comparisons of complex rust values
Rust
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
field-by-field-derive
field-by-field
.gitignore
.travis.yml
Cargo.toml
LICENSE
README.md

README.md

Field-By-Field Comparisons

You know, for tests.

Build Status

These crates (field-by-field and field-by-field-derive) implement comparisons between complex structs or enums with error messages that describe which fields caused an error. This is mostly useful for particularly large structs or enums.

Usage

Add this to your Cargo.toml:

[dependencies]
field-by-field = { git = "https://github.com/quodlibetor/field-by-field" }
field-by-field-derive = { git = "https://github.com/quodlibetor/field-by-field" }

Derive FieldByField, and then write some tests, using actual.assert_equal_field_by_field(&expected).

Note: This is still experimental. I'm not sure exactly where I'd like to take this library, but if there's enough interest I'm curious how much meta magic we can use to make testing in Rust best in the world. There are a couple test-helper libraries (spectral, expectest, hamcrest all exist) How much more magic seems worth adding to these other test crates affects what I might end up doing in here.

Example

#[cfg(test)]
extern crate field_by_field;
#[cfg(test)]
#[macro_use]
extern crate field_by_field_derive;

#[cfg_attr(test, derive(FieldByField))]
#[derive(Debug)]
struct MyStruct {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
}

#[cfg(test)]
mod tests {
    use field_by_field::EqualFieldByField;
    use MyStruct;

    #[test]
    fn is_it_equal() {
        let actual = MyStruct { a: 1, b: 3, c: 3, d: 3, e: 3 };
        let expect = MyStruct { a: 3, b: 3, c: 3, d: 2, e: 3 };

        actual.assert_equal_field_by_field(&expect);
    }
}

This will fail with the following error message:

---- is_it_equal stdout ----
	thread 'is_it_equal' panicked at '
    Items are not equal:
        a: 1 != 3
        d: 3 != 2
    actually: MyStruct { a: 1, b: 3, c: 3, d: 3, e: 3 }
    expected: MyStruct { a: 3, b: 3, c: 3, d: 2, e: 3 }
', example.rs:9

Additionally, all of the files in field-by-field-derive/tests will demonstrate usage and show what error messages look like if you remove the #[should_panic] annotations.