001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.configuration.event;
018:
019: import java.util.Collection;
020:
021: import junit.framework.TestCase;
022:
023: /**
024: * Test class for EventSource.
025: *
026: * @version $Id: TestEventSource.java 495918 2007-01-13 16:33:02Z oheger $
027: */
028: public class TestEventSource extends TestCase {
029: /** Constant for the event type used for testing. */
030: static final int TEST_TYPE = 42;
031:
032: /** Constant for the event property name. */
033: static final String TEST_PROPNAME = "test.property.name";
034:
035: /** Constant for the event property value. */
036: static final Object TEST_PROPVALUE = "a test property value";
037:
038: /** The object under test. */
039: CountingEventSource source;
040:
041: protected void setUp() throws Exception {
042: super .setUp();
043: source = new CountingEventSource();
044: }
045:
046: /**
047: * Tests a newly created source object.
048: */
049: public void testInit() {
050: assertTrue("Listeners list is not empty", source
051: .getConfigurationListeners().isEmpty());
052: assertFalse("Removing listener", source
053: .removeConfigurationListener(new TestListener()));
054: assertFalse("Detail events are enabled", source
055: .isDetailEvents());
056: assertTrue("Error listeners list is not empty", source
057: .getErrorListeners().isEmpty());
058: }
059:
060: /**
061: * Tests registering a new listener.
062: */
063: public void testAddConfigurationListener() {
064: TestListener l = new TestListener();
065: source.addConfigurationListener(l);
066: Collection listeners = source.getConfigurationListeners();
067: assertEquals("Wrong number of listeners", 1, listeners.size());
068: assertTrue("Listener not in list", listeners.contains(l));
069: }
070:
071: /**
072: * Tests adding an undefined configuration listener. This should cause an
073: * exception.
074: */
075: public void testAddNullConfigurationListener() {
076: try {
077: source.addConfigurationListener(null);
078: fail("Could add null listener!");
079: } catch (IllegalArgumentException iex) {
080: // ok
081: }
082: }
083:
084: /**
085: * Tests removing a listener.
086: */
087: public void testRemoveConfigurationListener() {
088: TestListener l = new TestListener();
089: assertFalse("Listener can be removed?", source
090: .removeConfigurationListener(l));
091: source.addConfigurationListener(l);
092: source.addConfigurationListener(new TestListener());
093: assertFalse("Unknown listener can be removed", source
094: .removeConfigurationListener(new TestListener()));
095: assertTrue("Could not remove listener", source
096: .removeConfigurationListener(l));
097: assertFalse("Listener still in list", source
098: .getConfigurationListeners().contains(l));
099: }
100:
101: /**
102: * Tests if a null listener can be removed. This should be a no-op.
103: */
104: public void testRemoveNullConfigurationListener() {
105: source.addConfigurationListener(new TestListener());
106: assertFalse("Null listener can be removed", source
107: .removeConfigurationListener(null));
108: assertEquals("Listener list was modified", 1, source
109: .getConfigurationListeners().size());
110: }
111:
112: /**
113: * Tests whether the listeners list is read only.
114: */
115: public void testGetConfigurationListenersUpdate() {
116: source.addConfigurationListener(new TestListener());
117: Collection list = source.getConfigurationListeners();
118: try {
119: list.add("test");
120: fail("Could manipulate list!");
121: } catch (Exception ex) {
122: // ok
123: }
124: }
125:
126: /**
127: * Tests that the collection returned by getConfigurationListeners() is
128: * really a snapshot. A later added listener must not be visible.
129: */
130: public void testGetConfigurationListenersAddNew() {
131: Collection list = source.getConfigurationListeners();
132: source.addConfigurationListener(new TestListener());
133: assertTrue("Listener snapshot not empty", list.isEmpty());
134: }
135:
136: /**
137: * Tests enabling and disabling the detail events flag.
138: */
139: public void testSetDetailEvents() {
140: source.setDetailEvents(true);
141: assertTrue("Detail events are disabled", source
142: .isDetailEvents());
143: source.setDetailEvents(true);
144: source.setDetailEvents(false);
145: assertTrue("Detail events are disabled again", source
146: .isDetailEvents());
147: source.setDetailEvents(false);
148: assertFalse("Detail events are still enabled", source
149: .isDetailEvents());
150: }
151:
152: /**
153: * Tests delivering an event to a listener.
154: */
155: public void testFireEvent() {
156: TestListener l = new TestListener();
157: source.addConfigurationListener(l);
158: source
159: .fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
160: true);
161: assertEquals("Not 1 event created", 1, source.eventCount);
162: assertEquals("Listener not called once", 1, l.numberOfCalls);
163: assertEquals("Wrong event type", TEST_TYPE, l.lastEvent
164: .getType());
165: assertEquals("Wrong property name", TEST_PROPNAME, l.lastEvent
166: .getPropertyName());
167: assertEquals("Wrong property value", TEST_PROPVALUE,
168: l.lastEvent.getPropertyValue());
169: assertTrue("Wrong before event flag", l.lastEvent
170: .isBeforeUpdate());
171: }
172:
173: /**
174: * Tests firering an event if there are no listeners.
175: */
176: public void testFireEventNoListeners() {
177: source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
178: false);
179: assertEquals("An event object was created", 0,
180: source.eventCount);
181: }
182:
183: /**
184: * Tests generating a detail event if detail events are not allowed.
185: */
186: public void testFireEventNoDetails() {
187: TestListener l = new TestListener();
188: source.addConfigurationListener(l);
189: source.setDetailEvents(false);
190: source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
191: false);
192: assertEquals("Event object was created", 0, source.eventCount);
193: assertEquals("Listener was called", 0, l.numberOfCalls);
194: }
195:
196: /**
197: * Tests whether an event listener can deregister itself in reaction of a
198: * delivered event.
199: */
200: public void testRemoveListenerInFireEvent() {
201: ConfigurationListener lstRemove = new ConfigurationListener() {
202: public void configurationChanged(ConfigurationEvent event) {
203: source.removeConfigurationListener(this );
204: }
205: };
206:
207: source.addConfigurationListener(lstRemove);
208: TestListener l = new TestListener();
209: source.addConfigurationListener(l);
210: source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
211: false);
212: assertEquals("Listener was not called", 1, l.numberOfCalls);
213: assertEquals("Listener was not removed", 1, source
214: .getConfigurationListeners().size());
215: }
216:
217: /**
218: * Tests registering a new error listener.
219: */
220: public void testAddErrorListener() {
221: TestListener l = new TestListener();
222: source.addErrorListener(l);
223: Collection listeners = source.getErrorListeners();
224: assertEquals("Wrong number of listeners", 1, listeners.size());
225: assertTrue("Listener not in list", listeners.contains(l));
226: }
227:
228: /**
229: * Tests adding an undefined error listener. This should cause an exception.
230: */
231: public void testAddNullErrorListener() {
232: try {
233: source.addErrorListener(null);
234: fail("Could add null error listener!");
235: } catch (IllegalArgumentException iex) {
236: // ok
237: }
238: }
239:
240: /**
241: * Tests removing an error listener.
242: */
243: public void testRemoveErrorListener() {
244: TestListener l = new TestListener();
245: assertFalse("Listener can be removed?", source
246: .removeErrorListener(l));
247: source.addErrorListener(l);
248: source.addErrorListener(new TestListener());
249: assertFalse("Unknown listener can be removed", source
250: .removeErrorListener(new TestListener()));
251: assertTrue("Could not remove listener", source
252: .removeErrorListener(l));
253: assertFalse("Listener still in list", source
254: .getErrorListeners().contains(l));
255: }
256:
257: /**
258: * Tests if a null error listener can be removed. This should be a no-op.
259: */
260: public void testRemoveNullErrorListener() {
261: source.addErrorListener(new TestListener());
262: assertFalse("Null listener can be removed", source
263: .removeErrorListener(null));
264: assertEquals("Listener list was modified", 1, source
265: .getErrorListeners().size());
266: }
267:
268: /**
269: * Tests whether the listeners list is read only.
270: */
271: public void testGetErrorListenersUpdate() {
272: source.addErrorListener(new TestListener());
273: Collection list = source.getErrorListeners();
274: try {
275: list.add("test");
276: fail("Could manipulate list!");
277: } catch (Exception ex) {
278: // ok
279: }
280: }
281:
282: /**
283: * Tests delivering an error event to a listener.
284: */
285: public void testFireError() {
286: TestListener l = new TestListener();
287: source.addErrorListener(l);
288: Exception testException = new Exception("A test");
289: source.fireError(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
290: testException);
291: assertEquals("Not 1 event created", 1, source.errorCount);
292: assertEquals("Error listener not called once", 1,
293: l.numberOfErrors);
294: assertEquals("Normal event was generated", 0, l.numberOfCalls);
295: assertEquals("Wrong event type", TEST_TYPE, l.lastEvent
296: .getType());
297: assertEquals("Wrong property name", TEST_PROPNAME, l.lastEvent
298: .getPropertyName());
299: assertEquals("Wrong property value", TEST_PROPVALUE,
300: l.lastEvent.getPropertyValue());
301: assertEquals("Wrong Throwable object", testException,
302: ((ConfigurationErrorEvent) l.lastEvent).getCause());
303: }
304:
305: /**
306: * Tests firering an error event if there are no error listeners.
307: */
308: public void testFireErrorNoListeners() {
309: source.fireError(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE,
310: new Exception());
311: assertEquals("An error event object was created", 0,
312: source.errorCount);
313: }
314:
315: /**
316: * Tests cloning an event source object. The registered listeners should not
317: * be registered at the clone.
318: */
319: public void testClone() throws CloneNotSupportedException {
320: source.addConfigurationListener(new TestListener());
321: source.addErrorListener(new TestListener());
322: EventSource copy = (EventSource) source.clone();
323: assertTrue("Configuration listeners registered for clone", copy
324: .getConfigurationListeners().isEmpty());
325: assertTrue("Error listeners registered for clone", copy
326: .getErrorListeners().isEmpty());
327: }
328:
329: /**
330: * A test event listener implementation.
331: */
332: static class TestListener implements ConfigurationListener,
333: ConfigurationErrorListener {
334: ConfigurationEvent lastEvent;
335:
336: int numberOfCalls;
337:
338: int numberOfErrors;
339:
340: public void configurationChanged(ConfigurationEvent event) {
341: lastEvent = event;
342: numberOfCalls++;
343: }
344:
345: public void configurationError(ConfigurationErrorEvent event) {
346: lastEvent = event;
347: numberOfErrors++;
348: }
349: }
350:
351: /**
352: * A specialized event source implementation that counts the number of
353: * created event objects. It is used to test whether the
354: * <code>fireEvent()</code> methods only creates event objects if
355: * necessary. It also allows testing the clone() operation.
356: */
357: static class CountingEventSource extends EventSource implements
358: Cloneable {
359: int eventCount;
360:
361: int errorCount;
362:
363: protected ConfigurationEvent createEvent(int type,
364: String propName, Object propValue, boolean before) {
365: eventCount++;
366: return super .createEvent(type, propName, propValue, before);
367: }
368:
369: protected ConfigurationErrorEvent createErrorEvent(int type,
370: String propName, Object value, Throwable ex) {
371: errorCount++;
372: return super.createErrorEvent(type, propName, value, ex);
373: }
374: }
375: }
|