1 |
/* |
2 |
* Written by Martin Buchholz with assistance from members of JCP JSR-166 |
3 |
* Expert Group and released to the public domain, as explained at |
4 |
* http://creativecommons.org/publicdomain/zero/1.0/ |
5 |
*/ |
6 |
|
7 |
/* |
8 |
* @test |
9 |
* @bug 6950540 |
10 |
* @summary Attempt to add a null throws NullPointerException |
11 |
*/ |
12 |
|
13 |
import java.util.ArrayList; |
14 |
import java.util.Collection; |
15 |
import java.util.Comparator; |
16 |
import java.util.PriorityQueue; |
17 |
import java.util.SortedSet; |
18 |
import java.util.TreeSet; |
19 |
import java.util.concurrent.ArrayBlockingQueue; |
20 |
import java.util.concurrent.LinkedBlockingDeque; |
21 |
import java.util.concurrent.LinkedBlockingQueue; |
22 |
import java.util.concurrent.PriorityBlockingQueue; |
23 |
|
24 |
public class NoNulls { |
25 |
void test(String[] args) throws Throwable { |
26 |
final Comparator<String> nullTolerantComparator |
27 |
= new Comparator<>() { |
28 |
public int compare(String x, String y) { |
29 |
return (x == null ? -1 : |
30 |
y == null ? 1 : |
31 |
x.compareTo(y)); |
32 |
}}; |
33 |
|
34 |
final SortedSet<String> nullSortedSet |
35 |
= new TreeSet<>(nullTolerantComparator); |
36 |
nullSortedSet.add(null); |
37 |
|
38 |
final PriorityQueue<String> nullPriorityQueue |
39 |
= new PriorityQueue<>() { |
40 |
public Object[] toArray() { return new Object[] { null };}}; |
41 |
|
42 |
final Collection<String> nullCollection = new ArrayList<>(); |
43 |
nullCollection.add(null); |
44 |
|
45 |
THROWS(NullPointerException.class, |
46 |
new F() { void f() { |
47 |
new PriorityQueue<String>(nullCollection); |
48 |
}}, |
49 |
new F() { void f() { |
50 |
new PriorityBlockingQueue<String>(nullCollection); |
51 |
}}, |
52 |
new F() { void f() { |
53 |
new ArrayBlockingQueue<String>(10, false, nullCollection); |
54 |
}}, |
55 |
new F() { void f() { |
56 |
new ArrayBlockingQueue<String>(10, true, nullCollection); |
57 |
}}, |
58 |
new F() { void f() { |
59 |
new LinkedBlockingQueue<String>(nullCollection); |
60 |
}}, |
61 |
new F() { void f() { |
62 |
new LinkedBlockingDeque<String>(nullCollection); |
63 |
}}, |
64 |
|
65 |
new F() { void f() { |
66 |
new PriorityQueue<String>((Collection<String>) nullPriorityQueue); |
67 |
}}, |
68 |
new F() { void f() { |
69 |
new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue); |
70 |
}}, |
71 |
|
72 |
new F() { void f() { |
73 |
new PriorityQueue<String>(nullSortedSet); |
74 |
}}, |
75 |
new F() { void f() { |
76 |
new PriorityBlockingQueue<String>(nullSortedSet); |
77 |
}}, |
78 |
|
79 |
new F() { void f() { |
80 |
new PriorityQueue<String>((Collection<String>) nullSortedSet); |
81 |
}}, |
82 |
new F() { void f() { |
83 |
new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet); |
84 |
}}, |
85 |
|
86 |
new F() { void f() { |
87 |
new PriorityQueue<String>(nullPriorityQueue); |
88 |
}}, |
89 |
new F() { void f() { |
90 |
new PriorityBlockingQueue<String>(nullPriorityQueue); |
91 |
}}, |
92 |
|
93 |
new F() { void f() { |
94 |
new PriorityQueue<String>().add(null); |
95 |
}}, |
96 |
new F() { void f() { |
97 |
new PriorityBlockingQueue<String>().add(null); |
98 |
}}, |
99 |
new F() { void f() { |
100 |
new ArrayBlockingQueue<String>(10, false).add(null); |
101 |
}}, |
102 |
new F() { void f() { |
103 |
new ArrayBlockingQueue<String>(10, true).add(null); |
104 |
}}, |
105 |
new F() { void f() { |
106 |
new LinkedBlockingQueue<String>().add(null); |
107 |
}}, |
108 |
new F() { void f() { |
109 |
new LinkedBlockingDeque<String>().add(null); |
110 |
}}, |
111 |
|
112 |
new F() { void f() { |
113 |
new PriorityQueue<String>().offer(null); |
114 |
}}, |
115 |
new F() { void f() { |
116 |
new PriorityBlockingQueue<String>().offer(null); |
117 |
}}); |
118 |
|
119 |
nullSortedSet.add("foo"); |
120 |
nullCollection.add("foo"); |
121 |
THROWS(NullPointerException.class, |
122 |
new F() { void f() { |
123 |
new PriorityQueue<String>(nullCollection); |
124 |
}}, |
125 |
new F() { void f() { |
126 |
new PriorityBlockingQueue<String>(nullCollection); |
127 |
}}, |
128 |
|
129 |
new F() { void f() { |
130 |
new PriorityQueue<String>((Collection<String>) nullPriorityQueue); |
131 |
}}, |
132 |
new F() { void f() { |
133 |
new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue); |
134 |
}}, |
135 |
|
136 |
new F() { void f() { |
137 |
new PriorityQueue<String>(nullSortedSet); |
138 |
}}, |
139 |
new F() { void f() { |
140 |
new PriorityBlockingQueue<String>(nullSortedSet); |
141 |
}}, |
142 |
|
143 |
new F() { void f() { |
144 |
new PriorityQueue<String>((Collection<String>) nullSortedSet); |
145 |
}}, |
146 |
new F() { void f() { |
147 |
new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet); |
148 |
}}); |
149 |
|
150 |
} |
151 |
|
152 |
//--------------------- Infrastructure --------------------------- |
153 |
volatile int passed = 0, failed = 0; |
154 |
void pass() {passed++;} |
155 |
void fail() {failed++; Thread.dumpStack();} |
156 |
void fail(String msg) {System.err.println(msg); fail();} |
157 |
void unexpected(Throwable t) {failed++; t.printStackTrace();} |
158 |
void check(boolean cond) {if (cond) pass(); else fail();} |
159 |
void equal(Object x, Object y) { |
160 |
if (x == null ? y == null : x.equals(y)) pass(); |
161 |
else fail(x + " not equal to " + y);} |
162 |
public static void main(String[] args) throws Throwable { |
163 |
new NoNulls().instanceMain(args);} |
164 |
public void instanceMain(String[] args) throws Throwable { |
165 |
try {test(args);} catch (Throwable t) {unexpected(t);} |
166 |
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
167 |
if (failed > 0) throw new AssertionError("Some tests failed");} |
168 |
abstract class F {abstract void f() throws Throwable;} |
169 |
void THROWS(Class<? extends Throwable> k, F... fs) { |
170 |
for (F f : fs) |
171 |
try {f.f(); fail("Expected " + k.getName() + " not thrown");} |
172 |
catch (Throwable t) { |
173 |
if (k.isAssignableFrom(t.getClass())) pass(); |
174 |
else unexpected(t);}} |
175 |
} |