1 /* 2 * Copyright (c) 2009, 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 javafx.collections; 27 28 import com.sun.javafx.collections.ObservableListWrapper; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.List; 33 import org.junit.Before; 34 import org.junit.Test; 35 import static org.junit.Assert.*; 36 37 public class ListChangeBuilderTest { 38 39 private ListChangeBuilder<String> builder; 40 private ObservableListWrapper<String> observableList; 41 private ArrayList<String> list; 42 private MockListObserver<String> observer; 43 44 @Before 45 public void setUp() { 46 observer = new MockListObserver<String>(); 47 list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); 48 observableList = new ObservableListWrapper<String>(list); 49 observableList.addListener(observer); 50 builder = new ListChangeBuilder<String>(observableList); 51 } 52 53 @Test 54 public void testAddRemove() { 55 builder.beginChange(); 56 list.remove(2); 57 builder.nextRemove(2, "c"); 58 list.add(2, "cc"); 59 list.add(3, "ccc"); 60 builder.nextAdd(2, 4); 61 list.remove(2); 62 builder.nextRemove(2, "cc"); 63 list.remove(3); 64 builder.nextRemove(3, "d"); 65 list.add(0, "aa"); 66 builder.nextAdd(0, 1); 67 builder.endChange(); 68 69 assertEquals(list, Arrays.asList("aa", "a", "b", "ccc")); 70 71 observer.checkAddRemove(0, observableList, Collections.EMPTY_LIST, 0, 1); 72 observer.checkAddRemove(1, observableList, Arrays.asList("c", "d"), 3, 4); 73 } 74 75 @Test 76 public void testAddRemove_2() { 77 builder.beginChange(); 78 list.add("e"); 79 builder.nextAdd(4, 5); 80 list.add(3, "dd"); 81 builder.nextAdd(3, 4); 82 list.remove(4); 83 builder.nextRemove(4, "d"); 84 85 list.remove(0); 86 builder.nextRemove(0, "a"); 87 builder.endChange(); 88 89 assertEquals(list, Arrays.asList("b", "c", "dd", "e")); 90 91 observer.checkAddRemove(0, observableList, Arrays.asList("a"), 0, 0); 92 observer.checkAddRemove(1, observableList, Arrays.asList("d"), 2, 4); 93 } 94 95 @Test 96 public void testAddRemove_3() { 97 builder.beginChange(); 98 list.add("e"); 99 builder.nextAdd(4, 5); 100 101 list.set(0, "aa"); 102 builder.nextReplace(0, 1, Arrays.asList("a")); 103 104 list.remove(4); 105 builder.nextRemove(4, "e"); 106 107 list.remove(0); 108 builder.nextRemove(0, "aa"); 109 builder.endChange(); 110 111 assertEquals(list, Arrays.asList("b", "c", "d")); 112 113 observer.check1AddRemove(observableList, Arrays.asList("a"), 0, 0); 114 115 } 116 117 @Test 118 public void testAddRemove_4() { 119 builder.beginChange(); 120 121 list.add("e"); 122 builder.nextAdd(4, 5); 123 124 list.remove(1); 125 builder.nextRemove(1, "b"); 126 127 list.add(1, "bb"); 128 builder.nextAdd(1, 2); 129 130 builder.endChange(); 131 132 assertEquals(list, Arrays.asList("a", "bb", "c", "d", "e")); 133 134 observer.checkAddRemove(0, observableList, Arrays.asList("b"), 1, 2); 135 observer.checkAddRemove(1, observableList, Collections.EMPTY_LIST, 4, 5); 136 } 137 138 //RT-37089 139 @Test 140 public void testAddRemove_5() { 141 builder.beginChange(); 142 143 list.addAll(1, Arrays.asList("x", "y")); 144 builder.nextAdd(1, 3); 145 146 list.remove(2); 147 builder.nextRemove(2, "y"); 148 149 builder.endChange(); 150 151 observer.check1AddRemove(observableList, Collections.EMPTY_LIST, 1, 2); 152 153 } 154 155 @Test 156 public void testAdd() { 157 builder.beginChange(); 158 159 list.add(1, "aa"); 160 builder.nextAdd(1, 2); 161 list.add(5, "e"); 162 builder.nextAdd(5, 6); 163 list.add(1, "aa"); 164 builder.nextAdd(1, 2); 165 list.add(2, "aa"); 166 builder.nextAdd(2, 3); 167 list.add(4, "aa"); 168 builder.nextAdd(4, 5); 169 170 builder.endChange(); 171 172 assertEquals(list, Arrays.asList("a", "aa","aa","aa","aa", "b", "c", "d", "e")); 173 174 observer.checkAddRemove(0, observableList, Collections.EMPTY_LIST, 1, 5); 175 observer.checkAddRemove(1, observableList, Collections.EMPTY_LIST, 8, 9); 176 177 } 178 179 @Test 180 public void testRemove() { 181 builder.beginChange(); 182 list.remove(0); 183 builder.nextRemove(0, "a"); 184 list.remove(2); 185 builder.nextRemove(2, "d"); 186 list.remove(0); 187 builder.nextRemove(0, "b"); 188 builder.endChange(); 189 190 assertEquals(list, Arrays.asList("c")); 191 192 observer.checkAddRemove(0, observableList, Arrays.asList("a", "b"), 0, 0); 193 observer.checkAddRemove(1, observableList, Arrays.asList("d"), 1, 1); 194 195 } 196 197 @Test 198 public void testRemove_2() { 199 builder.beginChange(); 200 list.remove(1); 201 builder.nextRemove(1, "b"); 202 list.remove(2); 203 builder.nextRemove(2, "d"); 204 list.remove(0); 205 builder.nextRemove(0, "a"); 206 builder.endChange(); 207 208 assertEquals(list, Arrays.asList("c")); 209 210 observer.checkAddRemove(0, observableList, Arrays.asList("a", "b"), 0, 0); 211 observer.checkAddRemove(1, observableList, Arrays.asList("d"), 1, 1); 212 213 } 214 215 @Test 216 public void testUpdate() { 217 builder.beginChange(); 218 builder.nextUpdate(1); 219 builder.nextUpdate(0); 220 builder.nextUpdate(3); 221 builder.endChange(); 222 223 observer.checkUpdate(0, observableList, 0, 2); 224 observer.checkUpdate(1, observableList, 3, 4); 225 } 226 227 @Test 228 public void testUpdate_2() { 229 builder.beginChange(); 230 builder.nextUpdate(3); 231 builder.nextUpdate(1); 232 builder.nextUpdate(0); 233 builder.nextUpdate(0); 234 builder.nextUpdate(2); 235 builder.endChange(); 236 237 observer.checkUpdate(0, observableList, 0, 4); 238 } 239 240 @Test 241 public void testPermutation() { 242 builder.beginChange(); 243 244 builder.nextPermutation(0, 4, new int[] {3, 2, 1, 0}); 245 builder.nextPermutation(1, 4, new int[] {3, 2, 1}); 246 builder.endChange(); 247 248 observer.check1Permutation(observableList, new int[] {1, 2, 3, 0}); 249 } 250 251 @Test 252 public void testUpdateAndAddRemove() { 253 builder.beginChange(); 254 builder.nextUpdate(1); 255 builder.nextUpdate(2); 256 list.remove(2); 257 builder.nextRemove(2, "c"); 258 list.add(2, "cc"); 259 list.add(3, "ccc"); 260 builder.nextAdd(2, 4); 261 builder.nextUpdate(2); 262 list.remove(2); 263 builder.nextRemove(2, "cc"); 264 list.remove(3); 265 builder.nextRemove(3, "d"); 266 list.add(0, "aa"); 267 builder.nextAdd(0, 1); 268 builder.endChange(); 269 270 assertEquals(list, Arrays.asList("aa", "a", "b", "ccc")); 271 272 observer.checkAddRemove(0, observableList, Collections.EMPTY_LIST, 0, 1); 273 observer.checkAddRemove(1, observableList, Arrays.asList("c", "d"), 3, 4); 274 observer.checkUpdate(2, observableList, 2, 3); 275 } 276 277 @Test 278 public void testUpdateAndAddRemove_2() { 279 builder.beginChange(); 280 builder.nextUpdate(0); 281 builder.nextUpdate(1); 282 list.add(1,"aaa"); 283 list.add(1,"aa"); 284 builder.nextAdd(1, 3); 285 builder.endChange(); 286 287 assertEquals(list, Arrays.asList("a", "aa", "aaa", "b", "c", "d")); 288 289 observer.checkAddRemove(0, observableList, Collections.EMPTY_LIST, 1, 3); 290 observer.checkUpdate(1, observableList, 0, 1); 291 observer.checkUpdate(2, observableList, 3, 4); 292 } 293 294 @Test 295 public void testUpdateAndAddRemove_3() { 296 builder.beginChange(); 297 builder.nextUpdate(2); 298 builder.nextUpdate(3); 299 list.add(1,"aa"); 300 builder.nextAdd(1, 2); 301 list.remove(0); 302 builder.nextRemove(0, "a"); 303 builder.endChange(); 304 305 assertEquals(list, Arrays.asList("aa", "b", "c", "d")); 306 307 observer.checkAddRemove(0, observableList, Arrays.asList("a"), 0, 1); 308 observer.checkUpdate(1, observableList, 2, 4); 309 } 310 311 @Test 312 public void testUpdateAndPermutation() { 313 builder.beginChange(); 314 315 builder.nextUpdate(1); 316 builder.nextUpdate(2); 317 builder.nextPermutation(1, 4, new int[] {3, 2, 1}); 318 builder.endChange(); 319 320 observer.checkPermutation(0, observableList, 1, 4, new int[] {3, 2, 1}); 321 observer.checkUpdate(1, observableList, 2, 4); 322 } 323 324 @Test 325 public void testUpdateAndPermutation_2() { 326 builder.beginChange(); 327 328 builder.nextUpdate(0); 329 builder.nextUpdate(2); 330 builder.nextPermutation(0, 4, new int[] {1, 3, 2, 0}); 331 builder.endChange(); 332 333 observer.checkPermutation(0, observableList, 0, 4, new int[] {1, 3, 2, 0}); 334 observer.checkUpdate(1, observableList, 1, 3); 335 } 336 337 @Test 338 public void testAddAndPermutation() { 339 builder.beginChange(); 340 341 builder.nextAdd(1, 2); // as-if "b" was added 342 builder.nextPermutation(0, 3, new int[] { 2, 0, 1}); // new order is "b", "c", "a", "d" 343 344 builder.endChange(); 345 // "c", "a", "d" before "b" was added 346 observer.checkPermutation(0, observableList, 0, 3, new int[] {1, 0, 2}); 347 348 observer.checkAddRemove(1, observableList, Collections.EMPTY_LIST, 0, 1); 349 } 350 351 @Test 352 public void testRemoveAndPermutation() { 353 builder.beginChange(); 354 355 List<String> removed = Arrays.asList("bb", "bbb"); 356 357 builder.nextRemove(2, removed); 358 builder.nextPermutation(0, 3, new int[] {2, 0, 1}); 359 360 builder.endChange(); 361 362 observer.checkPermutation(0, observableList, 0, 6, new int[] {4, 0, 2, 3, 1, 5}); 363 observer.checkAddRemove(1, observableList, removed, 1, 1); 364 365 } 366 367 @Test 368 public void testAddRemoveAndPermutation() { 369 builder.beginChange(); 370 371 // Expect list to be "b", "c1", "c2", "d" 372 List<String> removed = Arrays.asList("c1", "c2"); 373 // After add: "a", "b", "c1", "c2", "d" 374 builder.nextAdd(0, 1); 375 // After replace "a", "b", "c", "d" 376 builder.nextReplace(2, 3, removed); 377 builder.nextPermutation(1, 4, new int[] {3, 1, 2}); 378 379 builder.endChange(); 380 381 observer.checkPermutation(0, observableList, 0, 4, new int[] {3, 1, 2, 0}); 382 observer.checkAddRemove(1, observableList, removed, 0, 2); 383 } 384 385 @Test 386 public void testPermutationAndAddRemove() { 387 builder.beginChange(); 388 389 // Expect list to be "b", "c1", "c2", "d" 390 // After perm "b", "c2", "d", "c1" 391 builder.nextPermutation(1, 4, new int[] {3, 1, 2}); 392 // After add: "a", "b", "c2", "d", "c1" 393 builder.nextAdd(0, 1); 394 builder.nextReplace(2, 3, Arrays.asList("c2")); 395 builder.nextRemove(4, Arrays.asList("c1")); 396 397 builder.endChange(); 398 399 observer.checkPermutation(0, observableList, 1, 4, new int[] {3, 1, 2}); 400 observer.checkAddRemove(1, observableList, Collections.EMPTY_LIST, 0, 1); 401 observer.checkAddRemove(2, observableList, Arrays.asList("c2"), 2, 3); 402 observer.checkAddRemove(3, observableList, Arrays.asList("c1"), 4, 4); 403 } 404 405 @Test 406 public void testPermutationAddRemoveAndPermutation() { 407 408 builder.beginChange(); 409 // Expect list to be "b", "c1", "d" 410 List<String> removed = Arrays.asList("c1"); 411 // After perm: "c1", "b", "d" 412 builder.nextPermutation(0, 2, new int[] { 1, 0 }); 413 // After add: "a", "c1", "b", "d" 414 builder.nextAdd(0, 1); 415 // After remove/add "a", "b", "c", "d" 416 builder.nextRemove(1, removed); 417 builder.nextAdd(2, 3); 418 // After permutation "a", "c", "d", "b" 419 builder.nextPermutation(1, 4, new int[] {3, 1, 2}); 420 421 builder.endChange(); 422 423 // When combined, it's from the expected list: 424 // permutation to "c1", "d", "b" 425 observer.checkPermutation(0, observableList, 0, 3, new int[] {2, 0, 1}); 426 // add remove to "a", "c", "d", "b" 427 observer.checkAddRemove(1, observableList, removed, 0, 2); 428 } 429 430 @Test(expected=IllegalStateException.class) 431 public void testNextAddWithoutBegin() { 432 builder.nextAdd(0, 1); 433 } 434 435 @Test(expected=IllegalStateException.class) 436 public void testNextRemoveWithoutBegin() { 437 builder.nextRemove(0, (String)null); 438 } 439 440 @Test(expected=IllegalStateException.class) 441 public void testNextRemove2WithoutBegin() { 442 builder.nextRemove(0, Collections.EMPTY_LIST); 443 } 444 445 @Test(expected=IllegalStateException.class) 446 public void testNextUpdateWithoutBegin() { 447 builder.nextUpdate(0); 448 } 449 450 @Test(expected=IllegalStateException.class) 451 public void testNextSetWithoutBegin() { 452 builder.nextSet(0, null); 453 } 454 455 @Test(expected=IllegalStateException.class) 456 public void testNextReplaceWithoutBegin() { 457 builder.nextReplace(0, 1, Collections.EMPTY_LIST); 458 } 459 460 @Test 461 public void testEmpty() { 462 builder.beginChange(); 463 builder.endChange(); 464 465 observer.check0(); 466 } 467 468 @Test 469 public void testToString_Update() { 470 observableList.removeListener(observer); 471 observableList.addListener((ListChangeListener.Change<? extends String> change) -> { 472 assertNotNull(change.toString()); 473 }); 474 builder.beginChange(); 475 476 builder.nextUpdate(0); 477 478 builder.endChange(); 479 } 480 481 @Test 482 public void testToString_Add() { 483 observableList.removeListener(observer); 484 observableList.addListener((ListChangeListener.Change<? extends String> change) -> { 485 assertNotNull(change.toString()); 486 }); 487 builder.beginChange(); 488 489 builder.nextAdd(0, 1); 490 491 builder.endChange(); 492 } 493 494 @Test 495 public void testToString_Remove() { 496 observableList.removeListener(observer); 497 observableList.addListener((ListChangeListener.Change<? extends String> change) -> { 498 assertNotNull(change.toString()); 499 }); 500 builder.beginChange(); 501 502 builder.nextRemove(0, ""); 503 504 builder.endChange(); 505 } 506 507 @Test 508 public void testToString_Composed() { 509 observableList.removeListener(observer); 510 observableList.addListener((ListChangeListener.Change<? extends String> change) -> { 511 assertNotNull(change.toString()); 512 }); 513 builder.beginChange(); 514 515 builder.nextUpdate(0); 516 517 builder.nextAdd(0, 3); 518 519 builder.endChange(); 520 } 521 522 @Test 523 public void testToString_Permutation() { 524 observableList.removeListener(observer); 525 observableList.addListener((ListChangeListener.Change<? extends String> change) -> { 526 assertNotNull(change.toString()); 527 }); 528 builder.beginChange(); 529 530 builder.nextPermutation(0, 2, new int[] {1, 0}); 531 532 builder.endChange(); 533 } 534 535 }