Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 182059 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/tests/databinding/observable/value/WritableValueTest.java (-38 / +44 lines)
Lines 12-22 Link Here
12
12
13
package org.eclipse.core.tests.databinding.observable.value;
13
package org.eclipse.core.tests.databinding.observable.value;
14
14
15
import junit.framework.Test;
16
import junit.framework.TestSuite;
17
18
import org.eclipse.core.databinding.observable.IObservable;
15
import org.eclipse.core.databinding.observable.Realm;
19
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
16
import org.eclipse.core.databinding.observable.value.WritableValue;
21
import org.eclipse.core.databinding.observable.value.WritableValue;
22
import org.eclipse.jface.conformance.databinding.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.conformance.databinding.ObservableValueContractTests;
24
import org.eclipse.jface.conformance.databinding.SuiteBuilder;
17
import org.eclipse.jface.databinding.swt.SWTObservables;
25
import org.eclipse.jface.databinding.swt.SWTObservables;
18
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
26
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
19
import org.eclipse.jface.tests.databinding.EventTrackers.ValueChangeEventTracker;
20
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.swt.widgets.Display;
21
28
22
/**
29
/**
Lines 24-65 Link Here
24
 */
31
 */
25
public class WritableValueTest extends AbstractDefaultRealmTestCase {
32
public class WritableValueTest extends AbstractDefaultRealmTestCase {
26
	/**
33
	/**
27
	 * Asserts that ValueChange events are only fired when the value changes.
28
	 * 
29
	 * @throws Exception
30
	 */
31
	public void testValueChangeOnlyFiresOnChange() throws Exception {
32
		WritableValue writableValue = new WritableValue();
33
		ValueChangeEventTracker counter = new ValueChangeEventTracker();
34
		writableValue.addValueChangeListener(counter);
35
36
		assertEquals(0, counter.count);
37
		// set same
38
		writableValue.setValue(null);
39
		assertEquals(0, counter.count);
40
41
		// set different
42
		writableValue.setValue("value");
43
		assertEquals(1, counter.count);
44
45
		// set same
46
		writableValue.setValue("value");
47
		assertEquals(1, counter.count);
48
49
		// set different
50
		writableValue.setValue(null);
51
		assertEquals(2, counter.count);
52
	}
53
54
	public void testDoSetValue() throws Exception {
55
		WritableValue writableValue = new WritableValue(SWTObservables
56
				.getRealm(Display.getDefault()));
57
		Object value = new Object();
58
		writableValue.setValue(value);
59
		assertEquals(value, writableValue.getValue());
60
	}
61
62
	/**
63
	 * All constructors delegate to the 3 arg constructor.
34
	 * All constructors delegate to the 3 arg constructor.
64
	 * 
35
	 * 
65
	 * @throws Exception
36
	 * @throws Exception
Lines 70-76 Link Here
70
		assertNull(value.getValue());
41
		assertNull(value.getValue());
71
		assertNull(value.getValueType());
42
		assertNull(value.getValueType());
72
	}
43
	}
73
	
44
74
	public void testWithValueType() throws Exception {
45
	public void testWithValueType() throws Exception {
75
		Object elementType = String.class;
46
		Object elementType = String.class;
76
		WritableValue value = WritableValue.withValueType(elementType);
47
		WritableValue value = WritableValue.withValueType(elementType);
Lines 78-81 Link Here
78
		assertEquals(Realm.getDefault(), value.getRealm());
49
		assertEquals(Realm.getDefault(), value.getRealm());
79
		assertEquals(elementType, value.getValueType());
50
		assertEquals(elementType, value.getValueType());
80
	}
51
	}
52
53
	public static Test suite() {
54
		TestSuite suite = new TestSuite();
55
		Object[] params = new Object[] { new Delegate() };
56
57
		SuiteBuilder
58
				.forSuite(suite)
59
				.addTests(WritableValueTest.class)
60
				.addParameterizedTests(ObservableValueContractTests.class, params);
61
62
		return suite;
63
	}
64
	
65
	/* package */ static class Delegate extends AbstractObservableValueContractDelegate {
66
		private WritableValue current;
67
		
68
		public IObservableValue createObservableValue() {
69
			Realm.runWithDefault(SWTObservables.getRealm(Display.getDefault()), new Runnable() {
70
				public void run() {
71
					current = new WritableValue("", String.class);
72
				}
73
			});
74
			
75
			return current;
76
		}
77
		
78
		public void change(IObservable observable) {
79
			WritableValue writableValue = (WritableValue) observable;
80
			writableValue.setValue(writableValue.getValue() + "a");
81
		}
82
		
83
		public Object getValueType(IObservableValue observable) {
84
			return String.class;
85
		}
86
	}
81
}
87
}
(-)src/org/eclipse/core/tests/databinding/observable/AbstractObservableTest.java (-1 / +62 lines)
Lines 12-17 Link Here
12
12
13
package org.eclipse.core.tests.databinding.observable;
13
package org.eclipse.core.tests.databinding.observable;
14
14
15
import junit.framework.Test;
16
import junit.framework.TestSuite;
17
15
import org.eclipse.core.databinding.observable.AbstractObservable;
18
import org.eclipse.core.databinding.observable.AbstractObservable;
16
import org.eclipse.core.databinding.observable.ChangeEvent;
19
import org.eclipse.core.databinding.observable.ChangeEvent;
17
import org.eclipse.core.databinding.observable.IChangeListener;
20
import org.eclipse.core.databinding.observable.IChangeListener;
Lines 19-27 Link Here
19
import org.eclipse.core.databinding.observable.IStaleListener;
22
import org.eclipse.core.databinding.observable.IStaleListener;
20
import org.eclipse.core.databinding.observable.Realm;
23
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.StaleEvent;
24
import org.eclipse.core.databinding.observable.StaleEvent;
25
import org.eclipse.jface.conformance.databinding.AbstractObservableContractDelegate;
26
import org.eclipse.jface.conformance.databinding.ObservableContractTests;
27
import org.eclipse.jface.conformance.databinding.ObservableStaleContractTests;
28
import org.eclipse.jface.conformance.databinding.SuiteBuilder;
29
import org.eclipse.jface.databinding.swt.SWTObservables;
22
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
30
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
23
import org.eclipse.jface.tests.databinding.RealmTester;
31
import org.eclipse.jface.tests.databinding.RealmTester;
24
import org.eclipse.jface.tests.databinding.RealmTester.CurrentRealm;
32
import org.eclipse.jface.tests.databinding.RealmTester.CurrentRealm;
33
import org.eclipse.swt.widgets.Display;
25
34
26
/**
35
/**
27
 * Tests for AbstractObservable.
36
 * Tests for AbstractObservable.
Lines 187-192 Link Here
187
196
188
	private class ChangeListener implements IChangeListener {
197
	private class ChangeListener implements IChangeListener {
189
		int count;
198
		int count;
199
190
		IObservable source;
200
		IObservable source;
191
201
192
		public void handleChange(ChangeEvent event) {
202
		public void handleChange(ChangeEvent event) {
Lines 197-202 Link Here
197
207
198
	private class StaleListener implements IStaleListener {
208
	private class StaleListener implements IStaleListener {
199
		int count;
209
		int count;
210
200
		IObservable source;
211
		IObservable source;
201
212
202
		public void handleStale(StaleEvent event) {
213
		public void handleStale(StaleEvent event) {
Lines 205-211 Link Here
205
		}
216
		}
206
	}
217
	}
207
218
219
	public static Test suite() {
220
		TestSuite suite = new TestSuite();
221
		Object[] params = new Object[] { new Delegate() };
222
223
		SuiteBuilder
224
				.forSuite(suite)
225
				.addTests(AbstractObservableTest.class)
226
				.addParameterizedTests(ObservableContractTests.class, params)
227
				.addParameterizedTests(ObservableStaleContractTests.class,
228
						params);
229
230
		return suite;
231
	}
232
233
	/* package */static class Delegate extends
