1 /*
   2  * Copyright (c) 2015, 2017, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.ByteArrayInputStream;
  25 import java.io.ByteArrayOutputStream;
  26 import java.io.IOException;
  27 import java.io.ObjectInputStream;
  28 import java.io.ObjectOutputStream;
  29 import java.io.Serializable;
  30 import java.util.ArrayList;
  31 import java.util.Arrays;
  32 import java.util.Collections;
  33 import java.util.Iterator;
  34 import java.util.List;
  35 
  36 import org.testng.annotations.DataProvider;
  37 import org.testng.annotations.Test;
  38 
  39 import static java.util.Arrays.asList;
  40 
  41 import static org.testng.Assert.assertEquals;
  42 import static org.testng.Assert.assertFalse;
  43 import static org.testng.Assert.assertNotEquals;
  44 import static org.testng.Assert.assertNotSame;
  45 import static org.testng.Assert.assertSame;
  46 import static org.testng.Assert.assertTrue;
  47 import static org.testng.Assert.fail;
  48 
  49 /*
  50  * @test
  51  * @bug 8048330
  52  * @summary Test convenience static factory methods on List.
  53  * @run testng ListFactories
  54  */
  55 
  56 public class ListFactories {
  57 
  58     static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
  59     static final String[] stringArray;
  60     static {
  61         String[] sa = new String[NUM_STRINGS];
  62         for (int i = 0; i < NUM_STRINGS; i++) {
  63             sa[i] = String.valueOf((char)('a' + i));
  64         }
  65         stringArray = sa;
  66     }
  67 
  68     // returns array of [actual, expected]
  69     static Object[] a(List<String> act, List<String> exp) {
  70         return new Object[] { act, exp };
  71     }
  72 
  73     @DataProvider(name="empty")
  74     public Iterator<Object[]> empty() {
  75         return Collections.singletonList(
  76             a(List.of(), asList())
  77         ).iterator();
  78     }
  79 
  80     @DataProvider(name="nonempty")
  81     public Iterator<Object[]> nonempty() {
  82         return asList(
  83             a(List.of("a"),
  84                asList("a")),
  85             a(List.of("a", "b"),
  86                asList("a", "b")),
  87             a(List.of("a", "b", "c"),
  88                asList("a", "b", "c")),
  89             a(List.of("a", "b", "c", "d"),
  90                asList("a", "b", "c", "d")),
  91             a(List.of("a", "b", "c", "d", "e"),
  92                asList("a", "b", "c", "d", "e")),
  93             a(List.of("a", "b", "c", "d", "e", "f"),
  94                asList("a", "b", "c", "d", "e", "f")),
  95             a(List.of("a", "b", "c", "d", "e", "f", "g"),
  96                asList("a", "b", "c", "d", "e", "f", "g")),
  97             a(List.of("a", "b", "c", "d", "e", "f", "g", "h"),
  98                asList("a", "b", "c", "d", "e", "f", "g", "h")),
  99             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
 100                asList("a", "b", "c", "d", "e", "f", "g", "h", "i")),
 101             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
 102                asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
 103             a(List.of(stringArray),
 104                asList(stringArray))
 105         ).iterator();
 106     }
 107 
 108     @DataProvider(name="sublists")
 109     public Iterator<Object[]> sublists() {
 110         return asList(
 111             a(List.<String>of().subList(0,0),
 112                asList()),
 113             a(List.of("a").subList(0,0),
 114                asList("a").subList(0,0)),
 115             a(List.of("a", "b").subList(0,1),
 116                asList("a", "b").subList(0,1)),
 117             a(List.of("a", "b", "c").subList(1,3),
 118                asList("a", "b", "c").subList(1,3)),
 119             a(List.of("a", "b", "c", "d").subList(0,4),
 120                asList("a", "b", "c", "d").subList(0,4)),
 121             a(List.of("a", "b", "c", "d", "e").subList(0,3),
 122                asList("a", "b", "c", "d", "e").subList(0,3)),
 123             a(List.of("a", "b", "c", "d", "e", "f").subList(3, 5),
 124                asList("a", "b", "c", "d", "e", "f").subList(3, 5)),
 125             a(List.of("a", "b", "c", "d", "e", "f", "g").subList(0, 7),
 126                asList("a", "b", "c", "d", "e", "f", "g").subList(0, 7)),
 127             a(List.of("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0),
 128                asList("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0)),
 129             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5),
 130                asList("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5)),
 131             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10),
 132                asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10)),
 133             a(List.of(stringArray).subList(5, NUM_STRINGS),
 134                asList(Arrays.copyOfRange(stringArray, 5, NUM_STRINGS)))
 135                 ).iterator();
 136     }
 137 
 138     @DataProvider(name="all")
 139     public Iterator<Object[]> all() {
 140         List<Object[]> all = new ArrayList<>();
 141         empty().forEachRemaining(all::add);
 142         nonempty().forEachRemaining(all::add);
 143         sublists().forEachRemaining(all::add);
 144         return all.iterator();
 145     }
 146 
 147     @DataProvider(name="nonsublists")
 148     public Iterator<Object[]> nonsublists() {
 149         List<Object[]> all = new ArrayList<>();
 150         empty().forEachRemaining(all::add);
 151         nonempty().forEachRemaining(all::add);
 152         return all.iterator();
 153     }
 154 
 155     @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
 156     public void cannotAddLast(List<String> act, List<String> exp) {
 157         act.add("x");
 158     }
 159 
 160     @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
 161     public void cannotAddFirst(List<String> act, List<String> exp) {
 162         act.add(0, "x");
 163     }
 164 
 165     @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
 166     public void cannotRemove(List<String> act, List<String> exp) {
 167         act.remove(0);
 168     }
 169 
 170     @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
 171     public void cannotSet(List<String> act, List<String> exp) {
 172         act.set(0, "x");
 173     }
 174 
 175     @Test(dataProvider="all")
 176     public void contentsMatch(List<String> act, List<String> exp) {
 177         assertEquals(act, exp);
 178     }
 179 
 180     @Test(expectedExceptions=NullPointerException.class)
 181     public void nullDisallowed1() {
 182         List.of((Object)null); // force one-arg overload
 183     }
 184 
 185     @Test(expectedExceptions=NullPointerException.class)
 186     public void nullDisallowed2a() {
 187         List.of("a", null);
 188     }
 189 
 190     @Test(expectedExceptions=NullPointerException.class)
 191     public void nullDisallowed2b() {
 192         List.of(null, "b");
 193     }
 194 
 195     @Test(expectedExceptions=NullPointerException.class)
 196     public void nullDisallowed3() {
 197         List.of("a", "b", null);
 198     }
 199 
 200     @Test(expectedExceptions=NullPointerException.class)
 201     public void nullDisallowed4() {
 202         List.of("a", "b", "c", null);
 203     }
 204 
 205     @Test(expectedExceptions=NullPointerException.class)
 206     public void nullDisallowed5() {
 207         List.of("a", "b", "c", "d", null);
 208     }
 209 
 210     @Test(expectedExceptions=NullPointerException.class)
 211     public void nullDisallowed6() {
 212         List.of("a", "b", "c", "d", "e", null);
 213     }
 214 
 215     @Test(expectedExceptions=NullPointerException.class)
 216     public void nullDisallowed7() {
 217         List.of("a", "b", "c", "d", "e", "f", null);
 218     }
 219 
 220     @Test(expectedExceptions=NullPointerException.class)
 221     public void nullDisallowed8() {
 222         List.of("a", "b", "c", "d", "e", "f", "g", null);
 223     }
 224 
 225     @Test(expectedExceptions=NullPointerException.class)
 226     public void nullDisallowed9() {
 227         List.of("a", "b", "c", "d", "e", "f", "g", "h", null);
 228     }
 229 
 230     @Test(expectedExceptions=NullPointerException.class)
 231     public void nullDisallowed10() {
 232         List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
 233     }
 234 
 235     @Test(expectedExceptions=NullPointerException.class)
 236     public void nullDisallowedN() {
 237         String[] array = stringArray.clone();
 238         array[0] = null;
 239         List.of(array);
 240     }
 241 
 242     @Test(expectedExceptions=NullPointerException.class)
 243     public void nullArrayDisallowed() {
 244         List.of((Object[])null);
 245     }
 246 
 247     @Test
 248     public void ensureArrayCannotModifyList() {
 249         String[] array = stringArray.clone();
 250         List<String> list = List.of(array);
 251         array[0] = "xyzzy";
 252         assertEquals(list, Arrays.asList(stringArray));
 253     }
 254 
 255     @Test
 256     public void indexOf() {
 257         assertEquals(List.of("a").indexOf("a"), 0);
 258         assertEquals(List.of("a", "a").indexOf("a"), 0);
 259         assertEquals(List.of("b", "a", "a").indexOf("a"), 1);
 260         assertEquals(List.of("b", "b", "a", "a").indexOf("a"), 2);
 261         assertEquals(List.of("b", "b", "b", "a", "a").indexOf("a"), 3);
 262         assertEquals(List.of("b", "b", "b", "b", "a", "a").indexOf("a"), 4);
 263 
 264         assertEquals(List.of("a").subList(0, 1).indexOf("a"), 0);
 265         assertEquals(List.of("a", "a").subList(0, 2).indexOf("a"), 0);
 266         assertEquals(List.of("b", "a", "a").subList(0, 3).indexOf("a"), 1);
 267         assertEquals(List.of("b", "b", "a", "a").subList(0, 4).indexOf("a"), 2);
 268         assertEquals(List.of("b", "b", "b", "a", "a").subList(0, 5).indexOf("a"), 3);
 269         assertEquals(List.of("b", "b", "b", "b", "a", "a").subList(0, 6).indexOf("a"), 4);
 270 
 271         assertEquals(List.of("a").lastIndexOf("a"), 0);
 272         assertEquals(List.of("a", "a").lastIndexOf("a"), 1);
 273         assertEquals(List.of("b", "a", "a").lastIndexOf("a"), 2);
 274         assertEquals(List.of("b", "b", "a", "a").lastIndexOf("a"), 3);
 275         assertEquals(List.of("b", "b", "b", "a", "a").lastIndexOf("a"), 4);
 276         assertEquals(List.of("b", "b", "b", "b", "a", "a").lastIndexOf("a"), 5);
 277 
 278         assertEquals(List.of("a").subList(0, 1).lastIndexOf("a"), 0);
 279         assertEquals(List.of("a", "a").subList(0, 2).lastIndexOf("a"), 1);
 280         assertEquals(List.of("b", "a", "a").subList(0, 3).lastIndexOf("a"), 2);
 281         assertEquals(List.of("b", "b", "a", "a").subList(0, 4).lastIndexOf("a"), 3);
 282         assertEquals(List.of("b", "b", "b", "a", "a").subList(0, 5).lastIndexOf("a"), 4);
 283         assertEquals(List.of("b", "b", "b", "b", "a", "a").subList(0, 6).lastIndexOf("a"), 5);
 284     }
 285 
 286     // List.of().subList views should not be Serializable
 287     @Test(dataProvider="sublists")
 288     public void isNotSerializable(List<String> act, List<String> exp) {
 289         assertFalse(act instanceof Serializable);
 290     }
 291 
 292     // ... but List.of() should be
 293     @Test(dataProvider="nonsublists")
 294     public void serialEquality(List<String> act, List<String> exp) {
 295         // assume that act.equals(exp) tested elsewhere
 296         List<String> copy = serialClone(act);
 297         assertEquals(act, copy);
 298         assertEquals(copy, exp);
 299     }
 300 
 301     @SuppressWarnings("unchecked")
 302     static <T> T serialClone(T obj) {
 303         try {
 304             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 305             try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
 306                 oos.writeObject(obj);
 307             }
 308             ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 309             ObjectInputStream ois = new ObjectInputStream(bais);
 310             return (T) ois.readObject();
 311         } catch (IOException | ClassNotFoundException e) {
 312             throw new AssertionError(e);
 313         }
 314     }
 315 
 316     List<Integer> genList() {
 317         return new ArrayList<>(Arrays.asList(1, 2, 3));
 318     }
 319 
 320     @Test
 321     public void copyOfResultsEqual() {
 322         List<Integer> orig = genList();
 323         List<Integer> copy = List.copyOf(orig);
 324 
 325         assertEquals(orig, copy);
 326         assertEquals(copy, orig);
 327     }
 328 
 329     @Test
 330     public void copyOfModifiedUnequal() {
 331         List<Integer> orig = genList();
 332         List<Integer> copy = List.copyOf(orig);
 333         orig.add(4);
 334 
 335         assertNotEquals(orig, copy);
 336         assertNotEquals(copy, orig);
 337     }
 338 
 339     @Test
 340     public void copyOfIdentity() {
 341         List<Integer> orig = genList();
 342         List<Integer> copy1 = List.copyOf(orig);
 343         List<Integer> copy2 = List.copyOf(copy1);
 344 
 345         assertNotSame(orig, copy1);
 346         assertSame(copy1, copy2);
 347     }
 348 
 349     @Test(expectedExceptions=NullPointerException.class)
 350     public void copyOfRejectsNullCollection() {
 351         List<Integer> list = List.copyOf(null);
 352     }
 353 
 354     @Test(expectedExceptions=NullPointerException.class)
 355     public void copyOfRejectsNullElements() {
 356         List<Integer> list = List.copyOf(Arrays.asList(1, null, 3));
 357     }
 358 }