asserting/
number.rs

1//! Implementations of assertions specific for numbers.
2
3use crate::assertions::{AssertInfinity, AssertNotANumber, AssertNumericIdentity, AssertSignum};
4use crate::colored::{mark_missing, mark_missing_substr, mark_unexpected};
5use crate::expectations::{
6    IsANumber, IsFinite, IsInfinite, IsNegative, IsNotANumber, IsNotNegative, IsNotPositive, IsOne,
7    IsPositive, IsZero,
8};
9use crate::properties::{
10    AdditiveIdentityProperty, InfinityProperty, IsNanProperty, MultiplicativeIdentityProperty,
11    SignumProperty,
12};
13use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec};
14use crate::std::fmt::Debug;
15use crate::std::format;
16use crate::std::string::String;
17
18impl<S, R> AssertSignum for Spec<'_, S, R>
19where
20    S: SignumProperty + Debug,
21    R: FailingStrategy,
22{
23    fn is_negative(self) -> Self {
24        self.expecting(IsNegative)
25    }
26
27    fn is_not_negative(self) -> Self {
28        self.expecting(IsNotNegative)
29    }
30
31    fn is_positive(self) -> Self {
32        self.expecting(IsPositive)
33    }
34
35    fn is_not_positive(self) -> Self {
36        self.expecting(IsNotPositive)
37    }
38}
39
40impl<S> Expectation<S> for IsNegative
41where
42    S: SignumProperty + Debug,
43{
44    fn test(&mut self, subject: &S) -> bool {
45        subject.is_negative_property()
46    }
47
48    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
49        let marked_actual = mark_unexpected(actual, format);
50        let marked_expected = mark_missing_substr("< 0", format);
51        format!("expected {expression} is negative\n   but was: {marked_actual}\n  expected: {marked_expected}")
52    }
53}
54
55impl<S> Expectation<S> for IsNotNegative
56where
57    S: SignumProperty + Debug,
58{
59    fn test(&mut self, subject: &S) -> bool {
60        !subject.is_negative_property()
61    }
62
63    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
64        let marked_actual = mark_unexpected(actual, format);
65        let marked_expected = mark_missing_substr(">= 0", format);
66        format!("expected {expression} is not negative\n   but was: {marked_actual}\n  expected: {marked_expected}")
67    }
68}
69
70impl<S> Expectation<S> for IsPositive
71where
72    S: SignumProperty + Debug,
73{
74    fn test(&mut self, subject: &S) -> bool {
75        subject.is_positive_property()
76    }
77
78    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
79        let marked_actual = mark_unexpected(actual, format);
80        let marked_expected = mark_missing_substr("> 0", format);
81        format!("expected {expression} is positive\n   but was: {marked_actual}\n  expected: {marked_expected}")
82    }
83}
84
85impl<S> Expectation<S> for IsNotPositive
86where
87    S: SignumProperty + Debug,
88{
89    fn test(&mut self, subject: &S) -> bool {
90        !subject.is_positive_property()
91    }
92
93    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
94        let marked_actual = mark_unexpected(actual, format);
95        let marked_expected = mark_missing_substr("<= 0", format);
96        format!("expected {expression} is not positive\n   but was: {marked_actual}\n  expected: {marked_expected}")
97    }
98}
99
100impl<S, R> AssertNumericIdentity for Spec<'_, S, R>
101where
102    S: AdditiveIdentityProperty + MultiplicativeIdentityProperty + PartialEq + Debug,
103    R: FailingStrategy,
104{
105    fn is_zero(self) -> Self {
106        self.expecting(IsZero)
107    }
108
109    fn is_one(self) -> Self {
110        self.expecting(IsOne)
111    }
112}
113
114impl<S> Expectation<S> for IsZero
115where
116    S: AdditiveIdentityProperty + PartialEq + Debug,
117{
118    fn test(&mut self, subject: &S) -> bool {
119        *subject == <S as AdditiveIdentityProperty>::ADDITIVE_IDENTITY
120    }
121
122    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
123        let marked_actual = mark_unexpected(actual, format);
124        let marked_expected = mark_missing(&S::ADDITIVE_IDENTITY, format);
125        format!("expected {expression} is zero\n   but was: {marked_actual}\n  expected: {marked_expected}")
126    }
127}
128
129impl<S> Expectation<S> for IsOne
130where
131    S: MultiplicativeIdentityProperty + PartialEq + Debug,
132{
133    fn test(&mut self, subject: &S) -> bool {
134        *subject == <S as MultiplicativeIdentityProperty>::MULTIPLICATIVE_IDENTITY
135    }
136
137    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
138        let marked_actual = mark_unexpected(actual, format);
139        let marked_expected = mark_missing(&S::MULTIPLICATIVE_IDENTITY, format);
140        format!("expected {expression} is one\n   but was: {marked_actual}\n  expected: {marked_expected}")
141    }
142}
143
144impl<S, R> AssertInfinity for Spec<'_, S, R>
145where
146    S: InfinityProperty + Debug,
147    R: FailingStrategy,
148{
149    fn is_infinite(self) -> Self {
150        self.expecting(IsInfinite)
151    }
152
153    fn is_finite(self) -> Self {
154        self.expecting(IsFinite)
155    }
156}
157
158impl<S> Expectation<S> for IsFinite
159where
160    S: InfinityProperty + Debug,
161{
162    fn test(&mut self, subject: &S) -> bool {
163        subject.is_finite_property()
164    }
165
166    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
167        let marked_actual = mark_unexpected(actual, format);
168        let marked_expected = mark_missing_substr("a finite number", format);
169        format!("expected {expression} is finite\n   but was: {marked_actual}\n  expected: {marked_expected}")
170    }
171}
172
173impl<S> Expectation<S> for IsInfinite
174where
175    S: InfinityProperty + Debug,
176{
177    fn test(&mut self, subject: &S) -> bool {
178        subject.is_infinite_property()
179    }
180
181    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
182        let marked_actual = mark_unexpected(actual, format);
183        let marked_expected = mark_missing_substr("an infinite number", format);
184        format!("expected {expression} is infinite\n   but was: {marked_actual}\n  expected: {marked_expected}")
185    }
186}
187
188impl<S, R> AssertNotANumber for Spec<'_, S, R>
189where
190    S: IsNanProperty + Debug,
191    R: FailingStrategy,
192{
193    fn is_not_a_number(self) -> Self {
194        self.expecting(IsNotANumber)
195    }
196
197    fn is_a_number(self) -> Self {
198        self.expecting(IsANumber)
199    }
200}
201
202impl<S> Expectation<S> for IsANumber
203where
204    S: IsNanProperty + Debug,
205{
206    fn test(&mut self, subject: &S) -> bool {
207        !subject.is_nan_property()
208    }
209
210    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
211        let marked_actual = mark_unexpected(actual, format);
212        let marked_expected = mark_missing_substr("a number", format);
213        format!("expected {expression} is a number\n   but was: {marked_actual}\n  expected: {marked_expected}")
214    }
215}
216
217impl<S> Expectation<S> for IsNotANumber
218where
219    S: IsNanProperty + Debug,
220{
221    fn test(&mut self, subject: &S) -> bool {
222        subject.is_nan_property()
223    }
224
225    fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String {
226        let marked_actual = mark_unexpected(actual, format);
227        let marked_expected = mark_missing_substr("NaN", format);
228        format!("expected {expression} is not a number (NaN)\n   but was: {marked_actual}\n  expected: {marked_expected}")
229    }
230}