Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ sdiff = { version = "0.1", optional = true }
anyhow = "1"
proptest = "1"
serial_test = "3"
time = { version = "0.3", default-features = false, features = ["macros"] }
version-sync = "0.9"

[lints.rust]
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ for all types that implement `PartialEq<E>` with `E` being the type of the expec

for all types that implement `PartialOrd<E>` 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 |
| 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

Expand Down
1 change: 1 addition & 0 deletions examples/fixture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ mod dummy_extern_uses {
#[cfg(feature = "colored")]
use sdiff as _;
use serial_test as _;
use time as _;
use version_sync as _;
}
35 changes: 35 additions & 0 deletions src/assertions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ pub trait AssertIsCloseToWithDefaultMargin<E> {
/// # Examples
///
/// ```
/// use time::macros::date;
/// use asserting::prelude::*;
///
/// let some_result: u16 = 42;
Expand All @@ -122,6 +123,18 @@ pub trait AssertIsCloseToWithDefaultMargin<E> {
/// assert_that!(some_result).is_at_least(41);
/// assert_that!(some_result).is_greater_than(41);
/// assert_that!(some_result).is_less_than(43);
///
/// let some_letter: char = 'M';
///
/// assert_that!(some_letter).is_before('P');
/// assert_that!(some_letter).is_after('K');
/// assert_that!(some_letter).is_between('A', 'Z');
///
/// let some_date = date!(2025-04-20);
///
/// assert_that!(some_date).is_before(date!(2025-04-21));
/// assert_that!(some_date).is_after(date!(2025-04-19));
/// assert_that!(some_date).is_between(date!(2025-04-19), date!(2025-04-21));
///```
pub trait AssertOrder<E> {
/// Verifies that the subject is less than some expected value.
Expand All @@ -140,6 +153,28 @@ pub trait AssertOrder<E> {
/// value.
#[track_caller]
fn is_at_least(self, expected: E) -> Self;

/// Verifies that the subject is before some expected value.
///
/// This is equivalent to asserting a subject to be less than the expected
/// value.
#[track_caller]
fn is_before(self, expected: E) -> Self;

/// Verifies that the subject is after some expected value.
///
/// This is equivalent to asserting a subject to be greater than the
/// expected value.
#[track_caller]
fn is_after(self, expected: E) -> Self;

/// Verifies that the subject is between a min value and a max value.
///
/// Min and max values are included. This is equivalent to asserting a
/// subject to be greater than or equal to the min value and to be less than
/// or equal to the max value.
#[track_caller]
fn is_between(self, min: E, max: E) -> Self;
}

/// Assert whether a value is within an expected range.
Expand Down
16 changes: 16 additions & 0 deletions src/expectations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ pub struct IsAtLeast<E> {
pub expected: E,
}

#[must_use]
pub struct IsBefore<E> {
pub expected: E,
}

#[must_use]
pub struct IsAfter<E> {
pub expected: E,
}

#[must_use]
pub struct IsBetween<E> {
pub min: E,
pub max: E,
}

#[must_use]
pub struct IsInRange<E> {
pub expected_range: RangeInclusive<E>,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,5 +653,6 @@ type TestCodeSnippetsInReadme = ();
mod dummy_extern_uses {
use proptest as _;
use serial_test as _;
use time as _;
use version_sync as _;
}
82 changes: 81 additions & 1 deletion src/order/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

use crate::assertions::AssertOrder;
use crate::colored::{mark_missing, mark_unexpected};
use crate::expectations::{IsAtLeast, IsAtMost, IsGreaterThan, IsLessThan};
use crate::expectations::{
IsAfter, IsAtLeast, IsAtMost, IsBefore, IsBetween, IsGreaterThan, IsLessThan,
};
use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec};
use crate::std::fmt::Debug;
use crate::std::{format, string::String};
Expand All @@ -28,6 +30,18 @@ where
fn is_at_least(self, expected: E) -> Self {
self.expecting(IsAtLeast { expected })
}

fn is_before(self, expected: E) -> Self {
self.expecting(IsBefore { expected })
}

fn is_after(self, expected: E) -> Self {
self.expecting(IsAfter { expected })
}

fn is_between(self, min: E, max: E) -> Self {
self.expecting(IsBetween { min, max })
}
}

impl<S, E> Expectation<S> for IsLessThan<E>
Expand Down Expand Up @@ -106,5 +120,71 @@ where
}
}

impl<S, E> Expectation<S> for IsBefore<E>
where
S: PartialOrd<E> + Debug,
E: Debug,
{
fn test(&mut self, subject: &S) -> bool {
subject < &self.expected
}

fn message(&self, expression: Expression<'_>, actual: &S, format: &DiffFormat) -> String {
let marked_actual = mark_unexpected(actual, format);
let marked_expected = mark_missing(&self.expected, format);
format!(
"expected {expression} is before {:?}\n but was: {marked_actual}\n expected: < {marked_expected}",
self.expected,
)
}
}

