From 3882c4ee6aec07aed2980a6dceab9ca1e35dda2c Mon Sep 17 00:00:00 2001 From: haraldmaida Date: Sat, 17 Oct 2026 13:24:16 +0200 Subject: [PATCH 1/4] doc: move "Available Assertions" chapter from README.md to separate file --- README.md | 364 +--------------------------------- docs/available-assertions.md | 367 +++++++++++++++++++++++++++++++++++ 2 files changed, 376 insertions(+), 355 deletions(-) create mode 100644 docs/available-assertions.md diff --git a/README.md b/README.md index 21ee1ec..381aff7 100644 --- a/README.md +++ b/README.md @@ -116,360 +116,20 @@ the environment variable only works when the crate feature `std` is enabled too. the default colors red and green are used. *Asserting* respects the [`NO_COLOR`] environment variable. If the `NO_COLOR` environment variable -is set no colors are used regardless of the configured highlight mode. +is set, no colors are used regardless of the configured highlight mode. ## Available Assertions -This chapter gives an overview for the assertions provided by `asserting`. For a comprehensive list -of available assertions including examples browse the documentation of the [`assertions`] module. -The documentation of the assertion traits contains examples on how to use each assertion. The -[crate-level documentation][docs-url] contains lots of examples as a quick introduction. +The `asserting` crate provides a broad set of assertions for testing and validation purposes. An +overview of the available assertions can be found in the +[Available Assertions](docs/available-assertions.md) document. -### Equality +All provided assertions are defined by an assertion-trait in the [`assertions`] module. Each +assertion method comes with a short explanation of how to use it and examples in the API +documentation. So the relevant documentation is at your hand within your editor or IDE when you +are writing assertions in tests. -for all types that implement `PartialEq` with `E` being the type of the expected value: - -| assertion | description | -|-----------------|----------------------------------------------------------| -| is_equal_to | verify that the subject is equal to an expected value | -| is_not_equal_to | verify that the subject is not equal to a specific value | - -for all types that implement `PartialEq` and the subject is of the same type as the expected value: - -| assertion | description | -|----------------|-----------------------------------------------------------------------------------------------| -| is_same_as | verify that the subject is of the same type and has the same value than the expected value | -| is_not_same_as | verify that the subject is of the same type and has a different value than the expected value | - -### Order - -for all types that implement `PartialOrd` with `E` being the type of the expected value: - -| assertion | description | -|-----------------|----------------------------------------------------------------------------------------| -| is_greater_than | verify that the subject is greater than the expected value | -| is_less_than | verify that the subject is less than the expected value | -| is_at_least | verify that the subject is greater than or equal to the expected value | -| is_at_most | verify that the subject is less than or equal to the expected value | -| is_before | verify that the subject is less than (before) the expected value | -| is_after | verify that the subject is greater than (after) the expected value | -| is_between | verify that the subject is between a min value (inclusive) and a max value (inclusive) | - -### Range - -for all types `T` that implement `PartialOrd` and `E` implementing `PartialOrd` with `E` -being the type of the expected value: - -| assertion | description | -|-----------------|-------------------------------------------------------| -| is_in_range | verify that the subject is in the expected range | -| is_not_in_range | verify that the subject is not in the specified range | - -### Integer and Float - -for numbers of types - -* integer primitives: `i8`, `i16`, `i32`, `i64`, `i128` and `isize` -* floating point numbers: `f32` and `f64` -* `num_bigint::BigInt` (requires crate feature `num-bigint`) -* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) -* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) - -| assertion | description | -|-----------------|------------------------------------------------------| -| is_negative | verify that the subject is a negative number | -| is_not_negative | verify that the subject is a positive number or zero | -| is_positive | verify that the subject is a positive number | -| is_not_positive | verify that the subject is a finite number | - -for numbers of types - -* integer primitives: `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `u8`, `u16`, `u32`, `u64`, `u128` - and `usize` -* floating point numbers: `f32` and `f64` -* `num_bigint::BigInt` and `num_bigint::BigUint` (requires crate feature `num-bigint`) -* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) -* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) - -| assertion | description | -|-----------|--------------------------------------------------------------| -| is_zero | verify that the subject is the additive identity (zero) | -| is_one | verify that the subject is the multiplicative identity (one) | - -for floating point numbers of type `f32` and `f64`: - -| assertion | description | -|-----------------|-----------------------------------------------| -| is_infinite | verify that the subject is an infinite number | -| is_finite | verify that the subject is a finite number | -| is_not_a_number | verify that the subject is not a number | -| is_a_number | verify that the subject is a number | - -### Decimal number - -for decimal numbers of types - -* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) -* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) - -| assertion | description | -|------------------|----------------------------------------------------| -| has_scale_of | verify that the subject has the expected scale | -| has_precision_of | verify that the subject has the expected precision | -| is_integer | verify that the subject has zero fractional digits | - -### Float comparison - -for floating point numbers of type `f32` and `f64`. - -requires crate feature `float-cmp` which is enabled by default. - -| assertion | description | -|-----------------------------|--------------------------------------------------------------------------------------------------| -| is_close_to | verify that the subject is approximately equal to the expected value within a default margin | -| is_not_close_to | verify that the subject is not approximately equal to the expected value within a default margin | -| is_close_to_with_margin | verify that the subject is approximately equal to the expected value within the given margin | -| is_not_close_to_with_margin | verify that the subject is not approximately equal to the expected value within the given margin | - -### Date and Time - -for date, time and date-time values of the crates `chrono`, `jiff` and `time`. - -requires crate feature `chrono`, `jiff` or `time`. - -| assertion | description | -|-----------------------------|--------------------------------------------------------------------------------------------------| -| is_close_to_with_margin | verify that the subject is approximately equal to the expected value within the given margin | -| is_not_close_to_with_margin | verify that the subject is not approximately equal to the expected value within the given margin | - -### Character - -for `char`. - -| assertion | description | -|-----------------|-----------------------------------------------------------------| -| is_lowercase | verify that the character is lowercase | -| is_uppercase | verify that the character is uppercase | -| is_ascii | verify that the character is an ASCII character | -| is_alphabetic | verify that the character is an alphabetic character | -| is_alphanumeric | verify that the character is an alphabetic character or a digit | -| is_control_char | verify that the character is a control character | -| is_digit | verify that the character is a digit in the given radix | -| is_whitespace | verify that the character is whitespace | - -### Boolean - -for `bool`. - -| assertion | description | -|-----------|----------------------------------| -| is_true | verify that the subject is true | -| is_false | verify that the subject is false | - -### String - -for strings of type `String` and `str`: - -| assertion | description | -|-----------------------------|----------------------------------------------------------------------------------| -| is_empty | verify that a string is empty | -| is_not_empty | verify that a string is not empty | -| has_length | verify that a string has exactly the expected length | -| has_length_in_range | verify that a string has a length that is in the expected range | -| has_length_less_than | verify that a string has a length less than the expected length | -| has_length_greater_than | verify that a string has a length greater than the expected length | -| has_at_most_length | verify that a string has a length less than or equal to the expected length | -| has_at_least_length | verify that a string has a length greater than or equal to the expected length | -| has_char_count | verify that a string contains exactly the expected number of characters | -| has_char_count_in_range | verify that a string contains a number of characters in the expected range | -| has_char_count_less_than | verify that a string contains less than the expected number of characters | -| has_char_count_greater_than | verify that a string contains more than the expected number of characters | -| has_at_most_char_count | verify that a string contains at most the expected number of characters | -| has_at_least_char_count | verify that a string contains at least the expected number of characters | -| contains | verify that a string contains the expected substring or character | -| does_not_contain | verify that a string does not contain the expected substring or character | -| starts_with | verify that a string starts with the expected substring or character | -| does_not_start_with | verify that a string does not start with the expected substring or character | -| ends_with | verify that a string ends with the expected substring or character | -| does_not_end_with | verify that a string does not end with the expected substring or character | -| contains_any_of | verify that a string contains any character from a collection of `char`s | -| does_not_contain_any_of | verify that a string does not contain any character from a collection of `char`s | -| matches | verify that a string matches the given regex (requires `regex` feature) | -| does_not_match | verify that a string does not match the given regex (requires `regex` feature) | - -for strings of type `CString` and `CStr`: - -| assertion | description | -|-------------------------|--------------------------------------------------------------------------------| -| is_empty | verify that a string is empty | -| is_not_empty | verify that a string is not empty | -| has_length | verify that a string has exactly the expected length | -| has_length_in_range | verify that a string has a length that is in the expected range | -| has_length_less_than | verify that a string has a length less than the expected length | -| has_length_greater_than | verify that a string has a length greater than the expected length | -| has_at_most_length | verify that a string has a length less than or equal to the expected length | -| has_at_least_length | verify that a string has a length greater than or equal to the expected length | - -for strings of type `OsString` and `OsStr` (requires crate feature `std`): - -| assertion | description | -|-------------------------|--------------------------------------------------------------------------------| -| is_empty | verify that a string is empty | -| is_not_empty | verify that a string is not empty | -| has_length | verify that a string has exactly the expected length | -| has_length_in_range | verify that a string has a length that is in the expected range | -| has_length_less_than | verify that a string has a length less than the expected length | -| has_length_greater_than | verify that a string has a length greater than the expected length | -| has_at_most_length | verify that a string has a length less than or equal to the expected length | -| has_at_least_length | verify that a string has a length greater than or equal to the expected length | - -### Option - -for the `Option` type. - -| assertion | description | -|-----------|------------------------------------------------------------------------| -| is_some | verify that an option has some value | -| is_none | verify that an option has no value | -| has_value | verify that an option has a value equal to the expected one | -| some | verify that an option has some value and map the subject to this value | - -### Result - -for the `Result` type. - -| assertion | description | -|-------------------|----------------------------------------------------------------------------------------------------------| -| is_ok | verify that a result has an ok value | -| is_err | verify that a result has an err value | -| has_value | verify that a result has an ok value that is equal to the expected value | -| has_error | verify that a result has an err value that is equal to the expected error | -| has_error_message | verify that a result has an err value with a string representation that is equal to the expected message | -| ok | verify that a result has an ok value and map the subject to this ok value | -| err | verify that a result has an err value and map the subject to this err value | - -### Error - -for types that implement `std::error::Error`. - -| assertion | description | -|--------------------|----------------------------------------------------------------------------------------------------| -| has_no_source | verify that an error has no source | -| has_source | verify that an error has some source | -| has_source_message | verify that an error has a source which converts to a string that is equal to the expected message | - -### Debug and Display string - -for types that implement `core::fmt::Debug`: - -| assertion | description | -|----------------------------|----------------------------------------------------------------------------| -| has_debug_string | verify that a type formatted for debug is equal to the expected string | -| does_not_have_debug_string | verify that a type formatted for debug is not equal to the expected string | -| debug_string | map the subject to its debug string representation | - -for types that implement `core::fmt::Display`: - -| assertion | description | -|------------------------------|------------------------------------------------------------------------------| -| has_display_string | verify that a type formatted for display is equal to the expected string | -| does_not_have_display_string | verify that a type formatted for display is not equal to the expected string | -| display_string | map the subject to its display string representation | - -### Emptiness - -for collections and strings. - -| assertion | description | -|--------------|--------------------------------------| -| is_empty | verify that the subject is empty | -| is_not_empty | verify that the subject is not empty | - -The implementation of these assertions is based on the property trait [`IsEmptyProperty`]. -Implementing this property for any type enables these assertions for that type. - -### Length (Size) - -for collections and strings. - -| assertion | description | -|-------------------------|-----------------------------------------------------------------------------------| -| has_length | verify that the subject has exactly the expected length | -| has_length_in_range | verify that the subject has a length that is in the expected range | -| has_length_less_than | verify that the subject has a length less than the expected length | -| has_length_greater_than | verify that the subject has a length greater than the expected length | -| has_at_most_length | verify that the subject has a length less than or equal to the expected length | -| has_at_least_length | verify that the subject has a length greater than or equal to the expected length | - -The implementation of these assertions is based on the property trait [`LengthProperty`]. -Implementing this property for any type enables these assertions for that type. - -### Iterator / Collection - -for all iterators. - -| assertion | description | -|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------| -| contains | verify that an iterator/collection contains an item that is equal to the expected value | -| does_not_contain | verify that an iterator/collection does not contain an item that is equal to the expected value | -| contains_exactly_in_any_order | verify that an iterator/collection contains exactly the expected values and nothing else in any order | -| contains_any_of | verify that an iterator/collection contains at least one of the specified values | -| does_not_contain_any_of | verify that an iterator/collection does not contain any of the specified values | -| contains_all_of | verify that an iterator/collection contains all the expected values in any order (and maybe more) | -| contains_only | verify that an iterator/collection contains only the specified values and nothing else in any order and ignoring duplicates | -| contains_only_once | verify that an iterator/collection contains only the specified values in any order and each of them only once | -| single_element | verify that an iterator/collection contains exaclty one element and return a `Spec` for that one element | -| filtered_on | filter the elements of an iterator/collection on a condition and return a `Spec` that contains the filtered elements | -| any_satisfies | verify that at least one element of an iterator/collection satisfies a predicate | -| all_satisfy | verify that all elements of an iterator/collection satisfy a predicate | -| none_satisfies | verify that none of the elements of an iterator/collection satisfies a predicate | -| each_element | verify that all elements of an iterator/collection satisfy the given assertions | -| any_element | verify that at least one element of an iterator/collection satisfies the given assertions | - -for iterators that yield items in a well-defined order. - -| assertion | description | -|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------| -| contains_exactly | verify that an iterator/collection contains exactly the expected values and nothing else in the given order | -| contains_sequence | verify that an iterator/collection contains the given sequence of values in the given order and without extra values between the sequence values | -| contains_all_in_order | verify that an iterator/collection contains all the given values and in the given order, possibly with other values between them | -| starts_with | verify that an iterator/collection contains the given values as the first elements in order | -| ends_with | verify that an iterator/collection contains the given values as the last elements in order | -| first_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the first element | -| last_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the last element | -| nth_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the nth element | -| elements_at | pick the elements of an iterator/collection at the given positions and return a `Spec` containing the selected elements | - -### Maps - -For all types that implement the [`MapProperties`] trait. Currently, it is implemented for -`std::collections::HashMap`, `std::collections::BTreeMap` and `hashbrown::HashMap`. - -| assertion | description | -|-------------------------|----------------------------------------------------------------------------------------------------------------------------------| -| contains_key | verify that a map contains a mapping for the expected key | -| contains_keys | verify that a map contains a mapping for each of the expected keys, ignoring order and duplicates | -| contains_exactly_keys | verify that a map contains exactly one mapping for each of the expected keys and no other mapping, ignoring order and duplicates | -| does_not_contain_key | verify that a map does not contain any mapping for the given key | -| does_not_contain_keys | verify that a map does not contain any mapping for the given keys | -| contains_value | verify that a map contains at least one mapping where the value is equal to the expected one | -| contains_values | verify that a map contains for each expected value at least one mapping where the value is equal, ignoring order and duplicates | -| does_not_contain_value | verify that a map does not contain any mapping where the value is equal to the given one | -| does_not_contain_values | verify that a map does not contain any mapping where the value is equal to one of the given values | - -### Panic - -for code inside a closure. - -requires the crate feature `panic` which is enabled by default. - -| assertion | description | -|---------------------|--------------------------------------------------------| -| does_not_panic | verify that some code does not panic | -| panics | verify that some code panics | -| panics_with_message | verify that some code panics with the expected message | - -To start assertions on code, use the `assert_that_code!()` macro. +The [crate-level documentation][docs-url] contains lots of examples as a quick introduction. ## Custom assertions @@ -520,12 +180,6 @@ possibilities for custom assertions, including examples. [`assertions`]: https://docs.rs/asserting/latest/asserting/assertions/ -[`IsEmptyProperty`]: https://docs.rs/asserting/latest/asserting/properties/trait.IsEmptyProperty.html - -[`LengthProperty`]: https://docs.rs/asserting/latest/asserting/properties/trait.LengthProperty.html - -[`MapProperties`]: https://docs.rs/asserting/latest/asserting/properties/trait.MapProperties.html - [`NO_COLOR`]: https://no-color.org/ [AssertJ]: https://assertj.github.io/doc/ diff --git a/docs/available-assertions.md b/docs/available-assertions.md new file mode 100644 index 0000000..75021a7 --- /dev/null +++ b/docs/available-assertions.md @@ -0,0 +1,367 @@ +## Available Assertions + +This document gives an overview of the assertions provided by `asserting`. + +For a comprehensive list of available assertions, including examples, browse the documentation of +the [`assertions`] module. The documentation of the assertion traits contains examples on how to use +each assertion. The [crate-level documentation][docs-url] contains lots of examples as a quick +introduction. + +### Equality + +for all types that implement `PartialEq` with `E` being the type of the expected value: + +| assertion | description | +|-----------------|----------------------------------------------------------| +| is_equal_to | verify that the subject is equal to an expected value | +| is_not_equal_to | verify that the subject is not equal to a specific value | + +for all types that implement `PartialEq` and the subject is of the same type as the expected value: + +| assertion | description | +|----------------|-----------------------------------------------------------------------------------------------| +| is_same_as | verify that the subject is of the same type and has the same value than the expected value | +| is_not_same_as | verify that the subject is of the same type and has a different value than the expected value | + +### Order + +for all types that implement `PartialOrd` with `E` being the type of the expected value: + +| assertion | description | +|-----------------|----------------------------------------------------------------------------------------| +| is_greater_than | verify that the subject is greater than the expected value | +| is_less_than | verify that the subject is less than the expected value | +| is_at_least | verify that the subject is greater than or equal to the expected value | +| is_at_most | verify that the subject is less than or equal to the expected value | +| is_before | verify that the subject is less than (before) the expected value | +| is_after | verify that the subject is greater than (after) the expected value | +| is_between | verify that the subject is between a min value (inclusive) and a max value (inclusive) | + +### Range + +for all types `T` that implement `PartialOrd` and `E` implementing `PartialOrd` with `E` +being the type of the expected value: + +| assertion | description | +|-----------------|-------------------------------------------------------| +| is_in_range | verify that the subject is in the expected range | +| is_not_in_range | verify that the subject is not in the specified range | + +### Integer and Float + +for numbers of types + +* integer primitives: `i8`, `i16`, `i32`, `i64`, `i128` and `isize` +* floating point numbers: `f32` and `f64` +* `num_bigint::BigInt` (requires crate feature `num-bigint`) +* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) +* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) + +| assertion | description | +|-----------------|------------------------------------------------------| +| is_negative | verify that the subject is a negative number | +| is_not_negative | verify that the subject is a positive number or zero | +| is_positive | verify that the subject is a positive number | +| is_not_positive | verify that the subject is a finite number | + +for numbers of types + +* integer primitives: `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `u8`, `u16`, `u32`, `u64`, `u128` + and `usize` +* floating point numbers: `f32` and `f64` +* `num_bigint::BigInt` and `num_bigint::BigUint` (requires crate feature `num-bigint`) +* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) +* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) + +| assertion | description | +|-----------|--------------------------------------------------------------| +| is_zero | verify that the subject is the additive identity (zero) | +| is_one | verify that the subject is the multiplicative identity (one) | + +for floating point numbers of type `f32` and `f64`: + +| assertion | description | +|-----------------|-----------------------------------------------| +| is_infinite | verify that the subject is an infinite number | +| is_finite | verify that the subject is a finite number | +| is_not_a_number | verify that the subject is not a number | +| is_a_number | verify that the subject is a number | + +### Decimal number + +for decimal numbers of types + +* `bigdecimal:BigDecimal` and `bigdecimal:BigDecimalRef` (requires crate feature `bigdecimal`) +* `rust_decimal::Decimal` (requires crate feature `rust-decimal`) + +| assertion | description | +|------------------|----------------------------------------------------| +| has_scale_of | verify that the subject has the expected scale | +| has_precision_of | verify that the subject has the expected precision | +| is_integer | verify that the subject has zero fractional digits | + +### Float comparison + +for floating point numbers of type `f32` and `f64`. + +requires crate feature `float-cmp` which is enabled by default. + +| assertion | description | +|-----------------------------|--------------------------------------------------------------------------------------------------| +| is_close_to | verify that the subject is approximately equal to the expected value within a default margin | +| is_not_close_to | verify that the subject is not approximately equal to the expected value within a default margin | +| is_close_to_with_margin | verify that the subject is approximately equal to the expected value within the given margin | +| is_not_close_to_with_margin | verify that the subject is not approximately equal to the expected value within the given margin | + +### Date and Time + +for date, time and date-time values of the crates `chrono`, `jiff` and `time`. + +requires crate feature `chrono`, `jiff` or `time`. + +| assertion | description | +|-----------------------------|--------------------------------------------------------------------------------------------------| +| is_close_to_with_margin | verify that the subject is approximately equal to the expected value within the given margin | +| is_not_close_to_with_margin | verify that the subject is not approximately equal to the expected value within the given margin | + +### Character + +for `char`. + +| assertion | description | +|-----------------|-----------------------------------------------------------------| +| is_lowercase | verify that the character is lowercase | +| is_uppercase | verify that the character is uppercase | +| is_ascii | verify that the character is an ASCII character | +| is_alphabetic | verify that the character is an alphabetic character | +| is_alphanumeric | verify that the character is an alphabetic character or a digit | +| is_control_char | verify that the character is a control character | +| is_digit | verify that the character is a digit in the given radix | +| is_whitespace | verify that the character is whitespace | + +### Boolean + +for `bool`. + +| assertion | description | +|-----------|----------------------------------| +| is_true | verify that the subject is true | +| is_false | verify that the subject is false | + +### String + +for strings of type `String` and `str`: + +| assertion | description | +|-----------------------------|----------------------------------------------------------------------------------| +| is_empty | verify that a string is empty | +| is_not_empty | verify that a string is not empty | +| has_length | verify that a string has exactly the expected length | +| has_length_in_range | verify that a string has a length that is in the expected range | +| has_length_less_than | verify that a string has a length less than the expected length | +| has_length_greater_than | verify that a string has a length greater than the expected length | +| has_at_most_length | verify that a string has a length less than or equal to the expected length | +| has_at_least_length | verify that a string has a length greater than or equal to the expected length | +| has_char_count | verify that a string contains exactly the expected number of characters | +| has_char_count_in_range | verify that a string contains a number of characters in the expected range | +| has_char_count_less_than | verify that a string contains less than the expected number of characters | +| has_char_count_greater_than | verify that a string contains more than the expected number of characters | +| has_at_most_char_count | verify that a string contains at most the expected number of characters | +| has_at_least_char_count | verify that a string contains at least the expected number of characters | +| contains | verify that a string contains the expected substring or character | +| does_not_contain | verify that a string does not contain the expected substring or character | +| starts_with | verify that a string starts with the expected substring or character | +| does_not_start_with | verify that a string does not start with the expected substring or character | +| ends_with | verify that a string ends with the expected substring or character | +| does_not_end_with | verify that a string does not end with the expected substring or character | +| contains_any_of | verify that a string contains any character from a collection of `char`s | +| does_not_contain_any_of | verify that a string does not contain any character from a collection of `char`s | +| matches | verify that a string matches the given regex (requires `regex` feature) | +| does_not_match | verify that a string does not match the given regex (requires `regex` feature) | + +for strings of type `CString` and `CStr`: + +| assertion | description | +|-------------------------|--------------------------------------------------------------------------------| +| is_empty | verify that a string is empty | +| is_not_empty | verify that a string is not empty | +| has_length | verify that a string has exactly the expected length | +| has_length_in_range | verify that a string has a length that is in the expected range | +| has_length_less_than | verify that a string has a length less than the expected length | +| has_length_greater_than | verify that a string has a length greater than the expected length | +| has_at_most_length | verify that a string has a length less than or equal to the expected length | +| has_at_least_length | verify that a string has a length greater than or equal to the expected length | + +for strings of type `OsString` and `OsStr` (requires crate feature `std`): + +| assertion | description | +|-------------------------|--------------------------------------------------------------------------------| +| is_empty | verify that a string is empty | +| is_not_empty | verify that a string is not empty | +| has_length | verify that a string has exactly the expected length | +| has_length_in_range | verify that a string has a length that is in the expected range | +| has_length_less_than | verify that a string has a length less than the expected length | +| has_length_greater_than | verify that a string has a length greater than the expected length | +| has_at_most_length | verify that a string has a length less than or equal to the expected length | +| has_at_least_length | verify that a string has a length greater than or equal to the expected length | + +### Option + +for the `Option` type. + +| assertion | description | +|-----------|------------------------------------------------------------------------| +| is_some | verify that an option has some value | +| is_none | verify that an option has no value | +| has_value | verify that an option has a value equal to the expected one | +| some | verify that an option has some value and map the subject to this value | + +### Result + +for the `Result` type. + +| assertion | description | +|-------------------|----------------------------------------------------------------------------------------------------------| +| is_ok | verify that a result has an ok value | +| is_err | verify that a result has an err value | +| has_value | verify that a result has an ok value that is equal to the expected value | +| has_error | verify that a result has an err value that is equal to the expected error | +| has_error_message | verify that a result has an err value with a string representation that is equal to the expected message | +| ok | verify that a result has an ok value and map the subject to this ok value | +| err | verify that a result has an err value and map the subject to this err value | + +### Error + +for types that implement `std::error::Error`. + +| assertion | description | +|--------------------|----------------------------------------------------------------------------------------------------| +| has_no_source | verify that an error has no source | +| has_source | verify that an error has some source | +| has_source_message | verify that an error has a source which converts to a string that is equal to the expected message | + +### Debug and Display string + +for types that implement `core::fmt::Debug`: + +| assertion | description | +|----------------------------|----------------------------------------------------------------------------| +| has_debug_string | verify that a type formatted for debug is equal to the expected string | +| does_not_have_debug_string | verify that a type formatted for debug is not equal to the expected string | +| debug_string | map the subject to its debug string representation | + +for types that implement `core::fmt::Display`: + +| assertion | description | +|------------------------------|------------------------------------------------------------------------------| +| has_display_string | verify that a type formatted for display is equal to the expected string | +| does_not_have_display_string | verify that a type formatted for display is not equal to the expected string | +| display_string | map the subject to its display string representation | + +### Emptiness + +for collections and strings. + +| assertion | description | +|--------------|--------------------------------------| +| is_empty | verify that the subject is empty | +| is_not_empty | verify that the subject is not empty | + +The implementation of these assertions is based on the property trait [`IsEmptyProperty`]. +Implementing this property for any type enables these assertions for that type. + +### Length (Size) + +for collections and strings. + +| assertion | description | +|-------------------------|-----------------------------------------------------------------------------------| +| has_length | verify that the subject has exactly the expected length | +| has_length_in_range | verify that the subject has a length that is in the expected range | +| has_length_less_than | verify that the subject has a length less than the expected length | +| has_length_greater_than | verify that the subject has a length greater than the expected length | +| has_at_most_length | verify that the subject has a length less than or equal to the expected length | +| has_at_least_length | verify that the subject has a length greater than or equal to the expected length | + +The implementation of these assertions is based on the property trait [`LengthProperty`]. +Implementing this property for any type enables these assertions for that type. + +### Iterator / Collection + +for all iterators. + +| assertion | description | +|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------| +| contains | verify that an iterator/collection contains an item that is equal to the expected value | +| does_not_contain | verify that an iterator/collection does not contain an item that is equal to the expected value | +| contains_exactly_in_any_order | verify that an iterator/collection contains exactly the expected values and nothing else in any order | +| contains_any_of | verify that an iterator/collection contains at least one of the specified values | +| does_not_contain_any_of | verify that an iterator/collection does not contain any of the specified values | +| contains_all_of | verify that an iterator/collection contains all the expected values in any order (and maybe more) | +| contains_only | verify that an iterator/collection contains only the specified values and nothing else in any order and ignoring duplicates | +| contains_only_once | verify that an iterator/collection contains only the specified values in any order and each of them only once | +| single_element | verify that an iterator/collection contains exaclty one element and return a `Spec` for that one element | +| filtered_on | filter the elements of an iterator/collection on a condition and return a `Spec` that contains the filtered elements | +| any_satisfies | verify that at least one element of an iterator/collection satisfies a predicate | +| all_satisfy | verify that all elements of an iterator/collection satisfy a predicate | +| none_satisfies | verify that none of the elements of an iterator/collection satisfies a predicate | +| each_element | verify that all elements of an iterator/collection satisfy the given assertions | +| any_element | verify that at least one element of an iterator/collection satisfies the given assertions | + +for iterators that yield items in a well-defined order. + +| assertion | description | +|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------| +| contains_exactly | verify that an iterator/collection contains exactly the expected values and nothing else in the given order | +| contains_sequence | verify that an iterator/collection contains the given sequence of values in the given order and without extra values between the sequence values | +| contains_all_in_order | verify that an iterator/collection contains all the given values and in the given order, possibly with other values between them | +| starts_with | verify that an iterator/collection contains the given values as the first elements in order | +| ends_with | verify that an iterator/collection contains the given values as the last elements in order | +| first_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the first element | +| last_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the last element | +| nth_element | verify that an iterator/collection contains at least one element and return a `Spec` containing the nth element | +| elements_at | pick the elements of an iterator/collection at the given positions and return a `Spec` containing the selected elements | + +### Maps + +For all types that implement the [`MapProperties`] trait. Currently, it is implemented for +`std::collections::HashMap`, `std::collections::BTreeMap` and `hashbrown::HashMap`. + +| assertion | description | +|-------------------------|----------------------------------------------------------------------------------------------------------------------------------| +| contains_key | verify that a map contains a mapping for the expected key | +| contains_keys | verify that a map contains a mapping for each of the expected keys, ignoring order and duplicates | +| contains_exactly_keys | verify that a map contains exactly one mapping for each of the expected keys and no other mapping, ignoring order and duplicates | +| does_not_contain_key | verify that a map does not contain any mapping for the given key | +| does_not_contain_keys | verify that a map does not contain any mapping for the given keys | +| contains_value | verify that a map contains at least one mapping where the value is equal to the expected one | +| contains_values | verify that a map contains for each expected value at least one mapping where the value is equal, ignoring order and duplicates | +| does_not_contain_value | verify that a map does not contain any mapping where the value is equal to the given one | +| does_not_contain_values | verify that a map does not contain any mapping where the value is equal to one of the given values | + +### Panic + +for code inside a closure. + +requires the crate feature `panic` which is enabled by default. + +| assertion | description | +|---------------------|--------------------------------------------------------| +| does_not_panic | verify that some code does not panic | +| panics | verify that some code panics | +| panics_with_message | verify that some code panics with the expected message | + +To start assertions on code, use the `assert_that_code!()` macro. + + + + +[docs-url]: https://docs.rs/asserting + +[`assertions`]: https://docs.rs/asserting/latest/asserting/assertions/ + +[`IsEmptyProperty`]: https://docs.rs/asserting/latest/asserting/properties/trait.IsEmptyProperty.html + +[`LengthProperty`]: https://docs.rs/asserting/latest/asserting/properties/trait.LengthProperty.html + +[`MapProperties`]: https://docs.rs/asserting/latest/asserting/properties/trait.MapProperties.html From 2a136a046823d7f80918736f2d70398aaa8fdb1a Mon Sep 17 00:00:00 2001 From: haraldmaida Date: Sat, 17 Oct 2026 13:46:09 +0200 Subject: [PATCH 2/4] chore: rewrite README.md with absolute URLs for crates.io --- Cargo.toml | 1 + build.rs | 26 ++++++ docs/cratesio/README.md | 185 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 build.rs create mode 100644 docs/cratesio/README.md diff --git a/Cargo.toml b/Cargo.toml index 523cc7b..218cc20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ license = "MIT OR Apache-2.0" edition = "2024" rust-version = "1.88.0" repository = "https://github.com/innoave/asserting" +readme = "docs/cratesio/README.md" description = """ Fluent assertions for tests in Rust that are convenient to write and easy to extend. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..65d11df --- /dev/null +++ b/build.rs @@ -0,0 +1,26 @@ +//! This file is used to generate the README.md file for crates.io. +#![allow(clippy::expect_used)] + +const README_PATH: &str = "README.md"; +const CRATESIO_README_PATH: &str = "docs/cratesio/README.md"; +const REPOSITORY_URL: &str = "https://github.com/innoave/asserting/tree/v"; + +use std::{env, fs}; + +fn main() { + rewrite_readme_for_cratesio_with_absolute_urls(); +} + +fn rewrite_readme_for_cratesio_with_absolute_urls() { + let version = env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION must be set"); + + println!("cargo:rerun-if-changed={}", README_PATH); + + if let Ok(content) = fs::read_to_string(README_PATH) { + let target_url = format!("]({REPOSITORY_URL}{version}/docs/"); + let updated_content = content.replace("](docs/", &target_url); + + // Write README with absolute URLs for crates.io + let _ = fs::write(CRATESIO_README_PATH, updated_content); + } +} diff --git a/docs/cratesio/README.md b/docs/cratesio/README.md new file mode 100644 index 0000000..0987d5b --- /dev/null +++ b/docs/cratesio/README.md @@ -0,0 +1,185 @@ +# Asserting + +[![crates.io][crates-badge]][crates-url] +[![docs.rs][docs-badge]][docs-url] +![MSRV][msrv-badge] +[![code coverage][code-coverage-badge]][code-coverage-url] + +Fluent assertions for tests in Rust. An extensive collection of assertions to express the intent of +the expected result in a test. + +Fluent assertions help with expressing the intent of a test. Other developers quickly understand +what the expected result of a test should be. One remembers more easily what could be wrong in the +case of a test fails some months later due to a regression. The autocomplete feature of a coding +editor or IDE helps with writing assertions as it suggests possible assertion methods. Distinct and +more helpful error messages help to spot the difference between the expected value and the actual +result. Fluent assertions read like natural English. + +Features of `asserting`: + +* assertions are convenient to write and easy to read +* helpful error messages in case of failing assertions +* colored diffs between expected and actual values + (see ["Highlighted differences"](#highlighted-differences)) +* chaining of multiple assertions on the same subject (see ["Chaining assertions"]) +* concise and expressive assertions for more complex types like collections +* field-by-field recursive comparison (see ["Field-by-field recursive comparison"]) +* soft assertions (execute multiple assertions before panicking) (see ["Soft assertions"]) +* support for asserting custom types with provided assertions (see ["Asserting custom types"]) +* custom representation of values in failure reports or if a (foreign) type does not implement + [`Debug`] (see ["Type formatting (aka Representation)"]) +* provide a reasonable number of assertions out of the box +* do not require that asserted types have to implement traits if it is not absolutely necessary +* custom assertions (see ["Custom assertions"](#custom-assertions)) +* support no-std environments + +For an overview of the provided features and many examples on how to use `asserting` see the +[crate-level documentation][docs-url]. + +The assertion methods are mostly inspired by the [AssertJ] library for Java but adopted to Rust's +syntax and idioms. + +To see what is changed with each release, see the [changelog](CHANGELOG.md). + +## no-std support + +To use `asserting` in a no-std environment, disable the default features. Features that do not +require std can still be added. + +```toml +[dev-dependencies] +asserting = { version = "0.17", default-features = false, features = ["colored", "float-cmp", "recursive", "regex"] } +``` + +Note that an allocator is needed for no-std. + +## Crate Features + +Overview of the crate features of `asserting`. The column "no-std" specifies if this feature is +available in no-std environments. The column "default" specifies if this feature is enabled by +default. + +| Feature | Description | no-std | default | +|----------------|-------------------------------------------------------------------------------------------------------------------------------------|:------:|:-------:| +| `std` | Use the `std` library | no | yes | +| `colored` | Colored highlighting of differences between actual and expected value | yes | yes | +| `recursive` | Field-by-field recursive comparison mode | yes | yes | +| `float-cmp` | Floating point comparison (`ìs_close_to`) | yes | yes | +| `regex` | String matches Regex assertions (`matching`) | yes | yes | +| `panic` | Assert that code panics (with the expected message) | no | yes | +| `num-bigint` | Enhanced support for `num-bigint::BigInt` | yes | no | +| `bigdecimal` | Enhanced support for `bigdecimal::BigDecimal` | yes | no | +| `rust-decimal` | Enhanded support for `rust_decimal::Decimal` | yes | no | +| `temporal` | Support for writing assertions for temporal types | yes | no | +| `chrono` | `is_close_to_with_margin` assertion for `chrono` types:
`NaiveDate`, `NaiveTime`, `NaiveDateTime` and `DateTime` | yes | no | +| `jiff` | `is_close_to_with_margin` assertion for `jiff` types:
`Timestamp`, `civil::Date`, `civil::Time`, `civil::DateTime` and `Zoned` | yes | no | +| `time` | `is_close_to_with_margin` assertion for `time` types:
`Timestamp`, `Date`, `Time`, `PlainDateTime` and `OffsetDateTime` | yes | no | + +## Highlighted differences + +`asserting` can highlight the differences between the expected value (s) and the actual value (s) +when printing assertion failures to the terminal. The colored diffs in assertion failures look like +this: + +![colored diffs in terminal](examples/colored_diffs.png) + +Highlighted differences in the failure message help with spotting the difference between actual and +expected values and make finding the reason for a failing test much easier. + +It supports different variants of how differences are highlighted. + +| Mode | Effect | +|------------|-----------------------------------------------------------------------------------------------------------------------------------| +| bold | Differences are printed in bold letters, without coloring. | +| red-green | Differences are printed in the colors green and red. | +| red-blue | Differences are printed in the CVD-friendly colors blue and red. | +| red-yellow | Differences are printed in the colors yellow and red. | +| off | Switches off highlighting. The differences are not highlighted at all. | + +The mode can be configured by setting the environment variable `ASSERTING_HIGHLIGHT_DIFFS` to one of +the modes in the table above. The value is case-insensitive. E.g., setting the environment variable +to values like `Red-Blue`, `Bold` or `OFF` works as well. + +The intended way for configuring the highlighting mode is to set the environment variable in the +configuration for `Cargo` by adding it to the `[env]` section in your `~/.cargo/config.toml` file: + +```toml,no_sync +[env] +ASSERTING_HIGHLIGHT_DIFFS = "red-blue" +``` + +By default, the mode `red-green` is used. Differences are colored in +green and red. + +Differences are only highlighted if the crate feature `colored` is enabled. The configuration via +the environment variable only works when the crate feature `std` is enabled too. In no-std projects, +the default colors red and green are used. + +*Asserting* respects the [`NO_COLOR`] environment variable. If the `NO_COLOR` environment variable +is set, no colors are used regardless of the configured highlight mode. + +## Available Assertions + +The `asserting` crate provides a broad set of assertions for testing and validation purposes. An +overview of the available assertions can be found in the +[Available Assertions](https://github.com/innoave/asserting/tree/v0.17.0/docs/available-assertions.md) document. + +All provided assertions are defined by an assertion-trait in the [`assertions`] module. Each +assertion method comes with a short explanation of how to use it and examples in the API +documentation. So the relevant documentation is at your hand within your editor or IDE when you +are writing assertions in tests. + +The [crate-level documentation][docs-url] contains lots of examples as a quick introduction. + +## Custom assertions + +`asserting` provides three kinds of custom assertions: + +1. use any predicate function as a custom assertion (see "[predicate as custom assertion]") +2. property-based assertions can be used with any type that implements the related property (see + "[property-based assertions]") +3. write custom assertion methods by defining and implementing an extension trait (see + "[custom assertions]") + +The mentioned references link to a chapter in the crate's documentation that describes the +possibilities for custom assertions, including examples. + + + +[crates-badge]: https://img.shields.io/crates/v/asserting.svg + +[crates-url]: https://crates.io/crates/asserting + +[docs-badge]: https://docs.rs/asserting/badge.svg + +[docs-url]: https://docs.rs/asserting + +[msrv-badge]: https://img.shields.io/crates/msrv/asserting?color=chocolate + +[code-coverage-badge]: https://codecov.io/github/innoave/asserting/graph/badge.svg?token=o0w7R7J0Op + +[code-coverage-url]: https://codecov.io/github/innoave/asserting + + + +["Asserting custom types"]: https://docs.rs/asserting/latest/asserting/#asserting-custom-types + +["Chaining assertions"]: https://docs.rs/asserting/latest/asserting/#chaining-assertions-on-the-same-subject + +["Field-by-field recursive comparison"]: https://docs.rs/asserting/latest/asserting/#field-by-field-recursive-comparison + +["Type formatting (aka Representation)"]: https://docs.rs/asserting/latest/asserting/#type-formatting-aka-representation + +["soft assertions"]: https://docs.rs/asserting/#soft-assertions + +[custom assertions]: https://docs.rs/asserting/#custom-assertions + +[predicate as custom assertion]: https://docs.rs/asserting/#predicate-as-custom-assertion + +[property-based assertions]: https://docs.rs/asserting/#property-based-assertions + +[`assertions`]: https://docs.rs/asserting/latest/asserting/assertions/ + +[`NO_COLOR`]: https://no-color.org/ + +[AssertJ]: https://assertj.github.io/doc/ From e0fa064717c4073aaee275e29c168afd7f4ed5d2 Mon Sep 17 00:00:00 2001 From: haraldmaida Date: Sat, 17 Oct 2026 13:51:11 +0200 Subject: [PATCH 3/4] chore: fix code formatting --- examples/custom_assertion_reusing_existing.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/custom_assertion_reusing_existing.rs b/examples/custom_assertion_reusing_existing.rs index 656e67c..305665c 100644 --- a/examples/custom_assertion_reusing_existing.rs +++ b/examples/custom_assertion_reusing_existing.rs @@ -83,9 +83,9 @@ where .extracting_ref("body", |s| &s.body) .contains_exactly(expected_body) .and() - .extracting_ref("head", |s| &s.head) - .is_equal_to(expected_head) - .display_failures(); + .extracting_ref("head", |s| &s.head) + .is_equal_to(expected_head) + .display_failures(); // if there are failures, we fail the whole assertion according to the // current `FailingStrategy`. if !failures.is_empty() { From f93bbd68ec67bdfdaae40445108de1194ac90889 Mon Sep 17 00:00:00 2001 From: haraldmaida Date: Sat, 17 Oct 2026 13:53:15 +0200 Subject: [PATCH 4/4] chore: fix clippy warning --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 65d11df..df604f9 100644 --- a/build.rs +++ b/build.rs @@ -14,7 +14,7 @@ fn main() { fn rewrite_readme_for_cratesio_with_absolute_urls() { let version = env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION must be set"); - println!("cargo:rerun-if-changed={}", README_PATH); + println!("cargo:rerun-if-changed={README_PATH}"); if let Ok(content) = fs::read_to_string(README_PATH) { let target_url = format!("]({REPOSITORY_URL}{version}/docs/");