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.util.ArrayList;
  30 import java.util.Arrays;
  31 import java.util.Collections;
  32 import java.util.Iterator;
  33 import java.util.List;
  34 
  35 import org.testng.annotations.DataProvider;
  36 import org.testng.annotations.Test;
  37 
  38 import static java.util.Arrays.asList;
  39 
  40 import static org.testng.Assert.assertEquals;
  41 import static org.testng.Assert.assertFalse;
  42 import static org.testng.Assert.assertNotEquals;
  43 import static org.testng.Assert.assertNotSame;
  44 import static org.testng.Assert.assertSame;
  45 import static org.testng.Assert.assertTrue;
  46 import static org.testng.Assert.fail;
  47 
  48 /*
  49  * @test
  50  * @bug 8048330
  51  * @summary Test convenience static factory methods on List.
  52  * @run testng ListFactories
  53  */
  54 
  55 public class ListFactories {
  56 
  57     static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
  58     static final String[] stringArray;
  59     static {
  60         String[] sa = new String[NUM_STRINGS];
  61         for (int i = 0; i < NUM_STRINGS; i++) {
  62             sa[i] = String.valueOf((char)('a' + i));
  63         }
  64         stringArray = sa;
  65     }
  66 
  67     // returns array of [actual, expected]
  68     static Object[] a(List<String> act, List<String> exp) {
  69         return new Object[] { act, exp };
  70     }
  71 
  72     @DataProvider(name="empty")
  73     public Iterator<Object[]> empty() {
  74         return Collections.singletonList(
  75             a(List.of(), Collections.emptyList())
  76         ).iterator();
  77     }
  78 
  79     @DataProvider(name="nonempty")
  80     public Iterator<Object[]> nonempty() {
  81         return asList(
  82             a(List.of("a"),
  83                asList("a")),
  84             a(List.of("a", "b"),
  85                asList("a", "b")),
  86             a(List.of("a", "b", "c"),
  87                asList("a", "b", "c")),
  88             a(List.of("a", "b", "c", "d"),
  89                asList("a", "b", "c", "d")),
  90             a(List.of("a", "b", "c", "d", "e"),
  91                asList("a", "b", "c", "d", "e")),
  92             a(List.of("a", "b", "c", "d", "e", "f"),
  93                asList("a", "b", "c", "d", "e", "f")),
  94             a(List.of("a", "b", "c", "d", "e", "f", "g"),
  95                asList("a", "b", "c", "d", "e", "f", "g")),
  96             a(List.of("a", "b", "c", "d", "e", "f", "g", "h"),
  97                asList("a", "b", "c", "d", "e", "f", "g", "h")),
  98             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
  99                asList("a", "b", "c", "d", "e", "f", "g", "h", "i")),
 100             a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
 101                asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
 102             a(List.of(stringArray),
 103                asList(stringArray))
 104         ).iterator();
 105     }
 106 
 107     @DataProvider(name="all")
 108     public Iterator<Object[]> all() {
 109         List<Object[]> all = new ArrayList<>();
 110         empty().forEachRemaining(all::add);
 111         nonempty().forEachRemaining(all::add);
 112         return all.iterator();
 113     }
 114 
 115     @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
 116     public void cannotAddLast(List<String> act, List<String> exp) {
 117         act.add("x");
 118     }
 119 
 120     @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
 121     public void cannotAddFirst(List<String> act, List<String> exp) {
 122         act.add(0, "x");
 123     }
 124 
 125     @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
 126     public void cannotRemove(List<String> act, List<String> exp) {
 127         act.remove(0);
 128     }
 129 
 130     @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
 131     public void cannotSet(List<String> act, List<String> exp) {
 132         act.set(0, "x");
 133     }
 134 
 135     @Test(dataProvider="all")
 136     public void contentsMatch(List<String> act, List<String> exp) {
 137         assertEquals(act, exp);
 138     }
 139 
 140     @Test(expectedExceptions=NullPointerException.class)
 141     public void nullDisallowed1() {
 142         List.of((Object)null); // force one-arg overload
 143     }
 144 
 145     @Test(expectedExceptions=NullPointerException.class)
 146     public void nullDisallowed2a() {
 147         List.of("a", null);
 148     }
 149 
 150     @Test(expectedExceptions=NullPointerException.class)
 151     public void nullDisallowed2b() {
 152         List.of(null, "b");
 153     }
 154 
 155     @Test(expectedExceptions=NullPointerException.class)
 156     public void nullDisallowed3() {
 157         List.of("a", "b", null);
 158     }
 159 
 160     @Test(expectedExceptions=NullPointerException.class)
 161     public void nullDisallowed4() {
 162         List.of("a", "b", "c", null);
 163     }
 164 
 165     @Test(expectedExceptions=NullPointerException.class)
 166     public void nullDisallowed5() {
 167         List.of("a", "b", "c", "d", null);
 168     }
 169 
 170     @Test(expectedExceptions=NullPointerException.class)
 171     public void nullDisallowed6() {
 172         List.of("a", "b", "c", "d", "e", null);
 173     }
 174 
 175     @Test(expectedExceptions=NullPointerException.class)
 176     public void nullDisallowed7() {
 177         List.of("a", "b", "c", "d", "e", "f", null);
 178     }
 179 
 180     @Test(expectedExceptions=NullPointerException.class)
 181     public void nullDisallowed8() {
 182         List.of("a", "b", "c", "d", "e", "f", "g", null);
 183     }
 184 
 185     @Test(expectedExceptions=NullPointerException.class)
 186     public void nullDisallowed9() {
 187         List.of("a", "b", "c", "d", "e", "f", "g", "h", null);
 188     }
 189 
 190     @Test(expectedExceptions=NullPointerException.class)
 191     public void nullDisallowed10() {
 192         List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
 193     }
 194 
 195     @Test(expectedExceptions=NullPointerException.class)
 196     public void nullDisallowedN() {
 197         String[] array = stringArray.clone();
 198         array[0] = null;
 199         List.of(array);
 200     }
 201 
 202     @Test(expectedExceptions=NullPointerException.class)
 203     public void nullArrayDisallowed() {
 204         List.of((Object[])null);
 205     }
 206 
 207     @Test
 208     public void ensureArrayCannotModifyList() {
 209         String[] array = stringArray.clone();
 210         List<String> list = List.of(array);
 211         array[0] = "xyzzy";
 212         assertEquals(list, Arrays.asList(stringArray));
 213     }
 214 
 215     @Test(dataProvider="all")
 216     public void serialEquality(List<String> act, List<String> exp) {
 217         // assume that act.equals(exp) tested elsewhere
 218         List<String> copy = serialClone(act);
 219         assertEquals(act, copy);
 220         assertEquals(copy, exp);
 221     }
 222 
 223     @SuppressWarnings("unchecked")
 224     static <T> T serialClone(T obj) {
 225         try {
 226             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 227             try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
 228                 oos.writeObject(obj);
 229             }
 230             ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 231             ObjectInputStream ois = new ObjectInputStream(bais);
 232             return (T) ois.readObject();
 233         } catch (IOException | ClassNotFoundException e) {
 234             throw new AssertionError(e);
 235         }
 236     }
 237 
 238     List<Integer> genList() {
 239         return new ArrayList<>(Arrays.asList(1, 2, 3));
 240     }
 241 
 242     @Test
 243     public void copyOfResultsEqual() {
 244         List<Integer> orig = genList();
 245         List<Integer> copy = List.copyOf(orig);
 246 
 247         assertEquals(orig, copy);
 248         assertEquals(copy, orig);
 249     }
 250 
 251     @Test
 252     public void copyOfModifiedUnequal() {
 253         List<Integer> orig = genList();
 254         List<Integer> copy = List.copyOf(orig);
 255         orig.add(4);
 256 
 257         assertNotEquals(orig, copy);
 258         assertNotEquals(copy, orig);
 259     }
 260 
 261     @Test
 262     public void copyOfIdentity() {
 263         List<Integer> orig = genList();
 264         List<Integer> copy1 = List.copyOf(orig);
 265         List<Integer> copy2 = List.copyOf(copy1);
 266 
 267         assertNotSame(orig, copy1);
 268         assertSame(copy1, copy2);
 269     }
 270 
 271     @Test(expectedExceptions=NullPointerException.class)
 272     public void copyOfRejectsNullCollection() {
 273         List<Integer> list = List.copyOf(null);
 274     }
 275 
 276     @Test(expectedExceptions=NullPointerException.class)
 277     public void copyOfRejectsNullElements() {
 278         List<Integer> list = List.copyOf(Arrays.asList(1, null, 3));
 279     }
 280 }