1 /*******************************************************************************
2  * Copyright (c) 2007, 2008 IBM Corporation 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  *     IBM Corporation - initial API and implementation
13  *     Matthew Hall - bug 226216
14  *******************************************************************************/
15 
16 package org.eclipse.core.tests.databinding.observable;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20 import static org.junit.Assert.fail;
21 
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25 
26 import org.eclipse.core.databinding.observable.Diffs;
27 import org.eclipse.core.databinding.observable.list.ListDiff;
28 import org.eclipse.core.databinding.observable.list.ListDiffEntry;
29 import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
30 import org.junit.Test;
31 
32 /**
33  * @since 1.1
34  */
35 public class Diffs_ListDiffTests {
36 	@Test
testListDiffEntryToStringDoesNotThrowNPEForNullListDiffEntry()37 	public void testListDiffEntryToStringDoesNotThrowNPEForNullListDiffEntry() {
38 		ListDiffEntry entry = new ListDiffEntry() {
39 			@Override
40 			public Object getElement() {
41 				return null;
42 			}
43 
44 			@Override
45 			public int getPosition() {
46 				return 0;
47 			}
48 
49 			@Override
50 			public boolean isAddition() {
51 				return false;
52 			}
53 		};
54 
55 		try {
56 			entry.toString();
57 			assertTrue(true);
58 		} catch (NullPointerException e) {
59 			fail("NPE was thrown.");
60 		}
61 	}
62 
63 	@Test
testListDiffToStringDoesNotThrowNPEForNullListDiff()64 	public void testListDiffToStringDoesNotThrowNPEForNullListDiff() {
65 		ListDiff diff = new ListDiff() {
66 			@Override
67 			public ListDiffEntry[] getDifferences() {
68 				return null;
69 			}
70 		};
71 
72 		try {
73 			diff.toString();
74 			assertTrue(true);
75 		} catch (NullPointerException e) {
76 			fail("NPE was thrown.");
77 		}
78 	}
79 
80 	@Test
testListDiffToStringDoesNotThrowNPEForNullListDiffEntry()81 	public void testListDiffToStringDoesNotThrowNPEForNullListDiffEntry() {
82 		ListDiff diff = new ListDiff() {
83 			@Override
84 			public ListDiffEntry[] getDifferences() {
85 				return new ListDiffEntry[1];
86 			}
87 		};
88 
89 		try {
90 			diff.toString();
91 			assertTrue(true);
92 		} catch (NullPointerException e) {
93 			fail("NPE was thrown.");
94 		}
95 	}
96 
97 	@Test
testDiffScenario1()98 	public void testDiffScenario1() throws Exception {
99 		ListDiff diff = diff(null, null);
100 		assertEquals(0, diff.getDifferences().length);
101 	}
102 
diff(String[] oldArray, String[] newArray)103 	private ListDiff diff(String[] oldArray, String[] newArray) {
104 		List<String> a = Arrays.asList((oldArray != null) ? oldArray : new String[] {});
105 		List<String> b = Arrays.asList((newArray != null) ? newArray : new String[] {});
106 
107 		return Diffs.computeListDiff(a, b);
108 	}
109 
110 	@Test
testDiffScenario2()111 	public void testDiffScenario2() throws Exception {
112 		ListDiff diff = diff(new String[] { "a" }, null);
113 		assertEquals(1, diff.getDifferences().length);
114 		assertEntry(diff.getDifferences()[0], false, 0, "a");
115 	}
116 
117 	@Test
testDiffScenario3()118 	public void testDiffScenario3() throws Exception {
119 		ListDiff diff = diff(null, new String[] { "a" });
120 		assertEquals(1, diff.getDifferences().length);
121 		assertEntry(diff.getDifferences()[0], true, 0, "a");
122 	}
123 
124 	@Test
testDiffScenario4()125 	public void testDiffScenario4() throws Exception {
126 		ListDiff diff = diff(new String[] { "a" }, new String[] { "a" });
127 		assertEquals(0, diff.getDifferences().length);
128 	}
129 
130 	@Test
testDiffScenario5()131 	public void testDiffScenario5() throws Exception {
132 		ListDiff diff = diff(new String[] { "a" }, new String[] { "b" });
133 		assertEquals(2, diff.getDifferences().length);
134 
135 		assertEntry(diff.getDifferences()[0], true, 0, "b");
136 		assertEntry(diff.getDifferences()[1], false, 1, "a");
137 	}
138 
139 	@Test
testDiffScenario6()140 	public void testDiffScenario6() throws Exception {
141 		ListDiff diff = diff(new String[] { "a" }, new String[] { "a", "b" });
142 
143 		assertEquals(1, diff.getDifferences().length);
144 		assertEntry(diff.getDifferences()[0], true, 1, "b");
145 	}
146 
147 	@Test
testDiffScenario7()148 	public void testDiffScenario7() throws Exception {
149 		ListDiff diff = diff(new String[] { "a" }, new String[] { "b", "a" });
150 
151 		assertEquals(1, diff.getDifferences().length);
152 		assertEntry(diff.getDifferences()[0], true, 0, "b");
153 	}
154 
155 	@Test
testDiffScenario8()156 	public void testDiffScenario8() throws Exception {
157 		ListDiff diff = diff(new String[] { "a" }, new String[] { "b", "b" });
158 
159 		assertEquals(3, diff.getDifferences().length);
160 		assertEntry(diff.getDifferences()[0], true, 0, "b");
161 		assertEntry(diff.getDifferences()[1], true, 1, "b");
162 		assertEntry(diff.getDifferences()[2], false, 2, "a");
163 	}
164 
165 	@Test
testDiffScenario9()166 	public void testDiffScenario9() throws Exception {
167 		ListDiff diff = diff(new String[] { "a" }, new String[] { "a", "b", "c" });
168 
169 		assertEquals(2, diff.getDifferences().length);
170 		assertEntry(diff.getDifferences()[0], true, 1, "b");
171 		assertEntry(diff.getDifferences()[1], true, 2, "c");
172 	}
173 
174 	@Test
testDiffScenario10()175 	public void testDiffScenario10() throws Exception {
176 		ListDiff diff = diff(new String[] { "b" }, new String[] { "a", "b", "c" });
177 
178 		assertEquals(2, diff.getDifferences().length);
179 		assertEntry(diff.getDifferences()[0], true, 0, "a");
180 		assertEntry(diff.getDifferences()[1], true, 2, "c");
181 	}
182 
183 	@Test
testDiffScenario11()184 	public void testDiffScenario11() throws Exception {
185 		ListDiff diff = diff(new String[] { "c" }, new String[] { "a", "b", "c" });
186 
187 		assertEquals(2, diff.getDifferences().length);
188 		assertEntry(diff.getDifferences()[0], true, 0, "a");
189 		assertEntry(diff.getDifferences()[1], true, 1, "b");
190 	}
191 
192 	@Test
testDiffScenario12()193 	public void testDiffScenario12() throws Exception {
194 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "a", "b", "c" });
195 
196 		assertEquals(0, diff.getDifferences().length);
197 	}
198 
199 	@Test
testDiffScenario13()200 	public void testDiffScenario13() throws Exception {
201 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "b", "c" });
202 
203 		assertEquals(1, diff.getDifferences().length);
204 		assertEntry(diff.getDifferences()[0], false, 0, "a");
205 	}
206 
207 	@Test
testDiffScenarios14()208 	public void testDiffScenarios14() throws Exception {
209 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "a", "c" });
210 
211 		assertEquals(1, diff.getDifferences().length);
212 		assertEntry(diff.getDifferences()[0], false, 1, "b");
213 	}
214 
215 	@Test
testDiffScenarios15()216 	public void testDiffScenarios15() throws Exception {
217 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "a", "b" });
218 
219 		assertEquals(1, diff.getDifferences().length);
220 		assertEntry(diff.getDifferences()[0], false, 2, "c");
221 	}
222 
223 	@Test
testDiffScenarios16()224 	public void testDiffScenarios16() throws Exception {
225 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "c", "b", "a" });
226 
227 		assertEquals(4, diff.getDifferences().length);
228 		assertEntry(diff.getDifferences()[0], false, 2, "c");
229 		assertEntry(diff.getDifferences()[1], true, 0, "c");
230 		assertEntry(diff.getDifferences()[2], false, 2, "b");
231 		assertEntry(diff.getDifferences()[3], true, 1, "b");
232 	}
233 
234 	@Test
testDiffScenarios17()235 	public void testDiffScenarios17() throws Exception {
236 		ListDiff diff = diff(new String[] { "a", "b", "c" }, new String[] { "c", "b" });
237 
238 		assertEquals(3, diff.getDifferences().length);
239 		assertEntry(diff.getDifferences()[0], false, 0, "a");
240 		assertEntry(diff.getDifferences()[1], false, 1, "c");
241 		assertEntry(diff.getDifferences()[2], true, 0, "c");
242 	}
243 
assertEntry(ListDiffEntry entry, boolean addition, int position, String element)244 	private static void assertEntry(ListDiffEntry entry, boolean addition, int position, String element) {
245 		assertEquals("addition", addition, entry.isAddition());
246 		assertEquals("position", position, entry.getPosition());
247 		assertEquals("element", element, entry.getElement());
248 	}
249 
250 	@Test
testComputeListDiff_SingleInsert()251 	public void testComputeListDiff_SingleInsert() {
252 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "c" }), Arrays.asList(new Object[] { "a", "b", "c" }));
253 	}
254 
255 	@Test
testComputeListDiff_SingleAppend()256 	public void testComputeListDiff_SingleAppend() {
257 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b" }), Arrays.asList(new Object[] { "a", "b", "c" }));
258 	}
259 
260 	@Test
testComputeListDiff_SingleRemove()261 	public void testComputeListDiff_SingleRemove() {
262 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b", "c" }), Arrays.asList(new Object[] { "a", "b" }));
263 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b", "c" }), Arrays.asList(new Object[] { "a", "c" }));
264 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b", "c" }), Arrays.asList(new Object[] { "b", "c" }));
265 	}
266 
267 	@Test
testComputeListDiff_MoveDown1()268 	public void testComputeListDiff_MoveDown1() {
269 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b" }), Arrays.asList(new Object[] { "b", "a" }));
270 	}
271 
272 	@Test
testComputeListDiff_MoveDown2()273 	public void testComputeListDiff_MoveDown2() {
274 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b", "c" }),
275 				Arrays.asList(new Object[] { "b", "c", "a" }));
276 	}
277 
278 	@Test
testComputeListDiff_MoveUp1()279 	public void testComputeListDiff_MoveUp1() {
280 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b" }), Arrays.asList(new Object[] { "b", "a" }));
281 	}
282 
283 	@Test
testComputeListDiff_MoveUp2()284 	public void testComputeListDiff_MoveUp2() {
285 		checkComputedListDiff(Arrays.asList(new Object[] { "a", "b", "c" }),
286 				Arrays.asList(new Object[] { "c", "a", "b" }));
287 	}
288 
checkComputedListDiff(List<Object> oldList, List<Object> newList)289 	private static void checkComputedListDiff(List<Object> oldList, List<Object> newList) {
290 		ListDiff diff = Diffs.computeListDiff(oldList, newList);
291 
292 		final List<Object> list = new ArrayList<>(oldList);
293 		diff.accept(new ListDiffVisitor() {
294 			@Override
295 			public void handleAdd(int index, Object element) {
296 				list.add(index, element);
297 			}
298 
299 			@Override
300 			public void handleRemove(int index, Object element) {
301 				assertEquals(element, list.remove(index));
302 			}
303 
304 			@Override
305 			public void handleReplace(int index, Object oldElement, Object newElement) {
306 				assertEquals(oldElement, list.set(index, newElement));
307 			}
308 		});
309 
310 		assertEquals("Applying diff to old list should make it equal to new list", newList, list);
311 	}
312 }
313