234
			AbstractObservableContractDelegate {
235
		private IObservable currentObservable;
236
237
		public void change(IObservable observable) {
238
			((ObservableStub) observable).fireChange();
239
		}
240
241
		public void setStale(IObservable observable, boolean stale) {
242
			((ObservableStub) observable).setStale(stale);
243
		}
244
245
		public IObservable createObservable() {
246
			Realm.runWithDefault(SWTObservables.getRealm(Display.getDefault()),
247
					new Runnable() {
248
						public void run() {
249
							currentObservable = new ObservableStub();
250
						}
251
					});
252
253
			return currentObservable;
254
		}
255
	}
256
208
	private static class ObservableStub extends AbstractObservable {
257
	private static class ObservableStub extends AbstractObservable {
258
		private boolean stale;
259
209
		public ObservableStub() {
260
		public ObservableStub() {
210
			this(Realm.getDefault());
261
			this(Realm.getDefault());
211
		}
262
		}
Lines 218-223 Link Here
218
		}
269
		}
219
270
220
		private boolean firstListenerAdded;
271
		private boolean firstListenerAdded;
272
221
		private boolean lastListenerRemoved;
273
		private boolean lastListenerRemoved;
222
274
223
		protected Object doGetValue() {
275
		protected Object doGetValue() {
Lines 237-243 Link Here
237
		}
289
		}
238
290
239
		public boolean isStale() {
291
		public boolean isStale() {
240
			return false;
292
			return stale;
293
		}
294
295
		public void setStale(boolean stale) {
296
			boolean old = this.stale;
297
			this.stale = stale;
298
299
			if (stale && !old) {
300
				fireStale();
301
			}
241
		}
302
		}
