Skip to main content

asserting/
length.rs

1//! Implementations of the emptiness and length assertions.
2
3use crate::assertions::{AssertEmptiness, AssertHasLength};
4use crate::colored::{mark_missing, mark_unexpected};
5use crate::expectations::{
6    has_at_least_length, has_at_most_length, has_length, has_length_greater_than,
7    has_length_in_range, has_length_less_than, is_empty, not, HasAtLeastLength, HasAtMostLength,
8    HasLength, HasLengthGreaterThan, HasLengthInRange, HasLengthLessThan, IsEmpty,
9};
10use crate::properties::{IsEmptyProperty, LengthProperty};
11use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec};
12use crate::std::fmt::Debug;
13use crate::std::ops::RangeBounds;
14use crate::std::{format, string::String};
15
16impl<S, R> AssertEmptiness for Spec<'_, S, R>
17where
18    S: IsEmptyProperty + Debug,
19    R: FailingStrategy,
20{
21    fn is_empty(self) -> Self {
22        self.expecting(is_empty())
23    }
24
25    fn is_not_empty(self) -> Self {
26        self.expecting(not(is_empty()))
27    }
28}
29
30impl<S> Expectation<S> for IsEmpty
31where
32    S: IsEmptyProperty + Debug,
33{
34    fn test(&mut self, subject: &S) -> bool {
35        subject.is_empty_property()
36    }
37
38    fn message(
39        &self,
40        expression: &Expression<'_>,
41        actual: &S,
42        inverted: bool,
43        format: &DiffFormat,
44    ) -> String {
45        let (not, expected) = if inverted {
46            ("not ", "<non-empty>")
47        } else {
48            ("", "<empty>")
49        };
50        let marked_actual = mark_unexpected(actual, format);
51        format!("expected {expression} to be {not}empty\n   but was: {marked_actual}\n  expected: {expected}")
52    }
53}
54
55impl Invertible for IsEmpty {}
56
57impl<S, R> AssertHasLength<usize> for Spec<'_, S, R>
58where
59    S: LengthProperty + Debug,
60    R: FailingStrategy,
61{
62    fn has_length(self, expected_length: usize) -> Self {
63        self.expecting(has_length(expected_length))
64    }
65
66    fn has_length_in_range<U>(self, expected_range: U) -> Self
67    where
68        U: RangeBounds<usize> + Debug,
69    {
70        self.expecting(has_length_in_range(expected_range))
71    }
72
73    fn has_length_less_than(self, expected_length: usize) -> Self {
74        self.expecting(has_length_less_than(expected_length))
75    }
76
77    fn has_length_greater_than(self, expected_length: usize) -> Self {
78        self.expecting(has_length_greater_than(expected_length))
79    }
80
81    fn has_at_most_length(self, expected_length: usize) -> Self {
82        self.expecting(has_at_most_length(expected_length))
83    }
84
85    fn has_at_least_length(self, expected_length: usize) -> Self {
86        self.expecting(has_at_least_length(expected_length))
87    }
88}
89
90impl<S> Expectation<S> for HasLength<usize>
91where
92    S: LengthProperty + Debug,
93{
94    fn test(&mut self, subject: &S) -> bool {
95        subject.length_property() == self.expected_length
96    }
97
98    fn message(
99        &self,
100        expression: &Expression<'_>,
101        actual: &S,
102        inverted: bool,
103        format: &DiffFormat,
104    ) -> String {
105        let not = if inverted { "not " } else { "" };
106        let marked_actual = mark_unexpected(&actual.length_property(), format);
107        let marked_expected = mark_missing(&self.expected_length, format);
108        format!(
109            "expected {expression} to {not}have a length of {}\n   but was: {marked_actual}\n  expected: {not}{marked_expected}",
110            self.expected_length,
111        )
112    }
113}
114
115impl Invertible for HasLength<usize> {}
116
117impl<S, R> Expectation<S> for HasLengthInRange<R, usize>
118where
119    S: LengthProperty + Debug,
120    R: RangeBounds<usize> + Debug,
121{
122    fn test(&mut self, subject: &S) -> bool {
123        self.expected_range.contains(&subject.length_property())
124    }
125
126    fn message(
127        &self,
128        expression: &Expression<'_>,
129        actual: &S,
130        inverted: bool,
131        format: &DiffFormat,
132    ) -> String {
133        let not = if inverted { "not " } else { "" };
134        let marked_actual = mark_unexpected(&actual.length_property(), format);
135        let marked_expected = mark_missing(&self.expected_range, format);
136        format!(
137            "expected {expression} to {not}have a length within range {:?}\n   but was: {marked_actual}\n  expected: {not}{marked_expected}",
138            self.expected_range,
139        )
140    }
141}
142
143impl<R> Invertible for HasLengthInRange<R, usize> {}
144
145impl<S> Expectation<S> for HasLengthLessThan<usize>
146where
147    S: LengthProperty + Debug,
148{
149    fn test(&mut self, subject: &S) -> bool {
150        subject.length_property() < self.expected_length
151    }
152
153    fn message(
154        &self,
155        expression: &Expression<'_>,
156        actual: &S,
157        inverted: bool,
158        format: &DiffFormat,
159    ) -> String {
160        let (not, cmp) = if inverted { ("not ", ">=") } else { ("", "<") };
161        let marked_actual = mark_unexpected(&actual.length_property(), format);
162        let marked_expected = mark_missing(&self.expected_length, format);
163        format!(
164            "expected {expression} to {not}have a length less than {:?}\n   but was: {marked_actual}\n  expected: {cmp} {marked_expected}",
165            self.expected_length,
166        )
167    }
168}
169
170impl Invertible for HasLengthLessThan<usize> {}
171
172impl<S> Expectation<S> for HasLengthGreaterThan<usize>
173where
174    S: LengthProperty + Debug,
175{
176    fn test(&mut self, subject: &S) -> bool {
177        subject.length_property() > self.expected_length
178    }
179
180    fn message(
181        &self,
182        expression: &Expression<'_>,
183        actual: &S,
184        inverted: bool,
185        format: &DiffFormat,
186    ) -> String {
187        let (not, cmp) = if inverted { ("not ", "<=") } else { ("", ">") };
188        let marked_actual = mark_unexpected(&actual.length_property(), format);
189        let marked_expected = mark_missing(&self.expected_length, format);
190        format!(
191            "expected {expression} to {not}have a length greater than {:?}\n   but was: {marked_actual}\n  expected: {cmp} {marked_expected}",
192            self.expected_length,
193        )
194    }
195}
196
197impl Invertible for HasLengthGreaterThan<usize> {}
198
199impl<S> Expectation<S> for HasAtMostLength<usize>
200where
201    S: LengthProperty + Debug,
202{
203    fn test(&mut self, subject: &S) -> bool {
204        subject.length_property() <= self.expected_length
205    }
206
207    fn message(
208        &self,
209        expression: &Expression<'_>,
210        actual: &S,
211        inverted: bool,
212        format: &DiffFormat,
213    ) -> String {
214        let (not, cmp) = if inverted { ("not ", ">") } else { ("", "<=") };
215        let marked_actual = mark_unexpected(&actual.length_property(), format);
216        let marked_expected = mark_missing(&self.expected_length, format);
217        format!(
218            "expected {expression} to {not}have at most a length of {:?}\n   but was: {marked_actual}\n  expected: {cmp} {marked_expected}",
219            self.expected_length,
220        )
221    }
222}
223
224impl Invertible for HasAtMostLength<usize> {}
225
226impl<S> Expectation<S> for HasAtLeastLength<usize>
227where
228    S: LengthProperty + Debug,
229{
230    fn test(&mut self, subject: &S) -> bool {
231        subject.length_property() >= self.expected_length
232    }
233
234    fn message(
235        &self,
236        expression: &Expression<'_>,
237        actual: &S,
238        inverted: bool,
239        format: &DiffFormat,
240    ) -> String {
241        let (not, cmp) = if inverted { ("not ", "<") } else { ("", ">=") };
242        let marked_actual = mark_unexpected(&actual.length_property(), format);
243        let marked_expected = mark_missing(&self.expected_length, format);
244        format!(
245            "expected {expression} to {not}have at least a length of {:?}\n   but was: {marked_actual}\n  expected: {cmp} {marked_expected}",
246            self.expected_length,
247        )
248    }
249}
250
251impl Invertible for HasAtLeastLength<usize> {}