1/*
2 * Copyright (c) 2006, 2015, 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/*
25 * @test
26 * @bug 6267067 6351336 6389198
27 * @summary unit test for javac List
28 * @modules jdk.compiler/com.sun.tools.javac.util
29 */
30
31import java.util.*;
32import com.sun.tools.javac.util.List;
33
34public class TList {
35    public static void main(String[] args) {
36        new TList().run();
37    }
38
39    String[][] data = {
40        { },
41        { "1" },
42        { "1", "2" },
43        { "1", "2" }, // different but equal
44        { "1", "2", "3", "4", "X", "X", "X", "8", "9", "10" } // contains duplicates
45    };
46
47    Map<java.util.List<String>,List<String>> examples;
48
49    void run() {
50        examples = new LinkedHashMap<java.util.List<String>,List<String>>();
51        for (String[] values: data)
52            examples.put(Arrays.asList(values), createList(values));
53
54        // 6351336: com.sun.tools.javac.util.List shouldn't extend java.util.AbstractList
55        test_AbstractList();
56
57        // general unit tests for java.util.List methods, including...
58        // 6389198: com.sun.tools.javac.util.List.equals() violates java.util.List.equals() contract
59        test_add_E();
60        test_add_int_E();
61        test_addAll_Collection();
62        test_addAll_int_Collection();
63        test_clear();
64        test_contains_Object();
65        test_contains_All();
66        test_equals_Object();
67        test_get_int();
68        test_hashCode();
69        test_indexOf_Object();
70        test_isEmpty();
71        test_iterator();
72        test_lastIndexOf_Object();
73        test_listIterator();
74        test_listIterator_int();
75        test_remove_int();
76        test_remove_Object();
77        test_removeAll_Collection();
78        test_retainAll_Collection();
79        test_set_int_E();
80        test_size();
81        test_subList_int_int();
82        test_toArray();
83        test_toArray_TArray();
84
85        // tests for additional methods
86        test_prependList_List();
87        test_reverse();
88    }
89
90    // 6351336
91    void test_AbstractList() {
92        System.err.println("test AbstractList");
93        if (AbstractList.class.isAssignableFrom(List.class))
94            throw new AssertionError();
95    }
96
97    void test_add_E() {
98        System.err.println("test add(E)");
99        for (List<String> l: examples.values()) {
100            try {
101                l.add("test");
102                throw new AssertionError();
103            } catch (UnsupportedOperationException ex) {
104            }
105        }
106    }
107
108    void test_add_int_E() {
109        System.err.println("test add(int,E)");
110        for (List<String> l: examples.values()) {
111            try {
112                l.add(0, "test");
113                throw new AssertionError();
114            } catch (UnsupportedOperationException ex) {
115            }
116        }
117    }
118
119    void test_addAll_Collection() {
120        System.err.println("test addAll(Collection)");
121        for (List<String> l: examples.values()) {
122            int l_size = l.size();
123            for (java.util.List<String> arg: examples.keySet()) {
124                try {
125                    boolean modified = l.addAll(arg);
126                    if (modified)
127                        throw new AssertionError();
128                } catch (UnsupportedOperationException e) {
129                }
130                if (l.size() != l_size)
131                    throw new AssertionError();
132            }
133        }
134    }
135
136    void test_addAll_int_Collection() {
137        System.err.println("test addAll(int,Collection)");
138        for (List<String> l: examples.values()) {
139            int l_size = l.size();
140            for (java.util.List<String> arg: examples.keySet()) {
141                try {
142                    boolean modified = l.addAll(0, arg);
143                    if (modified)
144                        throw new AssertionError();
145                } catch (UnsupportedOperationException e) {
146                }
147                if (l.size() != l_size)
148                    throw new AssertionError();
149            }
150        }
151    }
152
153    void test_clear() {
154        System.err.println("test clear()");
155        for (List<String> l: examples.values()) {
156            int l_size = l.size();
157            try {
158                l.clear();
159                if (l_size > 0)
160                    throw new AssertionError();
161            } catch (UnsupportedOperationException e) {
162            }
163            if (l.size() != l_size)
164                throw new AssertionError();
165        }
166    }
167
168    void test_contains_Object() {
169        System.err.println("test contains(Object)");
170        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
171            java.util.List<String> ref = e.getKey();
172            List<String> l = e.getValue();
173            boolean expect = ref.contains("1");
174            boolean found = l.contains("1");
175            if (expect != found)
176                throw new AssertionError();
177        }
178    }
179
180    void test_contains_All() {
181        System.err.println("test containsAll()");
182        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
183            java.util.List<String> ref = e.getKey();
184            List<String> l = e.getValue();
185            for (java.util.List<String> arg: examples.keySet()) {
186                boolean expect = ref.containsAll(arg);
187                boolean found = l.containsAll(arg);
188                if (expect != found)
189                    throw new AssertionError();
190            }
191        }
192    }
193
194    // 6389198
195    void test_equals_Object() {
196        System.err.println("test equals(Object)");
197        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
198            java.util.List<String> ref = e.getKey();
199            List<String> l = e.getValue();
200            for (java.util.List<String> arg: examples.keySet()) {
201                boolean expect = ref.equals(arg);
202                boolean found = l.equals(arg);
203                if (expect != found) {
204                    System.err.println("ref: " + ref);
205                    System.err.println("l: " + l);
206                    System.err.println("arg: " + arg);
207                    System.err.println("expect: " + expect + ", found: " + found);
208                    throw new AssertionError();
209                }
210            }
211        }
212    }
213
214    void test_get_int() {
215        System.err.println("test get(int)");
216        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
217            java.util.List<String> ref = e.getKey();
218            List<String> l = e.getValue();
219            for (int i = -1; i <= ref.size(); i++) {
220                boolean expectException = i < 0 || i >= ref.size();
221                String expectValue = (expectException ? null : ref.get(i));
222                try {
223                    String foundValue = l.get(i);
224                    if (expectException || !equal(expectValue, foundValue))
225                        throw new AssertionError();
226                } catch (IndexOutOfBoundsException ex) {
227                    if (!expectException)
228                        throw new AssertionError();
229                }
230            }
231        }
232    }
233
234    void test_hashCode() {
235        System.err.println("test hashCode()");
236        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
237            java.util.List<String> ref = e.getKey();
238            List<String> l = e.getValue();
239            long expect = ref.hashCode();
240            long found = l.hashCode();
241            if (expect != found) {
242                System.err.println("ref: " + ref);
243                System.err.println("l: " + l);
244                System.err.println("expect: " + expect);
245                System.err.println("found: " + found);
246                throw new AssertionError();
247            }
248        }
249    }
250
251    void test_indexOf_Object() {
252        System.err.println("test indexOf(Object)");
253        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
254            java.util.List<String> ref = e.getKey();
255            List<String> l = e.getValue();
256            for (int i = -1; i < ref.size(); i++) {
257                String arg = (i == -1 ? "NOT IN LIST" : ref.get(i));
258                int expect = ref.indexOf(arg);
259                int found = l.indexOf(arg);
260                if (expect != found)
261                    throw new AssertionError();
262            }
263        }
264    }
265
266    void test_isEmpty() {
267        System.err.println("test isEmpty()");
268        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
269            java.util.List<String> ref = e.getKey();
270            List<String> l = e.getValue();
271            boolean expect = ref.isEmpty();
272            boolean found = l.isEmpty();
273            if (expect != found)
274                throw new AssertionError();
275        }
276    }
277
278    void test_iterator() {
279        System.err.println("test iterator()");
280        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
281            java.util.List<String> ref = e.getKey();
282            List<String> l = e.getValue();
283            if (!equal(l.iterator(), ref.iterator()))
284                throw new AssertionError();
285        }
286    }
287
288    void test_lastIndexOf_Object() {
289        System.err.println("test lastIndexOf(Object)");
290        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
291            java.util.List<String> ref = e.getKey();
292            List<String> l = e.getValue();
293            for (int i = -1; i < ref.size(); i++) {
294                String arg = (i == -1 ? "NOT IN LIST" : ref.get(i));
295                int expect = ref.lastIndexOf(arg);
296                int found = l.lastIndexOf(arg);
297                if (expect != found)
298                    throw new AssertionError();
299            }
300        }
301    }
302
303    void test_listIterator() {
304        System.err.println("test listIterator()");
305        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
306            java.util.List<String> ref = e.getKey();
307            List<String> l = e.getValue();
308            if (!equal(l.listIterator(), ref.listIterator()))
309                throw new AssertionError();
310        }
311    }
312
313    void test_listIterator_int() {
314        System.err.println("test listIterator(int)");
315        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
316            java.util.List<String> ref = e.getKey();
317            List<String> l = e.getValue();
318            for (int i = 0; i < ref.size(); i++) {
319                if (!equal(l.listIterator(i), ref.listIterator(i)))
320                    throw new AssertionError();
321            }
322        }
323    }
324
325    void test_remove_int() {
326        System.err.println("test remove(int)");
327        for (List<String> l: examples.values()) {
328            try {
329                l.remove(0);
330                throw new AssertionError();
331            } catch (UnsupportedOperationException ex) {
332            }
333        }
334    }
335
336    void test_remove_Object() {
337        System.err.println("test remove(Object)");
338        for (List<String> l: examples.values()) {
339            boolean hasX = l.contains("X");
340            try {
341                l.remove("X");
342                if (hasX)
343                    throw new AssertionError();
344            } catch (UnsupportedOperationException ex) {
345            }
346        }
347    }
348
349    void test_removeAll_Collection() {
350        System.err.println("test removeAll(Collection)");
351        for (List<String> l: examples.values()) {
352            int l_size = l.size();
353            for (java.util.List<String> arg: examples.keySet()) {
354                try {
355                    boolean modified = l.removeAll(arg);
356                    if (modified)
357                        throw new AssertionError();
358                } catch (UnsupportedOperationException e) {
359                }
360                if (l.size() != l_size)
361                    throw new AssertionError();
362            }
363        }
364    }
365
366    void test_retainAll_Collection() {
367        System.err.println("test retainAll(Collection)");
368        for (List<String> l: examples.values()) {
369            int l_size = l.size();
370            for (java.util.List<String> arg: examples.keySet()) {
371                try {
372                    boolean modified = l.retainAll(arg);
373                    if (modified)
374                        throw new AssertionError();
375                } catch (UnsupportedOperationException e) {
376                }
377                if (l.size() != l_size)
378                    throw new AssertionError();
379            }
380        }
381    }
382
383    void test_set_int_E() {
384        System.err.println("test set(int,E)");
385        for (List<String> l: examples.values()) {
386            try {
387                l.set(0, "X");
388                throw new AssertionError();
389            } catch (UnsupportedOperationException ex) {
390            }
391        }
392    }
393
394    void test_size() {
395        System.err.println("test size()");
396        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
397            java.util.List<String> ref = e.getKey();
398            List<String> l = e.getValue();
399            int  expect = ref.size();
400            int found = l.size();
401            if (expect != found)
402                throw new AssertionError();
403        }
404    }
405
406    void test_subList_int_int() {
407        System.err.println("test subList(int,int)");
408        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
409            java.util.List<String> ref = e.getKey();
410            List<String> l = e.getValue();
411            for (int lwb = 0; lwb < ref.size(); lwb++) {
412                for (int upb = lwb; upb <= ref.size(); upb++) {
413                    if (!equal(l.subList(lwb, upb), ref.subList(lwb,upb)))
414                    throw new AssertionError();
415                }
416            }
417        }
418    }
419
420    void test_toArray() {
421        System.err.println("test toArray()");
422        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
423            java.util.List<String> ref = e.getKey();
424            List<String> l = e.getValue();
425            if (!equal(l.toArray(), ref.toArray()))
426                throw new AssertionError();
427        }
428    }
429
430    void test_toArray_TArray() {
431        System.err.println("test toArray(E[])");
432        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
433            java.util.List<String> ref = e.getKey();
434            List<String> l = e.getValue();
435            if (!equal(l.toArray(new String[0]), ref.toArray(new String[0])))
436                throw new AssertionError();
437        }
438    }
439
440    void test_prependList_List() {
441        System.err.println("test prependList(List<E>)");
442        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
443            java.util.List<String> ref = e.getKey();
444            List<String> l = e.getValue();
445            for (Map.Entry<java.util.List<String>, List<String>> arg_e: examples.entrySet()) {
446                java.util.List<String> arg_ref = arg_e.getKey();
447                List<String> arg = arg_e.getValue();
448                java.util.List<String> expect = join(arg, ref);
449                List<String> found = l.prependList(arg);
450                // verify results, and that original and arg lists are unchanged
451                if (!equal(expect, found)) {
452                    System.err.println("ref: " + ref);
453                    System.err.println("l: " + l);
454                    System.err.println("arg: " + arg);
455                    System.err.println("expect: " + expect);
456                    System.err.println("found: " + found);
457                    throw new AssertionError();
458                }
459                if (!equal(l, ref))
460                    throw new AssertionError();
461                if (!equal(arg, arg_ref))
462                    throw new AssertionError();
463            }
464        }
465    }
466
467    void test_reverse() {
468        System.err.println("test reverse()");
469        for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
470            java.util.List<String> ref = e.getKey();
471            List<String> l = e.getValue();
472            java.util.List<String> expect = reverse(ref);
473            List<String> found = l.reverse();
474            if (l.size() < 2 && found != l)  // reverse of empty or singleton list is itself
475                throw new AssertionError();
476            if (!equal(l, ref)) // orginal should be unchanged
477                throw new AssertionError();
478            if (!equal(expect, found))
479                throw new AssertionError();
480        }
481    }
482
483    static <T> com.sun.tools.javac.util.List<T> createList(List<T> d) {
484        com.sun.tools.javac.util.List<T> l = com.sun.tools.javac.util.List.nil();
485        for (ListIterator<T> iter = d.listIterator(d.size()); iter.hasPrevious(); )
486            l = l.prepend(iter.previous());
487        return l;
488    }
489
490    static <T> com.sun.tools.javac.util.List<T> createList(T... d) {
491        com.sun.tools.javac.util.List<T> l = com.sun.tools.javac.util.List.nil();
492        for (int i = d.length - 1; i >= 0; i--)
493            l = l.prepend(d[i]);
494        return l;
495    }
496
497    static <T> boolean equal(T t1, T t2) {
498        return (t1 == null ? t2 == null : t1.equals(t2));
499    }
500
501    static <T> boolean equal(Iterator<T> iter1, Iterator<T> iter2) {
502        if (iter1 == null || iter2 == null)
503            return (iter1 == iter2);
504
505        while (iter1.hasNext() && iter2.hasNext()) {
506            if (!equal(iter1.next(), iter2.next()))
507                return false;
508        }
509
510        return (!iter1.hasNext() && !iter2.hasNext());
511    }
512
513    static <T> boolean equal(ListIterator<T> iter1, ListIterator<T> iter2) {
514        if (iter1 == null || iter2 == null)
515            return (iter1 == iter2);
516
517        if (iter1.previousIndex() != iter2.previousIndex())
518            return false;
519
520        while (iter1.hasPrevious() && iter2.hasPrevious()) {
521            iter1.previous();
522            iter2.previous();
523        }
524
525        return equal((Iterator<T>) iter1, (Iterator<T>) iter2);
526    }
527
528    static <T> boolean equal(T[] a1, T[] a2) {
529        if (a1 == null || a2 == null)
530            return (a1 == a2);
531
532        if (a1.length != a2.length)
533            return false;
534
535        for (int i = 0; i < a1.length; i++) {
536            if (!equal(a1[i], a2[i]))
537                return false;
538        }
539
540        return true;
541    }
542
543    static <T> java.util.List<T> join(java.util.List<T>... lists) {
544        java.util.List<T> r = new ArrayList<T>();
545        for (java.util.List<T> l: lists)
546            r.addAll(l);
547        return r;
548    }
549
550    static <T> java.util.List<T> reverse(java.util.List<T> l) {
551        java.util.List<T> r = new ArrayList<T>(l.size());
552        for (T t: l)
553            r.add(0, t);
554        return r;
555    }
556}
557