1+ using System ;
2+ using FluentAssertions ;
3+ using Xunit ;
4+
5+ namespace Light . GuardClauses . Tests . ComparableAssertions ;
6+
7+ public static class MustBeLessThanOrApproximatelyTests
8+ {
9+ [ Theory ]
10+ [ InlineData ( 17.3 , 17.4 ) ]
11+ [ InlineData ( 19.9999999 , 20.0 ) ]
12+ [ InlineData ( - 5.5 , - 5.49998 ) ]
13+ [ InlineData ( 0.0001 , 0.0001 ) ]
14+ public static void EqualOrLess_Double ( double first , double second ) =>
15+ first . MustBeLessThanOrApproximately ( second ) . Should ( ) . Be ( first ) ;
16+
17+ [ Theory ]
18+ [ InlineData ( 15.9 , 15.91 , 0.1 ) ]
19+ [ InlineData ( 24.45 , 24.49999 , 0.0001 ) ]
20+ [ InlineData ( - 3.2 , - 3.12 , 0.001 ) ]
21+ [ InlineData ( 2.37 , 2.369 , 0.05 ) ]
22+ public static void EqualOrLessWithTolerance_Double ( double first , double second , double tolerance ) =>
23+ first . MustBeLessThanOrApproximately ( second , tolerance ) . Should ( ) . Be ( first ) ;
24+
25+ [ Theory ]
26+ [ InlineData ( 100.2f , 100.225f ) ]
27+ [ InlineData ( - 5.900005f , - 5.9f ) ]
28+ [ InlineData ( - 0.02f , 0f ) ]
29+ [ InlineData ( 0f , 0.00001f ) ]
30+ public static void EqualOrLess_Float ( float first , float second ) =>
31+ first . MustBeLessThanOrApproximately ( second ) . Should ( ) . Be ( first ) ;
32+
33+ [ Theory ]
34+ [ InlineData ( 1.0f , 2.0f , 0.1f ) ]
35+ [ InlineData ( 1.0f , 1.0f , 0.1f ) ]
36+ [ InlineData ( 1.1f , 1.01f , 0.1f ) ]
37+ [ InlineData ( 1.0f , 2.0f , 1.0f ) ]
38+ public static void EqualOrLessWithTolerance_Float ( float first , float second , float tolerance ) =>
39+ first . MustBeLessThanOrApproximately ( second , tolerance ) . Should ( ) . Be ( first ) ;
40+
41+ [ Theory ]
42+ [ InlineData ( 5.3 , 5.0 , 0.1 ) ]
43+ [ InlineData ( 100.5 , 100.0 , 0.1 ) ]
44+ [ InlineData ( - 19.8 , - 20.0 , 0.1 ) ]
45+ [ InlineData ( 0.0003 , 0.0001 , 0.00005 ) ]
46+ public static void NotLessThanOrApproximately_Double ( double value , double other , double tolerance )
47+ {
48+ var act = ( ) => value . MustBeLessThanOrApproximately ( other , tolerance , nameof ( value ) ) ;
49+
50+ var exceptionAssertion = act . Should ( ) . Throw < ArgumentOutOfRangeException > ( ) . Which ;
51+ exceptionAssertion . Message . Should ( ) . Contain (
52+ $ "{ nameof ( value ) } must be less than or approximately equal to { other } with a tolerance of { tolerance } , but it actually is { value } ."
53+ ) ;
54+ exceptionAssertion . ParamName . Should ( ) . BeSameAs ( nameof ( value ) ) ;
55+ }
56+
57+ [ Theory ]
58+ [ InlineData ( 5.3f , 5.0f , 0.1f ) ]
59+ [ InlineData ( 100.5f , 100.0f , 0.1f ) ]
60+ [ InlineData ( - 19.8f , - 20.0f , 0.1f ) ]
61+ [ InlineData ( 0.0003f , 0.0001f , 0.00005f ) ]
62+ public static void NotLessThanOrApproximately_Float ( float value , float other , float tolerance )
63+ {
64+ var act = ( ) => value . MustBeLessThanOrApproximately ( other , tolerance , nameof ( value ) ) ;
65+
66+ var exceptionAssertion = act . Should ( ) . Throw < ArgumentOutOfRangeException > ( ) . Which ;
67+ exceptionAssertion . Message . Should ( ) . Contain (
68+ $ "{ nameof ( value ) } must be less than or approximately equal to { other } with a tolerance of { tolerance } , but it actually is { value } ."
69+ ) ;
70+ exceptionAssertion . ParamName . Should ( ) . BeSameAs ( nameof ( value ) ) ;
71+ }
72+
73+ [ Fact ]
74+ public static void DefaultTolerance_Double ( )
75+ {
76+ // Should pass - difference is 0.00005 which is less than default tolerance 0.0001
77+ const double value = 1.0 ;
78+ value . MustBeLessThanOrApproximately ( 1.00005 ) . Should ( ) . Be ( value ) ;
79+
80+ // Should throw - difference is 0.0002 which is greater than default tolerance 0.0001
81+ Action act = ( ) => 1.0002 . MustBeLessThanOrApproximately ( 1.0 , "parameter" ) ;
82+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
83+ . WithParameterName ( "parameter" ) ;
84+ }
85+
86+ [ Fact ]
87+ public static void DefaultTolerance_Float ( )
88+ {
89+ // Should pass - difference is 0.00005f which is less than default tolerance 0.0001f
90+ const float value = 1.0f ;
91+ value . MustBeLessThanOrApproximately ( 1.00005f ) . Should ( ) . Be ( value ) ;
92+
93+ // Should throw - difference is 0.0002f which is greater than default tolerance 0.0001f
94+ Action act = ( ) => 1.0002f . MustBeLessThanOrApproximately ( 1.0f , "parameter" ) ;
95+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
96+ . WithParameterName ( "parameter" ) ;
97+ }
98+
99+ [ Fact ]
100+ public static void CustomException_Double ( ) =>
101+ Test . CustomException (
102+ 5.3 ,
103+ 5.0 ,
104+ ( x , y , exceptionFactory ) => x . MustBeLessThanOrApproximately ( y , exceptionFactory )
105+ ) ;
106+
107+ [ Fact ]
108+ public static void CustomExceptionWithTolerance_Double ( ) =>
109+ Test . CustomException (
110+ 5.5 ,
111+ 5.0 ,
112+ 0.1 ,
113+ ( x , y , z , exceptionFactory ) => x . MustBeLessThanOrApproximately ( y , z , exceptionFactory )
114+ ) ;
115+
116+ [ Fact ]
117+ public static void CustomException_Float ( ) =>
118+ Test . CustomException (
119+ 5.3f ,
120+ 5.0f ,
121+ ( x , y , exceptionFactory ) => x . MustBeLessThanOrApproximately ( y , exceptionFactory )
122+ ) ;
123+
124+ [ Fact ]
125+ public static void CustomExceptionWithTolerance_Float ( ) =>
126+ Test . CustomException (
127+ 5.5f ,
128+ 5.0f ,
129+ 0.1f ,
130+ ( x , y , z , exceptionFactory ) => x . MustBeLessThanOrApproximately ( y , z , exceptionFactory )
131+ ) ;
132+
133+ [ Fact ]
134+ public static void NoCustomExceptionThrown_Double ( ) =>
135+ 5.1 . MustBeLessThanOrApproximately ( 5.2 , ( _ , _ ) => null ) . Should ( ) . Be ( 5.1 ) ;
136+
137+ [ Fact ]
138+ public static void NoCustomExceptionThrownWithTolerance_Double ( ) =>
139+ 5.0 . MustBeLessThanOrApproximately ( 5.2 , 0.1 , ( _ , _ , _ ) => null ) . Should ( ) . Be ( 5.0 ) ;
140+
141+ [ Fact ]
142+ public static void NoCustomExceptionThrown_Float ( ) =>
143+ 5.0f . MustBeLessThanOrApproximately ( 5.2f , ( _ , _ ) => null ) . Should ( ) . Be ( 5.0f ) ;
144+
145+ [ Fact ]
146+ public static void NoCustomExceptionThrownWithTolerance_Float ( ) =>
147+ 5.0f . MustBeLessThanOrApproximately ( 5.2f , 0.1f , ( _ , _ , _ ) => null ) . Should ( ) . Be ( 5.0f ) ;
148+
149+ [ Fact ]
150+ public static void CustomMessage_Double ( ) =>
151+ Test . CustomMessage < ArgumentOutOfRangeException > (
152+ message => 101.0 . MustBeLessThanOrApproximately ( 100.0 , 0.5 , message : message )
153+ ) ;
154+
155+ [ Fact ]
156+ public static void CustomMessage_Float ( ) =>
157+ Test . CustomMessage < ArgumentOutOfRangeException > (
158+ message => 101.0f . MustBeLessThanOrApproximately ( 100.0f , 0.5f , message : message )
159+ ) ;
160+
161+ [ Fact ]
162+ public static void CallerArgumentExpression_Double ( )
163+ {
164+ const double seventyNinePoint0 = 79.0 ;
165+
166+ var act = ( ) => seventyNinePoint0 . MustBeLessThanOrApproximately ( 78.1 ) ;
167+
168+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
169+ . WithParameterName ( nameof ( seventyNinePoint0 ) ) ;
170+ }
171+
172+ [ Fact ]
173+ public static void CallerArgumentExpressionWithTolerance_Double ( )
174+ {
175+ const double threePointFive = 3.5 ;
176+
177+ var act = ( ) => threePointFive . MustBeLessThanOrApproximately ( 3.14159 , 0.1 ) ;
178+
179+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
180+ . WithParameterName ( nameof ( threePointFive ) ) ;
181+ }
182+
183+ [ Fact ]
184+ public static void CallerArgumentExpression_Float ( )
185+ {
186+ const float seventyNinePoint0 = 79.0f ;
187+
188+ var act = ( ) => seventyNinePoint0 . MustBeLessThanOrApproximately ( 78.1f ) ;
189+
190+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
191+ . WithParameterName ( nameof ( seventyNinePoint0 ) ) ;
192+ }
193+
194+ [ Fact ]
195+ public static void CallerArgumentExpressionWithTolerance_Float ( )
196+ {
197+ const float threePointFive = 3.5f ;
198+
199+ var act = ( ) => threePointFive . MustBeLessThanOrApproximately ( 3.14159f , 0.1f ) ;
200+
201+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
202+ . WithParameterName ( nameof ( threePointFive ) ) ;
203+ }
204+
205+ #if NET8_0
206+ [ Theory ]
207+ [ InlineData ( 15.9 , 15.91 , 0.1 ) ]
208+ [ InlineData ( 24.45 , 24.4999 , 0.0001 ) ]
209+ [ InlineData ( - 3.2 , - 3.12 , 0.001 ) ]
210+ [ InlineData ( 2.37 , 2.369 , 0.05 ) ]
211+ [ InlineData ( 14.0 , 15.0 , 0.1 ) ] // Less than case
212+ [ InlineData ( 15.0 , 14.95 , 0.1 ) ] // Approximately equal case
213+ public static void EqualOrLessWithCustomTolerance_GenericDouble ( double first , double second , double tolerance ) =>
214+ first . MustBeLessThanOrApproximately < double > ( second , tolerance ) . Should ( ) . Be ( first ) ;
215+
216+ [ Theory ]
217+ [ InlineData ( 5 , 10 , 1 ) ] // Less than case
218+ [ InlineData ( 5 , 5 , 1 ) ] // Equal case
219+ [ InlineData ( 6 , 5 , 1 ) ] // Approximately equal case
220+ [ InlineData ( 7 , 5 , 2 ) ] // Not less than or approximately equal case
221+ public static void EqualOrLessWithCustomTolerance_GenericInt32 ( int first , int second , int tolerance ) =>
222+ first . MustBeLessThanOrApproximately ( second , tolerance ) . Should ( ) . Be ( first ) ;
223+
224+ [ Theory ]
225+ [ InlineData ( 5L , 10L , 1L ) ] // Less than case
226+ [ InlineData ( 5L , 5L , 1L ) ] // Equal case
227+ [ InlineData ( 6L , 5L , 1L ) ] // Approximately equal case
228+ [ InlineData ( 7L , 4L , 3L ) ] // Not less than or approximately equal case
229+ public static void EqualOrLessWithCustomTolerance_GenericInt64 ( long first , long second , long tolerance ) =>
230+ first . MustBeLessThanOrApproximately ( second , tolerance ) . Should ( ) . Be ( first ) ;
231+
232+ [ Theory ]
233+ [ MemberData ( nameof ( DecimalTestData ) ) ]
234+ public static void GenericDecimalWithCustomTolerance (
235+ decimal first ,
236+ decimal second ,
237+ decimal tolerance
238+ ) =>
239+ first . MustBeLessThanOrApproximately ( second , tolerance ) . Should ( ) . Be ( first ) ;
240+
241+ public static TheoryData < decimal , decimal , decimal > DecimalTestData ( ) => new ( )
242+ {
243+ { 1.1m , 1.3m , 0.1m } , // Less than case
244+ { 1.1m , 1.1m , 0.1m } , // Equal case
245+ { 1.1m , 1.0m , 0.2m } , // Approximately equal case
246+ { 1.3m , 1.292m , 0.1m } , // Not less than or approximately equal case
247+ } ;
248+
249+ [ Theory ]
250+ [ InlineData ( 5.3 , 5.0 , 0.1 ) ]
251+ [ InlineData ( 100.5 , 100.0 , 0.1 ) ]
252+ [ InlineData ( - 19.8 , - 20.0 , 0.1 ) ]
253+ [ InlineData ( 0.0003 , 0.0001 , 0.00005 ) ]
254+ public static void NotLessThanOrApproximately_Generic ( double value , double other , double tolerance )
255+ {
256+ var act = ( ) => value . MustBeLessThanOrApproximately < double > ( other , tolerance , nameof ( value ) ) ;
257+
258+ var exceptionAssertion = act . Should ( ) . Throw < ArgumentOutOfRangeException > ( ) . Which ;
259+ exceptionAssertion . Message . Should ( ) . Contain (
260+ $ "{ nameof ( value ) } must be less than or approximately equal to { other } with a tolerance of { tolerance } , but it actually is { value } ."
261+ ) ;
262+ exceptionAssertion . ParamName . Should ( ) . BeSameAs ( nameof ( value ) ) ;
263+ }
264+
265+ [ Fact ]
266+ public static void CustomExceptionWithTolerance_Generic ( ) =>
267+ Test . CustomException (
268+ 5.5 ,
269+ 5.0 ,
270+ 0.1 ,
271+ ( x , y , t , exceptionFactory ) => x . MustBeLessThanOrApproximately < double > ( y , t , exceptionFactory )
272+ ) ;
273+
274+ [ Fact ]
275+ public static void NoCustomExceptionThrown_Generic ( ) =>
276+ 5.0 . MustBeLessThanOrApproximately < double > ( 5.2 , 0.1 , ( _ , _ , _ ) => null ) . Should ( ) . Be ( 5.0 ) ;
277+
278+ [ Fact ]
279+ public static void CustomMessage_Generic ( ) =>
280+ Test . CustomMessage < ArgumentOutOfRangeException > (
281+ message => 101.0 . MustBeLessThanOrApproximately < double > ( 100.0 , 0.5 , message : message )
282+ ) ;
283+
284+ [ Fact ]
285+ public static void CallerArgumentExpressionWithTolerance_Generic ( )
286+ {
287+ const double seventyNinePoint0 = 79.0 ;
288+
289+ var act = ( ) => seventyNinePoint0 . MustBeLessThanOrApproximately < double > ( 78.1 , 0.5 ) ;
290+
291+ act . Should ( ) . Throw < ArgumentOutOfRangeException > ( )
292+ . WithParameterName ( nameof ( seventyNinePoint0 ) ) ;
293+ }
294+ #endif
295+ }
0 commit comments