1 /*******************************************************************************
2  * Copyright (c) 2007, 2008 Matthew Hall and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     Matthew Hall - initial API and implementation (bug 212468)
13  *     Matthew Hall - bug 213145
14  ******************************************************************************/
15 
16 package org.eclipse.core.tests.internal.databinding.observable;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 
22 import java.util.concurrent.atomic.AtomicInteger;
23 
24 import org.eclipse.core.databinding.observable.AbstractObservable;
25 import org.eclipse.core.databinding.observable.IObservable;
26 import org.eclipse.core.databinding.observable.Observables;
27 import org.eclipse.core.databinding.observable.Realm;
28 import org.eclipse.core.databinding.observable.value.IObservableValue;
29 import org.eclipse.core.databinding.observable.value.WritableValue;
30 import org.eclipse.core.internal.databinding.observable.StalenessObservableValue;
31 import org.eclipse.jface.databinding.conformance.ObservableValueContractTest;
32 import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
33 import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
34 import org.junit.Test;
35 
36 import junit.framework.TestSuite;
37 
38 /**
39  * Tests for StalenessObservableValue
40  *
41  * @since 1.1
42  */
43 public class StalenessObservableValueTest extends AbstractDefaultRealmTestCase {
44 
45 	/**
46 	 * Test that {@link StalenessObservableValue#getValue} returns the new value
47 	 * when called inside the value change listener.
48 	 */
49 	@Test
valueDuringListenerCallback()50 	public void valueDuringListenerCallback() {
51 		IObservableValue<String> source = new WritableValue<>("a", String.class);
52 		IObservableValue<String> delayed = Observables.observeDelayedValue(1, source);
53 		IObservableValue<Boolean> stale = Observables.observeStale(delayed);
54 
55 		AtomicInteger nrStaleEvents = new AtomicInteger();
56 
57 		stale.addValueChangeListener(e -> {
58 			if (nrStaleEvents.incrementAndGet() == 1) {
59 				assertTrue(stale.getValue());
60 				assertTrue(e.diff.getNewValue());
61 				assertFalse(e.diff.getOldValue());
62 			} else {
63 				assertFalse(stale.getValue());
64 				assertFalse(e.diff.getNewValue());
65 				assertTrue(e.diff.getOldValue());
66 			}
67 		});
68 
69 		source.setValue("b");
70 
71 		// Makes the observable non-stale
72 		delayed.getValue();
73 
74 		assertEquals(2, nrStaleEvents.get());
75 	}
76 
addConformanceTest(TestSuite suite)77 	public static void addConformanceTest(TestSuite suite) {
78 		suite.addTest(ObservableValueContractTest.suite(new Delegate()));
79 	}
80 
81 	static class ObservableStub extends AbstractObservable {
82 		boolean stale;
83 
ObservableStub(Realm realm)84 		public ObservableStub(Realm realm) {
85 			super(realm);
86 		}
87 
88 		@Override
isStale()89 		public boolean isStale() {
90 			return stale;
91 		}
92 
setStale(boolean stale)93 		public void setStale(boolean stale) {
94 			if (this.stale == stale)
95 				return;
96 
97 			this.stale = stale;
98 			if (stale) {
99 				fireStale();
100 			} else {
101 				fireChange();
102 			}
103 		}
104 	}
105 
106 	static class StalenessObservableValueStub extends StalenessObservableValue {
107 		ObservableStub target;
108 
StalenessObservableValueStub(ObservableStub target)109 		StalenessObservableValueStub(ObservableStub target) {
110 			super(target);
111 			this.target = target;
112 		}
113 	}
114 
115 	static class Delegate extends AbstractObservableValueContractDelegate {
116 		@Override
createObservableValue(Realm realm)117 		public IObservableValue<?> createObservableValue(Realm realm) {
118 			return new StalenessObservableValueStub(new ObservableStub(realm));
119 		}
120 
121 		@Override
change(IObservable observable)122 		public void change(IObservable observable) {
123 			ObservableStub target = ((StalenessObservableValueStub) observable).target;
124 			target.setStale(!target.isStale());
125 		}
126 
127 		@Override
getValueType(IObservableValue<?> observable)128 		public Object getValueType(IObservableValue<?> observable) {
129 			return Boolean.TYPE;
130 		}
131 	}
132 }