1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2.event;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.mockito.Mockito.mock;
26
27 import java.util.Arrays;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.NoSuchElementException;
32
33 import org.junit.jupiter.api.BeforeAll;
34 import org.junit.jupiter.api.BeforeEach;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40 public class TestEventListenerList {
41
42
43
44
45 private static class EventBase extends Event {
46 private static final long serialVersionUID = 1L;
47
48
49 private final String message;
50
51 public EventBase(final Object source, final EventType<? extends EventBase> type, final String msg) {
52 super(source, type);
53 message = msg;
54 }
55
56 public String getMessage() {
57 return message;
58 }
59 }
60
61
62
63
64 private static final class EventSub1 extends EventBase {
65 private static final long serialVersionUID = 1L;
66
67 public EventSub1(final Object source, final EventType<? extends EventSub1> type, final String msg) {
68 super(source, type, msg);
69 }
70 }
71
72
73
74
75 private static final class EventSub2 extends EventBase {
76 private static final long serialVersionUID = 1L;
77
78 public EventSub2(final Object source, final EventType<? extends EventSub2> type, final String msg) {
79 super(source, type, msg);
80 }
81 }
82
83
84
85
86
87 private static final class ListenerTestImpl implements EventListener<EventBase> {
88
89 private EventBase receivedEvent;
90
91
92
93
94
95
96
97
98 public void assertEvent(final Object expSource, final EventType<?> expType, final String expMessage) {
99 assertNotNull(receivedEvent);
100 assertEquals(expSource, receivedEvent.getSource());
101 assertEquals(expType, receivedEvent.getEventType());
102 assertEquals(expMessage, receivedEvent.getMessage());
103 }
104
105
106
107
108 public void assertNoEvent() {
109 assertNull(receivedEvent);
110 }
111
112 @Override
113 public void onEvent(final EventBase event) {
114 assertNull(receivedEvent, "Too many events: " + event);
115 receivedEvent = event;
116 }
117 }
118
119
120 private static final String MESSAGE = "TestEventMessage";
121
122
123 private static EventType<EventBase> typeBase;
124
125
126 private static EventType<EventSub1> typeSub1;
127
128
129 private static EventType<EventSub2> typeSub2;
130
131
132
133
134
135
136
137 private static <T> List<T> fetchElements(final Iterable<? extends T> iterable) {
138 final List<T> elems = new LinkedList<>();
139 for (final T listener : iterable) {
140 elems.add(listener);
141 }
142 return elems;
143 }
144
145 @BeforeAll
146 public static void setUpBeforeClass() throws Exception {
147 typeBase = new EventType<>(Event.ANY, "BASE");
148 typeSub1 = new EventType<>(typeBase, "SUB1");
149 typeSub2 = new EventType<>(typeBase, "SUB2");
150 }
151
152
153 private EventListenerList list;
154
155
156
157
158
159
160
161 private void checkEventListenersForType(final EventType<? extends Event> eventType, final EventListener<?>... expListeners) {
162 final List<?> listeners = fetchElements(list.getEventListeners(eventType));
163 assertEquals(Arrays.asList(expListeners), listeners);
164 }
165
166 @BeforeEach
167 public void setUp() throws Exception {
168 list = new EventListenerList();
169 }
170
171
172
173
174 @Test
175 public void testAddAll() {
176 final EventListener<EventBase> l1 = new ListenerTestImpl();
177 final EventListener<EventBase> l2 = new ListenerTestImpl();
178 final EventListener<EventBase> l3 = new ListenerTestImpl();
179 list.addEventListener(typeBase, l1);
180 final EventListenerList list2 = new EventListenerList();
181 list2.addEventListener(typeSub1, l2);
182 list2.addEventListener(typeBase, l3);
183
184 list.addAll(list2);
185 final Iterator<EventListenerRegistrationData<?>> it = list.getRegistrations().iterator();
186 EventListenerRegistrationData<?> reg = it.next();
187 assertEquals(typeBase, reg.getEventType());
188 assertEquals(l1, reg.getListener());
189 reg = it.next();
190 assertEquals(typeSub1, reg.getEventType());
191 assertEquals(l2, reg.getListener());
192 reg = it.next();
193 assertEquals(typeBase, reg.getEventType());
194 assertEquals(l3, reg.getListener());
195 }
196
197
198
199
200 @Test
201 public void testAddAllNull() {
202 assertThrows(IllegalArgumentException.class, () -> list.addAll(null));
203 }
204
205
206
207
208 @Test
209 public void testClear() {
210 list.addEventListener(typeSub1, new ListenerTestImpl());
211 list.addEventListener(typeSub2, new ListenerTestImpl());
212
213 list.clear();
214 assertTrue(list.getRegistrations().isEmpty());
215 }
216
217
218
219
220 @Test
221 public void testEventListenerIteratorNullEvent() {
222 list.addEventListener(typeBase, new ListenerTestImpl());
223 final EventListenerList.EventListenerIterator<EventBase> iterator = list.getEventListenerIterator(typeBase);
224 assertThrows(IllegalArgumentException.class, () -> iterator.invokeNext(null));
225 }
226
227
228
229
230 @Test
231 public void testEventListenerIteratorWrongEvent() {
232 final EventListener<EventSub2> listener = event -> {};
233 list.addEventListener(typeSub2, listener);
234 final EventListenerList.EventListenerIterator<EventSub2> iterator = list.getEventListenerIterator(typeSub2);
235 assertTrue(iterator.hasNext());
236 final Event event = new EventBase(this, typeBase, "Test");
237 assertThrows(IllegalArgumentException.class, () -> iterator.invokeNext(event));
238 }
239
240
241
242
243 @Test
244 public void testFireNullEvent() {
245 assertThrows(IllegalArgumentException.class, () -> list.fire(null));
246 }
247
248
249
250
251 @Test
252 public void testGetEventListenerRegistrationsForSuperType() {
253 final ListenerTestImpl l1 = new ListenerTestImpl();
254 final ListenerTestImpl l2 = new ListenerTestImpl();
255 @SuppressWarnings("unchecked")
256 final EventListener<Event> l3 = mock(EventListener.class);
257 list.addEventListener(typeSub1, l1);
258 list.addEventListener(Event.ANY, l3);
259 list.addEventListener(typeBase, l2);
260
261 final List<EventListenerRegistrationData<? extends EventBase>> regs = list.getRegistrationsForSuperType(typeBase);
262 final Iterator<EventListenerRegistrationData<? extends EventBase>> iterator = regs.iterator();
263 assertEquals(l1, iterator.next().getListener());
264 assertEquals(l2, iterator.next().getListener());
265 assertFalse(iterator.hasNext());
266 }
267
268
269
270
271 @Test
272 public void testGetEventListenersBaseType() {
273 final ListenerTestImpl listener1 = new ListenerTestImpl();
274 final ListenerTestImpl listener2 = new ListenerTestImpl();
275 list.addEventListener(typeBase, listener1);
276 list.addEventListener(typeBase, listener2);
277 checkEventListenersForType(typeSub1, listener1, listener2);
278 }
279
280
281
282
283
284 @Test
285 public void testGetEventListenersIteratorNextNoElement() {
286 final ListenerTestImpl listener1 = new ListenerTestImpl();
287 final ListenerTestImpl listener2 = new ListenerTestImpl();
288 list.addEventListener(typeBase, listener1);
289 list.addEventListener(typeBase, listener2);
290 final Iterator<EventListener<? super EventBase>> iterator = list.getEventListeners(typeBase).iterator();
291 for (int i = 0; i < 2; i++) {
292 iterator.next();
293 }
294 assertThrows(NoSuchElementException.class, iterator::next);
295 }
296
297
298
299
300 @Test
301 public void testGetEventListenersIteratorRemove() {
302 list.addEventListener(typeBase, new ListenerTestImpl());
303 final Iterator<EventListener<? super EventBase>> iterator = list.getEventListeners(typeBase).iterator();
304 assertTrue(iterator.hasNext());
305 assertThrows(UnsupportedOperationException.class, iterator::remove);
306 }
307
308
309
310
311 @Test
312 public void testGetEventListenersMatchingType() {
313 final ListenerTestImpl listener1 = new ListenerTestImpl();
314 final ListenerTestImpl listener2 = new ListenerTestImpl();
315 list.addEventListener(typeSub1, listener1);
316 list.addEventListener(typeSub2, listener2);
317 checkEventListenersForType(typeSub1, listener1);
318 }
319
320
321
322
323 @Test
324 public void testGetEventListenersNoMatch() {
325 list.addEventListener(typeSub1, new ListenerTestImpl());
326 checkEventListenersForType(typeSub2);
327 }
328
329
330
331
332 @Test
333 public void testGetEventListenersNull() {
334 assertTrue(fetchElements(list.getEventListeners(null)).isEmpty());
335 }
336
337
338
339
340 @Test
341 public void testGetRegistrations() {
342 final EventListenerRegistrationData<EventSub1> reg1 = new EventListenerRegistrationData<>(typeSub1, new ListenerTestImpl());
343 final EventListenerRegistrationData<EventSub2> reg2 = new EventListenerRegistrationData<>(typeSub2, new ListenerTestImpl());
344 list.addEventListener(reg1);
345 list.addEventListener(reg2);
346
347 final List<EventListenerRegistrationData<?>> registrations = list.getRegistrations();
348 assertEquals(Arrays.asList(reg1, reg2), registrations);
349 }
350
351
352
353
354 @Test
355 public void testGetRegistrationsModify() {
356 final EventListenerRegistrationData<EventBase> registrationData = new EventListenerRegistrationData<>(typeBase, new ListenerTestImpl());
357 final List<EventListenerRegistrationData<?>> registrations = list.getRegistrations();
358 assertThrows(UnsupportedOperationException.class, () -> registrations.add(registrationData));
359 }
360
361
362
363
364 @Test
365 public void testListenerRegistrationWithListenerData() {
366 final ListenerTestImpl listener = new ListenerTestImpl();
367 final EventListenerRegistrationData<EventSub1> regData = new EventListenerRegistrationData<>(typeSub1, listener);
368 list.addEventListener(regData);
369
370 list.fire(new EventSub1(this, typeSub1, MESSAGE));
371 listener.assertEvent(this, typeSub1, MESSAGE);
372 }
373
374
375
376
377 @Test
378 public void testListenerRegistrationWithNullListenerData() {
379 assertThrows(IllegalArgumentException.class, () -> list.addEventListener(null));
380 }
381
382
383
384
385 @Test
386 public void testMultipleListenerRegistration() {
387 final ListenerTestImpl listener = new ListenerTestImpl();
388 list.addEventListener(typeSub1, listener);
389 list.addEventListener(typeSub2, listener);
390
391 list.fire(new EventSub2(this, typeSub2, MESSAGE));
392 list.removeEventListener(typeSub1, listener);
393 list.fire(new EventSub1(this, typeSub1, MESSAGE));
394 listener.assertEvent(this, typeSub2, MESSAGE);
395 }
396
397
398
399
400 @Test
401 public void testReceiveEventDifferentType() {
402 final ListenerTestImpl listener1 = new ListenerTestImpl();
403 final ListenerTestImpl listener2 = new ListenerTestImpl();
404 list.addEventListener(typeSub1, listener1);
405 list.addEventListener(typeSub2, listener2);
406
407 list.fire(new EventSub1(this, typeSub1, MESSAGE));
408 listener1.assertEvent(this, typeSub1, MESSAGE);
409 listener2.assertNoEvent();
410 }
411
412
413
414
415 @Test
416 public void testReceiveEventMultipleListeners() {
417 final ListenerTestImpl listener1 = new ListenerTestImpl();
418 final ListenerTestImpl listener2 = new ListenerTestImpl();
419 list.addEventListener(typeSub1, listener1);
420 list.addEventListener(typeSub1, listener2);
421
422 list.fire(new EventSub1(this, typeSub1, MESSAGE));
423 listener1.assertEvent(this, typeSub1, MESSAGE);
424 listener2.assertEvent(this, typeSub1, MESSAGE);
425 }
426
427
428
429
430 @Test
431 public void testReceiveEventOfExactType() {
432 final ListenerTestImpl listener = new ListenerTestImpl();
433 list.addEventListener(typeSub1, listener);
434
435 list.fire(new EventSub1(this, typeSub1, MESSAGE));
436 listener.assertEvent(this, typeSub1, MESSAGE);
437 }
438
439
440
441
442 @Test
443 public void testReceiveEventSubType() {
444 final ListenerTestImpl listener = new ListenerTestImpl();
445 list.addEventListener(typeBase, listener);
446
447 list.fire(new EventSub1(this, typeSub1, MESSAGE));
448 listener.assertEvent(this, typeSub1, MESSAGE);
449 }
450
451
452
453
454 @Test
455 public void testRegisterEventTypeNull() {
456 final ListenerTestImpl listener = new ListenerTestImpl();
457 assertThrows(IllegalArgumentException.class, () -> list.addEventListener(null, listener));
458 }
459
460
461
462
463 @Test
464 public void testRegisterListenerNull() {
465 assertThrows(IllegalArgumentException.class, () -> list.addEventListener(typeBase, null));
466 }
467
468
469
470
471 @Test
472 public void testRemoveEventListenerExisting() {
473 final ListenerTestImpl listener = new ListenerTestImpl();
474 list.addEventListener(typeSub1, listener);
475
476 assertTrue(list.removeEventListener(typeSub1, listener));
477 list.fire(new EventSub1(this, typeSub1, MESSAGE));
478 listener.assertNoEvent();
479 }
480
481
482
483
484 @Test
485 public void testRemoveEventListenerNonExistingEventType() {
486 final ListenerTestImpl listener = new ListenerTestImpl();
487 list.addEventListener(typeSub1, listener);
488
489 assertFalse(list.removeEventListener(typeBase, listener));
490 }
491
492
493
494
495 @Test
496 public void testRemoveEventListenerNonExistingListener() {
497 list.addEventListener(typeBase, new ListenerTestImpl());
498 assertFalse(list.removeEventListener(typeBase, new ListenerTestImpl()));
499 }
500
501
502
503
504 @Test
505 public void testRemoveEventListenerNullListener() {
506 assertFalse(list.removeEventListener(typeBase, null));
507 }
508
509
510
511
512 @Test
513 public void testRemoveEventListenerNullRegistration() {
514 assertFalse(list.removeEventListener(null));
515 }
516
517
518
519
520 @Test
521 public void testRemoveEventListenerNullType() {
522 assertFalse(list.removeEventListener(null, new ListenerTestImpl()));
523 }
524
525
526
527
528 @Test
529 public void testSuppressEventOfSuperType() {
530 final ListenerTestImpl listener = new ListenerTestImpl();
531 list.addEventListener(typeSub1, listener);
532
533 list.fire(new EventBase(this, typeBase, MESSAGE));
534 listener.assertNoEvent();
535 }
536 }