1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4;
18
19 import static org.junit.jupiter.api.Assertions.assertAll;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertSame;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import org.apache.commons.collections4.functors.EqualPredicate;
32 import org.apache.commons.collections4.functors.ExceptionClosure;
33 import org.apache.commons.collections4.functors.FalsePredicate;
34 import org.apache.commons.collections4.functors.NOPClosure;
35 import org.apache.commons.collections4.functors.TruePredicate;
36 import org.junit.jupiter.api.Test;
37
38
39
40
41 public class ClosureUtilsTest {
42
43 static class MockClosure<T> implements Closure<T> {
44 int count;
45
46 @Override
47 public void execute(final T object) {
48 count++;
49 }
50
51 public void reset() {
52 count = 0;
53 }
54 }
55
56 static class MockTransformer<T> implements Transformer<T, T> {
57 int count;
58
59 @Override
60 public T transform(final T object) {
61 count++;
62 return object;
63 }
64 }
65
66 private static final Object cString = "Hello";
67
68 @Test
69 @SuppressWarnings("unchecked")
70 public void testChainedClosure() {
71 MockClosure<Object> a = new MockClosure<>();
72 MockClosure<Object> b = new MockClosure<>();
73 ClosureUtils.chainedClosure(a, b).execute(null);
74 assertEquals(1, a.count);
75 assertEquals(1, b.count);
76
77 a = new MockClosure<>();
78 b = new MockClosure<>();
79 ClosureUtils.<Object>chainedClosure(a, b, a).execute(null);
80 assertEquals(2, a.count);
81 assertEquals(1, b.count);
82
83 a = new MockClosure<>();
84 b = new MockClosure<>();
85 final Collection<Closure<Object>> coll = new ArrayList<>();
86 coll.add(b);
87 coll.add(a);
88 coll.add(b);
89 ClosureUtils.<Object>chainedClosure(coll).execute(null);
90 assertEquals(1, a.count);
91 assertEquals(2, b.count);
92
93 assertSame(NOPClosure.INSTANCE, ClosureUtils.<Object>chainedClosure());
94 assertSame(NOPClosure.INSTANCE, ClosureUtils.<Object>chainedClosure(Collections.<Closure<Object>>emptyList()));
95 assertAll(
96 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.chainedClosure(null, null)),
97 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<Object>chainedClosure((Closure[]) null)),
98 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<Object>chainedClosure((Collection<Closure<Object>>) null)),
99 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<Object>chainedClosure(null, null)),
100 () -> {
101 final Collection<Closure<Object>> finalColl = new ArrayList<>();
102 finalColl.add(null);
103 finalColl.add(null);
104 assertThrows(NullPointerException.class, () -> ClosureUtils.chainedClosure(finalColl));
105 }
106 );
107 }
108
109 @Test
110 public void testDoWhileClosure() {
111 MockClosure<Object> cmd = new MockClosure<>();
112 ClosureUtils.doWhileClosure(cmd, FalsePredicate.falsePredicate()).execute(null);
113 assertEquals(1, cmd.count);
114
115 cmd = new MockClosure<>();
116 ClosureUtils.doWhileClosure(cmd, PredicateUtils.uniquePredicate()).execute(null);
117 assertEquals(2, cmd.count);
118
119 assertThrows(NullPointerException.class, () -> ClosureUtils.doWhileClosure(null, null));
120 }
121
122 @Test
123 public void testExceptionClosure() {
124 assertNotNull(ClosureUtils.exceptionClosure());
125 assertSame(ClosureUtils.exceptionClosure(), ClosureUtils.exceptionClosure());
126 assertAll(
127 () -> assertThrows(FunctorException.class, () -> ClosureUtils.exceptionClosure().execute(null)),
128 () -> assertThrows(FunctorException.class, () -> ClosureUtils.exceptionClosure().execute(cString))
129 );
130 }
131
132 @Test
133 public void testForClosure() {
134 final MockClosure<Object> cmd = new MockClosure<>();
135 ClosureUtils.forClosure(5, cmd).execute(null);
136 assertEquals(5, cmd.count);
137 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(0, new MockClosure<>()));
138 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(-1, new MockClosure<>()));
139 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(1, null));
140 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(3, null));
141 assertSame(cmd, ClosureUtils.forClosure(1, cmd));
142 }
143
144 @Test
145 public void testIfClosure() {
146 MockClosure<Object> a = new MockClosure<>();
147 MockClosure<Object> b;
148 ClosureUtils.ifClosure(TruePredicate.truePredicate(), a).execute(null);
149 assertEquals(1, a.count);
150
151 a = new MockClosure<>();
152 ClosureUtils.ifClosure(FalsePredicate.<Object>falsePredicate(), a).execute(null);
153 assertEquals(0, a.count);
154
155 a = new MockClosure<>();
156 b = new MockClosure<>();
157 ClosureUtils.ifClosure(TruePredicate.<Object>truePredicate(), a, b).execute(null);
158 assertEquals(1, a.count);
159 assertEquals(0, b.count);
160
161 a = new MockClosure<>();
162 b = new MockClosure<>();
163 ClosureUtils.ifClosure(FalsePredicate.<Object>falsePredicate(), a, b).execute(null);
164 assertEquals(0, a.count);
165 assertEquals(1, b.count);
166 }
167
168 @Test
169 public void testInvokeClosure() {
170 StringBuilder buf = new StringBuilder("Hello");
171 ClosureUtils.invokerClosure("reverse").execute(buf);
172 assertEquals("olleH", buf.toString());
173 buf = new StringBuilder("Hello");
174 ClosureUtils.invokerClosure("setLength", new Class[] {Integer.TYPE}, new Object[] {Integer.valueOf(2)}).execute(buf);
175 assertEquals("He", buf.toString());
176 }
177
178 @Test
179 public void testNopClosure() {
180 final StringBuilder buf = new StringBuilder("Hello");
181 ClosureUtils.nopClosure().execute(null);
182 assertEquals("Hello", buf.toString());
183 ClosureUtils.nopClosure().execute("Hello");
184 assertEquals("Hello", buf.toString());
185 }
186
187
188
189
190
191 @Test
192 public void testSingletonPatternInSerialization() {
193 final Object[] singletons = {
194 ExceptionClosure.INSTANCE,
195 NOPClosure.INSTANCE,
196 };
197
198 for (final Object original : singletons) {
199 TestUtils.assertSameAfterSerialization(
200 "Singleton pattern broken for " + original.getClass(),
201 original
202 );
203 }
204 }
205
206 @Test
207 @SuppressWarnings("unchecked")
208 public void testSwitchClosure() {
209 final MockClosure<String> a = new MockClosure<>();
210 final MockClosure<String> b = new MockClosure<>();
211 ClosureUtils.<String>switchClosure(
212 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
213 new Closure[] { a, b }).execute("WELL");
214 assertEquals(0, a.count);
215 assertEquals(0, b.count);
216
217 a.reset();
218 b.reset();
219 ClosureUtils.<String>switchClosure(
220 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
221 new Closure[] { a, b }).execute("HELLO");
222 assertEquals(1, a.count);
223 assertEquals(0, b.count);
224
225 a.reset();
226 b.reset();
227 final MockClosure<String> c = new MockClosure<>();
228 ClosureUtils.<String>switchClosure(
229 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
230 new Closure[] { a, b }, c).execute("WELL");
231 assertEquals(0, a.count);
232 assertEquals(0, b.count);
233 assertEquals(1, c.count);
234
235 a.reset();
236 b.reset();
237 final Map<Predicate<String>, Closure<String>> map = new HashMap<>();
238 map.put(EqualPredicate.equalPredicate("HELLO"), a);
239 map.put(EqualPredicate.equalPredicate("THERE"), b);
240 ClosureUtils.<String>switchClosure(map).execute(null);
241 assertEquals(0, a.count);
242 assertEquals(0, b.count);
243
244 a.reset();
245 b.reset();
246 map.clear();
247 map.put(EqualPredicate.equalPredicate("HELLO"), a);
248 map.put(EqualPredicate.equalPredicate("THERE"), b);
249 ClosureUtils.switchClosure(map).execute("THERE");
250 assertEquals(0, a.count);
251 assertEquals(1, b.count);
252
253 a.reset();
254 b.reset();
255 c.reset();
256 map.clear();
257 map.put(EqualPredicate.equalPredicate("HELLO"), a);
258 map.put(EqualPredicate.equalPredicate("THERE"), b);
259 map.put(null, c);
260 ClosureUtils.switchClosure(map).execute("WELL");
261 assertEquals(0, a.count);
262 assertEquals(0, b.count);
263 assertEquals(1, c.count);
264
265 assertEquals(NOPClosure.INSTANCE, ClosureUtils.<String>switchClosure(new Predicate[0], new Closure[0]));
266 assertEquals(NOPClosure.INSTANCE, ClosureUtils.<String>switchClosure(new HashMap<>()));
267 map.clear();
268 map.put(null, null);
269 assertEquals(NOPClosure.INSTANCE, ClosureUtils.switchClosure(map));
270 assertAll(
271 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.switchClosure(null, null)),
272 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure((Predicate<String>[]) null, (Closure<String>[]) null)),
273 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure((Map<Predicate<String>, Closure<String>>) null)),
274 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure(new Predicate[2], new Closure[2])),
275 () -> assertThrows(IllegalArgumentException.class, () -> ClosureUtils.<String>switchClosure(
276 new Predicate[]{TruePredicate.<String>truePredicate()},
277 new Closure[]{a, b}))
278 );
279 }
280
281 @Test
282 public void testSwitchMapClosure() {
283 final MockClosure<String> a = new MockClosure<>();
284 final MockClosure<String> b = new MockClosure<>();
285 final Map<String, Closure<String>> map = new HashMap<>();
286 map.put("HELLO", a);
287 map.put("THERE", b);
288 ClosureUtils.switchMapClosure(map).execute(null);
289 assertEquals(0, a.count);
290 assertEquals(0, b.count);
291
292 a.reset();
293 b.reset();
294 map.clear();
295 map.put("HELLO", a);
296 map.put("THERE", b);
297 ClosureUtils.switchMapClosure(map).execute("THERE");
298 assertEquals(0, a.count);
299 assertEquals(1, b.count);
300
301 a.reset();
302 b.reset();
303 map.clear();
304 final MockClosure<String> c = new MockClosure<>();
305 map.put("HELLO", a);
306 map.put("THERE", b);
307 map.put(null, c);
308 ClosureUtils.switchMapClosure(map).execute("WELL");
309 assertEquals(0, a.count);
310 assertEquals(0, b.count);
311 assertEquals(1, c.count);
312
313 assertEquals(NOPClosure.INSTANCE, ClosureUtils.switchMapClosure(new HashMap<>()));
314
315 assertThrows(NullPointerException.class, () -> ClosureUtils.switchMapClosure(null));
316 }
317
318 @Test
319 public void testTransformerClosure() {
320 final MockTransformer<Object> mock = new MockTransformer<>();
321 final Closure<Object> closure = ClosureUtils.asClosure(mock);
322 closure.execute(null);
323 assertEquals(1, mock.count);
324 closure.execute(null);
325 assertEquals(2, mock.count);
326
327 assertEquals(ClosureUtils.nopClosure(), ClosureUtils.asClosure(null));
328 }
329
330 @Test
331 public void testWhileClosure() {
332 MockClosure<Object> cmd = new MockClosure<>();
333 ClosureUtils.whileClosure(FalsePredicate.falsePredicate(), cmd).execute(null);
334 assertEquals(0, cmd.count);
335
336 cmd = new MockClosure<>();
337 ClosureUtils.whileClosure(PredicateUtils.uniquePredicate(), cmd).execute(null);
338 assertEquals(1, cmd.count);
339 assertAll(
340 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(null, ClosureUtils.nopClosure())),
341 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(FalsePredicate.falsePredicate(), null)),
342 () -> assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(null, null))
343 );
344 }
345
346 }