impl<S, E> Expectation<S> for IsAfter<E>
where
S: PartialOrd<E> + Debug,
E: Debug,
{
fn test(&mut self, subject: &S) -> bool {
subject > &self.expected
}

fn message(&self, expression: Expression<'_>, actual: &S, format: &DiffFormat) -> String {
let marked_actual = mark_unexpected(actual, format);
let marked_expected = mark_missing(&self.expected, format);
format!(
"expected {expression} is after {:?}\n but was: {marked_actual}\n expected: > {marked_expected}",
self.expected,
)
}
}

impl<S, E> Expectation<S> for IsBetween<E>
where
S: PartialOrd<E> + Debug,
E: Debug,
{
fn test(&mut self, subject: &S) -> bool {
subject >= &self.min && subject <= &self.max
}

fn message(&self, expression: Expression<'_>, actual: &S, format: &DiffFormat) -> String {
let marked_actual = mark_unexpected(actual, format);
let marked_start = if actual < &self.min {
mark_missing(&self.min, format)
} else {
format!("{:?}", &self.min)
};
let marked_end = if actual > &self.max {
mark_missing(&self.max, format)
} else {
format!("{:?}", &self.max)
};
format!(
"expected {expression} is between {:?} and {:?}\n but was: {marked_actual}\n expected: {marked_start} <= x <= {marked_end}",
self.min, self.max
)
}
}

#[cfg(test)]
mod tests;
117 changes: 117 additions & 0 deletions src/order/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,83 @@ fn verify_char_is_at_least_other_char_fails() {
);
}

#[test]
fn char_is_before_other_char() {
let subject = 'L';

assert_that(subject).is_before('M');
}

#[test]
fn verify_char_is_before_other_char_fails() {
let subject = 'L';

let failures = verify_that(subject)
.named("my_thing")
.is_before('L')
.display_failures();

assert_eq!(
failures,
&[r"assertion failed: expected my_thing is before 'L'
but was: 'L'
expected: < 'L'
"]
);
}

#[test]
fn char_is_after_other_char() {
let subject = 'L';

assert_that(subject).is_after('K');
}

#[test]
fn verify_char_is_after_other_char_fails() {
let subject = 'L';

let failures = verify_that(subject)
.named("my_thing")
.is_after('L')
.display_failures();

assert_eq!(
failures,
&[r"assertion failed: expected my_thing is after 'L'
but was: 'L'
expected: > 'L'
"]
);
}

#[test]
fn char_is_between_a_min_char_and_a_max_char() {
let subject = 'L';

assert_that(subject).is_between('K', 'M');
assert_that(subject).is_between('L', 'P');
assert_that(subject).is_between('H', 'L');
}

#[test]
fn verify_char_is_between_a_min_char_and_a_max_char_fails() {
let subject = 'L';

let failures = verify_that(subject)
.named("my_thing")
.is_between('M', 'P')
.display_failures();

assert_eq!(
failures,
&[r"assertion failed: expected my_thing is between 'M' and 'P'
but was: 'L'
expected: 'M' <= x <= 'P'
"]
);
}

#[cfg(feature = "colored")]
mod colored {
use crate::prelude::*;
Expand Down Expand Up @@ -285,4 +362,44 @@ mod colored {
"]
);
}

#[test]
fn highlight_diffs_is_between_but_is_below_min() {
let subject = 'L';

let failures = verify_that(subject)
.with_diff_format(DIFF_FORMAT_RED_YELLOW)
.is_between('M', 'P')
.display_failures();

assert_eq!(
failures,
&[
"assertion failed: expected subject is between 'M' and 'P'\n \
but was: \u{1b}[31m'L'\u{1b}[0m\n \
expected: \u{1b}[33m'M'\u{1b}[0m <= x <= 'P'\n\
"
]
);
}

#[test]
fn highlight_diffs_is_between_but_is_above_max() {
let subject = 'L';

let failures = verify_that(subject)
.with_diff_format(DIFF_FORMAT_RED_YELLOW)
.is_between('H', 'K')
.display_failures();

assert_eq!(
failures,
&[
"assertion failed: expected subject is between 'H' and 'K'\n \
but was: \u{1b}[31m'L'\u{1b}[0m\n \
expected: 'H' <= x <= \u{1b}[33m'K'\u{1b}[0m\n\
"
]
);
}
}
1 change: 1 addition & 0 deletions tests/version_numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod dummy_extern_uses {
#[cfg(feature = "colored")]
use sdiff as _;
use serial_test as _;
use time as _;
}

#[test]
Expand Down
Loading