242
303
243
		protected boolean hasListeners() {
304
		protected boolean hasListeners() {
(-)src/org/eclipse/jface/tests/internal/databinding/internal/swt/ButtonObservableValueTest.java (-14 / +48 lines)
Lines 11-18 Link Here
11
11
12
package org.eclipse.jface.tests.internal.databinding.internal.swt;
12
package org.eclipse.jface.tests.internal.databinding.internal.swt;
13
13
14
import junit.framework.Test;
14
import junit.framework.TestCase;
15
import junit.framework.TestCase;
16
import junit.framework.TestSuite;
15
17
18
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.value.IObservableValue;
20
import org.eclipse.jface.conformance.databinding.AbstractObservableValueContractDelegate;
21
import org.eclipse.jface.conformance.databinding.ObservableValueContractTests;
22
import org.eclipse.jface.conformance.databinding.SuiteBuilder;
16
import org.eclipse.jface.internal.databinding.internal.swt.ButtonObservableValue;
23
import org.eclipse.jface.internal.databinding.internal.swt.ButtonObservableValue;
17
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Button;
25
import org.eclipse.swt.widgets.Button;
Lines 20-39 Link Here
20
27
21
/**
28
/**
22
 * @since 3.2
29
 * @since 3.2
23
 *
24
 */
30
 */
25
public class ButtonObservableValueTest extends TestCase {
31
public class ButtonObservableValueTest extends TestCase {    
26
    public void testSetValue() throws Exception {
32
    public static Test suite() {
27
        Shell shell = new Shell();
33
		TestSuite suite = new TestSuite();
28
        Button button = new Button(shell, SWT.CHECK);
34
		Object[] params = new Object[] { new Delegate() };
29
        ButtonObservableValue observableValue = new ButtonObservableValue(button);
35
30
        assertEquals(Boolean.FALSE, observableValue.getValue());
36
		SuiteBuilder
31
        assertFalse(button.getSelection());
37
				.forSuite(suite)
32
        
38
				.addParameterizedTests(ObservableValueContractTests.class, params);
33
        Boolean value = Boolean.TRUE;
39
34
        observableValue.setValue(value);
40
		return suite;
35
        assertTrue("button value", button.getSelection());
41
	}
36
        assertEquals("observable value", value, observableValue.getValue());
42
    
37
        shell.dispose();
43
    /* package */ static class Delegate extends AbstractObservableValueContractDelegate {
44
    	Shell shell;
45
    	Button button;
46
    	
47
    	public void setUp() {
48
    		super.setUp();
49
    		
50
    		shell = new Shell();
51
    		button = new Button(shell, SWT.CHECK);
52
    	}
53
    	
54
    	public void tearDown() {
55
    		super.tearDown();
56
    		
57
    		shell.dispose();
58
    	}
59
    	
60
    	public IObservableValue createObservableValue() {
61
    		return new ButtonObservableValue(button);
62
    	}
63
    	
64
    	public Object getValueType(IObservableValue observable) {
65
    		return Boolean.TYPE;
66
    	}
67
    	
68
    	public void change(IObservable observable) {
69
    		button.setSelection(!button.getSelection());
70
    		button.notifyListeners(SWT.Selection, null);
71
    	}
38
    }
72
    }
39
}
73
}
(-)src/org/eclipse/jface/tests/databinding/BindingTestSuite.java (-3 / +5 lines)
Lines 147-153 Link Here
147
		addTestSuite(StringToNumberConverterTest.class);
147
		addTestSuite(StringToNumberConverterTest.class);
148
148
149
		// org.eclipse.core.tests.databinding.observable
149
		// org.eclipse.core.tests.databinding.observable
150
		addTestSuite(AbstractObservableTest.class);
150
		addTest(AbstractObservableTest.suite());
151
		addTestSuite(Diffs_ListDiffTests.class);
151
		addTestSuite(Diffs_ListDiffTests.class);
152
		addTestSuite(DiffsTest.class);
152
		addTestSuite(DiffsTest.class);
153
		addTestSuite(ObservablesTest.class);
153
		addTestSuite(ObservablesTest.class);
Lines 174-180 Link Here
174
		addTestSuite(AbstractObservableValueTest.class);
174
		addTestSuite(AbstractObservableValueTest.class);
175
		addTestSuite(AbstractVetoableValueTest.class);
175
		addTestSuite(AbstractVetoableValueTest.class);
176
		addTestSuite(ComputedValueTest.class);
176
		addTestSuite(ComputedValueTest.class);
177
		addTestSuite(WritableValueTest.class);
177
		addTest(WritableValueTest.suite());
178
//		addTestSuite(WritableValueTest.class);
178
		
179
		
179
		//org.eclipse.core.tests.databinding.validation
180
		//org.eclipse.core.tests.databinding.validation
180
		addTestSuite(ValidationStatusTest.class);
181
		addTestSuite(ValidationStatusTest.class);
Lines 261-267 Link Here
261
		addTestSuite(EditMaskParserTest.class);
262
		addTestSuite(EditMaskParserTest.class);
262
263
263
		//org.eclipse.jface.tests.internal.databinding.internal.swt
264
		//org.eclipse.jface.tests.internal.databinding.internal.swt
264
		addTestSuite(ButtonObservableValueTest.class);
265
		addTest(ButtonObservableValueTest.suite());
266
//		addTestSuite(ButtonObservableValueTest.class);
265
		addTestSuite(CComboObservableValueTest.class);
267
		addTestSuite(CComboObservableValueTest.class);
266
		addTestSuite(CLabelObservableValueTest.class);
268
		addTestSuite(CLabelObservableValueTest.class);
267
		addTestSuite(ComboObservableValueTest.class);
269
		addTestSuite(ComboObservableValueTest.class);
(-)src/org/eclipse/jface/conformance/databinding/SuiteBuilder.java (+138 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import java.lang.reflect.Constructor;
15
import java.lang.reflect.Method;
16
17
import junit.framework.Test;
18
import junit.framework.TestSuite;
19
20
/**
21
 * Builds a test suite.
22
 * 
23
 * @since 1.1
24
 */
25
// TODO remove the forSuite(...) method and add a toSuite() method that returns
26
// a new TestSuite.
27
public class SuiteBuilder {
28
	private TestSuite suite;
29
30
	private SuiteBuilder(TestSuite suite) {
31
		// prohibit public construction
32
		this.suite = suite;
33
	}
34
35
	/**
36
	 * Adds all test methods from the provided <code>testCase</code> to the
37
	 * suite.
38
	 * 
39
	 * @param testCase
40
	 * @return builder
41
	 */
42
	public SuiteBuilder addTests(Class testCase) {
43
		suite.addTestSuite(testCase);
44
		return this;
45
	}
46
47
	/**
48
	 * Adds all test methods from the provided <code>testCase</code> with the
49
	 * provided <code>parameters</code>. A constructor must exist in the
50
	 * testCase that accepts a String as the first parameter followed by
51
	 * parameters matching the provided parameters. If an appropriate
52
	 * constructor is not found an exception will be thrown.
53
	 * 
54
	 * @param testCase
55
	 * @param parameters
56
	 * @return builder
57
	 */
58
	public SuiteBuilder addParameterizedTests(Class testCase,
59
			Object[] parameters) {
60
		Method[] methods = testCase.getMethods();
61
62
		Constructor constructor = findConstructor(testCase, parameters);
63
		if (constructor == null) {
64
			throw new IllegalArgumentException(
65
					"The parameters provided don't match a constructor found in ["
66
							+ testCase.getName() + "]");
67
		}
68
69
		for (int i = 0; i < methods.length; i++) {
70
			String name = methods[i].getName();
71
			if (name.startsWith("test")) {
72
				try {
73
					suite.addTest((Test) constructor.newInstance(toParamArray(
74
							name, parameters)));
75
				} catch (Exception e) {
76
					throw new RuntimeException(e);
77
				}
78
			}
79
		}
80
81
		return this;
82
	}
83
84
	private Object[] toParamArray(String testName, Object[] parameters) {
85
		Object[] result = new Object[parameters.length + 1];
86
		result[0] = testName;
87
		System.arraycopy(parameters, 0, result, 1, parameters.length);
88
		return result;
89
	}
90
91
	/**
92
	 * Returns the constructor that has a String as the first parameters and
93
	 * then matches the type of the parameters.
94
	 * 
95
	 * @param parameters
96
	 * @return
97
	 */
98
	private static Constructor findConstructor(Class clazz, Object[] parameters) {
99
		Constructor[] constructors = clazz.getConstructors();
100
		int expectedParametersLength = parameters.length + 1;
101
102
		for (int i = 0; i < constructors.length; i++) {
103
			Constructor constructor = constructors[i];
104
			Class[] types = constructor.getParameterTypes();
105
106
			if (types.length != expectedParametersLength
107
					|| !String.class.equals(types[i])) {
108
				continue;
109
			}
110
111
			boolean skip = false;
112
			for (int j = 1; j < types.length; j++) {
113
				Class type = types[j];
114
				if (!type.isInstance(parameters[j - 1])) {
115
					skip = true;
116
					break;
117
				}
118
			}
119
120
			if (!skip) {
121
				return constructor;
122
			}
123
		}
124
125
		return null;
126
	}
127
128
	public static SuiteBuilder forSuite(TestSuite suite) {
129
		return new SuiteBuilder(suite);
130
	}
131
132
	/* package */static class UniqueTest {
133
		/* package */UniqueTest(Class clazz, String testName,
134
				Object[] parameters) {
135
136
		}
137
	}
138
}
(-)src/org/eclipse/jface/conformance/databinding/ObservableStaleContractTests.java (+163 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.core.databinding.observable.IObservable;
17
import org.eclipse.core.databinding.observable.IStaleListener;
18
import org.eclipse.core.databinding.observable.Realm;
19
import org.eclipse.core.databinding.observable.StaleEvent;
20
import org.eclipse.jface.conformance.databinding.ObservableContractTests.DummyRealm;
21
22
/**
23
 * @since 3.3
24
 */
25
public class ObservableStaleContractTests extends TestCase {
26
	private IObservableContractDelegate delegate;
27
	private Realm previousRealm;
28
	
29
	public ObservableStaleContractTests(String testName, IObservableContractDelegate delegate) {
30
		super(testName);
31
		this.delegate = delegate;
32
	}
33
	
34
	protected void setUp() throws Exception {
35
		super.setUp();
36
37
		previousRealm = Realm.getDefault();
38
		delegate.setUp();
39
	}
40
41
	protected void tearDown() throws Exception {
42
		super.tearDown();
43
44
		delegate.tearDown();
45
		DummyRealm.setDefaultRealm(previousRealm);
46
	}
47
	
48
	public void testIsStaleReturnsTrueWhenStale() throws Exception {
49
		IObservable observable = delegate.createObservable();
50
		delegate.setStale(observable, true);
51
		assertTrue("When stale isStale() should return true.", observable.isStale());
52
	}
53
	
54
	public void testIsStaleReturnsFalseWhenNotStale() throws Exception {
55
		IObservable observable = delegate.createObservable();
56
		delegate.setStale(observable, false);
57
		assertFalse("When not stale isStale() should return false.", observable.isStale());
58
	}
59
60
	public void testBecomingStaleFiresStaleEvent() throws Exception {
61
		IObservable observable = delegate.createObservable();
62
		StaleListener listener = new StaleListener();
63
64
		// precondition
65
		ensureStale(observable, false);
66
67
		observable.addStaleListener(listener);
68
		delegate.setStale(observable, true);
69
70
		assertEquals("When becoming stale listeners should be notified.", 1, listener.count);
71
	}
72
73
	public void testStaleEventObservable() throws Exception {
74
		IObservable observable = delegate.createObservable();
75
		StaleListener listener = new StaleListener();
76
77
		// precondition
78
		ensureStale(observable, false);
79
80
		observable.addStaleListener(listener);
81
		delegate.setStale(observable, true);
82
83
		StaleEvent event = listener.event;
84
		assertNotNull("stale event was null", event);
85
		assertEquals("When notifying listeners of becoming stale the observable should be the source of the event.", observable,
86
				event.getObservable());
87
	}
88
89
	public void testRemoveStaleListenerRemovesListener() throws Exception {
90
		StaleListener listener = new StaleListener();
91
		IObservable observable = delegate.createObservable();
92
93
		observable.addStaleListener(listener);
94
		ensureStale(observable, false);
95
		delegate.setStale(observable, true);
96
97
		// precondition check
98
		assertEquals("set stale did not notify listeners", 1, listener.count);
99
100
		observable.removeStaleListener(listener);
101
		ensureStale(observable, false);
102
		delegate.setStale(observable, true);
103
104
		assertEquals("Once removed stale listeners should not be notified of becoming stale.", 1,
105
				listener.count);
106
	}
107
108
	public void testStaleListenersAreNotNotifiedWhenObservableIsNoLongerStale()
109
			throws Exception {
110
		IObservable observable = delegate.createObservable();
111
		ensureStale(observable, true);
112
113
		StaleListener listener = new StaleListener();
114
		observable.addStaleListener(listener);
115
		delegate.setStale(observable, false);
116
117
		assertEquals("Stale listeners should not be notified when the stale state changes from true to false.", 0,
118
				listener.count);
119
	}
120
121
	public void testObservableRealmIsCurrentOnStale() throws Exception {
122
		IObservable observable = delegate.createObservable();
123
		ensureStale(observable, false);
124
125
		StaleListener listener = new StaleListener();
126
		observable.addStaleListener(listener);
127
		delegate.setStale(observable, true);
128
129
		assertTrue("When notifying listeners of becoming stale the observable's realm should be the current realm.",
130
				listener.isCurrentRealm);
131
	}
132
	
133
	/**
134
	 * Ensures that stale is set to the provided state. Will throw an
135
	 * AssertionFailedError if setting of the state is unsuccessful.
136
	 * 
137
	 * @param observable
138
	 * @param stale
139
	 */
140
	private void ensureStale(IObservable observable, boolean stale) {
141
		if (observable.isStale() != stale) {
142
			delegate.setStale(observable, stale);
143
		}
144
145
		assertEquals(stale, observable.isStale());
146
	}
147
	
148
	/* package */static class StaleListener implements IStaleListener {
149
		int count;
150
151
		StaleEvent event;
152
153
		boolean isCurrentRealm;
154
155
		public void handleStale(StaleEvent staleEvent) {
156
			count++;
157
			this.event = staleEvent;
158
			this.isCurrentRealm = staleEvent.getObservable().getRealm()
159
					.isCurrent();
160
		}
161
	}
162
163
}
(-)src/org/eclipse/jface/conformance/databinding/ObservableContractTests.java (+157 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.core.databinding.observable.ChangeEvent;
17
import org.eclipse.core.databinding.observable.IChangeListener;
18
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.Realm;
20
21
/**
22
 * TestCase that asserts the conformance of an observable to the defined
23
 * contract for changes.
24
 * 
25
 * @since 3.2
26
 */
27
public class ObservableContractTests extends TestCase {
28
	private Realm previousRealm;
29
30
	private IObservableContractDelegate delegate;
31
32
	public ObservableContractTests(IObservableContractDelegate delegate) {
33
		super();
34
		
35
		this.delegate = delegate;
36
	}
37
	
38
	public ObservableContractTests(String testName,
39
			IObservableContractDelegate delegate) {
40
		super(testName);
41
		this.delegate = delegate;
42
	}
43
44
	protected void setUp() throws Exception {
45
		super.setUp();
46
47
		previousRealm = Realm.getDefault();
48
		delegate.setUp();
49
	}
50
51
	protected void tearDown() throws Exception {
52
		super.tearDown();
53
54
		delegate.tearDown();
55
		DummyRealm.setDefaultRealm(previousRealm);
56
	}
57
58
	public void testRealmIsNotNull() throws Exception {
59
		IObservable observable = delegate.createObservable();
60
61
		assertNotNull("The observable's realm should not be null.", observable.getRealm());
62
	}
63
64
	public void testChangeFiresChangeEvent() throws Exception {
65
		ChangeListener listener = new ChangeListener();
66
		IObservable observable = delegate.createObservable();
67
68
		observable.addChangeListener(listener);
69
		delegate.change(observable);
70
71
		assertEquals("A change in the observable should notify change listeners.", listener.count, 1);
72
	}
73
74
	public void testChangeEventObservable() throws Exception {
75
		ChangeListener listener = new ChangeListener();
76
		IObservable observable = delegate.createObservable();
77
78
		observable.addChangeListener(listener);
79
		delegate.change(observable);
80
81
		ChangeEvent event = listener.event;
82
		assertNotNull("change event was null", event);
83
		
84
		assertSame("In the change event the source of the change should be the observable.", observable,
85
				event.getObservable());
86
	}
87
88
	public void testObservableRealmIsTheCurrentRealmOnChange() throws Exception {
89
		IObservable observable = delegate.createObservable();
90
		ChangeListener listener = new ChangeListener();
91
		observable.addChangeListener(listener);
92
93
		delegate.change(observable);
94
		assertTrue("On change the current realm should be the realm of the observable.",
95
				listener.isCurrentRealm);
96
	}
97
98
	public void testRemoveChangeListenerRemovesListener() throws Exception {
99
		ChangeListener listener = new ChangeListener();
100
		IObservable observable = delegate.createObservable();
101
102
		observable.addChangeListener(listener);
103
		delegate.change(observable);
104
105
		// precondition check
106
		assertEquals("change did not notify listeners", 1, listener.count);
107
108
		observable.removeChangeListener(listener);
109
		delegate.change(observable);
110
111
		assertEquals("When a change listener is removed it should not still receive change events.", 1,
112
				listener.count);
113
	}
114
115
	public void testIsNotStale() throws Exception {
116
		IObservable observable = delegate.createObservable();
117
118
		delegate.setStale(observable, false);
119
		assertFalse("When an observable is not stale isStale() should return false.", observable.isStale());
120
	}
121
122
	/**
123
	 * Workaround to be able to set the default realm outside a runnable. The
124
	 * setDefaultRealm(...) method is the only usable method.
125
	 * 
126
	 * @since 3.2
127
	 */
128
	/* package */static class DummyRealm extends Realm {
129
		/**
130
		 * Can't be instantiated.
131
		 */
132
		private DummyRealm() {
133
		}
134
135
		static void setDefaultRealm(Realm realm) {
136
			setDefault(realm);
137
		}
138
139
		public boolean isCurrent() {
140
			throw new UnsupportedOperationException();
141
		}
142
	}
143
144
	/* package */static class ChangeListener implements IChangeListener {
145
		int count;
146
147
		ChangeEvent event;
148
149
		boolean isCurrentRealm;
150
151
		public void handleChange(ChangeEvent event) {
152
			count++;
153
			this.event = event;
154
			this.isCurrentRealm = event.getObservable().getRealm().isCurrent();
155
		}
156
	}
157
}
(-)src/org/eclipse/jface/conformance/databinding/AbstractObservableValueContractDelegate.java (+40 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import org.eclipse.core.databinding.observable.IObservable;
15
import org.eclipse.core.databinding.observable.value.IObservableValue;
16
17
/**
18
 * Abstract implementation of {@link IObservableValueContractDelegate}.
19
 * 
20
 * @since 1.1
21
 */
22
public abstract class AbstractObservableValueContractDelegate extends
23
		AbstractObservableContractDelegate implements
24
		IObservableValueContractDelegate {
25
26
	/**
27
	 * Invokes {@link #createObservableValue()}.
28
	 */
29
	public final IObservable createObservable() {
30
		return createObservableValue();
31
	}
32
33
	/**
34
	 * Default implementation returns <code>null</code>.
35
	 */
36
	public Object getValueType(IObservableValue observable) {
37
		// no op
38
		return null;
39
	}
40
}
(-)src/org/eclipse/jface/conformance/databinding/IObservableValueContractDelegate.java (+43 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import org.eclipse.core.databinding.observable.value.IObservableValue;
15
16
/**
17
 * Delegate interface for an observable value.
18
 * 
19
 * <p>
20
 * Do not directly implement this interface. Please extend
21
 * {@link AbstractObservableValueContractDelegate} instead.
22
 * </p>
23
 * 
24
 * @since 1.1
25
 */
26
public interface IObservableValueContractDelegate extends
27
		IObservableContractDelegate {
28
29
	/**
30
	 * Creates a new observable value.
31
	 * 
32
	 * @return observable value
33
	 */
34
	IObservableValue createObservableValue();
35
36
	/**
37
	 * Returns the expected type of the observable.
38
	 * 
39
	 * @param observable
40
	 * @return type
41
	 */
42
	Object getValueType(IObservableValue observable);
43
}
(-)src/org/eclipse/jface/conformance/databinding/ObservableValueContractTests.java (+208 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
import org.eclipse.core.databinding.observable.ChangeEvent;
18
import org.eclipse.core.databinding.observable.IChangeListener;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
22
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
23
24
/**
25
 * @since 3.2
26
 */
27
public class ObservableValueContractTests extends ObservableContractTests {
28
29
	private IObservableValueContractDelegate delegate;
30
31
	public ObservableValueContractTests(
32
			IObservableValueContractDelegate delegate) {
33
		super(delegate);
34
		this.delegate = delegate;
35
	}
36
37
	/**
38
	 * @param testName
39
	 * @param delegate
40
	 */
41
	public ObservableValueContractTests(String testName,
42
			IObservableValueContractDelegate delegate) {
43
		super(testName, delegate);
44
45
		this.delegate = delegate;
46
	}
47
48
	public void testChangeNotifiesValueChangeListeners() throws Exception {
49
		IObservableValue observable = delegate.createObservableValue();
50
		ValueChangeListener listener = new ValueChangeListener(observable)
51
				.init();
52
53
		delegate.change(observable);
54
		assertEquals("On change value change listeners should be notified.", 1,
55
				listener.count);
56
	}
57
58
	public void testSettingSameValueDoesNotNotifiyValueChangeListeners()
59
			throws Exception {
60
		IObservableValue observable = delegate.createObservableValue();
61
		delegate.change(observable);
62
63
		ValueChangeListener listener = new ValueChangeListener(observable)
64
				.init();
65
		Object value = observable.getValue();
66
		observable.setValue(value);
67
68
		assertEquals(
69
				"When the current value is set on the observable a change does not occur thus value change listeners should not be notified.",
70
				0, listener.count);
71
	}
72
73
	public void testSettingSameValueDoesNotNotifyChangeListeners()
74
			throws Exception {
75
		IObservableValue observable = delegate.createObservableValue();
76
		delegate.change(observable);
77
78
		ChangeListener listener = new ChangeListener(observable).init();
79
		Object value = observable.getValue();
80
		observable.setValue(value);
81
82
		assertEquals(
83
				"When the current value is set on the observable a change does not occur thus change listeners should not be notified.",
84
				0, listener.count);
85
	}
86
87
	public void testObservableTypeIsTheExpectedType() throws Exception {
88
		IObservableValue observable = delegate.createObservableValue();
89
		assertEquals("Type of the value should be returned from getType().",
90
				delegate.getValueType(observable), observable.getValueType());
91
	}
92
93
	public void testChangeListenersAreNotifiedBeforeValueChangeListeners()
94
			throws Exception {
95
		final List listeners = new ArrayList();
96
		IChangeListener changeListener = new IChangeListener() {
97
			public void handleChange(ChangeEvent event) {
98
				listeners.add(this);
99
			}
100
		};
101
102
		IValueChangeListener valueChangeListener = new IValueChangeListener() {
103
			public void handleValueChange(ValueChangeEvent event) {
104
				listeners.add(this);
105
			}
106
		};
107
108
		IObservableValue observable = delegate.createObservableValue();
109
		observable.addChangeListener(changeListener);
110
		observable.addValueChangeListener(valueChangeListener);
111
112
		delegate.change(observable);
113
		// not asserting the fact that both are notified as this is asserted in
114
		// other tests
115
		assertEquals(
116
				"Change listeners should be notified before value change listeners.",
117
				changeListener, listeners.get(0));
118
		assertEquals(
119
				"Value change listeners should be notified after change listeners.",
120
				valueChangeListener, listeners.get(1));
121
	}
122
123
	public void testValueChangeEventOldValueIsPreviousValue() throws Exception {
124
		IObservableValue observable = delegate.createObservableValue();
125
		ValueChangeListener listener = new ValueChangeListener(observable)
126
				.init();
127
		Object oldValue = observable.getValue();
128
129
		delegate.change(observable);
130
131
		ValueChangeEvent event = listener.event;
132
		assertEquals(
133
				"When a value change event is fired the old value should be the previous value of the observable value.",
134
				oldValue, event.diff.getOldValue());
135
	}
136
137
	public void testValueChangeEventObservableValue() throws Exception {
138
		IObservableValue observable = delegate.createObservableValue();
139
		ValueChangeListener listener = new ValueChangeListener(observable)
140
				.init();
141
		delegate.change(observable);
142
143
		ValueChangeEvent event = listener.event;
144
		assertEquals(
145
				"When a value change event is fired the new value should be the same as the current value of the observable value.",
146
				observable.getValue(), event.diff.getNewValue());
147
	}
148
149
	public void testRemoveValueChangeListenerRemovesListener() throws Exception {
150
		IObservableValue observable = delegate.createObservableValue();
151
		ValueChangeListener listener = new ValueChangeListener(observable)
152
				.init();
153
		delegate.change(observable);
154
155
		// precondition
156
		assertEquals("Value change listeners should be notified on change.", 1,
157
				listener.count);
158
159
		observable.removeValueChangeListener(listener);
160
		delegate.change(observable);
161
162
		assertEquals(
163
				"Value change listeners should not be notified after they've been removed from the observable.",
164
				1, listener.count);
165
	}
166
167
	/* package */static class ChangeListener implements IChangeListener {
168
		int count;
169
170
		IObservable observable;
171
172
		ChangeListener(IObservable observable) {
173
			this.observable = observable;
174
		}
175
176
		ChangeListener init() {
177
			observable.addChangeListener(this);
178
			return this;
179
		}
180
181
		public void handleChange(ChangeEvent event) {
182
			count++;
183
		}
184
	}
185
186
	/* package */static class ValueChangeListener implements
187
			IValueChangeListener {
188
		int count;
189
190
		ValueChangeEvent event;
191
192
		private IObservableValue observable;
193
194
		ValueChangeListener(IObservableValue observable) {
195
			this.observable = observable;
196
		}
197
198
		ValueChangeListener init() {
199
			observable.addValueChangeListener(this);
200
			return this;
201
		}
202
203
		public void handleValueChange(ValueChangeEvent event) {
204
			count++;
205
			this.event = event;
206
		}
207
	}
208
}
(-)src/org/eclipse/jface/conformance/databinding/AbstractObservableContractDelegate.java (+39 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import org.eclipse.core.databinding.observable.IObservable;
15
16
/**
17
 * Abstract implementation of {@link IObservableContractDelegate}.
18
 * 
19
 * @since 1.1
20
 */
21
public abstract class AbstractObservableContractDelegate implements
22
		IObservableContractDelegate {
23
24
	public void setUp() {
25
		// no op
26
	}
27
28
	public void tearDown() {
29
		// no op
30
	}
31
32
	public void change(IObservable observable) {
33
		// no op
34
	}
35
36
	public void setStale(IObservable observable, boolean stale) {
37
		// no op
38
	}
39
}
(-)src/org/eclipse/jface/conformance/databinding/IObservableContractDelegate.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.conformance.databinding;
13
14
import org.eclipse.core.databinding.observable.IObservable;
15
16
/**
17
 * Delegate interface for observables.
18
 * 
19
 * <p>
20
 * Do not directly implement this interface. Please extend
21
 * {@link AbstractObservableContractDelegate} instead.
22
 * </p>
23
 * 
24
 * @since 1.1
25
 */
26
public interface IObservableContractDelegate {
27
	/**
28
	 * Notifies the delegate of the start of a test.
29
	 */
30
	void setUp();
31
32
	/**
33
	 * Notifies the delegate of the end of a test.
34
	 */
35
	void tearDown();
36
37
	/**
38
	 * Invokes an operation to set the stale state to the provided value.
39
	 * 
40
	 * @param observable
41
	 * @param stale
42
	 */
43
	void setStale(IObservable observable, boolean stale);
44
45
	/**
46
	 * Creates a new observable.
47
	 * 
48
	 * @return observable
49
	 */
50
	public IObservable createObservable();
51
52
	/**
53
	 * Invokes a change operation on the observable resulting in a change event
54
	 * being fired from the observable.
55
	 * 
56
	 * @param observable
57
	 */
58
	public void change(IObservable observable);
59
}

Return to bug 182059