001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: ******************************************************************************/package org.eclipse.jface.conformance.databinding;
011:
012: import java.util.Arrays;
013: import java.util.Collections;
014:
015: import org.eclipse.core.databinding.observable.ChangeEvent;
016: import org.eclipse.core.databinding.observable.IChangeListener;
017: import org.eclipse.core.databinding.observable.IObservableCollection;
018: import org.eclipse.jface.tests.databinding.RealmTester;
019: import org.eclipse.jface.tests.databinding.EventTrackers.ChangeEventTracker;
020: import org.eclipse.jface.tests.databinding.RealmTester.CurrentRealm;
021:
022: /**
023: * Mutability tests for IObservableCollection.
024: * <p>
025: * This class is experimental and can change at any time. It is recommended to
026: * not subclass or assume the test names will not change. The only API that is
027: * guaranteed to not change are the constructors. The tests will remain public
028: * and not final in order to allow for consumers to turn off a test if needed by
029: * subclassing.
030: * </p>
031: *
032: * @since 3.2
033: */
034: public class MutableObservableCollectionContractTest extends
035: ObservableDelegateTest {
036: private IObservableCollectionContractDelegate delegate;
037:
038: private IObservableCollection collection;
039:
040: public MutableObservableCollectionContractTest(
041: IObservableCollectionContractDelegate delegate) {
042: super (delegate);
043: this .delegate = delegate;
044: }
045:
046: public MutableObservableCollectionContractTest(String name,
047: IObservableCollectionContractDelegate delegate) {
048: super (name, delegate);
049: this .delegate = delegate;
050: }
051:
052: protected void setUp() throws Exception {
053: super .setUp();
054:
055: collection = (IObservableCollection) super .getObservable();
056: }
057:
058: public void testAdd_ChangeEvent() throws Exception {
059: assertChangeEventFired(new Runnable() {
060: public void run() {
061: collection.add(delegate.createElement(collection));
062: }
063: }, "Collection.add(Object)", collection);
064: }
065:
066: public void testAdd_RealmCheck() throws Exception {
067: RealmTester.exerciseCurrent(new Runnable() {
068: public void run() {
069: collection.add(delegate.createElement(collection));
070: }
071: }, (CurrentRealm) collection.getRealm());
072: }
073:
074: public void testAdd_ChangeEventFiredAfterElementIsAdded()
075: throws Exception {
076: final Object element = delegate.createElement(collection);
077:
078: assertContainsDuringChangeEvent(new Runnable() {
079: public void run() {
080: collection.add(element);
081: }
082: }, "Collection.add(Object)", collection, element);
083: }
084:
085: public void testAddAll_ChangeEvent() throws Exception {
086: assertChangeEventFired(new Runnable() {
087: public void run() {
088: collection.addAll(Arrays.asList(new Object[] { delegate
089: .createElement(collection) }));
090: }
091: }, "Collection.addAll(Collection)", collection);
092: }
093:
094: public void testAddAll_RealmCheck() throws Exception {
095: RealmTester.exerciseCurrent(new Runnable() {
096: public void run() {
097: collection.addAll(Arrays.asList(new Object[] { delegate
098: .createElement(collection) }));
099: }
100: }, (CurrentRealm) collection.getRealm());
101: }
102:
103: public void testAddAll_ChangeEventFiredAfterElementsAreAdded()
104: throws Exception {
105: final Object element = delegate.createElement(collection);
106:
107: assertContainsDuringChangeEvent(new Runnable() {
108: public void run() {
109: collection.addAll(Arrays
110: .asList(new Object[] { element }));
111: }
112: }, "Collection.addAll(Collection)", collection, element);
113: }
114:
115: public void testRemove_ChangeEvent() throws Exception {
116: final Object element = delegate.createElement(collection);
117: collection.add(element);
118:
119: assertChangeEventFired(new Runnable() {
120: public void run() {
121: collection.remove(element);
122: }
123: }, "Collection.remove(Object)", collection);
124: }
125:
126: public void testRemove_RealmCheck() throws Exception {
127: RealmTester.exerciseCurrent(new Runnable() {
128: public void run() {
129: collection.remove(delegate.createElement(collection));
130: }
131: }, (CurrentRealm) collection.getRealm());
132: }
133:
134: public void testRemove_ChangeEventFiredAfterElementIsRemoved()
135: throws Exception {
136: final Object element = delegate.createElement(collection);
137: collection.add(element);
138:
139: assertDoesNotContainDuringChangeEvent(new Runnable() {
140: public void run() {
141: collection.remove(element);
142: }
143: }, "Collection.remove(Object)", collection, element);
144: }
145:
146: public void testRemoveAll_ChangeEvent() throws Exception {
147: final Object element = delegate.createElement(collection);
148: collection.add(element);
149:
150: assertChangeEventFired(new Runnable() {
151: public void run() {
152: collection.removeAll(Arrays
153: .asList(new Object[] { element }));
154: }
155: }, "Collection.removeAll(Collection)", collection);
156: }
157:
158: public void testRemoveAll_RealmCheck() throws Exception {
159: RealmTester.exerciseCurrent(new Runnable() {
160: public void run() {
161: collection.removeAll(Arrays
162: .asList(new Object[] { delegate
163: .createElement(collection) }));
164: }
165: }, (CurrentRealm) collection.getRealm());
166: }
167:
168: public void testRemoveAll_ChangeEventFiredAfterElementsAreRemoved()
169: throws Exception {
170: final Object element = delegate.createElement(collection);
171: collection.add(element);
172:
173: assertDoesNotContainDuringChangeEvent(new Runnable() {
174: public void run() {
175: collection.removeAll(Arrays
176: .asList(new Object[] { element }));
177: }
178: }, "Collection.removeAll(Collection)", collection, element);
179: }
180:
181: public void testRetainAll_ChangeEvent() throws Exception {
182: final Object element1 = delegate.createElement(collection);
183: collection.add(element1);
184: Object element2 = delegate.createElement(collection);
185: collection.add(element2);
186:
187: assertChangeEventFired(new Runnable() {
188: public void run() {
189: collection.retainAll(Arrays
190: .asList(new Object[] { element1 }));
191: }
192:
193: }, "Collection.retainAll(Collection)", collection);
194: }
195:
196: public void testRetainAll_RealmCheck() throws Exception {
197: RealmTester.exerciseCurrent(new Runnable() {
198: public void run() {
199: collection.retainAll(Collections.EMPTY_LIST);
200: }
201: }, (CurrentRealm) collection.getRealm());
202: }
203:
204: public void testRetainAll_ChangeEventFiredAfterElementsAreRetained()
205: throws Exception {
206: Object element1 = delegate.createElement(collection);
207: collection.add(element1);
208: Object element2 = delegate.createElement(collection);
209: collection.add(element2);
210:
211: // precondition
212: assertTrue(collection.contains(element1));
213: assertTrue(collection.contains(element2));
214:
215: ContainsListener listener1 = new ContainsListener(collection,
216: element1).init();
217: ContainsListener listener2 = new ContainsListener(collection,
218: element2).init();
219:
220: // set contains the the opposite of the expected outcome to ensure they
221: // get set
222: listener1.contains = false;
223: listener2.contains = true;
224:
225: collection.retainAll(Arrays.asList(new Object[] { element1 }));
226: assertTrue(
227: formatFail("When Collection.retainAll(...) fires the change event the element should have been retained in the Collection."),
228: listener1.contains);
229: assertFalse(
230: formatFail("When Collection.retainAll(...) fires the change event the element should have been removed from the Collection."),
231: listener2.contains);
232: }
233:
234: public void testClear_ChangeEvent() throws Exception {
235: collection.add(delegate.createElement(collection));
236:
237: assertChangeEventFired(new Runnable() {
238: public void run() {
239: collection.clear();
240: }
241: }, "List.clear()", collection);
242: }
243:
244: public void testClear_RealmCheck() throws Exception {
245: RealmTester.exerciseCurrent(new Runnable() {
246: public void run() {
247: collection.clear();
248: }
249: }, (CurrentRealm) collection.getRealm());
250: }
251:
252: public void testClear_ChangeEventFiredAfterElementIsRemoved()
253: throws Exception {
254: Object element = delegate.createElement(collection);
255: collection.add(element);
256:
257: assertDoesNotContainDuringChangeEvent(new Runnable() {
258: public void run() {
259: collection.clear();
260: }
261: }, "List.clear()", collection, element);
262: }
263:
264: /**
265: * Asserts that a ChangeEvent is fired once when the provided
266: * <code>runnable</code> is invoked and the source is the provided
267: * <code>collection</code>.
268: *
269: * @param runnable
270: * @param methodName
271: * @param collection
272: */
273: /* package */void assertChangeEventFired(Runnable runnable,
274: String methodName, IObservableCollection collection) {
275: ChangeEventTracker listener = new ChangeEventTracker();
276: collection.addChangeListener(listener);
277: runnable.run();
278:
279: assertEquals(formatFail(methodName
280: + " should fire one ChangeEvent."), 1, listener.count);
281: assertEquals(
282: formatFail(methodName
283: + "'s change event observable should be the created Collection."),
284: collection, listener.event.getObservable());
285: }
286:
287: /**
288: * Asserts that when the change event is fired for the action contained in
289: * the <code>runnable</code> the change will have been applied to the
290: * <code>collection</code>.
291: *
292: * @param runnable
293: * @param methodName
294: * @param collection
295: * @param elementContained
296: */
297: /* package */void assertDoesNotContainDuringChangeEvent(
298: Runnable runnable, String methodName,
299: IObservableCollection collection, Object elementNotContained) {
300:
301: // precondition
302: assertTrue(collection.contains(elementNotContained));
303:
304: ContainsListener listener = new ContainsListener(collection,
305: elementNotContained).init();
306: listener.contains = true;
307: collection.remove(elementNotContained);
308: assertFalse(
309: formatFail(new StringBuffer("When ")
310: .append(methodName)
311: .append(
312: " fires a change event the element should have been removed from the Collection.")
313: .toString()), listener.contains);
314: }
315:
316: /**
317: * Asserts that when the change event is fired for the action contained in
318: * the <code>runnable</code> the change will have been applied to the
319: * <code>collection</code>.
320: *
321: * @param runnable
322: * @param methodName
323: * @param collection
324: * @param elementContained
325: */
326: /* package */void assertContainsDuringChangeEvent(
327: Runnable runnable, String methodName,
328: IObservableCollection collection, Object elementContained) {
329: ContainsListener listener = new ContainsListener(collection,
330: elementContained).init();
331:
332: // precondition
333: assertFalse(collection.contains(elementContained));
334: runnable.run();
335:
336: assertTrue(
337: formatFail(new StringBuffer("When ")
338: .append(methodName)
339: .append(
340: " fires a change event the element should have been added to the Collection.")
341: .toString()), listener.contains);
342: }
343:
344: /* package */static class ContainsListener implements
345: IChangeListener {
346: boolean contains;
347:
348: final private Object element;
349:
350: final private IObservableCollection collection;
351:
352: ContainsListener(IObservableCollection collection,
353: Object element) {
354: this .element = element;
355: this .collection = collection;
356: }
357:
358: ContainsListener init() {
359: collection.addChangeListener(this );
360: return this ;
361: }
362:
363: public void handleChange(ChangeEvent event) {
364: contains = collection.contains(element);
365: }
366: }
367: }
|