1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.event;
18
19 import java.util.LinkedList;
20
21 import org.apache.commons.configuration.AbstractConfiguration;
22 import org.apache.commons.configuration.event.ConfigurationEvent;
23 import org.apache.commons.configuration.event.ConfigurationListener;
24
25 import junit.framework.TestCase;
26
27 /***
28 * Base class for testing events generated by configuration classes derived from
29 * AbstractConfiguration. This class implements a couple of tests related to
30 * event generation. Concrete sub classes only have to implement the
31 * <code>createConfiguration()</code> method for creating an instance of a
32 * specific configuration class. Because tests for detail events depend on a
33 * concrete implementation an exact sequence of events cannot be checked.
34 * Instead the corresponding test methods check whether the enclosing events
35 * (not the detail events) are of the expected type.
36 *
37 * @version $Id: AbstractTestConfigurationEvents.java 439648 2006-09-02 20:42:10Z oheger $
38 */
39 public abstract class AbstractTestConfigurationEvents extends TestCase
40 {
41 /*** Constant for a test property name. */
42 static final String TEST_PROPNAME = "event.test";
43
44 /*** Constant for a test property value. */
45 static final String TEST_PROPVALUE = "a value";
46
47 /*** Constant for an existing property. */
48 static final String EXIST_PROPERTY = "event.property";
49
50 /*** The configuration to be tested. */
51 protected AbstractConfiguration config;
52
53 /*** A test event listener. */
54 protected TestConfigurationListener l;
55
56 protected void setUp() throws Exception
57 {
58 super.setUp();
59 config = createConfiguration();
60 config.addProperty(EXIST_PROPERTY, "existing value");
61 l = new TestConfigurationListener();
62 config.addConfigurationListener(l);
63 }
64
65 /***
66 * Creates the configuration instance to be tested.
67 *
68 * @return the configuration instance under test
69 */
70 protected abstract AbstractConfiguration createConfiguration();
71
72 /***
73 * Tests events generated by addProperty().
74 */
75 public void testAddPropertyEvent()
76 {
77 config.addProperty(TEST_PROPNAME, TEST_PROPVALUE);
78 l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_PROPNAME,
79 TEST_PROPVALUE, true);
80 l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_PROPNAME,
81 TEST_PROPVALUE, false);
82 l.done();
83 }
84
85 /***
86 * Tests events generated by addProperty() when detail events are enabled.
87 */
88 public void testAddPropertyEventWithDetails()
89 {
90 config.setDetailEvents(true);
91 config.addProperty(TEST_PROPNAME, TEST_PROPVALUE);
92 l.checkEventCount(2);
93 l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_PROPNAME,
94 TEST_PROPVALUE, true);
95 l.skipToLast(AbstractConfiguration.EVENT_ADD_PROPERTY);
96 l.checkEvent(AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_PROPNAME,
97 TEST_PROPVALUE, false);
98 l.done();
99 }
100
101 /***
102 * Tests events generated by clearProperty().
103 */
104 public void testClearPropertyEvent()
105 {
106 config.clearProperty(EXIST_PROPERTY);
107 l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
108 EXIST_PROPERTY, null, true);
109 l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
110 EXIST_PROPERTY, null, false);
111 l.done();
112 }
113
114 /***
115 * Tests events generated by clearProperty() when detail events are enabled.
116 */
117 public void testClearPropertyEventWithDetails()
118 {
119 config.setDetailEvents(true);
120 config.clearProperty(EXIST_PROPERTY);
121 l.checkEventCount(2);
122 l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
123 EXIST_PROPERTY, null, true);
124 l.skipToLast(AbstractConfiguration.EVENT_CLEAR_PROPERTY);
125 l.checkEvent(AbstractConfiguration.EVENT_CLEAR_PROPERTY,
126 EXIST_PROPERTY, null, false);
127 l.done();
128 }
129
130 /***
131 * Tests events generated by setProperty().
132 */
133 public void testSetPropertyEvent()
134 {
135 config.setProperty(EXIST_PROPERTY, TEST_PROPVALUE);
136 l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY, EXIST_PROPERTY,
137 TEST_PROPVALUE, true);
138 l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY, EXIST_PROPERTY,
139 TEST_PROPVALUE, false);
140 l.done();
141 }
142
143 /***
144 * Tests events generated by setProperty() when detail events are enabled.
145 */
146 public void testSetPropertyEventWithDetails()
147 {
148 config.setDetailEvents(true);
149 config.setProperty(EXIST_PROPERTY, TEST_PROPVALUE);
150 l.checkEventCount(2);
151 l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY, EXIST_PROPERTY,
152 TEST_PROPVALUE, true);
153 l.skipToLast(AbstractConfiguration.EVENT_SET_PROPERTY);
154 l.checkEvent(AbstractConfiguration.EVENT_SET_PROPERTY, EXIST_PROPERTY,
155 TEST_PROPVALUE, false);
156 l.done();
157 }
158
159 /***
160 * Tests the events generated by the clear() method.
161 */
162 public void testClearEvent()
163 {
164 config.clear();
165 l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null, true);
166 l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null, false);
167 l.done();
168 }
169
170 /***
171 * Tests the events generated by the clear method when detail events are
172 * enabled.
173 */
174 public void testClearEventWithDetails()
175 {
176 config.setDetailEvents(true);
177 config.clear();
178 l.checkEventCount(2);
179 l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null, true);
180 l.skipToLast(AbstractConfiguration.EVENT_CLEAR);
181 l.checkEvent(AbstractConfiguration.EVENT_CLEAR, null, null, false);
182 l.done();
183 }
184
185 /***
186 * A test event listener class used for testing events generated by the
187 * configuration.
188 */
189 class TestConfigurationListener implements ConfigurationListener
190 {
191 /*** Stores the received events. */
192 private LinkedList events = new LinkedList();
193
194 public void configurationChanged(ConfigurationEvent event)
195 {
196 events.add(event);
197 }
198
199 /***
200 * Checks if at least <code>minEvents</code> events have been
201 * received.
202 *
203 * @param minEvents the minimum number of expected events
204 */
205 public void checkEventCount(int minEvents)
206 {
207 assertTrue("Too view events received", events.size() >= minEvents);
208 }
209
210 /***
211 * Checks an expected event.
212 *
213 * @param type the event type
214 * @param propName the expected property name
215 * @param propValue the expected property value
216 * @param before the expected before flag
217 */
218 public void checkEvent(int type, String propName, Object propValue,
219 boolean before)
220 {
221 assertFalse("Too few events received", events.isEmpty());
222 ConfigurationEvent e = (ConfigurationEvent) events.removeFirst();
223 assertEquals("Wrong event source", config, e.getSource());
224 assertEquals("Wrong event type", type, e.getType());
225 assertEquals("Wrong property name", propName, e.getPropertyName());
226 assertEquals("Wrong property value", propValue, e
227 .getPropertyValue());
228 assertEquals("Wrong before flag", before, e.isBeforeUpdate());
229 }
230
231 /***
232 * Skips to the last received event and checks that no events of the
233 * given type have been received. This method is used by checks for
234 * detail events to ignore the detail events.
235 *
236 * @param type the event type
237 */
238 public void skipToLast(int type)
239 {
240 while (events.size() > 1)
241 {
242 ConfigurationEvent e = (ConfigurationEvent) events
243 .removeFirst();
244 assertTrue("Found end event in details", type != e.getType());
245 }
246 }
247
248 /***
249 * Checks if all events has been processed.
250 */
251 public void done()
252 {
253 assertTrue("Too many events received", events.isEmpty());
254 }
255 }
256 }