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.ArrayList;
013: import java.util.Arrays;
014: import java.util.List;
015:
016: import org.eclipse.core.databinding.observable.list.IObservableList;
017: import org.eclipse.core.databinding.observable.list.ListDiffEntry;
018: import org.eclipse.jface.tests.databinding.EventTrackers.ChangeEventTracker;
019: import org.eclipse.jface.tests.databinding.EventTrackers.ListChangeEventTracker;
020:
021: /**
022: * Mutability tests for IObservableList.
023: *
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 MutableObservableListContractTest extends
035: MutableObservableCollectionContractTest {
036: private IObservableCollectionContractDelegate delegate;
037:
038: private IObservableList list;
039:
040: /**
041: * @param delegate
042: */
043: public MutableObservableListContractTest(
044: IObservableCollectionContractDelegate delegate) {
045: super (delegate);
046: this .delegate = delegate;
047: }
048:
049: public MutableObservableListContractTest(String testName,
050: IObservableCollectionContractDelegate delegate) {
051: super (testName, delegate);
052: this .delegate = delegate;
053: }
054:
055: protected void setUp() throws Exception {
056: super .setUp();
057: list = (IObservableList) getObservable();
058: }
059:
060: public void testAdd_ListChangeEvent() throws Exception {
061: assertListChangeEventFired(new Runnable() {
062: public void run() {
063: list.add(delegate.createElement(list));
064: }
065: }, "List.add(Object)", list);
066: }
067:
068: public void testAdd_ListDiffEntry() throws Exception {
069: list.add(delegate.createElement(list));
070: final Object element = delegate.createElement(list);
071:
072: assertAddDiffEntry(new Runnable() {
073: public void run() {
074: list.add(element);
075: }
076: }, "List.add(Object)", list, element, 1);
077: }
078:
079: public void testAddAtIndex_ChangeEvent() throws Exception {
080: assertChangeEventFired(new Runnable() {
081: public void run() {
082: list.add(0, delegate.createElement(list));
083: }
084: }, "List.add(int, Object)", list);
085: }
086:
087: public void testAddAtIndex_ListChangeEvent() throws Exception {
088: assertListChangeEventFired(new Runnable() {
089: public void run() {
090: list.add(0, delegate.createElement(list));
091: }
092: }, "List.add(int, Object)", list);
093: }
094:
095: public void testAddAtIndex_ChangeEventFiredAfterElementIsAdded()
096: throws Exception {
097: final Object element = delegate.createElement(list);
098:
099: assertContainsDuringChangeEvent(new Runnable() {
100: public void run() {
101: list.add(0, element);
102: }
103: }, "List.add(int, Collection)", list, element);
104: }
105:
106: public void testAddAtIndex_ListDiffEntry() throws Exception {
107: list.add(delegate.createElement(list));
108: final Object element = delegate.createElement(list);
109:
110: assertAddDiffEntry(new Runnable() {
111: public void run() {
112: list.add(1, element);
113: }
114: }, "List.add(int, Object)", list, element, 1);
115: }
116:
117: public void testAddAll_ListChangeEvent() throws Exception {
118: assertListChangeEventFired(new Runnable() {
119: public void run() {
120: list.addAll(Arrays.asList(new Object[] { delegate
121: .createElement(list) }));
122: }
123: }, "List.addAll(Collection", list);
124: }
125:
126: public void testAddAll_ListDiffEntry() throws Exception {
127: final Object element = delegate.createElement(list);
128:
129: assertAddDiffEntry(new Runnable() {
130: public void run() {
131: list.addAll(Arrays.asList(new Object[] { element }));
132: }
133: }, "List.addAll(Collection)", list, element, 0);
134: }
135:
136: public void testAddAllAtIndex_ChangeEvent() throws Exception {
137: assertChangeEventFired(new Runnable() {
138: public void run() {
139: list.addAll(0, Arrays.asList(new Object[] { delegate
140: .createElement(list) }));
141: }
142: }, "List.addAll(int, Collection)", list);
143: }
144:
145: public void testAddAllAtIndex_ListChangeEvent() throws Exception {
146: assertListChangeEventFired(new Runnable() {
147: public void run() {
148: list.addAll(0, Arrays.asList(new Object[] { delegate
149: .createElement(list) }));
150: }
151: }, "List.addAll(int, Collection)", list);
152: }
153:
154: public void testAddAllAtIndex_ChangeEventFiredAfterElementIsAdded()
155: throws Exception {
156: final Object element = delegate.createElement(list);
157:
158: assertContainsDuringChangeEvent(new Runnable() {
159: public void run() {
160: list.addAll(0, Arrays.asList(new Object[] { element }));
161: }
162: }, "List.addAll(int, Collection)", list, element);
163: }
164:
165: public void testAddAllAtIndex_ListDiffEntry() throws Exception {
166: list.add(delegate.createElement(list));
167: final Object element = delegate.createElement(list);
168:
169: assertAddDiffEntry(new Runnable() {
170: public void run() {
171: list.addAll(1, Arrays.asList(new Object[] { element }));
172: }
173: }, "List.addAll(int, Collection)", list, element, 1);
174: }
175:
176: public void testSet_ChangeEvent() throws Exception {
177: list.add(delegate.createElement(list));
178:
179: assertChangeEventFired(new Runnable() {
180: public void run() {
181: list.set(0, delegate.createElement(list));
182: }
183: }, "List.set(int, Object)", list);
184: }
185:
186: public void testSet_ListChangeEvent() throws Exception {
187: list.add(delegate.createElement(list));
188:
189: assertListChangeEventFired(new Runnable() {
190: public void run() {
191: list.set(0, delegate.createElement(list));
192: }
193: }, "List.set(int, Object)", list);
194: }
195:
196: public void testSet_ChangeEventFiredAfterElementIsSet()
197: throws Exception {
198: Object element1 = delegate.createElement(list);
199: list.add(element1);
200: final Object element2 = delegate.createElement(list);
201:
202: assertContainsDuringChangeEvent(new Runnable() {
203: public void run() {
204: list.set(0, element2);
205: }
206: }, "List.set(int, Object)", list, element2);
207: }
208:
209: public void testSet_ListDiffEntry() throws Exception {
210: list.add(delegate.createElement(list));
211: Object oldElement = delegate.createElement(list);
212: list.add(oldElement);
213:
214: ListChangeEventTracker listener = new ListChangeEventTracker();
215: list.addListChangeListener(listener);
216:
217: Object newElement = delegate.createElement(list);
218: list.set(1, newElement);
219:
220: ListDiffEntry[] entries = listener.event.diff.getDifferences();
221: assertEquals(
222: "List.set(int, Object) should result in 2 list diff entries.",
223: 2, entries.length);
224:
225: ListDiffEntry add = null;
226: ListDiffEntry remove = null;
227:
228: if (entries[0].isAddition() && !entries[1].isAddition()) {
229: add = entries[0];
230: remove = entries[1];
231: } else if (!entries[0].isAddition() && entries[1].isAddition()) {
232: add = entries[1];
233: remove = entries[0];
234: } else {
235: fail("List.set(int, Object) should result in an add and a remove entry.");
236: }
237:
238: assertEquals(
239: "List.set(int, Object) removed element should be the old element.",
240: oldElement, remove.getElement());
241: assertEquals(
242: "List.set(int, Object) removed index should be the index the new element was set at.",
243: 1, remove.getPosition());
244:
245: assertEquals(
246: "List.set(int, Object) added element should be the set element.",
247: newElement, add.getElement());
248: assertEquals(
249: "List.set(int, Object) add index should be the index the new element was set at.",
250: 1, add.getPosition());
251: }
252:
253: public void testRemove_ListChangeEvent() throws Exception {
254: final Object element = delegate.createElement(list);
255: list.add(element);
256:
257: assertListChangeEventFired(new Runnable() {
258: public void run() {
259: list.remove(element);
260: }
261: }, "List.remove(Object)", list);
262: }
263:
264: public void testRemove_ListDiffEntry() throws Exception {
265: list.add(delegate.createElement(list));
266: final Object element = delegate.createElement(list);
267: list.add(element);
268:
269: assertRemoveDiffEntry(new Runnable() {
270: public void run() {
271: list.remove(element);
272: }
273: }, "List.remove(Object)", list, element, 1);
274: }
275:
276: public void testRemoveAtIndex_ChangeEvent() throws Exception {
277: list.add(delegate.createElement(list));
278:
279: assertChangeEventFired(new Runnable() {
280: public void run() {
281: list.remove(0);
282: }
283: }, "List.remove(int)", list);
284: }
285:
286: public void testRemoveAtIndex_ListChangeEvent() throws Exception {
287: list.add(delegate.createElement(list));
288:
289: assertListChangeEventFired(new Runnable() {
290: public void run() {
291: list.remove(0);
292: }
293: }, "List.remove(int)", list);
294: }
295:
296: public void testRemoveAtIndex_ChangeEventFiredAfterElementIsRemoved()
297: throws Exception {
298: final Object element = delegate.createElement(list);
299: list.add(element);
300:
301: assertDoesNotContainDuringChangeEvent(new Runnable() {
302: public void run() {
303: list.remove(0);
304: }
305: }, "List.remove(int)", list, element);
306: }
307:
308: public void testRemoveAtIndex_ListDiffEntry() throws Exception {
309: list.add(delegate.createElement(list));
310: Object element = delegate.createElement(list);
311: list.add(element);
312:
313: assertRemoveDiffEntry(new Runnable() {
314: public void run() {
315: list.remove(1);
316: }
317: }, "List.remove(int)", list, element, 1);
318: }
319:
320: public void testRemoveAll_ListChangeEvent() throws Exception {
321: final Object element = delegate.createElement(list);
322:
323: assertListChangeEventFired(new Runnable() {
324: public void run() {
325: list.removeAll(Arrays.asList(new Object[] { element }));
326: }
327: }, "List.removeAll(Collection)", list);
328: }
329:
330: public void testRemoveAll_ListDiffEntry() throws Exception {
331: final Object element = delegate.createElement(list);
332: list.add(element);
333:
334: assertRemoveDiffEntry(new Runnable() {
335: public void run() {
336: list.removeAll(Arrays.asList(new Object[] { element }));
337: }
338: }, "List.removeAll(Collection)", list, element, 0);
339: }
340:
341: public void testRetainAll_ListChangeEvent() throws Exception {
342: final Object element1 = delegate.createElement(list);
343: list.add(element1);
344: list.add(delegate.createElement(list));
345:
346: assertListChangeEventFired(new Runnable() {
347: public void run() {
348: list
349: .retainAll(Arrays
350: .asList(new Object[] { element1 }));
351: }
352: }, "List.retainAll(Collection", list);
353: }
354:
355: public void testRetainAll_ListDiffEntry() throws Exception {
356: final Object element1 = delegate.createElement(list);
357: list.add(element1);
358: Object element2 = delegate.createElement(list);
359: list.add(delegate.createElement(list));
360:
361: assertRemoveDiffEntry(new Runnable() {
362: public void run() {
363: list
364: .retainAll(Arrays
365: .asList(new Object[] { element1 }));
366: }
367: }, "List.retainAll(Collection)", list, element2, 1);
368: }
369:
370: public void testClear_ListChangeEvent() throws Exception {
371: list.add(delegate.createElement(list));
372:
373: assertListChangeEventFired(new Runnable() {
374: public void run() {
375: list.clear();
376: }
377: }, "List.clear()", list);
378: }
379:
380: public void testClear_ListDiffEntry() throws Exception {
381: Object element = delegate.createElement(list);
382: list.add(element);
383:
384: assertRemoveDiffEntry(new Runnable() {
385: public void run() {
386: list.clear();
387: }
388: }, "List.clear()", list, element, 0);
389: }
390:
391: /**
392: * Asserts standard behaviors of firing list change events.
393: * <ul>
394: * <li>Event fires once.</li>
395: * <li>Source of the event is the provided <code>list</code>.
396: * <li>The list change event is fired after the change event.</li>
397: * </ul>
398: *
399: * @param runnable
400: * @param methodName
401: * @param list
402: */
403: private void assertListChangeEventFired(Runnable runnable,
404: String methodName, IObservableList list) {
405: List queue = new ArrayList();
406: ListChangeEventTracker listListener = new ListChangeEventTracker(
407: queue);
408: ChangeEventTracker changeListener = new ChangeEventTracker(
409: queue);
410:
411: list.addListChangeListener(listListener);
412: list.addChangeListener(changeListener);
413:
414: runnable.run();
415:
416: assertEquals(formatFail(methodName
417: + " should fire one ListChangeEvent."), 1,
418: listListener.count);
419: assertEquals(
420: formatFail(methodName
421: + "'s change event observable should be the created List."),
422: list, listListener.event.getObservable());
423:
424: assertEquals(
425: formatFail("Two notifications should have been received."),
426: 2, queue.size());
427: assertEquals("ChangeEvent of " + methodName
428: + " should have fired before the ListChangeEvent.",
429: changeListener, queue.get(0));
430: assertEquals("ListChangeEvent of " + methodName
431: + " should have fired after the ChangeEvent.",
432: listListener, queue.get(1));
433: }
434:
435: /**
436: * Asserts the list diff entry for a remove operation.
437: *
438: * @param runnable
439: * @param methodName
440: * @param list
441: * @param element
442: * @param index
443: */
444: private void assertRemoveDiffEntry(Runnable runnable,
445: String methodName, IObservableList list, Object element,
446: int index) {
447: ListChangeEventTracker listener = new ListChangeEventTracker();
448: list.addListChangeListener(listener);
449:
450: runnable.run();
451:
452: ListDiffEntry[] entries = listener.event.diff.getDifferences();
453: assertEquals(methodName + " should result in one diff entry.",
454: 1, entries.length);
455:
456: ListDiffEntry entry = entries[0];
457: assertFalse(methodName
458: + " should result in a diff entry that is an removal.",
459: entry.isAddition());
460: assertEquals(
461: methodName
462: + " remove diff entry should have removed the element.",
463: element, entry.getElement());
464: assertEquals(
465: methodName
466: + " remove diff entry should have removed the element from the provided index.",
467: index, entry.getPosition());
468: }
469:
470: /**
471: * Asserts the list diff entry for an add operation.
472: *
473: * @param runnable
474: * @param methodName
475: * @param list
476: * @param element
477: * @param index
478: */
479: private void assertAddDiffEntry(Runnable runnable,
480: String methodName, IObservableList list, Object element,
481: int index) {
482: ListChangeEventTracker listener = new ListChangeEventTracker();
483: list.addListChangeListener(listener);
484:
485: runnable.run();
486:
487: ListDiffEntry[] entries = listener.event.diff.getDifferences();
488: assertEquals(methodName + " should result in one diff entry.",
489: 1, entries.length);
490:
491: ListDiffEntry entry = entries[0];
492: assertTrue(
493: methodName
494: + " should result in a diff entry that is an addition.",
495: entry.isAddition());
496: assertEquals(methodName
497: + " add diff entry should have added the element.",
498: element, entry.getElement());
499: assertEquals(
500: methodName
501: + "add diff entry should have added the element at the provided index.",
502: index, entry.getPosition());
503: }
504: }
|