1 /*******************************************************************************
2  * Copyright (c) 2007, 2009 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 206839)
13  *     Matthew Hall - bug 213145, 194734, 195222
14  *******************************************************************************/
15 package org.eclipse.jface.tests.internal.databinding.viewers;
16 
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.assertNull;
19 import static org.junit.Assert.assertSame;
20 import static org.junit.Assert.fail;
21 
22 import org.eclipse.core.databinding.observable.IObservable;
23 import org.eclipse.core.databinding.observable.Realm;
24 import org.eclipse.core.databinding.observable.value.IObservableValue;
25 import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
26 import org.eclipse.jface.databinding.conformance.MutableObservableValueContractTest;
27 import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
28 import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
29 import org.eclipse.jface.databinding.viewers.typed.ViewerProperties;
30 import org.eclipse.jface.databinding.viewers.ViewersObservables;
31 import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
32 import org.eclipse.jface.viewers.IStructuredContentProvider;
33 import org.eclipse.jface.viewers.TableViewer;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.widgets.Shell;
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Test;
39 
40 import junit.framework.TestSuite;
41 
42 /**
43  * Tests for ViewerInputObservableValue.
44  *
45  * @since 1.2
46  */
47 public class ViewerInputObservableValueTest extends AbstractDefaultRealmTestCase {
48 	private TableViewer viewer;
49 	private static String[] model = new String[] { "0", "1" };
50 
51 	@Override
52 	@Before
setUp()53 	public void setUp() throws Exception {
54 		super.setUp();
55 		Shell shell = new Shell();
56 		viewer = new TableViewer(shell, SWT.NONE);
57 		viewer.setContentProvider(new ContentProvider());
58 	}
59 
60 	@Override
61 	@After
tearDown()62 	public void tearDown() throws Exception {
63 		Shell shell = viewer.getTable().getShell();
64 		if (!shell.isDisposed())
65 			shell.dispose();
66 		super.tearDown();
67 	}
68 
69 	@Test
testConstructor_IllegalArgumentException()70 	public void testConstructor_IllegalArgumentException() {
71 		try {
72 			ViewersObservables.observeInput(null);
73 			fail("Expected IllegalArgumentException for null argument");
74 		} catch (IllegalArgumentException expected) {
75 		}
76 	}
77 
78 	@Test
testSetInputOnViewer_FiresChangeEventOnGetValue()79 	public void testSetInputOnViewer_FiresChangeEventOnGetValue() {
80 		IObservableValue observable = ViewersObservables.observeInput(viewer);
81 		ValueChangeEventTracker listener = ValueChangeEventTracker
82 				.observe(observable);
83 
84 		assertNull(viewer.getInput());
85 		assertEquals(0, listener.count);
86 
87 		viewer.setInput(model);
88 
89 		assertEquals(model, viewer.getInput());
90 		assertEquals(0, listener.count);
91 
92 		// Call to getValue() causes observable to discover change
93 		assertEquals(model, observable.getValue());
94 		assertEquals(1, listener.count);
95 
96 		viewer.setInput(null);
97 		assertEquals(null, viewer.getInput());
98 
99 		assertEquals(null, observable.getValue());
100 		assertEquals(2, listener.count);
101 	}
102 
103 	@Test
testGetSetValue_FiresChangeEvents()104 	public void testGetSetValue_FiresChangeEvents() {
105 		IObservableValue observable = ViewersObservables.observeInput(viewer);
106 		ValueChangeEventTracker listener = new ValueChangeEventTracker();
107 		observable.addValueChangeListener(listener);
108 
109 		assertNull(observable.getValue());
110 		assertEquals(0, listener.count);
111 
112 		observable.setValue(model);
113 
114 		assertEquals(model, observable.getValue());
115 		assertEquals(1, listener.count);
116 		assertValueChangeEventEquals(observable, null, model, listener.event);
117 
118 		observable.setValue(null);
119 
120 		assertNull(observable.getValue());
121 		assertEquals(2, listener.count);
122 		assertValueChangeEventEquals(observable, model, null, listener.event);
123 	}
124 
125 	@Test
testGetValueType_AlwaysNull()126 	public void testGetValueType_AlwaysNull() throws Exception {
127 		IObservableValue observable = ViewersObservables.observeInput(viewer);
128 		assertEquals(null, observable.getValueType());
129 	}
130 
131 	@Test
testDispose()132 	public void testDispose() throws Exception {
133 		IObservableValue observable = ViewersObservables.observeInput(viewer);
134 		observable.dispose();
135 		try {
136 			observable.setValue(model);
137 			fail("Expected NullPointerException");
138 		} catch (NullPointerException expected) {
139 		}
140 	}
141 
assertValueChangeEventEquals( IObservableValue expectedObservable, Object expectedOldValue, Object expectedNewValue, ValueChangeEvent event)142 	private void assertValueChangeEventEquals(
143 			IObservableValue expectedObservable, Object expectedOldValue,
144 			Object expectedNewValue, ValueChangeEvent event) {
145 		assertSame(expectedObservable, event.getObservableValue());
146 		assertEquals(expectedOldValue, event.diff.getOldValue());
147 		assertEquals(expectedNewValue, event.diff.getNewValue());
148 	}
149 
150 	static class ContentProvider implements IStructuredContentProvider {
151 		@Override
getElements(Object inputElement)152 		public Object[] getElements(Object inputElement) {
153 			return (String[]) inputElement;
154 		}
155 	}
156 
addConformanceTest(TestSuite suite)157 	public static void addConformanceTest(TestSuite suite) {
158 		suite.addTest(MutableObservableValueContractTest.suite(new Delegate()));
159 	}
160 
161 	static class Delegate extends AbstractObservableValueContractDelegate {
162 		TableViewer viewer;
163 
164 		@Override
setUp()165 		public void setUp() {
166 			super.setUp();
167 			Shell shell = new Shell();
168 			viewer = new TableViewer(shell, SWT.NONE);
169 			viewer.setContentProvider(new ContentProvider());
170 		}
171 
172 		@Override
tearDown()173 		public void tearDown() {
174 			Shell shell = viewer.getTable().getShell();
175 			if (!shell.isDisposed())
176 				shell.dispose();
177 			super.tearDown();
178 		}
179 
180 		@Override
createObservableValue(Realm realm)181 		public IObservableValue createObservableValue(Realm realm) {
182 			return ViewerProperties.input().observe(realm, viewer);
183 		}
184 
185 		@Override
change(IObservable observable)186 		public void change(IObservable observable) {
187 			IObservableValue value = (IObservableValue) observable;
188 			value.setValue(createValue(value));
189 		}
190 
191 		@Override
createValue(IObservableValue observable)192 		public Object createValue(IObservableValue observable) {
193 			return new String[] { "one", "two" };
194 		}
195 
196 		@Override
getValueType(IObservableValue observable)197 		public Object getValueType(IObservableValue observable) {
198 			return null;
199 		}
200 	}
201 }
202