1 /*
   2  * Copyright (c) 2010, 2013, 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.*;
  32 import javafx.collections.FXCollections;
  33 import javafx.collections.ObservableList;
  34 
  35 import static org.junit.Assert.*;
  36 import org.junit.runner.RunWith;
  37 import org.junit.runners.Parameterized;
  38 
  39 /**
  40  * Tests for sublists of ObservableList.
  41  * 
  42  */
  43 @RunWith(Parameterized.class)
  44 public class ObservableSubListTest {
  45     final Callable<ObservableList<String>> listFactory;
  46     ObservableList<String> list;
  47     List<String> sublist;
  48     private MockListObserver<String> mlo;
  49 
  50     public ObservableSubListTest(final Callable<ObservableList<String>> listFactory) {
  51         this.listFactory = listFactory;
  52     }
  53 
  54     @Parameterized.Parameters
  55     public static Collection createParameters() {
  56         Object[][] data = new Object[][] {
  57             { TestedObservableLists.ARRAY_LIST },
  58             { TestedObservableLists.LINKED_LIST },
  59             { TestedObservableLists.VETOABLE_LIST },
  60             { TestedObservableLists.CHECKED_OBSERVABLE_ARRAY_LIST },
  61             { TestedObservableLists.SYNCHRONIZED_OBSERVABLE_ARRAY_LIST }
  62         };
  63         return Arrays.asList(data);
  64     }
  65 
  66     @Before
  67     public void setup() throws Exception {
  68         list = listFactory.call();
  69         mlo = new MockListObserver<String>();
  70         list.addListener(mlo);
  71         useListData("a", "b", "c", "d", "e", "f");
  72         sublist = list.subList(1, 5);
  73     }
  74 
  75     /**
  76      * Modifies the list in the fixture to use the strings passed in instead of
  77      * the default strings, and re-creates the observable list and the observer.
  78      * If no strings are passed in, the result is an empty list.
  79      *
  80      * @param strings the strings to use for the list in the fixture
  81      */
  82     void useListData(String... strings) {
  83         list.clear();
  84         list.addAll(Arrays.asList(strings));
  85         mlo.clear();
  86     }
  87 
  88     @Test(expected = IllegalArgumentException.class)
  89     public void testBadRange() {
  90         list.subList(3, 2);
  91     }
  92 
  93     @Test(expected = IndexOutOfBoundsException.class)
  94     public void testRangeTooLow() {
  95         list.subList(-2, 4);
  96     }
  97 
  98     @Test(expected = IndexOutOfBoundsException.class)
  99     public void testRangeTooHigh() {
 100         list.subList(3, 7);
 101     }
 102 
 103     @Test
 104     public void testWidestRange() {
 105         List<String> sub = list.subList(0, 6);
 106         assertEquals("[a, b, c, d, e, f]", sub.toString());
 107     }
 108 
 109     @Test
 110     public void testAdd() {
 111         sublist.add("X");
 112         assertEquals("[b, c, d, e, X]", sublist.toString());
 113         assertEquals("[a, b, c, d, e, X, f]", list.toString());
 114         assertEquals(5, sublist.size());
 115         mlo.check1AddRemove(list, null, 5, 6);
 116     }
 117 
 118     @Test
 119     public void testAddAll() {
 120         sublist.addAll(1, Arrays.asList("X", "Y", "Z"));
 121         assertEquals("[b, X, Y, Z, c, d, e]", sublist.toString());
 122         assertEquals("[a, b, X, Y, Z, c, d, e, f]", list.toString());
 123         assertEquals(7, sublist.size());
 124         mlo.check1AddRemove(list, null, 2, 5);
 125     }
 126 
 127     @Test
 128     public void testClear() {
 129         sublist.clear();
 130         assertEquals("[]", sublist.toString());
 131         assertEquals("[a, f]", list.toString());
 132         assertEquals(0, sublist.size());
 133         mlo.check1AddRemove(list, Arrays.asList("b", "c", "d", "e"), 1, 1);
 134     }
 135 
 136     @Test
 137     public void testContains() {
 138         assertTrue(sublist.contains("c"));
 139         assertFalse(sublist.contains("a"));
 140         assertFalse(sublist.contains(null));
 141         assertFalse(sublist.contains(Integer.valueOf(7)));
 142     }
 143 
 144     @Test
 145     public void testContainsAll() {
 146         assertTrue(sublist.containsAll(Arrays.asList("b", "c")));
 147         assertFalse(sublist.containsAll(Arrays.asList("a", "b")));
 148     }
 149 
 150     @Test
 151     public void testContainsNull() {
 152         list.add(3, null);
 153         sublist = list.subList(1, 5);
 154         assertTrue(sublist.contains(null));
 155     }
 156 
 157     @Test
 158     public void testEqualsOnAnotherType() {
 159         assertFalse(sublist.equals(Integer.valueOf(7)));
 160     }
 161 
 162     @Test
 163     public void testEqualsOnLongerList() {
 164         List<String> other = Arrays.asList("b", "c", "d", "e", "f");
 165         assertFalse(sublist.equals(other));
 166         assertTrue(other.hashCode() != sublist.hashCode());
 167     }
 168 
 169     @Test
 170     public void testEqualsOnShorterList() {
 171         List<String> other = Arrays.asList("b", "c", "d");
 172         assertFalse(sublist.equals(other));
 173         assertTrue(other.hashCode() != sublist.hashCode());
 174     }
 175 
 176     @Test
 177     public void testEquals() {
 178         List<String> other = Arrays.asList("b", "c", "d", "e");
 179         assertTrue(sublist.equals(other));
 180         assertEquals(other.hashCode(), sublist.hashCode());
 181     }
 182 
 183     @Test
 184     public void testEqualsWithNull() {
 185         sublist.add(2, null);
 186         List<String> other = Arrays.asList("b", "c", null, "e");
 187         assertFalse(sublist.equals(other));
 188         assertTrue(other.hashCode() != sublist.hashCode());
 189     }
 190 
 191     @Test
 192     public void testEqualsWithNullOnLongerList() {
 193         sublist.add(2, null);
 194         List<String> other = Arrays.asList("b", "c", null, "d", "e");
 195         assertTrue(sublist.equals(other));
 196         assertEquals(other.hashCode(), sublist.hashCode());
 197     }
 198 
 199     @Test
 200     public void testEqualsWithNullOnShorterList() {
 201         sublist.add(2, null);
 202         List<String> other = Arrays.asList("b", "c", null);
 203         assertFalse(sublist.equals(other));
 204         assertTrue(other.hashCode() != sublist.hashCode());
 205     }
 206 
 207     @Test
 208     public void testIndexOf() {
 209         assertEquals(2, sublist.indexOf("d"));
 210         assertEquals(-1, sublist.indexOf("a"));
 211     }
 212 
 213     @Test
 214     public void testIndexOfWithNull() {
 215         sublist.add(2, null);
 216         assertEquals(3, sublist.indexOf("d"));
 217         assertEquals(2, sublist.indexOf(null));
 218         assertEquals(-1, sublist.indexOf("f"));
 219     }
 220 
 221     @Test
 222     public void testIsEmpty() {
 223         assertFalse(sublist.isEmpty());
 224         List<String> otherSublist = list.subList(2, 2);
 225         assertTrue(otherSublist.isEmpty());
 226     }
 227 
 228     @Test
 229     public void testLastIndexOf() {
 230         list = FXCollections.observableList(new ArrayList<String>());
 231         list.addAll(Arrays.asList("a", null, "a", null, "a", null, "a"));
 232         sublist = list.subList(1, 5);
 233         
 234         assertEquals(3, sublist.lastIndexOf("a"));
 235         assertEquals(2, sublist.lastIndexOf(null));
 236     }
 237 
 238     @Test
 239     public void testRemoveAll() {
 240         list = FXCollections.observableList(new ArrayList<String>());
 241         list.addAll(Arrays.asList("a", "b", "c", "a", "b", "c"));
 242         sublist = list.subList(2, 4);
 243         list.addListener(mlo);
 244         sublist.removeAll(Arrays.asList("a", "b", "c"));
 245 
 246         assertEquals("[]", sublist.toString());
 247         assertEquals(0, sublist.size());
 248         assertEquals("[a, b, b, c]", list.toString());
 249         mlo.check1AddRemove(list, Arrays.asList("c", "a"), 2, 2);
 250     }
 251 
 252     @Test
 253     public void testRemoveIndex() {
 254         String s = sublist.remove(2);
 255         assertEquals("d", s);
 256         assertEquals(3, sublist.size());
 257         assertEquals("[b, c, e]", sublist.toString());
 258         assertEquals("[a, b, c, e, f]", list.toString());
 259         mlo.check1AddRemove(list, Collections.singletonList("d"), 3, 3);
 260     }
 261 
 262     @Test
 263     public void testRemoveNull() {
 264         sublist.add(2, null);
 265         assertTrue(sublist.remove(null));
 266         assertEquals(4, sublist.size());
 267         assertEquals("[b, c, d, e]", sublist.toString());
 268         assertEquals("[a, b, c, d, e, f]", list.toString());
 269     }
 270 
 271     @Test
 272     public void testRemoveObjectExists() {
 273         assertTrue(sublist.remove("b"));
 274         assertEquals(3, sublist.size());
 275         assertEquals("[c, d, e]", sublist.toString());
 276         assertEquals("[a, c, d, e, f]", list.toString());
 277         mlo.check1AddRemove(list, Collections.singletonList("b"), 1, 1);
 278     }
 279 
 280     @Test
 281     public void testRemoveObjectNotExists() {
 282         assertFalse(sublist.remove("f"));
 283         assertEquals(4, sublist.size());
 284         assertEquals("[b, c, d, e]", sublist.toString());
 285         assertEquals("[a, b, c, d, e, f]", list.toString());
 286         mlo.check0();
 287     }
 288 
 289     @Test
 290     public void testRetainAll() {
 291         list = FXCollections.observableList(new ArrayList<String>());
 292         list.addAll(Arrays.asList("a", "b", "c", "a", "b", "c"));
 293         list.addListener(mlo);
 294         sublist = list.subList(2, 4);
 295         sublist.retainAll(Arrays.asList("c", "b"));
 296 
 297         assertEquals("[c]", sublist.toString());
 298         assertEquals(1, sublist.size());
 299         assertEquals("[a, b, c, b, c]", list.toString());
 300         mlo.check1AddRemove(list, Collections.singletonList("a"), 3, 3);
 301     }
 302 
 303     @Test
 304     public void testSet() {
 305         String s = sublist.set(2, "X");
 306         assertEquals("d", s);
 307         assertEquals("[b, c, X, e]", sublist.toString());
 308         assertEquals("[a, b, c, X, e, f]", list.toString());
 309         mlo.check1AddRemove(list, Collections.singletonList("d"), 3, 4);
 310     }
 311 
 312     @Test
 313     public void testSize() {
 314         assertEquals(4, sublist.size());
 315         List<String> otherSublist = list.subList(3, 3);
 316         assertEquals(0, otherSublist.size());
 317     }
 318 
 319     @Test
 320     public void testSubSubList() {
 321         List<String> subsublist = sublist.subList(1, 3);
 322         assertEquals(2, subsublist.size());
 323         assertEquals("[c, d]", subsublist.toString());
 324     }
 325 
 326     @Test
 327     public void testSubSubListAdd() {
 328         List<String> subsublist = sublist.subList(1, 3);
 329         subsublist.add(1, "X");
 330         // sublist is now invalid
 331         assertEquals("[c, X, d]", subsublist.toString());
 332         assertEquals("[a, b, c, X, d, e, f]", list.toString());
 333     }
 334 
 335     @Test
 336     public void testSubSubListRemove() {
 337         List<String> subsublist = sublist.subList(1, 3);
 338         assertEquals("c", subsublist.remove(0));
 339         // sublist is now invalid
 340         assertEquals("[d]", subsublist.toString());
 341         assertEquals("[a, b, d, e, f]", list.toString());
 342     }
 343 
 344     @Test
 345     public void testSubSubListSet() {
 346         List<String> subsublist = sublist.subList(1, 3);
 347         String s = subsublist.set(1, "X");
 348         assertEquals("d", s);
 349         assertEquals("[c, X]", subsublist.toString());
 350         assertEquals("[b, c, X, e]", sublist.toString());
 351         assertEquals("[a, b, c, X, e, f]", list.toString());
 352     }
 353 
 354     @Test
 355     public void testToString() {
 356         List<String> sub0 = list.subList(3, 3);
 357         List<String> sub1 = list.subList(3, 4);
 358         List<String> sub2 = list.subList(2, 5);
 359 
 360         assertEquals("[]", sub0.toString());
 361         assertEquals("[d]", sub1.toString());
 362         assertEquals("[c, d, e]", sub2.toString());
 363     }
 364 
 365     @Test
 366     public void testConcurrencyGet() {
 367         list.add("x");
 368         try { sublist.get(0); } catch (ConcurrentModificationException e) {return;}
 369         fail("Expected ConcurrentModificationException");
 370     }
 371     @Test
 372     public void testConcurrencyAdd() {
 373         list.add("x");
 374         try { sublist.add("y"); } catch (ConcurrentModificationException e) {return;}
 375         fail("Expected ConcurrentModificationException");
 376     }
 377     @Test
 378     public void testConcurrencyAddAll() {
 379         list.add("x");
 380         try { sublist.addAll(Collections.singleton("y")); } catch (ConcurrentModificationException e) {return;}
 381         fail("Expected ConcurrentModificationException");
 382     }
 383     @Test
 384     public void testConcurrencyClear() {
 385         list.add("x");
 386         try { sublist.addAll(Collections.singleton("y")); } catch (ConcurrentModificationException e) {return;}
 387         fail("Expected ConcurrentModificationException");
 388     }
 389     @Test
 390     public void testConcurrencyContains() {
 391         list.add("x");
 392         try { sublist.contains("x"); } catch (ConcurrentModificationException e) {return;}
 393         fail("Expected ConcurrentModificationException");
 394     }
 395     @Test
 396     public void testConcurrencyContainsAll() {
 397         list.add("x");
 398         try { sublist.containsAll(Collections.singletonList("x")); } catch (ConcurrentModificationException e) {return;}
 399         fail("Expected ConcurrentModificationException");
 400     }
 401     
 402     @Test
 403     public void testConcurrencyIsEmpty() {
 404         list.add("x");
 405         try { sublist.isEmpty(); } catch (ConcurrentModificationException e) {return;}
 406         fail("Expected ConcurrentModificationException");
 407     }
 408 
 409     @Test
 410     public void testConcurrencyIterator() {
 411         list.add("x");
 412         try { sublist.iterator().next(); } catch (ConcurrentModificationException e) {return;}
 413         fail("Expected ConcurrentModificationException");
 414     }
 415 
 416     @Test
 417     public void testConcurrencyRemove() {
 418         list.add("x");
 419         try { sublist.remove("y"); } catch (ConcurrentModificationException e) {return;}
 420         fail("Expected ConcurrentModificationException");
 421     }
 422 
 423     @Test
 424     public void testConcurrencyRemove0() {
 425         list.add("x");
 426         try { sublist.remove(0); } catch (ConcurrentModificationException e) {return;}
 427         fail("Expected ConcurrentModificationException");
 428     }
 429 
 430     @Test
 431     public void testConcurrencySet() {
 432         list.add("x");
 433         try { sublist.set(0, "y"); } catch (ConcurrentModificationException e) {return;}
 434         fail("Expected ConcurrentModificationException");
 435     }
 436 
 437     @Test
 438     public void testConcurrencyRemoveAll() {
 439         list.add("x");
 440         try { sublist.removeAll(Arrays.asList("c", "d")); } catch (ConcurrentModificationException e) {return;}
 441         fail("Expected ConcurrentModificationException");
 442     }
 443     
 444     @Test
 445     public void testConcurrencyRetainAll() {
 446         list.add("x");
 447         try { sublist.retainAll(Arrays.asList("c", "d")); } catch (ConcurrentModificationException e) {return;}
 448         fail("Expected ConcurrentModificationException");
 449     }
 450     @Test
 451     public void testConcurrencyRetainSize() {
 452         list.add("x");
 453         try { sublist.size(); } catch (ConcurrentModificationException e) {return;}
 454         fail("Expected ConcurrentModificationException");
 455     }
 456 }