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.LinkedList;
020:
021: import org.apache.commons.configuration.AbstractConfiguration;
022: import org.apache.commons.configuration.event.ConfigurationEvent;
023: import org.apache.commons.configuration.event.ConfigurationListener;
024:
025: import junit.framework.TestCase;
026:
027: /**
028: * Base class for testing events generated by configuration classes derived from
029: * AbstractConfiguration. This class implements a couple of tests related to
030: * event generation. Concrete sub classes only have to implement the
031: * <code>createConfiguration()</code> method for creating an instance of a
032: * specific configuration class. Because tests for detail events depend on a
033: * concrete implementation an exact sequence of events cannot be checked.
034: * Instead the corresponding test methods check whether the enclosing events
035: * (not the detail events) are of the expected type.
036: *
037: * @version $Id: AbstractTestConfigurationEvents.java 439648 2006-09-02 20:42:10Z oheger $
038: */
039: public abstract class AbstractTestConfigurationEvents extends TestCase {
040: /** Constant for a test property name. */
041: static final String TEST_PROPNAME = "event.test";
042:
043: /** Constant for a test property value. */
044: static final String TEST_PROPVALUE = "a value";
045:
046: /** Constant for an existing property. */
047: static final String EXIST_PROPERTY = "event.property";
048:
049: /** The configuration to be tested. */
050: protected AbstractConfiguration config;
051:
052: /** A test event listener. */
053: protected TestConfigurationListener l;
054:
055: protected void setUp() throws Exception {
056: super .setUp();
057: config = createConfiguration();
058: config.addProperty(EXIST_PROPERTY, "existing value");
059: l = new TestConfigurationListener();
060: config.addConfigurationListener(l);
061: }
062:
063: /**
064: * Creates the configuration instance to be tested.
065: *
066: * @return the configuration instance under test
067: */
068: protected abstract AbstractConfiguration createConfiguration();
069:
070: /**
071: * Tests events generated by addProperty().
072: */
073: public void testAddPropertyEvent() {
074: config.addProperty(TEST_PROPNAME, TEST_PROPVALUE);
075: l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY,
076: TEST_PROPNAME, TEST_PROPVALUE, true);
077: l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY,
078: TEST_PROPNAME, TEST_PROPVALUE, false);
079: l.done();
080: }
081:
082: /**
083: * Tests events generated by addProperty() when detail events are enabled.
084: */
085: public void testAddPropertyEventWithDetails() {
086: config.setDetailEvents(true);
087: config.addProperty(TEST_PROPNAME, TEST_PROPVALUE);
088: l.checkEventCount(2);
089: l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY,
090: TEST_PROPNAME, TEST_PROPVALUE, true);
091: l.skipToLast(AbstractConfiguration.EVENT_ADD_PROPERTY);
092: l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY,
093: TEST_PROPNAME, TEST_PROPVALUE, false);
094: l.done();
095: }
096:
097: /**
098: * Tests events generated by clearProperty().
099: */
100: public void testClearPropertyEvent() {
101: config.clearProperty(EXIST_PROPERTY);
102: l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
103: EXIST_PROPERTY, null, true);
104: l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
105: EXIST_PROPERTY, null, false);
106: l.done();
107: }
108:
109: /**
110: * Tests events generated by clearProperty() when detail events are enabled.
111: */
112: public void testClearPropertyEventWithDetails() {
113: config.setDetailEvents(true);
114: config.clearProperty(EXIST_PROPERTY);
115: l.checkEventCount(2);
116: l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
117: EXIST_PROPERTY, null, true);
118: l.skipToLast(AbstractConfiguration.EVENT_CLEAR_PROPERTY);
119: l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
120: EXIST_PROPERTY, null, false);
121: l.done();
122: }
123:
124: /**
125: * Tests events generated by setProperty().
126: */
127: public void testSetPropertyEvent() {
128: config.setProperty(EXIST_PROPERTY, TEST_PROPVALUE);
129: l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY,
130: EXIST_PROPERTY, TEST_PROPVALUE, true);
131: l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY,
132: EXIST_PROPERTY, TEST_PROPVALUE, false);
133: l.done();
134: }
135:
136: /**
137: * Tests events generated by setProperty() when detail events are enabled.
138: */
139: public void testSetPropertyEventWithDetails() {
140: config.setDetailEvents(true);
141: config.setProperty(EXIST_PROPERTY, TEST_PROPVALUE);
142: l.checkEventCount(2);
143: l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY,
144: EXIST_PROPERTY, TEST_PROPVALUE, true);
145: l.skipToLast(AbstractConfiguration.EVENT_SET_PROPERTY);
146: l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY,
147: EXIST_PROPERTY, TEST_PROPVALUE, false);
148: l.done();
149: }
150:
151: /**
152: * Tests the events generated by the clear() method.
153: */
154: public void testClearEvent() {
155: config.clear();
156: l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null,
157: true);
158: l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null,
159: false);
160: l.done();
161: }
162:
163: /**
164: * Tests the events generated by the clear method when detail events are
165: * enabled.
166: */
167: public void testClearEventWithDetails() {
168: config.setDetailEvents(true);
169: config.clear();
170: l.checkEventCount(2);
171: l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null,
172: true);
173: l.skipToLast(AbstractConfiguration.EVENT_CLEAR);
174: l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null,
175: false);
176: l.done();
177: }
178:
179: /**
180: * A test event listener class used for testing events generated by the
181: * configuration.
182: */
183: class TestConfigurationListener implements ConfigurationListener {
184: /** Stores the received events. */
185: private LinkedList events = new LinkedList();
186:
187: public void configurationChanged(ConfigurationEvent event) {
188: events.add(event);
189: }
190:
191: /**
192: * Checks if at least <code>minEvents</code> events have been
193: * received.
194: *
195: * @param minEvents the minimum number of expected events
196: */
197: public void checkEventCount(int minEvents) {
198: assertTrue("Too view events received",
199: events.size() >= minEvents);
200: }
201:
202: /**
203: * Checks an expected event.
204: *
205: * @param type the event type
206: * @param propName the expected property name
207: * @param propValue the expected property value
208: * @param before the expected before flag
209: */
210: public void checkEvent(int type, String propName,
211: Object propValue, boolean before) {
212: assertFalse("Too few events received", events.isEmpty());
213: ConfigurationEvent e = (ConfigurationEvent) events
214: .removeFirst();
215: assertEquals("Wrong event source", config, e.getSource());
216: assertEquals("Wrong event type", type, e.getType());
217: assertEquals("Wrong property name", propName, e
218: .getPropertyName());
219: assertEquals("Wrong property value", propValue, e
220: .getPropertyValue());
221: assertEquals("Wrong before flag", before, e
222: .isBeforeUpdate());
223: }
224:
225: /**
226: * Skips to the last received event and checks that no events of the
227: * given type have been received. This method is used by checks for
228: * detail events to ignore the detail events.
229: *
230: * @param type the event type
231: */
232: public void skipToLast(int type) {
233: while (events.size() > 1) {
234: ConfigurationEvent e = (ConfigurationEvent) events
235: .removeFirst();
236: assertTrue("Found end event in details", type != e
237: .getType());
238: }
239: }
240:
241: /**
242: * Checks if all events has been processed.
243: */
244: public void done() {
245: assertTrue("Too many events received", events.isEmpty());
246: }
247: }
248: }
|