View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.commons.lang;
18  
19  import static org.apache.juneau.commons.utils.CollectionUtils.*;
20  import static org.apache.juneau.junit.bct.BctAssertions.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import org.apache.juneau.*;
24  import org.junit.jupiter.api.*;
25  
26  class FloatValue_Test extends TestBase {
27  
28  	//-----------------------------------------------------------------------------------------------------------------
29  	// Basic tests
30  	//-----------------------------------------------------------------------------------------------------------------
31  
32  	@Test
33  	void a01_create() {
34  		var v = FloatValue.create();
35  		assertEquals(0.0f, v.get());
36  	}
37  
38  	@Test
39  	void a02_of() {
40  		var v = FloatValue.of(3.14f);
41  		assertEquals(3.14f, v.get(), 0.001f);
42  	}
43  
44  	@Test
45  	void a03_constructor() {
46  		var v = new FloatValue(2.71f);
47  		assertEquals(2.71f, v.get(), 0.001f);
48  	}
49  
50  	@Test
51  	void a04_constructor_withNull() {
52  		var v = new FloatValue(null);
53  		assertNull(v.get());
54  	}
55  
56  	//-----------------------------------------------------------------------------------------------------------------
57  	// Inherited Value<Float> methods
58  	//-----------------------------------------------------------------------------------------------------------------
59  
60  	@Test
61  	void b01_set() {
62  		var v = FloatValue.create();
63  		v.set(5.5f);
64  		assertEquals(5.5f, v.get(), 0.001f);
65  	}
66  
67  	@Test
68  	void b02_setIfEmpty() {
69  		var v = new FloatValue(null);
70  		v.setIfEmpty(1.5f);
71  		assertEquals(1.5f, v.get(), 0.001f);
72  
73  		v.setIfEmpty(2.5f);
74  		assertEquals(1.5f, v.get(), 0.001f); // Should not change
75  	}
76  
77  	@Test
78  	void b03_orElse() {
79  		var v = new FloatValue(null);
80  		assertEquals(9.9f, v.orElse(9.9f), 0.001f);
81  
82  		v.set(4.2f);
83  		assertEquals(4.2f, v.orElse(9.9f), 0.001f);
84  	}
85  
86  	@Test
87  	void b04_map() {
88  		var v = FloatValue.of(5.0f);
89  		var v2 = v.map(x -> x * 2);
90  		assertEquals(10.0f, v2.get(), 0.001f);
91  	}
92  
93  	@Test
94  	void b05_ifPresent() {
95  		var v = FloatValue.of(7.5f);
96  		var sb = new StringBuilder();
97  		v.ifPresent(x -> sb.append(x));
98  		assertEquals("7.5", sb.toString());
99  	}
100 
101 	@Test
102 	void b06_isPresent() {
103 		var v = new FloatValue(null);
104 		assertFalse(v.isPresent());
105 
106 		v.set(1.0f);
107 		assertTrue(v.isPresent());
108 	}
109 
110 	@Test
111 	void b07_isEmpty() {
112 		var v = new FloatValue(null);
113 		assertEmpty(v);
114 
115 		v.set(1.0f);
116 		assertNotEmpty(v);
117 	}
118 
119 	@Test
120 	void b08_getAndSet() {
121 		var v = FloatValue.of(1.5f);
122 		assertEquals(1.5f, v.getAndSet(2.5f), 0.001f);
123 		assertEquals(2.5f, v.get(), 0.001f);
124 	}
125 
126 	@Test
127 	void b09_getAndUnset() {
128 		var v = FloatValue.of(3.5f);
129 		assertEquals(3.5f, v.getAndUnset(), 0.001f);
130 		assertNull(v.get());
131 	}
132 
133 	//-----------------------------------------------------------------------------------------------------------------
134 	// Use case scenarios
135 	//-----------------------------------------------------------------------------------------------------------------
136 
137 	@Test
138 	void c01_trackingRunningAverage() {
139 		var sum = FloatValue.create();
140 		var count = FloatValue.create();
141 
142 		l(1.5f, 2.5f, 3.5f, 4.5f).forEach(x -> {
143 			sum.set(sum.get() + x);
144 			count.set(count.get() + 1);
145 		});
146 
147 		float average = sum.get() / count.get();
148 		assertEquals(3.0f, average, 0.001f);
149 	}
150 
151 	@Test
152 	void c02_accumulatingValues() {
153 		var total = FloatValue.create();
154 
155 		l(0.1f, 0.2f, 0.3f, 0.4f).forEach(x -> {
156 			total.set(total.get() + x);
157 		});
158 
159 		assertEquals(1.0f, total.get(), 0.001f);
160 	}
161 
162 	@Test
163 	void c03_trackingMinValue() {
164 		var min = FloatValue.of(Float.MAX_VALUE);
165 
166 		l(5.5f, 1.2f, 3.8f, 0.9f, 2.1f).forEach(x -> {
167 			if (x < min.get()) {
168 				min.set(x);
169 			}
170 		});
171 
172 		assertEquals(0.9f, min.get(), 0.001f);
173 	}
174 
175 	@Test
176 	void c04_multiplierChaining() {
177 		var multiplier = FloatValue.of(1.0f);
178 
179 		l(2.0f, 3.0f, 1.5f).forEach(x -> {
180 			multiplier.set(multiplier.get() * x);
181 		});
182 
183 		assertEquals(9.0f, multiplier.get(), 0.001f);
184 	}
185 
186 	//-----------------------------------------------------------------------------------------------------------------
187 	// is(float, float) - precision-based equality
188 	//-----------------------------------------------------------------------------------------------------------------
189 
190 	@Test
191 	void d01_is_exactMatch() {
192 		var v = FloatValue.of(3.14f);
193 		assertTrue(v.is(3.14f, 0.0f));
194 		assertTrue(v.is(3.14f, 0.001f));
195 	}
196 
197 	@Test
198 	void d02_is_withinPrecision() {
199 		var v = FloatValue.of(3.14f);
200 		assertTrue(v.is(3.14f, 0.01f));
201 		assertTrue(v.is(3.15f, 0.02f));
202 		assertFalse(v.is(3.15f, 0.001f));
203 	}
204 
205 	@Test
206 	void d03_is_nullValue() {
207 		var v = new FloatValue(null);
208 		assertFalse(v.is(3.14f, 0.01f));
209 		assertFalse(v.is(0.0f, 0.01f));
210 	}
211 
212 	@Test
213 	void d04_is_zeroPrecision() {
214 		var v = FloatValue.of(5.0f);
215 		assertTrue(v.is(5.0f, 0.0f));
216 		assertFalse(v.is(5.001f, 0.0f));
217 	}
218 
219 	@Test
220 	void d05_is_largePrecision() {
221 		var v = FloatValue.of(100.0f);
222 		assertTrue(v.is(50.0f, 100.0f));
223 		assertTrue(v.is(150.0f, 100.0f));
224 		assertFalse(v.is(201.0f, 100.0f));
225 	}
226 
227 	@Test
228 	void d06_is_precisionComparison() {
229 		// Demonstrates precision-based comparison
230 		var v = FloatValue.of(3.14159f);
231 		assertFalse(v.is(3.14f, 0.001f)); // Not within 0.001
232 		assertTrue(v.is(3.14f, 0.002f));  // Within 0.002
233 	}
234 
235 	@Test
236 	void d07_is_negativeValues() {
237 		var v = FloatValue.of(-5.5f);
238 		assertTrue(v.is(-5.5f, 0.0f));
239 		assertTrue(v.is(-5.4f, 0.2f));
240 		assertTrue(v.is(-5.6f, 0.2f));
241 		assertFalse(v.is(-5.0f, 0.4f));
242 	}
243 
244 	@Test
245 	void d08_is_negativePrecision_throwsException() {
246 		var v = FloatValue.of(3.14f);
247 		assertThrows(IllegalArgumentException.class, () -> v.is(3.14f, -0.01f));
248 	}
249 
250 	@Test
251 	void d09_is_boundaryValue() {
252 		var v = FloatValue.of(10.0f);
253 		assertTrue(v.is(10.5f, 0.5f)); // Exactly at boundary
254 		assertFalse(v.is(10.51f, 0.5f)); // Just outside boundary
255 	}
256 
257 	@Test
258 	void d10_is_verySmallNumbers() {
259 		var v = FloatValue.of(0.0001f);
260 		assertTrue(v.is(0.0002f, 0.00015f));
261 		assertFalse(v.is(0.0002f, 0.00005f));
262 	}
263 
264 	@Test
265 	void d11_is_afterSet() {
266 		var v = FloatValue.of(1.0f);
267 		assertTrue(v.is(1.0f, 0.01f));
268 
269 		v.set(2.0f);
270 		assertFalse(v.is(1.0f, 0.01f));
271 		assertTrue(v.is(2.0f, 0.01f));
272 	}
273 
274 	@Test
275 	void d12_is_scientificNotation() {
276 		var v = FloatValue.of(1.23e5f);
277 		assertTrue(v.is(1.23e5f, 0.0f));
278 		assertTrue(v.is(1.24e5f, 1000.0f));
279 		assertFalse(v.is(1.24e5f, 100.0f));
280 	}
281 
282 	//-----------------------------------------------------------------------------------------------------------------
283 	// isAny(float, float...) - precision-based matching
284 	//-----------------------------------------------------------------------------------------------------------------
285 
286 	@Test
287 	void e01_isAny_withinPrecision() {
288 		var v = FloatValue.of(3.14f);
289 		assertTrue(v.isAny(0.01f, 2.5f, 3.15f, 5.0f));  // Matches 3.15f within 0.01f
290 		assertTrue(v.isAny(0.01f, 3.14f, 3.15f));       // Matches both
291 		assertFalse(v.isAny(0.001f, 1.0f, 2.0f, 5.0f));  // No match within 0.001f
292 	}
293 
294 	@Test
295 	void e02_isAny_exactMatch() {
296 		var v = FloatValue.of(5.0f);
297 		assertTrue(v.isAny(0.0f, 5.0f, 6.0f, 7.0f));
298 		assertTrue(v.isAny(0.0f, 1.0f, 5.0f));
299 		assertFalse(v.isAny(0.0f, 1.0f, 2.0f, 3.0f));
300 	}
301 
302 	@Test
303 	void e03_isAny_nullValue() {
304 		var v = new FloatValue(null);
305 		assertFalse(v.isAny(0.01f, 1.0f, 2.0f, 3.0f));
306 		assertFalse(v.isAny(0.0f, 0.0f, 1.0f));
307 	}
308 
309 	@Test
310 	void e04_isAny_emptyArray() {
311 		var v = FloatValue.of(3.14f);
312 		assertFalse(v.isAny(0.01f));  // Only precision, no values
313 	}
314 
315 	@Test
316 	void e05_isAny_zeroPrecision() {
317 		var v = FloatValue.of(5.0f);
318 		assertTrue(v.isAny(0.0f, 5.0f, 6.0f));
319 		assertFalse(v.isAny(0.0f, 5.001f, 6.0f));
320 	}
321 
322 	@Test
323 	void e06_isAny_largePrecision() {
324 		var v = FloatValue.of(100.0f);
325 		assertTrue(v.isAny(100.0f, 50.0f, 150.0f, 200.0f));
326 		assertTrue(v.isAny(100.0f, 0.0f, 201.0f));  // 0.0f matches (100.0f - 0.0f = 100.0f <= 100.0f)
327 		assertTrue(v.isAny(100.0f, 0.0f, 202.0f));  // 0.0f matches (100.0f - 0.0f = 100.0f <= 100.0f)
328 		assertFalse(v.isAny(99.0f, 0.0f, 202.0f));  // Neither matches (100.0f - 0.0f = 100.0f > 99.0f, 100.0f - 202.0f = 102.0f > 99.0f)
329 	}
330 
331 	@Test
332 	void e07_isAny_precisionComparison() {
333 		var v = FloatValue.of(3.14159f);
334 		assertFalse(v.isAny(0.001f, 3.14f, 3.15f)); // Not within 0.001f
335 		assertTrue(v.isAny(0.002f, 3.14f, 3.15f));  // Within 0.002f
336 	}
337 
338 	@Test
339 	void e08_isAny_negativeValues() {
340 		var v = FloatValue.of(-5.5f);
341 		assertTrue(v.isAny(0.2f, -5.4f, -5.6f, -5.0f));
342 		assertTrue(v.isAny(0.0f, -5.5f, -6.0f));
343 		assertFalse(v.isAny(0.4f, -5.0f, -6.0f));
344 	}
345 
346 	@Test
347 	void e09_isAny_negativePrecision_throwsException() {
348 		var v = FloatValue.of(3.14f);
349 		assertThrows(IllegalArgumentException.class, () -> v.isAny(-0.01f, 3.14f, 3.15f));
350 	}
351 
352 	@Test
353 	void e10_isAny_boundaryValue() {
354 		var v = FloatValue.of(10.0f);
355 		assertTrue(v.isAny(0.5f, 9.5f, 10.5f, 11.0f)); // 9.5f and 10.5f are exactly at boundary
356 		assertTrue(v.isAny(0.5f, 9.5f, 10.51f, 11.0f)); // 9.5f matches (10.0f - 9.5f = 0.5f <= 0.5f)
357 		assertFalse(v.isAny(0.49f, 9.5f, 10.51f, 11.0f)); // None match (10.0f - 9.5f = 0.5f > 0.49f, 10.0f - 10.51f = 0.51f > 0.49f)
358 	}
359 
360 	@Test
361 	void e11_isAny_verySmallNumbers() {
362 		var v = FloatValue.of(0.0001f);
363 		assertTrue(v.isAny(0.00015f, 0.0002f, 0.0003f));
364 		assertFalse(v.isAny(0.00005f, 0.0002f, 0.0003f));
365 	}
366 
367 	@Test
368 	void e12_isAny_afterSet() {
369 		var v = FloatValue.of(1.0f);
370 		assertTrue(v.isAny(0.01f, 1.0f, 2.0f));
371 
372 		v.set(2.0f);
373 		assertFalse(v.isAny(0.01f, 1.0f, 1.5f));
374 		assertTrue(v.isAny(0.01f, 2.0f, 2.5f));
375 	}
376 }
377