mod fixture;
use asserting::prelude::*;
use asserting::spec::{FailingStrategy, Spec};
use std::borrow::Borrow;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Coord {
x: i32,
y: i32,
}
struct Snake {
length: usize,
head: Coord,
body: Vec<Coord>,
}
trait AssertSnake {
#[track_caller]
fn has_body(self, expected_body: &[Coord]) -> Self;
}
impl<S, R> AssertSnake for Spec<'_, S, R>
where
S: Borrow<Snake>,
R: FailingStrategy,
{
fn has_body(mut self, expected_body: &[Coord]) -> Self {
let expected_body = expected_body.to_vec();
let expected_head = expected_body[0];
let actual_body = self.subject().borrow();
let failures = verify_that(actual_body)
.with_configured_diff_format()
.extracting_ref("length", |s| &s.length)
.is_equal_to(expected_body.len())
.and()
.extracting_ref("body", |s| &s.body)
.contains_exactly(expected_body)
.and()
.extracting_ref("head", |s| &s.head)
.is_equal_to(expected_head)
.display_failures();
if !failures.is_empty() {
self.do_fail_with_message(format!(
"assertion of snake body failed: \n\n{}",
failures.join("\n")
));
}
self
}
}
fn test() {
let snake = Snake {
length: 2,
head: Coord { x: 3, y: 1 },
body: vec![
Coord { x: 2, y: 1 },
Coord { x: 1, y: 2 },
Coord { x: -1, y: 1 },
],
};
assert_that!(snake).has_body(&[
Coord { x: 2, y: 1 },
Coord { x: 1, y: 1 },
Coord { x: 1, y: 2 },
]);
}
fn main() {
test();
}