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.utils;
18  
19  import static org.apache.juneau.commons.utils.CollectionUtils.*;
20  import static org.apache.juneau.commons.utils.Utils.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import java.lang.annotation.*;
24  import java.util.*;
25  import java.util.concurrent.atomic.AtomicInteger;
26  import java.util.function.*;
27  
28  import org.apache.juneau.*;
29  import org.apache.juneau.commons.function.*;
30  import org.apache.juneau.commons.lang.*;
31  import org.junit.jupiter.api.*;
32  
33  @Retention(RetentionPolicy.RUNTIME)
34  @interface TestAnnotation {
35  	String value() default "";
36  	int num() default 0;
37  }
38  
39  class Utils_Test extends TestBase {
40  
41  	//====================================================================================================
42  	// Constructor (line 56)
43  	//====================================================================================================
44  	@Test
45  	void a00_constructor() {
46  		// Test line 56: class declaration
47  		// Utils has a protected constructor, so it can be subclassed.
48  		// Create a subclass to access the protected constructor
49  		class TestUtils extends Utils {
50  			TestUtils() {
51  				super(); // This calls the protected Utils() constructor
52  			}
53  		}
54  		var testUtils = new TestUtils();
55  		assertNotNull(testUtils);
56  	}
57  
58  	//====================================================================================================
59  	// b(Object)
60  	//====================================================================================================
61  	@Test
62  	void a001_b() {
63  		assertTrue(bool(true));
64  		assertTrue(bool("true"));
65  		assertTrue(bool("TRUE"));
66  		assertFalse(bool(false));
67  		assertFalse(bool("false"));
68  		assertFalse(bool("FALSE"));
69  		assertFalse(bool(null));
70  		assertFalse(bool(""));
71  		assertFalse(bool(123));
72  		assertFalse(bool(new Object()));
73  	}
74  
75  	//====================================================================================================
76  	// cast(Class<T>, Object)
77  	//====================================================================================================
78  	@Test
79  	void a002_cast() {
80  		var obj = "Hello";
81  		assertEquals("Hello", cast(String.class, obj));
82  		assertNull(cast(Integer.class, obj));
83  		assertNull(cast(String.class, null));
84  		assertEquals(123, cast(Integer.class, 123));
85  		assertNull(cast(String.class, 123));
86  	}
87  
88  	//====================================================================================================
89  	// cast(Class<T>, Object) - Additional tests for incorrect instance types
90  	//====================================================================================================
91  	@Test
92  	void a003_cast_additionalTests() {
93  		var obj = "Hello";
94  		// Test that incorrect instance types return null without throwing exception
95  		assertNull(cast(Integer.class, obj));
96  		assertNull(cast(String.class, 123));
97  
98  		// Test with different types
99  		assertEquals(123, cast(Integer.class, 123));
100 		assertNull(cast(String.class, 123));
101 
102 		// Test with null
103 		assertNull(cast(String.class, null));
104 	}
105 
106 	//====================================================================================================
107 	// cn(Object)
108 	//====================================================================================================
109 	@Test
110 	void a004_cn() {
111 		assertEquals("java.lang.String", cn(String.class));
112 		assertEquals("java.util.HashMap", cn(new HashMap<>()));
113 		assertEquals("java.util.Map$Entry", cn(Map.Entry.class));
114 		assertEquals("int", cn(int.class));
115 		assertEquals("boolean", cn(boolean.class));
116 		assertEquals("[Ljava.lang.String;", cn(String[].class));
117 		assertEquals("[I", cn(int[].class));
118 		assertNull(cn(null));
119 	}
120 
121 	//====================================================================================================
122 	// cns(Object)
123 	//====================================================================================================
124 	@Test
125 	void a005_cns() {
126 		assertEquals("String", cns(String.class));
127 		assertEquals("HashMap", cns(new HashMap<>()));
128 		assertEquals("Entry", cns(Map.Entry.class));
129 		assertEquals("int", cns(int.class));
130 		assertEquals("boolean", cns(boolean.class));
131 		assertEquals("String[]", cns(String[].class));
132 		assertEquals("int[]", cns(int[].class));
133 		assertNull(cns(null));
134 	}
135 
136 	//====================================================================================================
137 	// cnsq(Object)
138 	//====================================================================================================
139 	@Test
140 	void a006_cnsq() {
141 		assertEquals("String", cnsq(String.class));
142 		assertEquals("HashMap", cnsq(new HashMap<>()));
143 		assertEquals("Map.Entry", cnsq(Map.Entry.class));
144 		assertEquals("int", cnsq(int.class));
145 		assertEquals("boolean", cnsq(boolean.class));
146 		assertEquals("String[]", cnsq(String[].class));
147 		assertEquals("int[]", cnsq(int[].class));
148 		assertNull(cnsq(null));
149 	}
150 
151 	//====================================================================================================
152 	// cmp(Object, Object)
153 	//====================================================================================================
154 	@Test
155 	void a007_cmp() {
156 		assertTrue(cmp("apple", "banana") < 0);
157 		assertTrue(cmp("banana", "apple") > 0);
158 		assertEquals(0, cmp("apple", "apple"));
159 		assertEquals(0, cmp(null, null));
160 		assertTrue(cmp(null, "apple") < 0);
161 		assertTrue(cmp("apple", null) > 0);
162 		assertTrue(cmp(5, 10) < 0);
163 		assertTrue(cmp(10, 5) > 0);
164 		assertEquals(0, cmp(5, 5));
165 		assertEquals(0, cmp("apple", 5)); // Different types, cannot compare
166 
167 		// Test line 285 branch: same class but not Comparable
168 		class NotComparable {}
169 		var nc1 = new NotComparable();
170 		var nc2 = new NotComparable();
171 		assertEquals(0, cmp(nc1, nc2)); // Same class, but not Comparable - covers missing branch
172 	}
173 
174 	//====================================================================================================
175 	// ea(Class<T>)
176 	//====================================================================================================
177 	@Test
178 	void a008_ea() {
179 		var empty1 = ea(String.class);
180 		assertEquals(0, empty1.length);
181 		var empty2 = ea(Integer.class);
182 		assertEquals(0, empty2.length);
183 		var empty3 = ea(List.class);
184 		assertEquals(0, empty3.length);
185 	}
186 
187 	//====================================================================================================
188 	// emptyIfNull(Object)
189 	//====================================================================================================
190 	@Test
191 	void a009_emptyIfNull() {
192 		assertEquals("Hello", emptyIfNull("Hello"));
193 		assertEquals("123", emptyIfNull(123));
194 		assertEquals("", emptyIfNull(null));
195 	}
196 
197 	//====================================================================================================
198 	// env(String)
199 	//====================================================================================================
200 	@Test
201 	void a010_env() {
202 		// Test with system property
203 		System.setProperty("test.property", "testValue");
204 		var result = env("test.property");
205 		assertTrue(result.isPresent());
206 		assertEquals("testValue", result.get());
207 		System.clearProperty("test.property");
208 
209 		// Test with non-existent property
210 		var missing = env("nonexistent.property.xyz");
211 		assertFalse(missing.isPresent());
212 	}
213 
214 	//====================================================================================================
215 	// eq(boolean, String, String)
216 	//====================================================================================================
217 	@Test
218 	void a012_eq_caseSensitive() {
219 		assertTrue(eq(false, "Hello", "Hello"));
220 		assertFalse(eq(false, "Hello", "hello"));
221 		assertTrue(eq(false, null, null));
222 		assertFalse(eq(false, "Hello", null));
223 		assertFalse(eq(false, null, "Hello"));
224 		assertTrue(eq(true, "Hello", "hello"));
225 		assertTrue(eq(true, "Hello", "HELLO"));
226 		assertTrue(eq(true, null, null));
227 	}
228 
229 	//====================================================================================================
230 	// eq(T, T)
231 	//====================================================================================================
232 	@Test
233 	void a013_eq() {
234 		assertTrue(eq("Hello", "Hello"));
235 		assertFalse(eq("Hello", "World"));
236 		assertTrue(eq(null, null));
237 		assertFalse(eq("Hello", null));
238 		assertFalse(eq(null, "Hello"));
239 		assertTrue(eq(123, 123));
240 		assertFalse(eq(123, 456));
241 
242 		// Test arrays - covers line 456
243 		var arr1 = a(1, 2, 3);
244 		var arr2 = a(1, 2, 3);
245 		var arr3 = a(1, 2, 4);
246 		var arr4 = a(1, 2);  // Different length
247 		// Test line 456: both are arrays
248 		assertTrue(eq(arr1, arr2));  // Both arrays, same content
249 		assertFalse(eq(arr1, arr3));  // Both arrays, different content
250 		assertFalse(eq(arr1, arr4));  // Different lengths - covers line 459
251 		// Test line 456 branch: one is array, other is not
252 		assertFalse(eq(arr1, "not an array"));  // o1 is Array, o2 is not
253 		assertFalse(eq("not an array", arr1));  // o1 is not, o2 is Array
254 
255 		// Test annotations - use actual annotation instances from classes
256 		@TestAnnotation("test")
257 		class T1 {}
258 		@TestAnnotation("test")
259 		class T2 {}
260 		@TestAnnotation("different")
261 		class T3 {}
262 
263 		var a1 = T1.class.getAnnotation(TestAnnotation.class);
264 		var a2 = T2.class.getAnnotation(TestAnnotation.class);
265 		var a3 = T3.class.getAnnotation(TestAnnotation.class);
266 		// Test annotation equality - covers line 453 (both are annotations)
267 		assertTrue(eq(a1, a2));
268 		assertFalse(eq(a1, a3));
269 		// Test line 453 branch: one is annotation, other is not
270 		assertFalse(eq(a1, "not an annotation"));  // o1 is Annotation, o2 is not
271 		assertFalse(eq("not an annotation", a1));  // o1 is not, o2 is Annotation
272 	}
273 
274 	//====================================================================================================
275 	// eq(T, U, BiPredicate<T,U>)
276 	//====================================================================================================
277 	@Test
278 	void a014_eq_withPredicate() {
279 		class Role {
280 			int id;
281 			String name;
282 			Role(int id, String name) { this.id = id; this.name = name; }
283 		}
284 
285 		var r1 = new Role(1, "admin");
286 		var r2 = new Role(1, "admin");
287 		var r3 = new Role(2, "user");
288 
289 		assertTrue(eq(r1, r2, (x, y) -> x.id == y.id && x.name.equals(y.name)));
290 		assertFalse(eq(r1, r3, (x, y) -> x.id == y.id && x.name.equals(y.name)));
291 		assertTrue(eq(null, null, (x, y) -> false));
292 		assertFalse(eq(r1, null, (x, y) -> true));
293 		assertFalse(eq(null, r2, (x, y) -> true));
294 		assertTrue(eq(r1, r1, (x, y) -> false)); // Same reference
295 	}
296 
297 	//====================================================================================================
298 	// eqic(Object, Object)
299 	//====================================================================================================
300 	@Test
301 	void a015_eqic_object() {
302 		assertTrue(eqic("Hello", "Hello"));
303 		assertTrue(eqic("Hello", "hello"));
304 		assertTrue(eqic("Hello", "HELLO"));
305 		assertTrue(eqic(null, null));
306 		assertFalse(eqic("Hello", null));
307 		assertFalse(eqic(null, "Hello"));
308 		assertTrue(eqic(123, 123));
309 		assertFalse(eqic(123, 456));
310 	}
311 
312 	//====================================================================================================
313 	// eqic(String, String)
314 	//====================================================================================================
315 	@Test
316 	void a016_eqic_string() {
317 		assertTrue(eqic("Hello", "Hello"));
318 		assertTrue(eqic("Hello", "hello"));
319 		assertTrue(eqic("Hello", "HELLO"));
320 		assertTrue(eqic(null, null));
321 		assertFalse(eqic("Hello", null));
322 		assertFalse(eqic(null, "Hello"));
323 	}
324 
325 	//====================================================================================================
326 	// f(String, Object...)
327 	//====================================================================================================
328 	@Test
329 	void a017_f() {
330 		// Basic formatting
331 		assertEquals("Hello John, you have 5 items", f("Hello %s, you have %d items", "John", 5));
332 		assertEquals("Hello world", f("Hello %s", "world"));
333 
334 		// Floating point
335 		assertEquals("Price: $19.99", f("Price: $%.2f", 19.99));
336 		assertEquals("Value: 3.14", f("Value: %.2f", 3.14159));
337 
338 		// Multiple arguments
339 		assertEquals("Name: John, Age: 30, Salary: $50000.00",
340 			f("Name: %s, Age: %d, Salary: $%.2f", "John", 30, 50000.0));
341 
342 		// Null handling
343 		assertEquals("Value: null", f("Value: %s", (String)null));
344 		assertThrows(IllegalArgumentException.class, ()->f(null, "test"));
345 		assertEquals("test", f("test"));
346 
347 		// MessageFormat style
348 		assertEquals("Hello John, you have 5 items", f("Hello {0}, you have {1} items", "John", 5));
349 	}
350 
351 	//====================================================================================================
352 	// firstNonNull(T...)
353 	//====================================================================================================
354 	@Test
355 	void a018_firstNonNull() {
356 		assertEquals("Hello", firstNonNull(null, null, "Hello", "World"));
357 		assertEquals("Hello", firstNonNull("Hello", "World"));
358 		assertNull(firstNonNull(null, null));
359 		assertNull(firstNonNull());
360 		assertEquals(123, firstNonNull(null, null, 123, 456));
361 
362 		// Test line 614 branch: null array (varargs array itself is null)
363 		// This can happen if called with explicit null cast
364 		String[] nullArray = null;
365 		assertNull(firstNonNull(nullArray));  // Covers the nn(t) == false branch
366 	}
367 
368 	//====================================================================================================
369 	// fs(String, Object...)
370 	//====================================================================================================
371 	@Test
372 	void a019_fs() {
373 		// Basic supplier
374 		var supplier = fs("Hello %s, you have %d items", "John", 5);
375 		assertNotNull(supplier);
376 		assertEquals("Hello John, you have 5 items", supplier.get());
377 
378 		// Lazy evaluation - format only when get() is called
379 		var lazySupplier = fs("Price: $%.2f", 19.99);
380 		assertEquals("Price: $19.99", lazySupplier.get());
381 
382 		// Multiple calls return same result
383 		var supplier2 = fs("Value: %s", "test");
384 		assertEquals("Value: test", supplier2.get());
385 		assertEquals("Value: test", supplier2.get());
386 
387 		// Null handling
388 		var nullSupplier = fs(null, "test");
389 		assertThrows(IllegalArgumentException.class, ()->nullSupplier.get());
390 
391 		// Empty pattern
392 		var emptySupplier = fs("");
393 		assertEquals("", emptySupplier.get());
394 	}
395 
396 	//====================================================================================================
397 	// h(Object...)
398 	//====================================================================================================
399 	@Test
400 	void a020_hash() {
401 		var hash1 = h("Hello", 123, true);
402 		var hash2 = h("Hello", 123, true);
403 		assertEquals(hash1, hash2);
404 
405 		var hash3 = h("Hello", 123, false);
406 		assertNotEquals(hash1, hash3);
407 
408 		// Test with annotations
409 		@TestAnnotation("test")
410 		class T {}
411 		var a1 = T.class.getAnnotation(TestAnnotation.class);
412 		var hash4 = h(a1, "value");
413 		assertNotNull(hash4);
414 	}
415 
416 	//====================================================================================================
417 	// id(Object)
418 	//====================================================================================================
419 	@Test
420 	void a021_identity() {
421 		var obj = "test";
422 		var identity = id(obj);
423 		assertNotNull(identity);
424 		assertTrue(identity.contains("String"));
425 		assertTrue(identity.contains("@"));
426 		assertNull(id(null));
427 		assertNotNull(id(Optional.of("test")));
428 	}
429 
430 	//====================================================================================================
431 	// isArray(Object)
432 	//====================================================================================================
433 	@Test
434 	void a022_isArray() {
435 		assertTrue(isArray(new int[]{1, 2, 3}));
436 		assertTrue(isArray(a("a", "b")));
437 		assertTrue(isArray(a()));
438 		assertFalse(isArray("Hello"));
439 		assertFalse(isArray(null));
440 		assertFalse(isArray(123));
441 		assertFalse(isArray(new ArrayList<>()));
442 	}
443 
444 	//====================================================================================================
445 	// isBetween(int, int, int)
446 	//====================================================================================================
447 	@Test
448 	void a023_isBetween() {
449 		assertTrue(isBetween(5, 1, 10));
450 		assertTrue(isBetween(1, 1, 10));
451 		assertTrue(isBetween(10, 1, 10));
452 		assertFalse(isBetween(0, 1, 10));
453 		assertFalse(isBetween(11, 1, 10));
454 	}
455 
456 	//====================================================================================================
457 	// e(CharSequence)
458 	//====================================================================================================
459 	@Test
460 	void a024_isEmpty_CharSequence() {
461 		assertTrue(e((String)null));
462 		assertTrue(e(""));
463 		assertFalse(e("   "));
464 		assertFalse(e("hello"));
465 		assertFalse(e("a"));
466 	}
467 
468 	//====================================================================================================
469 	// e(Collection<?>)
470 	//====================================================================================================
471 	@Test
472 	void a025_isEmpty_Collection() {
473 		assertTrue(e((Collection<?>)null));
474 		assertTrue(e(Collections.emptyList()));
475 		assertTrue(e(new ArrayList<>()));
476 		assertFalse(e(Arrays.asList(1, 2, 3)));
477 		assertFalse(e(Collections.singletonList("test")));
478 	}
479 
480 	//====================================================================================================
481 	// e(Map<?,?>)
482 	//====================================================================================================
483 	@Test
484 	void a026_isEmpty_Map() {
485 		assertTrue(e((Map<?,?>)null));
486 		assertTrue(e(Collections.emptyMap()));
487 		assertTrue(e(new HashMap<>()));
488 		assertFalse(e(Map.of("key", "value")));
489 		assertFalse(e(Collections.singletonMap("key", "value")));
490 	}
491 
492 	//====================================================================================================
493 	// e(Object)
494 	//====================================================================================================
495 	@Test
496 	void a027_isEmpty_Object() {
497 		assertTrue(e((Object)null));
498 		assertTrue(e((Object)""));
499 		// Test line 834: Collection branch
500 		assertTrue(e((Object)Collections.emptyList()));
501 		assertFalse(e((Object)Arrays.asList(1, 2)));  // Non-empty collection
502 		// Test line 836: Map branch
503 		assertTrue(e((Object)Collections.emptyMap()));
504 		assertFalse(e((Object)Map.of("key", "value")));  // Non-empty map
505 		assertTrue(e(new int[0]));
506 		assertTrue(e(new String[0]));
507 		assertFalse(e((Object)"hello"));
508 		assertFalse(e(a(1, 2)));
509 		assertTrue(e(new Object() {
510 			@Override public String toString() { return ""; }
511 		}));
512 	}
513 
514 	//====================================================================================================
515 	// ne(CharSequence)
516 	//====================================================================================================
517 	@Test
518 	void a028_isNotEmpty_CharSequence() {
519 		assertFalse(ne((String)null));
520 		assertFalse(ne(""));
521 		assertTrue(ne("   "));
522 		assertTrue(ne("hello"));
523 		assertTrue(ne("a"));
524 	}
525 
526 	//====================================================================================================
527 	// ne(Collection<?>)
528 	//====================================================================================================
529 	@Test
530 	void a029_isNotEmpty_Collection() {
531 		assertFalse(ne((Collection<?>)null));
532 		assertFalse(ne(Collections.emptyList()));
533 		assertFalse(ne(new ArrayList<>()));
534 		assertTrue(ne(Arrays.asList(1, 2, 3)));
535 		assertTrue(ne(Collections.singletonList("test")));
536 	}
537 
538 	//====================================================================================================
539 	// ne(Map<?,?>)
540 	//====================================================================================================
541 	@Test
542 	void a030_isNotEmpty_Map() {
543 		assertFalse(ne((Map<?,?>)null));
544 		assertFalse(ne(Collections.emptyMap()));
545 		assertFalse(ne(new HashMap<>()));
546 		assertTrue(ne(Map.of("key", "value")));
547 		assertTrue(ne(Collections.singletonMap("key", "value")));
548 	}
549 
550 	//====================================================================================================
551 	// ne(Object)
552 	//====================================================================================================
553 	@Test
554 	void a031_isNotEmpty_Object() {
555 		assertFalse(ne((Object)null));
556 		// Test line 939: CharSequence branch
557 		assertFalse(ne((Object)""));
558 		assertTrue(ne((Object)"hello"));  // Non-empty CharSequence
559 		// Test line 941: Collection branch
560 		assertFalse(ne((Object)Collections.emptyList()));
561 		assertTrue(ne((Object)Arrays.asList(1, 2)));  // Non-empty collection
562 		// Test line 943: Map branch
563 		assertFalse(ne((Object)Collections.emptyMap()));
564 		assertTrue(ne((Object)Map.of("key", "value")));  // Non-empty map
565 		assertFalse(ne(new int[0]));
566 		assertFalse(ne(new String[0]));
567 		assertTrue(ne(a(1, 2)));
568 		// Test line 946: fallback case (non-String, non-Collection, non-Map, non-Array)
569 		assertTrue(ne(new Object() {
570 			@Override public String toString() { return "test"; }
571 		}));
572 		assertFalse(ne(new Object() {
573 			@Override public String toString() { return ""; }
574 		}));
575 	}
576 
577 	//====================================================================================================
578 	// nm1(T)
579 	//====================================================================================================
580 	@Test
581 	void a032_isNotMinusOne() {
582 		assertTrue(nm1(5));
583 		assertTrue(nm1(0));
584 		assertTrue(nm1(100));
585 		assertFalse(nm1(-1));
586 		assertFalse(nm1((Integer)null));
587 		assertTrue(nm1(5L));
588 		assertFalse(nm1(-1L));
589 	}
590 
591 	//====================================================================================================
592 	// isTrue(Boolean)
593 	//====================================================================================================
594 	@Test
595 	void a034_isTrue() {
596 		assertTrue(isTrue(true));
597 		assertFalse(isTrue(false));
598 		assertFalse(isTrue(null));
599 	}
600 
601 	//====================================================================================================
602 	// lc(String)
603 	//====================================================================================================
604 	@Test
605 	void a035_lc() {
606 		assertEquals("hello", lc("Hello"));
607 		assertEquals("hello", lc("HELLO"));
608 		assertEquals("hello world", lc("Hello World"));
609 		assertNull(lc(null));
610 		assertEquals("", lc(""));
611 	}
612 
613 	//====================================================================================================
614 	// mem(Supplier<T>)
615 	//====================================================================================================
616 	@Test
617 	void a036_memoize() {
618 		var callCount = new AtomicInteger(0);
619 		var supplier = mem(() -> {
620 			callCount.incrementAndGet();
621 			return "result";
622 		});
623 
624 		var result1 = supplier.get();
625 		var result2 = supplier.get();
626 		var result3 = supplier.get();
627 
628 		assertEquals("result", result1);
629 		assertEquals("result", result2);
630 		assertEquals("result", result3);
631 		assertEquals(1, callCount.get()); // Should only be called once
632 	}
633 
634 	//====================================================================================================
635 	// memr(Supplier<T>)
636 	//====================================================================================================
637 	@Test
638 	void a037_memoizeResettable() {
639 		var callCount = new AtomicInteger(0);
640 		var supplier = memr(() -> {
641 			callCount.incrementAndGet();
642 			return "result";
643 		});
644 
645 		var result1 = supplier.get();
646 		var result2 = supplier.get();
647 		assertEquals(1, callCount.get());
648 
649 		supplier.reset();
650 		var result3 = supplier.get();
651 		assertEquals(2, callCount.get());
652 
653 		assertEquals("result", result1);
654 		assertEquals("result", result2);
655 		assertEquals("result", result3);
656 	}
657 
658 	//====================================================================================================
659 	// n(Class<T>)
660 	//====================================================================================================
661 	@Test
662 	void a038_n() {
663 		assertNull(no(String.class));
664 		assertNull(no(Integer.class));
665 		assertNull(no(List.class));
666 	}
667 
668 	//====================================================================================================
669 	// ne(T, T)
670 	//====================================================================================================
671 	@Test
672 	void a039_ne() {
673 		assertTrue(neq("Hello", "World"));
674 		assertFalse(neq("Hello", "Hello"));
675 		assertFalse(neq(null, null));
676 		assertTrue(neq("Hello", null));
677 		assertTrue(neq(null, "Hello"));
678 		assertTrue(neq(123, 456));
679 		assertFalse(neq(123, 123));
680 	}
681 
682 	//====================================================================================================
683 	// ne(T, U, BiPredicate<T,U>)
684 	//====================================================================================================
685 	@Test
686 	void a040_ne_withPredicate() {
687 		class Role {
688 			int id;
689 			String name;
690 			Role(int id, String name) { this.id = id; this.name = name; }
691 		}
692 
693 		var r1 = new Role(1, "admin");
694 		var r2 = new Role(1, "admin");
695 		var r3 = new Role(2, "user");
696 
697 		assertFalse(neq(r1, r2, (x, y) -> x.id == y.id && x.name.equals(y.name)));
698 		assertTrue(neq(r1, r3, (x, y) -> x.id == y.id && x.name.equals(y.name)));
699 		assertFalse(neq(null, null, (x, y) -> true));
700 		assertTrue(neq(r1, null, (x, y) -> false));
701 		assertTrue(neq(null, r2, (x, y) -> false));
702 		assertFalse(neq(r1, r1, (x, y) -> true)); // Same reference
703 	}
704 
705 	//====================================================================================================
706 	// neic(String, String)
707 	//====================================================================================================
708 	@Test
709 	void a041_neic() {
710 		assertTrue(neqic("Hello", "World"));
711 		assertFalse(neqic("Hello", "hello"));
712 		assertFalse(neqic("Hello", "HELLO"));
713 		assertFalse(neqic(null, null));
714 		assertTrue(neqic("Hello", null));
715 		assertTrue(neqic(null, "Hello"));
716 	}
717 
718 	//====================================================================================================
719 	// nn(Object)
720 	//====================================================================================================
721 	@Test
722 	void a042_nn() {
723 		assertTrue(nn("test"));
724 		assertTrue(nn(123));
725 		assertTrue(nn(new Object()));
726 		assertTrue(nn(""));
727 		assertTrue(nn(0));
728 		assertTrue(nn(false));
729 		assertFalse(nn(null));
730 	}
731 
732 	//====================================================================================================
733 	// opt(T)
734 	//====================================================================================================
735 	@Test
736 	void a043_opt() {
737 		var opt1 = opt("Hello");
738 		assertTrue(opt1.isPresent());
739 		assertEquals("Hello", opt1.get());
740 
741 		var opt2 = opt(null);
742 		assertFalse(opt2.isPresent());
743 	}
744 
745 	//====================================================================================================
746 	// opte()
747 	//====================================================================================================
748 	@Test
749 	void a044_opte() {
750 		var empty = opte();
751 		assertFalse(empty.isPresent());
752 	}
753 
754 	//====================================================================================================
755 	// printLines(String[])
756 	//====================================================================================================
757 	@Test
758 	void a045_printLines() {
759 		// This test just verifies the method doesn't throw
760 		printLines(a("Line 1", "Line 2", "Line 3"));
761 		printLines(a());
762 	}
763 
764 	//====================================================================================================
765 	// r(Object)
766 	//====================================================================================================
767 	@Test
768 	void a046_r() {
769 		assertEquals("hello", r("hello"));
770 		assertEquals("123", r(123));
771 		assertEquals("[1,2,3]", r(Arrays.asList(1, 2, 3)));
772 		assertNull(r(null));
773 		var bytes = new byte[]{1, 2};
774 		assertEquals("0102", r(bytes));
775 	}
776 
777 	//====================================================================================================
778 	// s(Object)
779 	//====================================================================================================
780 	@Test
781 	void a047_s() {
782 		assertEquals("Hello", s("Hello"));
783 		assertEquals("123", s(123));
784 		assertEquals("true", s(true));
785 		assertNull(s(null));
786 	}
787 
788 	//====================================================================================================
789 	// safe(Snippet)
790 	//====================================================================================================
791 	@Test
792 	void a048_safe_Snippet() {
793 		// Test normal execution - covers line 1371
794 		AtomicInteger count = new AtomicInteger(0);
795 		safe((Snippet)() -> {
796 			count.incrementAndGet();
797 		});
798 		assertEquals(1, count.get());
799 
800 		// Test RuntimeException is rethrown - covers lines 1372-1373
801 		var re = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
802 			throw new RuntimeException("test");
803 		}));
804 		assertEquals("test", re.getMessage());
805 
806 		// Test checked exception is wrapped - covers lines 1374-1375
807 		var wrapped = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
808 			throw new Exception("test");
809 		}));
810 		assertNotNull(wrapped.getCause());
811 		assertEquals(Exception.class, wrapped.getCause().getClass());
812 		assertEquals("test", wrapped.getCause().getMessage());
813 
814 		// Test Error is wrapped - covers lines 1374-1375 with Error
815 		var wrappedError = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
816 			throw new Error("test error");
817 		}));
818 		assertNotNull(wrappedError.getCause());
819 		assertEquals(Error.class, wrappedError.getCause().getClass());
820 		assertEquals("test error", wrappedError.getCause().getMessage());
821 	}
822 
823 	//====================================================================================================
824 	// safe(Snippet, Function<Throwable, RuntimeException>)
825 	//====================================================================================================
826 	@Test
827 	void a049_safe_Snippet_withExceptionMapper() {
828 		// Test normal execution
829 		AtomicInteger count = new AtomicInteger(0);
830 		safe((Snippet)() -> {
831 			count.incrementAndGet();
832 		}, e -> new RuntimeException("mapped: " + e.getMessage()));
833 		assertEquals(1, count.get());
834 
835 		// Test RuntimeException is rethrown (not mapped)
836 		var re = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
837 			throw new RuntimeException("original");
838 		}, e -> new RuntimeException("mapped: " + e.getMessage())));
839 		assertEquals("original", re.getMessage());
840 
841 		// Test checked exception is mapped using the provided function
842 		var mapped = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
843 			throw new Exception("test exception");
844 		}, e -> new IllegalArgumentException("custom: " + e.getMessage())));
845 		assertEquals("custom: test exception", mapped.getMessage());
846 		assertTrue(mapped instanceof IllegalArgumentException);
847 
848 		// Test Error is mapped
849 		var mappedError = assertThrows(RuntimeException.class, () -> safe((Snippet)() -> {
850 			throw new Error("test error");
851 		}, e -> new IllegalStateException("error: " + e.getMessage())));
852 		assertEquals("error: test error", mappedError.getMessage());
853 		assertTrue(mappedError instanceof IllegalStateException);
854 
855 		// Test with custom exception type
856 		@SuppressWarnings("serial")
857 		class CustomRuntimeException extends RuntimeException {
858 			CustomRuntimeException(String message, Throwable cause) {
859 				super(message, cause);
860 			}
861 		}
862 		var custom = assertThrows(CustomRuntimeException.class, () -> safe((Snippet)() -> {
863 			throw new Exception("test");
864 		}, e -> new CustomRuntimeException("wrapped", e)));
865 		assertEquals("wrapped", custom.getMessage());
866 		assertNotNull(custom.getCause());
867 		assertEquals(Exception.class, custom.getCause().getClass());
868 	}
869 
870 	//====================================================================================================
871 	// safe(ThrowingSupplier<T>)
872 	//====================================================================================================
873 	@Test
874 	void a050_safe_ThrowingSupplier() {
875 		// Test normal execution
876 		var result = safe(() -> "result");
877 		assertEquals("result", result);
878 
879 		// Test RuntimeException is rethrown
880 		assertThrows(RuntimeException.class, () -> safe(() -> {
881 			throw new RuntimeException("test");
882 		}));
883 
884 		// Test checked exception is wrapped
885 		assertThrows(RuntimeException.class, () -> safe(() -> {
886 			throw new Exception("test");
887 		}));
888 	}
889 
890 	//====================================================================================================
891 	// safe(ThrowingSupplier<T>, Function<Exception, RuntimeException>)
892 	//====================================================================================================
893 	@Test
894 	void a051_safe_ThrowingSupplier_withExceptionMapper() {
895 		// Test normal execution
896 		ThrowingSupplier<String> supplier1 = () -> "result";
897 		Function<Exception, RuntimeException> mapper1 = e -> new RuntimeException("mapped: " + e.getMessage());
898 		String result = Utils.safe(supplier1, mapper1);
899 		assertEquals("result", result);
900 
901 		// Test RuntimeException is rethrown (not mapped)
902 		ThrowingSupplier<String> supplier2 = () -> {
903 			throw new RuntimeException("original");
904 		};
905 		Function<Exception, RuntimeException> mapper2 = e -> new RuntimeException("mapped: " + e.getMessage());
906 		var re = assertThrows(RuntimeException.class, () -> Utils.safe(supplier2, mapper2));
907 		assertEquals("original", re.getMessage());
908 
909 		// Test checked exception is mapped using the provided function
910 		ThrowingSupplier<String> supplier3 = () -> {
911 			throw new Exception("test exception");
912 		};
913 		Function<Exception, RuntimeException> mapper3 = e -> new IllegalArgumentException("custom: " + e.getMessage());
914 		var mapped = assertThrows(RuntimeException.class, () -> Utils.safe(supplier3, mapper3));
915 		assertEquals("custom: test exception", mapped.getMessage());
916 		assertTrue(mapped instanceof IllegalArgumentException);
917 
918 		// Test with custom exception type
919 		@SuppressWarnings("serial")
920 		class CustomRuntimeException extends RuntimeException {
921 			CustomRuntimeException(String message, Throwable cause) {
922 				super(message, cause);
923 			}
924 		}
925 		var custom = assertThrows(CustomRuntimeException.class, () -> Utils.<String>safeSupplier(() -> {
926 			throw new Exception("test");
927 		}, e -> new CustomRuntimeException("wrapped", e)));
928 		assertEquals("wrapped", custom.getMessage());
929 		assertNotNull(custom.getCause());
930 		assertEquals(Exception.class, custom.getCause().getClass());
931 	}
932 
933 	//====================================================================================================
934 	// safeOpt(ThrowingSupplier<T>)
935 	//====================================================================================================
936 	@Test
937 	void a052_safeOpt() {
938 		// Test normal execution
939 		var result = safeOpt(() -> "result");
940 		assertTrue(result.isPresent());
941 		assertEquals("result", result.get());
942 
943 		// Test exception returns empty
944 		var empty = safeOpt(() -> {
945 			throw new Exception("test");
946 		});
947 		assertFalse(empty.isPresent());
948 	}
949 
950 	//====================================================================================================
951 	// safeSupplier(ThrowableUtils.SupplierWithThrowable<T>)
952 	//====================================================================================================
953 	@Test
954 	void a053_safeSupplier() {
955 		// Test normal execution
956 		var result = safeSupplier(() -> "result");
957 		assertEquals("result", result);
958 
959 		// Test RuntimeException is rethrown
960 		assertThrows(RuntimeException.class, () -> safeSupplier(() -> {
961 			throw new RuntimeException("test");
962 		}));
963 
964 		// Test checked exception is wrapped
965 		assertThrows(RuntimeException.class, () -> safeSupplier(() -> {
966 			throw new Exception("test");
967 		}));
968 	}
969 
970 	//====================================================================================================
971 	// safeSupplier(ThrowableUtils.SupplierWithThrowable<T>, Function<Throwable, RuntimeException>)
972 	//====================================================================================================
973 	@Test
974 	void a054_safeSupplier_withExceptionMapper() {
975 		// Test normal execution
976 		String result = Utils.<String>safeSupplier(() -> "result", e -> new RuntimeException("mapped: " + e.getMessage()));
977 		assertEquals("result", result);
978 
979 		// Test RuntimeException is rethrown (not mapped)
980 		var re = assertThrows(RuntimeException.class, () -> Utils.<String>safeSupplier(() -> {
981 			throw new RuntimeException("original");
982 		}, e -> new RuntimeException("mapped: " + e.getMessage())));
983 		assertEquals("original", re.getMessage());
984 
985 		// Test checked exception is mapped using the provided function
986 		var mapped = assertThrows(RuntimeException.class, () -> Utils.<String>safeSupplier(() -> {
987 			throw new Exception("test exception");
988 		}, e -> new IllegalArgumentException("custom: " + e.getMessage())));
989 		assertEquals("custom: test exception", mapped.getMessage());
990 		assertTrue(mapped instanceof IllegalArgumentException);
991 
992 		// Test Error is mapped
993 		var mappedError = assertThrows(RuntimeException.class, () -> Utils.<String>safeSupplier(() -> {
994 			throw new Error("test error");
995 		}, e -> new IllegalStateException("error: " + e.getMessage())));
996 		assertEquals("error: test error", mappedError.getMessage());
997 		assertTrue(mappedError instanceof IllegalStateException);
998 
999 		// Test with custom exception type
1000 		@SuppressWarnings("serial")
1001 		class CustomRuntimeException extends RuntimeException {
1002 			CustomRuntimeException(String message, Throwable cause) {
1003 				super(message, cause);
1004 			}
1005 		}
1006 		var custom = assertThrows(CustomRuntimeException.class, () -> Utils.<String>safeSupplier(() -> {
1007 			throw new Exception("test");
1008 		}, e -> new CustomRuntimeException("wrapped", e)));
1009 		assertEquals("wrapped", custom.getMessage());
1010 		assertNotNull(custom.getCause());
1011 		assertEquals(Exception.class, custom.getCause().getClass());
1012 	}
1013 
1014 	//====================================================================================================
1015 	// sb(String)
1016 	//====================================================================================================
1017 	@Test
1018 	void a055_sb() {
1019 		var sb = sb("Hello");
1020 		assertNotNull(sb);
1021 		assertEquals("Hello", sb.toString());
1022 	}
1023 
1024 	//====================================================================================================
1025 	// ss(Supplier<?>)
1026 	//====================================================================================================
1027 	@Test
1028 	void a056_ss() {
1029 		var stringSupplier = ss(() -> "test");
1030 		assertEquals("test", stringSupplier.get());
1031 
1032 		var intSupplier = ss(() -> 123);
1033 		assertEquals("123", intSupplier.get());
1034 	}
1035 
1036 	//====================================================================================================
1037 	// uc(String)
1038 	//====================================================================================================
1039 	@Test
1040 	void a057_uc() {
1041 		assertEquals("HELLO", uc("Hello"));
1042 		assertEquals("HELLO", uc("hello"));
1043 		assertEquals("HELLO WORLD", uc("Hello World"));
1044 		assertNull(uc(null));
1045 		assertEquals("", uc(""));
1046 	}
1047 
1048 	//====================================================================================================
1049 	// unwrap(Object)
1050 	//====================================================================================================
1051 	@Test
1052 	void a058_unwrap() {
1053 		// Test with Supplier
1054 		Supplier<String> supplier = () -> "test";
1055 		assertEquals("test", unwrap(supplier));
1056 
1057 		// Test with Value
1058 		var value = Value.of("test");
1059 		assertEquals("test", unwrap(value));
1060 
1061 		// Test with Optional
1062 		var optional = Optional.of("test");
1063 		assertEquals("test", unwrap(optional));
1064 
1065 		// Test nested unwrapping
1066 		Supplier<Optional<String>> nested = () -> Optional.of("test");
1067 		assertEquals("test", unwrap(nested));
1068 
1069 		// Test regular object
1070 		assertEquals("test", unwrap("test"));
1071 		assertEquals(123, unwrap(123));
1072 	}
1073 
1074 	//====================================================================================================
1075 	// nullIfEmpty(String)
1076 	//====================================================================================================
1077 	@Test
1078 	void a059_nullIfEmpty_String() {
1079 		assertNull(nullIfEmpty((String)null));
1080 		assertNull(nullIfEmpty(""));
1081 		assertNotNull(nullIfEmpty("x"));
1082 		assertEquals("test", nullIfEmpty("test"));
1083 	}
1084 
1085 	//====================================================================================================
1086 	// nullIfEmpty(Map)
1087 	//====================================================================================================
1088 	@Test
1089 	void a060_nullIfEmpty_Map() {
1090 		// Null map
1091 		assertNull(nullIfEmpty((Map<String,Integer>)null));
1092 
1093 		// Empty map
1094 		Map<String,Integer> empty = new HashMap<>();
1095 		assertNull(nullIfEmpty(empty));
1096 
1097 		// Non-empty map
1098 		Map<String,Integer> nonEmpty = new HashMap<>();
1099 		nonEmpty.put("a", 1);
1100 		assertNotNull(nullIfEmpty(nonEmpty));
1101 		assertSame(nonEmpty, nullIfEmpty(nonEmpty));
1102 		assertEquals(1, nullIfEmpty(nonEmpty).size());
1103 	}
1104 
1105 	//====================================================================================================
1106 	// nullIfEmpty(List)
1107 	//====================================================================================================
1108 	@Test
1109 	void a061_nullIfEmpty_List() {
1110 		// Null list
1111 		assertNull(nullIfEmpty((List<String>)null));
1112 
1113 		// Empty list
1114 		List<String> empty = new ArrayList<>();
1115 		assertNull(nullIfEmpty(empty));
1116 
1117 		// Non-empty list
1118 		List<String> nonEmpty = new ArrayList<>();
1119 		nonEmpty.add("a");
1120 		assertNotNull(nullIfEmpty(nonEmpty));
1121 		assertSame(nonEmpty, nullIfEmpty(nonEmpty));
1122 		assertEquals(1, nullIfEmpty(nonEmpty).size());
1123 	}
1124 
1125 	//====================================================================================================
1126 	// nullIfEmpty(Set)
1127 	//====================================================================================================
1128 	@Test
1129 	void a062_nullIfEmpty_Set() {
1130 		// Null set
1131 		assertNull(nullIfEmpty((Set<String>)null));
1132 
1133 		// Empty set
1134 		Set<String> empty = new HashSet<>();
1135 		assertNull(nullIfEmpty(empty));
1136 
1137 		// Non-empty set
1138 		Set<String> nonEmpty = new HashSet<>();
1139 		nonEmpty.add("a");
1140 		assertNotNull(nullIfEmpty(nonEmpty));
1141 		assertSame(nonEmpty, nullIfEmpty(nonEmpty));
1142 		assertEquals(1, nullIfEmpty(nonEmpty).size());
1143 	}
1144 
1145 	//====================================================================================================
1146 	// e(Object) - Empty check
1147 	//====================================================================================================
1148 	@Test
1149 	void a063_e() {
1150 		assertTrue(e((String)null));
1151 		assertTrue(e(""));
1152 		assertTrue(e(Collections.emptyList()));
1153 		assertTrue(e(Collections.emptyMap()));
1154 		assertTrue(e(new String[0]));
1155 		assertFalse(e("Hello"));
1156 		assertFalse(e(Arrays.asList(1, 2)));
1157 		assertFalse(e(Map.of("key", "value")));
1158 		assertFalse(e(new String[]{"a"}));
1159 	}
1160 
1161 	//====================================================================================================
1162 	// ne(Object) - Not-empty check
1163 	//====================================================================================================
1164 	@Test
1165 	void a064_ne() {
1166 		assertFalse(ne((String)null));
1167 		assertFalse(ne(""));
1168 		assertFalse(ne(Collections.emptyList()));
1169 		assertFalse(ne(Collections.emptyMap()));
1170 		assertFalse(ne(new String[0]));
1171 		assertTrue(ne("Hello"));
1172 		assertTrue(ne(Arrays.asList(1, 2)));
1173 		assertTrue(ne(Map.of("key", "value")));
1174 		assertTrue(ne(new String[]{"a"}));
1175 	}
1176 
1177 	//====================================================================================================
1178 	// n(Object) - Null check
1179 	//====================================================================================================
1180 	@Test
1181 	void a065_n() {
1182 		assertTrue(n((Object)null));
1183 		assertFalse(n("Hello"));
1184 		assertFalse(n(123));
1185 		assertFalse(n(new Object()));
1186 	}
1187 
1188 
1189 	//====================================================================================================
1190 	// lt(T, T) - Less than
1191 	//====================================================================================================
1192 	@Test
1193 	void a067_lt() {
1194 		assertTrue(lt(5, 10));
1195 		assertTrue(lt("apple", "banana"));
1196 		assertFalse(lt(10, 5));
1197 		assertFalse(lt(5, 5));
1198 		assertFalse(lt("banana", "apple"));
1199 		assertTrue(lt(null, "apple")); // null is less than non-null
1200 		assertFalse(lt("apple", null));
1201 	}
1202 
1203 	//====================================================================================================
1204 	// lte(T, T) - Less than or equal
1205 	//====================================================================================================
1206 	@Test
1207 	void a068_lte() {
1208 		assertTrue(lte(5, 10));
1209 		assertTrue(lte(5, 5));
1210 		assertFalse(lte(10, 5));
1211 		assertTrue(lte("apple", "banana"));
1212 		assertTrue(lte("apple", "apple"));
1213 		assertTrue(lte(null, null)); // null equals null
1214 		assertTrue(lte(null, "apple")); // null is less than non-null
1215 		assertFalse(lte("apple", null));
1216 	}
1217 
1218 	//====================================================================================================
1219 	// gt(T, T) - Greater than
1220 	//====================================================================================================
1221 	@Test
1222 	void a069_gt() {
1223 		assertTrue(gt(10, 5));
1224 		assertTrue(gt("banana", "apple"));
1225 		assertFalse(gt(5, 10));
1226 		assertFalse(gt(5, 5));
1227 		assertFalse(gt("apple", "banana"));
1228 		assertFalse(gt(null, "apple")); // null is not greater
1229 		assertTrue(gt("apple", null)); // non-null is greater than null
1230 	}
1231 
1232 	//====================================================================================================
1233 	// gte(T, T) - Greater than or equal
1234 	//====================================================================================================
1235 	@Test
1236 	void a070_gte() {
1237 		assertTrue(gte(10, 5));
1238 		assertTrue(gte(5, 5));
1239 		assertFalse(gte(5, 10));
1240 		assertTrue(gte("banana", "apple"));
1241 		assertTrue(gte("apple", "apple"));
1242 		assertTrue(gte(null, null)); // null equals null
1243 		assertFalse(gte(null, "apple")); // null is not greater
1244 		assertTrue(gte("apple", null)); // non-null is greater than null
1245 	}
1246 
1247 	//====================================================================================================
1248 	// b(String) - Blank check
1249 	//====================================================================================================
1250 	@Test
1251 	void a071_b() {
1252 		assertTrue(b(null));
1253 		assertTrue(b(""));
1254 		assertTrue(b("   "));
1255 		assertTrue(b("\t\n"));
1256 		assertFalse(b("hello"));
1257 		assertFalse(b("  hello  "));
1258 	}
1259 
1260 	//====================================================================================================
1261 	// nb(String) - Not-blank check
1262 	//====================================================================================================
1263 	@Test
1264 	void a072_nb() {
1265 		assertFalse(nb(null));
1266 		assertFalse(nb(""));
1267 		assertFalse(nb("   "));
1268 		assertFalse(nb("\t\n"));
1269 		assertTrue(nb("hello"));
1270 		assertTrue(nb("  hello  "));
1271 	}
1272 
1273 	//====================================================================================================
1274 	// tr(String) - Trim
1275 	//====================================================================================================
1276 	@Test
1277 	void a073_tr() {
1278 		assertEquals("hello", tr("  hello  "));
1279 		assertEquals("hello", tr("hello"));
1280 		assertNull(tr(null));
1281 		assertEquals("", tr("   "));
1282 		assertEquals("a b", tr("  a b  "));
1283 	}
1284 
1285 	//====================================================================================================
1286 	// sw(String, String) - Starts with
1287 	//====================================================================================================
1288 	@Test
1289 	void a074_sw() {
1290 		assertTrue(sw("hello", "he"));
1291 		assertTrue(sw("hello", "hello"));
1292 		assertFalse(sw("hello", "lo"));
1293 		assertFalse(sw("hello", "xyz"));
1294 		assertFalse(sw(null, "he"));
1295 		assertFalse(sw("hello", null));
1296 		assertFalse(sw(null, null));
1297 	}
1298 
1299 	//====================================================================================================
1300 	// ew(String, String) - Ends with
1301 	//====================================================================================================
1302 	@Test
1303 	void a075_ew() {
1304 		assertTrue(ew("hello", "lo"));
1305 		assertTrue(ew("hello", "hello"));
1306 		assertFalse(ew("hello", "he"));
1307 		assertFalse(ew("hello", "xyz"));
1308 		assertFalse(ew(null, "lo"));
1309 		assertFalse(ew("hello", null));
1310 		assertFalse(ew(null, null));
1311 	}
1312 
1313 	//====================================================================================================
1314 	// co(String, String) - Contains
1315 	//====================================================================================================
1316 	@Test
1317 	void a076_co() {
1318 		assertTrue(co("hello", "ell"));
1319 		assertTrue(co("hello", "hello"));
1320 		assertTrue(co("hello", "h"));
1321 		assertTrue(co("hello", "o"));
1322 		assertFalse(co("hello", "xyz"));
1323 		assertFalse(co(null, "ell"));
1324 		assertFalse(co("hello", null));
1325 		assertFalse(co(null, null));
1326 	}
1327 
1328 	//====================================================================================================
1329 	// or(T...) - First non-null
1330 	//====================================================================================================
1331 	@Test
1332 	void a077_or() {
1333 		// Use explicit type parameters to avoid ambiguity with or(boolean...)
1334 		assertEquals("Hello", Utils.<String>or(null, null, "Hello", "World"));
1335 		assertEquals("Hello", Utils.<String>or("Hello", "World"));
1336 		assertNull(Utils.<String>or(null, null));
1337 		assertNull(Utils.<String>or((String[])null));
1338 		assertEquals("First", Utils.<String>or("First", "Second"));
1339 		assertEquals(123, Utils.<Integer>or(null, 123, 456));
1340 	}
1341 
1342 	//====================================================================================================
1343 	// def(T, T) - Default value
1344 	//====================================================================================================
1345 	@Test
1346 	void a078_def() {
1347 		assertEquals("Hello", def("Hello", "World"));
1348 		assertEquals("World", def(null, "World"));
1349 		assertEquals(123, def(123, 456));
1350 		assertEquals(456, def(null, 456));
1351 		assertNull(def(null, null));
1352 	}
1353 
1354 	//====================================================================================================
1355 	// and(boolean...) - Boolean AND
1356 	//====================================================================================================
1357 	@Test
1358 	void a079_and() {
1359 		assertTrue(and(true, true, true));
1360 		assertFalse(and(true, false, true));
1361 		assertFalse(and(false, false, false));
1362 		assertTrue(and()); // Empty array (vacuous truth)
1363 		assertTrue(and(true));
1364 		assertFalse(and(false));
1365 	}
1366 
1367 	//====================================================================================================
1368 	// or(boolean...) - Boolean OR
1369 	//====================================================================================================
1370 	@Test
1371 	void a080_or_boolean() {
1372 		// Use explicit boolean array to avoid ambiguity with or(T...)
1373 		boolean[] arr1 = {true, false, false};
1374 		assertTrue(or(arr1));
1375 		boolean[] arr2 = {false, true, false};
1376 		assertTrue(or(arr2));
1377 		boolean[] arr3 = {false, false, false};
1378 		assertFalse(or(arr3));
1379 		boolean[] arr4 = {};
1380 		assertFalse(or(arr4)); // Empty array
1381 		boolean[] arr5 = {true};
1382 		assertTrue(or(arr5));
1383 		boolean[] arr6 = {false};
1384 		assertFalse(or(arr6));
1385 	}
1386 
1387 	//====================================================================================================
1388 	// not(boolean) - Boolean NOT
1389 	//====================================================================================================
1390 	@Test
1391 	void a081_not() {
1392 		assertFalse(not(true));
1393 		assertTrue(not(false));
1394 	}
1395 
1396 	//====================================================================================================
1397 	// min(T, T) - Minimum
1398 	//====================================================================================================
1399 	@Test
1400 	void a082_min() {
1401 		assertEquals(5, min(5, 10));
1402 		assertEquals(5, min(10, 5));
1403 		assertEquals(5, min(5, 5));
1404 		assertEquals("apple", min("apple", "banana"));
1405 		assertEquals("apple", min("banana", "apple"));
1406 		assertEquals(10, min(null, 10));
1407 		assertEquals(10, min(10, null));
1408 		assertNull(min(null, null));
1409 	}
1410 
1411 	//====================================================================================================
1412 	// max(T, T) - Maximum
1413 	//====================================================================================================
1414 	@Test
1415 	void a083_max() {
1416 		assertEquals(10, max(5, 10));
1417 		assertEquals(10, max(10, 5));
1418 		assertEquals(10, max(10, 10));
1419 		assertEquals("banana", max("apple", "banana"));
1420 		assertEquals("banana", max("banana", "apple"));
1421 		assertEquals(10, max(null, 10));
1422 		assertEquals(10, max(10, null));
1423 		assertNull(max(null, null));
1424 	}
1425 
1426 	//====================================================================================================
1427 	// abs(Number) - Absolute value
1428 	//====================================================================================================
1429 	@Test
1430 	void a084_abs() {
1431 		assertEquals(5, abs(-5));
1432 		assertEquals(5, abs(5));
1433 		assertEquals(3.14, abs(-3.14));
1434 		assertEquals(3.14, abs(3.14));
1435 		assertEquals(10L, abs(-10L));
1436 		assertEquals(10L, abs(10L));
1437 		assertEquals((short)5, abs((short)-5));
1438 		assertEquals((byte)5, abs((byte)-5));
1439 		assertNull(abs(null));
1440 	}
1441 }
1442