001: /*******************************************************************************
002: * Copyright (c) 2006 Brad Reynolds.
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: * Brad Reynolds - initial API and implementation
010: * Brad Reynolds - bug 116920
011: ******************************************************************************/package org.eclipse.core.tests.databinding.observable;
012:
013: import junit.framework.Test;
014:
015: import org.eclipse.core.databinding.observable.AbstractObservable;
016: import org.eclipse.core.databinding.observable.IObservable;
017: import org.eclipse.core.databinding.observable.IStaleListener;
018: import org.eclipse.core.databinding.observable.Realm;
019: import org.eclipse.core.databinding.observable.StaleEvent;
020: import org.eclipse.jface.conformance.databinding.AbstractObservableContractDelegate;
021: import org.eclipse.jface.conformance.databinding.ObservableContractTest;
022: import org.eclipse.jface.conformance.databinding.ObservableStaleContractTest;
023: import org.eclipse.jface.conformance.databinding.SuiteBuilder;
024: import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
025: import org.eclipse.jface.tests.databinding.RealmTester;
026: import org.eclipse.jface.tests.databinding.EventTrackers.ChangeEventTracker;
027: import org.eclipse.jface.tests.databinding.RealmTester.CurrentRealm;
028:
029: /**
030: * Tests for AbstractObservable.
031: *
032: * @since 1.1
033: */
034: public class AbstractObservableTest extends
035: AbstractDefaultRealmTestCase {
036: private ObservableStub observable;
037:
038: protected void setUp() throws Exception {
039: super .setUp();
040: observable = new ObservableStub(Realm.getDefault());
041: }
042:
043: public void testStaleListener() throws Exception {
044: assertFalse(observable.hasListeners());
045:
046: StaleListener listener1 = new StaleListener();
047:
048: assertFalse(observable.firstListenerAdded);
049: observable.addStaleListener(listener1);
050: assertTrue(observable.firstListenerAdded);
051: observable.firstListenerAdded = false; // reset
052:
053: assertTrue(observable.hasListeners());
054: assertEquals(0, listener1.count);
055:
056: observable.fireStale();
057:
058: assertEquals(1, listener1.count);
059: assertSame(observable, listener1.source);
060:
061: // Add a second stale listener as 1 vs. 2 listener code is different.
062: StaleListener listener2 = new StaleListener();
063: assertEquals(0, listener2.count);
064: observable.addStaleListener(listener2);
065: observable.fireStale();
066:
067: assertEquals(2, listener1.count);
068: assertEquals(1, listener2.count);
069:
070: // Add a third stale listener as 2 vs. 3 or greater code is different.
071: StaleListener listener3 = new StaleListener();
072: observable.addStaleListener(listener3);
073: assertEquals(0, listener3.count);
074:
075: observable.fireStale();
076:
077: assertEquals(3, listener1.count);
078: assertEquals(2, listener2.count);
079: assertEquals(1, listener3.count);
080:
081: assertFalse(observable.lastListenerRemoved);
082: observable.removeStaleListener(listener1);
083: observable.removeStaleListener(listener2);
084: observable.removeStaleListener(listener3);
085: assertTrue(observable.lastListenerRemoved);
086:
087: assertFalse(observable.hasListeners());
088: }
089:
090: public void testChangeListener() throws Exception {
091: assertFalse(observable.hasListeners());
092:
093: ChangeEventTracker listener1 = new ChangeEventTracker();
094:
095: assertFalse(observable.firstListenerAdded);
096: observable.addChangeListener(listener1);
097: assertTrue(observable.firstListenerAdded);
098: observable.firstListenerAdded = false;
099:
100: assertTrue(observable.hasListeners());
101: assertEquals(0, listener1.count);
102:
103: observable.fireChange();
104:
105: assertEquals(1, listener1.count);
106: assertSame(observable, listener1.event.getSource());
107:
108: // Add a second listener as the 1 vs. 2 listener code is different.
109: ChangeEventTracker listener2 = new ChangeEventTracker();
110: observable.addChangeListener(listener2);
111: assertEquals(0, listener2.count);
112:
113: observable.fireChange();
114: assertEquals(2, listener1.count);
115: assertEquals(1, listener2.count);
116:
117: // Add a third listener as the 2 vs. 3 or greater code is different.
118: ChangeEventTracker listener3 = new ChangeEventTracker();
119: observable.addChangeListener(listener3);
120: assertEquals(0, listener3.count);
121:
122: observable.fireChange();
123:
124: assertEquals(3, listener1.count);
125: assertEquals(2, listener2.count);
126: assertEquals(1, listener3.count);
127:
128: assertFalse(observable.lastListenerRemoved);
129: observable.removeChangeListener(listener1);
130: observable.removeChangeListener(listener2);
131: observable.removeChangeListener(listener3);
132: assertTrue(observable.lastListenerRemoved);
133:
134: assertFalse(observable.hasListeners());
135: }
136:
137: public void testHasListenersWithChangeAndStaleListeners()
138: throws Exception {
139: ChangeEventTracker changeListener = new ChangeEventTracker();
140: StaleListener staleListener = new StaleListener();
141:
142: assertFalse(observable.hasListeners());
143: assertFalse(observable.firstListenerAdded);
144: assertFalse(observable.lastListenerRemoved);
145:
146: observable.addChangeListener(changeListener);
147: assertTrue(observable.hasListeners());
148: assertTrue(observable.firstListenerAdded);
149: assertFalse(observable.lastListenerRemoved);
150:
151: // reset
152: observable.firstListenerAdded = false;
153: observable.lastListenerRemoved = false;
154:
155: observable.addStaleListener(staleListener);
156: assertTrue(observable.hasListeners());
157: assertFalse(observable.firstListenerAdded);
158: assertFalse(observable.lastListenerRemoved);
159:
160: observable.removeChangeListener(changeListener);
161: assertTrue(observable.hasListeners());
162: assertFalse(observable.firstListenerAdded);
163: assertFalse(observable.lastListenerRemoved);
164:
165: observable.removeStaleListener(staleListener);
166: assertFalse(observable.hasListeners());
167: assertFalse(observable.firstListenerAdded);
168: assertTrue(observable.lastListenerRemoved);
169: }
170:
171: public void testFireStaleRealmChecks() throws Exception {
172: RealmTester.setDefault(new CurrentRealm(true));
173:
174: RealmTester.exerciseCurrent(new Runnable() {
175: public void run() {
176: observable = new ObservableStub();
177: observable.fireStale();
178: }
179: });
180: }
181:
182: public void testFireChangeRealmChecks() throws Exception {
183: RealmTester.setDefault(new CurrentRealm(true));
184:
185: RealmTester.exerciseCurrent(new Runnable() {
186: public void run() {
187: observable = new ObservableStub();
188: observable.fireChange();
189: }
190: });
191: }
192:
193: private class StaleListener implements IStaleListener {
194: int count;
195: IObservable source;
196:
197: public void handleStale(StaleEvent event) {
198: count++;
199: this .source = event.getObservable();
200: }
201: }
202:
203: public static Test suite() {
204: Delegate delegate = new Delegate();
205:
206: return new SuiteBuilder()
207: .addTests(AbstractObservableTest.class)
208: .addObservableContractTest(
209: ObservableContractTest.class, delegate)
210: .addObservableContractTest(
211: ObservableStaleContractTest.class, delegate)
212: .build();
213: }
214:
215: /* package */static class Delegate extends
216: AbstractObservableContractDelegate {
217:
218: public void change(IObservable observable) {
219: ((ObservableStub) observable).fireChange();
220: }
221:
222: public void setStale(IObservable observable, boolean stale) {
223: ((ObservableStub) observable).setStale(stale);
224: }
225:
226: public IObservable createObservable(Realm realm) {
227: return new ObservableStub(realm);
228: }
229: }
230:
231: private static class ObservableStub extends AbstractObservable {
232: private boolean stale;
233:
234: public ObservableStub() {
235: this (Realm.getDefault());
236: }
237:
238: /**
239: * @param realm
240: */
241: public ObservableStub(Realm realm) {
242: super (realm);
243: }
244:
245: private boolean firstListenerAdded;
246:
247: private boolean lastListenerRemoved;
248:
249: protected Object doGetValue() {
250: return null;
251: }
252:
253: public Object getValueType() {
254: return null;
255: }
256:
257: protected void fireStale() {
258: super .fireStale();
259: }
260:
261: protected void fireChange() {
262: super .fireChange();
263: }
264:
265: public boolean isStale() {
266: return stale;
267: }
268:
269: public void setStale(boolean stale) {
270: boolean old = this .stale;
271: this .stale = stale;
272:
273: if (stale && !old) {
274: fireStale();
275: }
276: }
277:
278: protected boolean hasListeners() {
279: return super .hasListeners();
280: }
281:
282: protected void firstListenerAdded() {
283: firstListenerAdded = true;
284: }
285:
286: protected void lastListenerRemoved() {
287: lastListenerRemoved = true;
288: }
289: }
290: }
|