1 /* 2 * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package test.javafx.collections; 27 28 import org.junit.Before; 29 import org.junit.Test; 30 31 import java.util.Arrays; 32 import java.util.Collection; 33 import java.util.Collections; 34 import java.util.List; 35 import javafx.collections.ListChangeListener; 36 import javafx.collections.ObservableList; 37 38 import static org.junit.Assert.*; 39 import org.junit.Ignore; 40 import org.junit.runner.RunWith; 41 import org.junit.runners.Parameterized; 42 43 /** 44 * Tests for ObservableList. 45 * 46 */ 47 @RunWith(Parameterized.class) 48 public class ObservableListTest { 49 50 static final List<String> EMPTY = Collections.emptyList(); 51 final Callable<ObservableList<String>> listFactory; 52 ObservableList<String> list; 53 MockListObserver<String> mlo; 54 55 56 public ObservableListTest(final Callable<ObservableList<String>> listFactory) { 57 this.listFactory = listFactory; 58 } 59 60 @Parameterized.Parameters 61 public static Collection createParameters() { 62 Object[][] data = new Object[][] { 63 { TestedObservableLists.ARRAY_LIST }, 64 { TestedObservableLists.LINKED_LIST }, 65 { TestedObservableLists.VETOABLE_LIST }, 66 { TestedObservableLists.CHECKED_OBSERVABLE_ARRAY_LIST }, 67 { TestedObservableLists.SYNCHRONIZED_OBSERVABLE_ARRAY_LIST }, 68 { TestedObservableLists.OBSERVABLE_LIST_PROPERTY } 69 }; 70 return Arrays.asList(data); 71 } 72 73 @Before 74 public void setUp() throws Exception { 75 list = listFactory.call(); 76 mlo = new MockListObserver<String>(); 77 list.addListener(mlo); 78 79 useListData("one", "two", "three"); 80 } 81 82 /** 83 * Modifies the list in the fixture to use the strings passed in instead of 84 * the default strings, and re-creates the observable list and the observer. 85 * If no strings are passed in, the result is an empty list. 86 * 87 * @param strings the strings to use for the list in the fixture 88 */ 89 void useListData(String... strings) { 90 list.clear(); 91 list.addAll(Arrays.asList(strings)); 92 mlo.clear(); 93 } 94 95 // ========== observer add/remove tests ========== 96 97 @Test 98 public void testObserverAddRemove() { 99 MockListObserver<String> mlo2 = new MockListObserver<String>(); 100 list.addListener(mlo2); 101 list.removeListener(mlo); 102 list.add("xyzzy"); 103 mlo.check0(); 104 mlo2.check1AddRemove(list, EMPTY, 3, 4); 105 } 106 107 @Test 108 @Ignore 109 public void testObserverAddTwice() { 110 list.addListener(mlo); // add it a second time 111 list.add("plugh"); 112 mlo.check1AddRemove(list, EMPTY, 3, 4); 113 } 114 115 @Test 116 public void testObserverRemoveTwice() { 117 list.removeListener(mlo); 118 list.removeListener(mlo); 119 list.add("plugh"); 120 mlo.check0(); 121 } 122 123 // ========== list mutation tests ========== 124 125 @Test 126 public void testAddToEmpty() { 127 useListData(); 128 list.add("asdf"); 129 mlo.check1AddRemove(list, EMPTY, 0, 1); 130 } 131 132 @Test 133 public void testAddAtEnd() { 134 list.add("four"); 135 mlo.check1AddRemove(list, EMPTY, 3, 4); 136 } 137 138 @Test 139 public void testAddInMiddle() { 140 list.add(1, "xyz"); 141 mlo.check1AddRemove(list, EMPTY, 1, 2); 142 } 143 144 @Test 145 public void testAddSeveralToEmpty() { 146 useListData(); 147 list.addAll(Arrays.asList("alpha", "bravo", "charlie")); 148 mlo.check1AddRemove(list, EMPTY, 0, 3); 149 } 150 151 @Test 152 public void testAddSeveralAtEnd() { 153 list.addAll(Arrays.asList("four", "five")); 154 mlo.check1AddRemove(list, EMPTY, 3, 5); 155 } 156 157 @Test 158 public void testAddSeveralInMiddle() { 159 list.addAll(1, Arrays.asList("a", "b")); 160 mlo.check1AddRemove(list, EMPTY, 1, 3); 161 } 162 163 @Test 164 public void testClearNonempty() { 165 list.clear(); 166 mlo.check1AddRemove(list, Arrays.asList("one", "two", "three"), 0, 0); 167 } 168 169 @Test 170 public void testRemoveByIndex() { 171 String r = list.remove(1); 172 mlo.check1AddRemove(list, Arrays.asList("two"), 1, 1); 173 assertEquals("two", r); 174 } 175 176 @Test 177 public void testRemoveObject() { 178 useListData("one", "x", "two", "three"); 179 boolean b = list.remove("two"); 180 mlo.check1AddRemove(list, Arrays.asList("two"), 2, 2); 181 assertTrue(b); 182 } 183 184 @Test 185 public void testRemoveNull() { 186 useListData("one", "two", null, "three"); 187 boolean b = list.remove(null); 188 mlo.check1AddRemove(list, Arrays.asList((String)null), 2, 2); 189 assertTrue(b); 190 } 191 192 @Test 193 public void testRemoveAll() { 194 useListData("one", "two", "three", "four", "five"); 195 list.removeAll(Arrays.asList("one", "two", "four", "six")); 196 assertEquals(2, mlo.calls.size()); 197 mlo.checkAddRemove(0, list, Arrays.asList("one", "two"), 0, 0); 198 mlo.checkAddRemove(1, list, Arrays.asList("four"), 1, 1); 199 } 200 201 @Test 202 public void testRemoveAll_1() { 203 useListData("a", "c", "d", "c"); 204 list.removeAll(Arrays.asList("c")); 205 assertEquals(2, mlo.calls.size()); 206 mlo.checkAddRemove(0, list, Arrays.asList("c"), 1, 1); 207 mlo.checkAddRemove(1, list, Arrays.asList("c"), 2, 2); 208 } 209 210 211 @Test 212 public void testRemoveAll_2() { 213 useListData("one", "two"); 214 list.removeAll(Arrays.asList("three", "four")); 215 mlo.check0(); 216 } 217 218 @Test 219 public void testRemoveAll_3() { 220 useListData("a", "c", "d", "c"); 221 list.removeAll(Arrays.asList("d")); 222 assertEquals(1, mlo.calls.size()); 223 mlo.checkAddRemove(0, list, Arrays.asList("d"), 2, 2); 224 } 225 226 @Test 227 public void testRemoveAll_4() { 228 useListData("a", "c", "d", "c"); 229 list.removeAll(Arrays.asList("d", "c")); 230 assertEquals(1, mlo.calls.size()); 231 mlo.checkAddRemove(0, list, Arrays.asList("c", "d", "c"), 1, 1); 232 } 233 234 @Test 235 public void testRetainAll() { 236 useListData("one", "two", "three", "four", "five"); 237 list.retainAll(Arrays.asList("two", "five", "six")); 238 assertEquals(2, mlo.calls.size()); 239 mlo.checkAddRemove(0, list, Arrays.asList("one"), 0, 0); 240 mlo.checkAddRemove(1, list, Arrays.asList("three", "four"), 1, 1); 241 } 242 243 @Test 244 public void testRemoveNonexistent() { 245 useListData("one", "two", "x", "three"); 246 boolean b = list.remove("four"); 247 mlo.check0(); 248 assertFalse(b); 249 } 250 251 @Test 252 public void testSet() { 253 String r = list.set(1, "fnord"); 254 mlo.check1AddRemove(list, Arrays.asList("two"), 1, 2); 255 assertEquals("two", r); 256 } 257 258 @Test 259 public void testObserverCanRemoveObservers() { 260 final ListChangeListener<String> listObserver = change -> { 261 change.getList().removeListener(mlo); 262 }; 263 list.addListener(listObserver); 264 list.add("x"); 265 mlo.clear(); 266 list.add("y"); 267 mlo.check0(); 268 list.removeListener(listObserver); 269 270 271 final StringListChangeListener listener = new StringListChangeListener(); 272 list.addListener(listener); 273 list.add("z"); 274 assertEquals(listener.counter, 1); 275 list.add("zz"); 276 assertEquals(listener.counter, 1); 277 } 278 279 @Test 280 public void testEqualsAndHashCode() { 281 final List<String> other = Arrays.asList("one", "two", "three"); 282 assertTrue(list.equals(other)); 283 assertEquals(list.hashCode(), other.hashCode()); 284 } 285 286 287 private static class StringListChangeListener implements ListChangeListener<String> { 288 289 private int counter; 290 291 @Override 292 public void onChanged(final Change<? extends String> change) { 293 change.getList().removeListener(this); 294 ++counter; 295 } 296 } 297 }