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.junit.bct.BctAssertions.*;
20  import static org.junit.jupiter.api.Assertions.*;
21  
22  import org.apache.juneau.*;
23  import org.junit.jupiter.api.*;
24  
25  class CharValue_Test extends TestBase {
26  
27  	//-----------------------------------------------------------------------------------------------------------------
28  	// Basic tests
29  	//-----------------------------------------------------------------------------------------------------------------
30  
31  	@Test
32  	void a01_create() {
33  		var v = CharValue.create();
34  		assertEquals('\0', v.get());
35  	}
36  
37  	@Test
38  	void a02_of() {
39  		var v = CharValue.of('A');
40  		assertEquals('A', v.get());
41  	}
42  
43  	@Test
44  	void a03_constructor() {
45  		var v = new CharValue('Z');
46  		assertEquals('Z', v.get());
47  	}
48  
49  	@Test
50  	void a04_constructor_withNull() {
51  		var v = new CharValue(null);
52  		assertNull(v.get());
53  	}
54  
55  	//-----------------------------------------------------------------------------------------------------------------
56  	// Inherited Value<Character> methods
57  	//-----------------------------------------------------------------------------------------------------------------
58  
59  	@Test
60  	void b01_set() {
61  		var v = CharValue.create();
62  		v.set('B');
63  		assertEquals('B', v.get());
64  	}
65  
66  	@Test
67  	void b02_setIfEmpty() {
68  		var v = new CharValue(null);
69  		v.setIfEmpty('X');
70  		assertEquals('X', v.get());
71  
72  		v.setIfEmpty('Y');
73  		assertEquals('X', v.get()); // Should not change
74  	}
75  
76  	@Test
77  	void b03_orElse() {
78  		var v = new CharValue(null);
79  		assertEquals('?', v.orElse('?'));
80  
81  		v.set('!');
82  		assertEquals('!', v.orElse('?'));
83  	}
84  
85  	@Test
86  	void b04_map() {
87  		var v = CharValue.of('a');
88  		Value<Character> v2 = v.map(Character::toUpperCase);
89  		assertEquals('A', v2.get());
90  	}
91  
92  	@Test
93  	void b05_ifPresent() {
94  		var v = CharValue.of('C');
95  		var sb = new StringBuilder();
96  		v.ifPresent(sb::append);
97  		assertEquals("C", sb.toString());
98  	}
99  
100 	@Test
101 	void b06_isPresent() {
102 		var v = new CharValue(null);
103 		assertFalse(v.isPresent());
104 
105 		v.set('D');
106 		assertTrue(v.isPresent());
107 	}
108 
109 	@Test
110 	void b07_isEmpty() {
111 		var v = new CharValue(null);
112 		assertEmpty(v);
113 
114 		v.set('E');
115 		assertNotEmpty(v);
116 	}
117 
118 	@Test
119 	void b08_getAndSet() {
120 		var v = CharValue.of('F');
121 		assertEquals('F', v.getAndSet('G'));
122 		assertEquals('G', v.get());
123 	}
124 
125 	@Test
126 	void b09_getAndUnset() {
127 		var v = CharValue.of('H');
128 		assertEquals('H', v.getAndUnset());
129 		assertNull(v.get());
130 	}
131 
132 	//-----------------------------------------------------------------------------------------------------------------
133 	// Use case scenarios
134 	//-----------------------------------------------------------------------------------------------------------------
135 
136 	@Test
137 	void c01_trackingLastCharacter() {
138 		var lastChar = CharValue.create();
139 
140 		"Hello World".chars().mapToObj(c -> (char)c).forEach(ch -> {
141 			lastChar.set(ch);
142 		});
143 
144 		assertEquals('d', lastChar.get());
145 	}
146 
147 	@Test
148 	void c02_findingFirstUppercase() {
149 		var firstUpper = CharValue.of('\0');
150 
151 		"helloWorld".chars().mapToObj(c -> (char)c).forEach(ch -> {
152 			if (Character.isUpperCase(ch) && firstUpper.get() == '\0') {
153 				firstUpper.set(ch);
154 			}
155 		});
156 
157 		assertEquals('W', firstUpper.get());
158 	}
159 
160 	@Test
161 	void c03_toggleCase() {
162 		var ch = CharValue.of('a');
163 
164 		// Toggle to uppercase
165 		ch.set(Character.toUpperCase(ch.get()));
166 		assertEquals('A', ch.get());
167 
168 		// Toggle back to lowercase
169 		ch.set(Character.toLowerCase(ch.get()));
170 		assertEquals('a', ch.get());
171 	}
172 
173 	@Test
174 	void c04_trackingMostFrequentChar() {
175 		String text = "aabbccccdd";
176 		var mostFrequent = CharValue.of('\0');
177 		var maxCount = IntegerValue.create();
178 
179 		for (var c = 'a'; c <= 'z'; c++) {
180 			final char current = c;
181 			var count = IntegerValue.create();
182 			text.chars().mapToObj(ch -> (char)ch).forEach(ch -> {
183 				if (ch == current) {
184 					count.getAndIncrement();
185 				}
186 			});
187 
188 			if (count.get() > maxCount.get()) {
189 				maxCount.set(count.get());
190 				mostFrequent.set(current);
191 			}
192 		}
193 
194 		assertEquals('c', mostFrequent.get());
195 		assertEquals(4, maxCount.get());
196 	}
197 
198 	//-----------------------------------------------------------------------------------------------------------------
199 	// Increment/Decrement operations
200 	//-----------------------------------------------------------------------------------------------------------------
201 
202 	@Test
203 	void d01_increment() {
204 		var v = CharValue.of('A');
205 		v.increment();
206 		assertEquals('B', v.get());
207 	}
208 
209 	@Test
210 	void d02_increment_fromNull() {
211 		var v = new CharValue(null);
212 		v.increment();
213 		assertEquals('\u0001', v.get());  // null treated as 0, so 0+1 = 1
214 	}
215 
216 	@Test
217 	void d03_increment_wrapsAround() {
218 		var v = CharValue.of((char)65535);  // Max char value
219 		v.increment();
220 		assertEquals('\u0000', v.get());  // Wraps to 0
221 	}
222 
223 	@Test
224 	void d04_decrement() {
225 		var v = CharValue.of('B');
226 		v.decrement();
227 		assertEquals('A', v.get());
228 	}
229 
230 	@Test
231 	void d05_decrement_fromNull() {
232 		var v = new CharValue(null);
233 		v.decrement();
234 		assertEquals('\uFFFF', v.get());  // null treated as 0, so 0-1 = 65535 (wraps)
235 	}
236 
237 	@Test
238 	void d06_decrement_wrapsAround() {
239 		var v = CharValue.of('\u0000');  // Min char value
240 		v.decrement();
241 		assertEquals('\uFFFF', v.get());  // Wraps to max
242 	}
243 
244 	@Test
245 	void d07_incrementAndGet() {
246 		var v = CharValue.of('A');
247 		var result = v.incrementAndGet();
248 		assertEquals('B', result);
249 		assertEquals('B', v.get());
250 	}
251 
252 	@Test
253 	void d08_incrementAndGet_fromNull() {
254 		var v = new CharValue(null);
255 		var result = v.incrementAndGet();
256 		assertEquals('\u0001', result);
257 		assertEquals('\u0001', v.get());
258 	}
259 
260 	@Test
261 	void d09_decrementAndGet() {
262 		var v = CharValue.of('B');
263 		var result = v.decrementAndGet();
264 		assertEquals('A', result);
265 		assertEquals('A', v.get());
266 	}
267 
268 	@Test
269 	void d10_decrementAndGet_fromNull() {
270 		var v = new CharValue(null);
271 		var result = v.decrementAndGet();
272 		assertEquals('\uFFFF', result);
273 		assertEquals('\uFFFF', v.get());
274 	}
275 
276 	//-----------------------------------------------------------------------------------------------------------------
277 	// Add operations
278 	//-----------------------------------------------------------------------------------------------------------------
279 
280 	@Test
281 	void e01_add() {
282 		var v = CharValue.of('A');
283 		v.add((char)5);
284 		assertEquals('F', v.get());
285 	}
286 
287 	@Test
288 	void e02_add_withNullValue() {
289 		var v = CharValue.of('A');
290 		v.add(null);
291 		assertEquals('A', v.get());  // null treated as 0, so A+0 = A
292 	}
293 
294 	@Test
295 	void e03_add_toNullValue() {
296 		var v = new CharValue(null);
297 		v.add('B');
298 		assertEquals('B', v.get());  // null treated as 0, so 0+B = B
299 	}
300 
301 	@Test
302 	void e04_add_bothNull() {
303 		var v = new CharValue(null);
304 		v.add(null);
305 		assertEquals('\u0000', v.get());  // null+null = 0+0 = 0
306 	}
307 
308 	@Test
309 	void e05_add_wrapsAround() {
310 		var v = CharValue.of((char)65534);
311 		v.add((char)2);
312 		assertEquals('\u0000', v.get());  // Wraps to 0
313 	}
314 
315 	@Test
316 	void e06_addAndGet() {
317 		var v = CharValue.of('A');
318 		var result = v.addAndGet((char)5);
319 		assertEquals('F', result);
320 		assertEquals('F', v.get());
321 	}
322 
323 	@Test
324 	void e07_addAndGet_withNullValue() {
325 		var v = CharValue.of('A');
326 		var result = v.addAndGet(null);
327 		assertEquals('A', result);
328 		assertEquals('A', v.get());
329 	}
330 
331 	@Test
332 	void e08_addAndGet_toNullValue() {
333 		var v = new CharValue(null);
334 		var result = v.addAndGet('B');
335 		assertEquals('B', result);
336 		assertEquals('B', v.get());
337 	}
338 
339 	//-----------------------------------------------------------------------------------------------------------------
340 	// Comparison operations
341 	//-----------------------------------------------------------------------------------------------------------------
342 
343 	@Test
344 	void f01_is() {
345 		var v = CharValue.of('A');
346 		assertTrue(v.is('A'));
347 		assertFalse(v.is('B'));
348 		assertFalse(v.is(null));
349 	}
350 
351 	@Test
352 	void f02_is_withNullValue() {
353 		var v = new CharValue(null);
354 		assertFalse(v.is('A'));
355 		assertTrue(v.is(null));
356 	}
357 
358 	@Test
359 	void f03_isAny_withVarargs() {
360 		var v = CharValue.of('B');
361 		assertTrue(v.isAny('A', 'B', 'C'));
362 		assertTrue(v.isAny('B'));
363 		assertFalse(v.isAny('X', 'Y', 'Z'));
364 		assertFalse(v.isAny());
365 	}
366 
367 	@Test
368 	void f04_isAny_withVarargs_nullValue() {
369 		var v = new CharValue(null);
370 		assertFalse(v.isAny('A', 'B', 'C'));
371 		assertTrue(v.isAny((Character)null));
372 		assertTrue(v.isAny('A', null, 'B'));
373 	}
374 
375 	@Test
376 	void f05_isAny_withString() {
377 		var v = CharValue.of('B');
378 		assertTrue(v.isAny("ABC"));
379 		assertTrue(v.isAny("XYZB"));
380 		assertFalse(v.isAny("XYZ"));
381 		assertFalse(v.isAny(""));
382 		assertFalse(v.isAny((String)null));
383 	}
384 
385 	@Test
386 	void f06_isAny_withString_nullValue() {
387 		var v = new CharValue(null);
388 		assertFalse(v.isAny("ABC"));
389 		assertFalse(v.isAny(""));
390 		assertFalse(v.isAny((String)null));
391 	}
392 }
393