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.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNotNull;
21 import static org.junit.jupiter.api.Assertions.assertSame;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23
24 import java.io.IOException;
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).accept(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
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 final Collection<Closure<Object>> finalColl = new ArrayList<>();
101 finalColl.add(null);
102 finalColl.add(null);
103 assertThrows(NullPointerException.class, () -> ClosureUtils.chainedClosure(finalColl));
104 }
105
106 @Test
107 public void testDoWhileClosure() {
108 MockClosure<Object> cmd = new MockClosure<>();
109 ClosureUtils.doWhileClosure(cmd, FalsePredicate.falsePredicate()).execute(null);
110 assertEquals(1, cmd.count);
111
112 cmd = new MockClosure<>();
113 ClosureUtils.doWhileClosure(cmd, PredicateUtils.uniquePredicate()).execute(null);
114 assertEquals(2, cmd.count);
115
116 assertThrows(NullPointerException.class, () -> ClosureUtils.doWhileClosure(null, null));
117 }
118
119 @Test
120 public void testExceptionClosure() {
121 assertNotNull(ClosureUtils.exceptionClosure());
122 assertSame(ClosureUtils.exceptionClosure(), ClosureUtils.exceptionClosure());
123
124 assertThrows(FunctorException.class, () -> ClosureUtils.exceptionClosure().execute(null));
125 assertThrows(FunctorException.class, () -> ClosureUtils.exceptionClosure().execute(cString));
126 }
127
128 @Test
129 public void testForClosure() {
130 final MockClosure<Object> cmd = new MockClosure<>();
131 ClosureUtils.forClosure(5, cmd).execute(null);
132 assertEquals(5, cmd.count);
133 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(0, new MockClosure<>()));
134 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(-1, new MockClosure<>()));
135 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(1, null));
136 assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(3, null));
137 assertSame(cmd, ClosureUtils.forClosure(1, cmd));
138 }
139
140 @Test
141 public void testIfClosure() {
142 MockClosure<Object> a = new MockClosure<>();
143 MockClosure<Object> b;
144 ClosureUtils.ifClosure(TruePredicate.truePredicate(), a).execute(null);
145 assertEquals(1, a.count);
146
147 a = new MockClosure<>();
148 ClosureUtils.ifClosure(FalsePredicate.<Object>falsePredicate(), a).execute(null);
149 assertEquals(0, a.count);
150
151 a = new MockClosure<>();
152 b = new MockClosure<>();
153 ClosureUtils.ifClosure(TruePredicate.<Object>truePredicate(), a, b).execute(null);
154 assertEquals(1, a.count);
155 assertEquals(0, b.count);
156
157 a = new MockClosure<>();
158 b = new MockClosure<>();
159 ClosureUtils.ifClosure(FalsePredicate.<Object>falsePredicate(), a, b).execute(null);
160 assertEquals(0, a.count);
161 assertEquals(1, b.count);
162 }
163
164 @Test
165 public void testInvokeClosure() {
166 StringBuilder buf = new StringBuilder("Hello");
167 ClosureUtils.invokerClosure("reverse").execute(buf);
168 assertEquals("olleH", buf.toString());
169 buf = new StringBuilder("Hello");
170 ClosureUtils.invokerClosure("setLength", new Class[] {Integer.TYPE}, new Object[] {Integer.valueOf(2)}).execute(buf);
171 assertEquals("He", buf.toString());
172 }
173
174 @Test
175 public void testNopClosure() {
176 final StringBuilder buf = new StringBuilder("Hello");
177 ClosureUtils.nopClosure().execute(null);
178 assertEquals("Hello", buf.toString());
179 ClosureUtils.nopClosure().execute("Hello");
180 assertEquals("Hello", buf.toString());
181 }
182
183
184
185
186
187 @Test
188 public void testSingletonPatternInSerialization() throws ClassNotFoundException, IOException {
189 final Object[] singletons = {
190 ExceptionClosure.INSTANCE,
191 NOPClosure.INSTANCE,
192 };
193
194 for (final Object original : singletons) {
195 TestUtils.assertSameAfterSerialization(
196 "Singleton pattern broken for " + original.getClass(),
197 original
198 );
199 }
200 }
201
202 @Test
203 @SuppressWarnings("unchecked")
204 public void testSwitchClosure() {
205 final MockClosure<String> a = new MockClosure<>();
206 final MockClosure<String> b = new MockClosure<>();
207 ClosureUtils.<String>switchClosure(
208 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
209 new Closure[] { a, b }).execute("WELL");
210 assertEquals(0, a.count);
211 assertEquals(0, b.count);
212
213 a.reset();
214 b.reset();
215 ClosureUtils.<String>switchClosure(
216 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
217 new Closure[] { a, b }).execute("HELLO");
218 assertEquals(1, a.count);
219 assertEquals(0, b.count);
220
221 a.reset();
222 b.reset();
223 final MockClosure<String> c = new MockClosure<>();
224 ClosureUtils.<String>switchClosure(
225 new Predicate[] { EqualPredicate.equalPredicate("HELLO"), EqualPredicate.equalPredicate("THERE") },
226 new Closure[] { a, b }, c).execute("WELL");
227 assertEquals(0, a.count);
228 assertEquals(0, b.count);
229 assertEquals(1, c.count);
230
231 a.reset();
232 b.reset();
233 final Map<Predicate<String>, Closure<String>> map = new HashMap<>();
234 map.put(EqualPredicate.equalPredicate("HELLO"), a);
235 map.put(EqualPredicate.equalPredicate("THERE"), b);
236 ClosureUtils.<String>switchClosure(map).execute(null);
237 assertEquals(0, a.count);
238 assertEquals(0, b.count);
239
240 a.reset();
241 b.reset();
242 map.clear();
243 map.put(EqualPredicate.equalPredicate("HELLO"), a);
244 map.put(EqualPredicate.equalPredicate("THERE"), b);
245 ClosureUtils.switchClosure(map).execute("THERE");
246 assertEquals(0, a.count);
247 assertEquals(1, b.count);
248
249 a.reset();
250 b.reset();
251 c.reset();
252 map.clear();
253 map.put(EqualPredicate.equalPredicate("HELLO"), a);
254 map.put(EqualPredicate.equalPredicate("THERE"), b);
255 map.put(null, c);
256 ClosureUtils.switchClosure(map).execute("WELL");
257 assertEquals(0, a.count);
258 assertEquals(0, b.count);
259 assertEquals(1, c.count);
260
261 assertEquals(NOPClosure.INSTANCE, ClosureUtils.<String>switchClosure(new Predicate[0], new Closure[0]));
262 assertEquals(NOPClosure.INSTANCE, ClosureUtils.<String>switchClosure(new HashMap<>()));
263 map.clear();
264 map.put(null, null);
265 assertEquals(NOPClosure.INSTANCE, ClosureUtils.switchClosure(map));
266
267 assertThrows(NullPointerException.class, () -> ClosureUtils.switchClosure(null, null));
268 assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure((Predicate<String>[]) null, (Closure<String>[]) null));
269 assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure((Map<Predicate<String>, Closure<String>>) null));
270 assertThrows(NullPointerException.class, () -> ClosureUtils.<String>switchClosure(new Predicate[2], new Closure[2]));
271 assertThrows(IllegalArgumentException.class,
272 () -> ClosureUtils.<String>switchClosure(new Predicate[] { TruePredicate.<String>truePredicate() }, new Closure[] { a, b }));
273 }
274
275 @Test
276 public void testSwitchMapClosure() {
277 final MockClosure<String> a = new MockClosure<>();
278 final MockClosure<String> b = new MockClosure<>();
279 final Map<String, Closure<String>> map = new HashMap<>();
280 map.put("HELLO", a);
281 map.put("THERE", b);
282 ClosureUtils.switchMapClosure(map).execute(null);
283 assertEquals(0, a.count);
284 assertEquals(0, b.count);
285
286 a.reset();
287 b.reset();
288 map.clear();
289 map.put("HELLO", a);
290 map.put("THERE", b);
291 ClosureUtils.switchMapClosure(map).execute("THERE");
292 assertEquals(0, a.count);
293 assertEquals(1, b.count);
294
295 a.reset();
296 b.reset();
297 map.clear();
298 final MockClosure<String> c = new MockClosure<>();
299 map.put("HELLO", a);
300 map.put("THERE", b);
301 map.put(null, c);
302 ClosureUtils.switchMapClosure(map).execute("WELL");
303 assertEquals(0, a.count);
304 assertEquals(0, b.count);
305 assertEquals(1, c.count);
306
307 assertEquals(NOPClosure.INSTANCE, ClosureUtils.switchMapClosure(new HashMap<>()));
308
309 assertThrows(NullPointerException.class, () -> ClosureUtils.switchMapClosure(null));
310 }
311
312 @Test
313 public void testTransformerClosure() {
314 final MockTransformer<Object> mock = new MockTransformer<>();
315 final Closure<Object> closure = ClosureUtils.asClosure(mock);
316 closure.execute(null);
317 assertEquals(1, mock.count);
318 closure.execute(null);
319 assertEquals(2, mock.count);
320
321 assertEquals(ClosureUtils.nopClosure(), ClosureUtils.asClosure(null));
322 }
323
324 @Test
325 public void testWhileClosure() {
326 MockClosure<Object> cmd = new MockClosure<>();
327 ClosureUtils.whileClosure(FalsePredicate.falsePredicate(), cmd).execute(null);
328 assertEquals(0, cmd.count);
329
330 cmd = new MockClosure<>();
331 ClosureUtils.whileClosure(PredicateUtils.uniquePredicate(), cmd).execute(null);
332 assertEquals(1, cmd.count);
333
334 assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(null, ClosureUtils.nopClosure()));
335 assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(FalsePredicate.falsePredicate(), null));
336 assertThrows(NullPointerException.class, () -> ClosureUtils.whileClosure(null, null));
337 }
338
339 }