1/*
2 * @test /nodynamiccopyright/
3 * @bug 6827009 8078561
4 * @summary Positive tests for strings in switch with few alternatives.
5 * @compile/fail/ref=OneCaseSwitches.out -XDrawDiagnostics -source 6 OneCaseSwitches.java
6 * @compile          OneCaseSwitches.java
7 * @run main OneCaseSwitches
8 * @author  Joseph D. Darcy
9 */
10
11import java.lang.reflect.*;
12import java.lang.annotation.*;
13import java.util.*;
14import static java.lang.annotation.RetentionPolicy.*;
15
16public class OneCaseSwitches {
17    @Retention(RUNTIME)
18    @interface TestMeForNull {}
19
20    @TestMeForNull
21    public static int zeroCasesNoDefault(String s, Set<String> stringSet, boolean expected) {
22        int failures = 0;
23        switch(s) {
24        }
25        return failures;
26    }
27
28    @TestMeForNull
29    public static int zeroCasesWithDefault(String s, Set<String> stringSet, boolean expected) {
30        int failures = 2;
31        boolean addResult;
32
33        switch(s) {
34        default:
35            failures = 0;
36            addResult = stringSet.add(s);
37            if (addResult != expected) {
38                failures++;
39                System.err.println("zeroCaseWithDefault: Expectedly got add result of " + addResult +
40                                   " on string " + s);
41            }
42        }
43
44        return failures;
45    }
46
47    @TestMeForNull
48    public static int zeroCasesWithDefaultBreak(String s, Set<String> stringSet, boolean expected) {
49        int failures = 2;
50        boolean addResult;
51
52        switch(s) {
53        default:
54            failures = zeroCasesWithDefault(s, stringSet, expected);
55            break;
56        }
57
58        return failures;
59    }
60
61    @TestMeForNull
62    public static int oneCaseNoDefault(String s, Set<String> stringSet, boolean expected) {
63        int failures = 2;
64        boolean addResult;
65
66        switch(s) {
67        case "foo":
68            failures = 0;
69            addResult = stringSet.add(s);
70            if (addResult != expected) {
71                failures++;
72                System.err.println("oneCaseNoDefault: Unexpectedly got add result of " + addResult +
73                                   " on string " + s);
74            }
75        }
76
77        return failures;
78    }
79
80    @TestMeForNull
81    public static int oneCaseNoDefaultBreak(String s, Set<String> stringSet, boolean expected) {
82        int failures = 2;
83        boolean addResult;
84
85        switch(s) {
86        case "foo":
87            failures = oneCaseNoDefaultBreak(s, stringSet, expected);
88            break;
89        }
90
91        return failures;
92    }
93
94    @TestMeForNull
95    public static int oneCaseWithDefault(String s, Set<String> stringSet, boolean expected) {
96        int failures = 2;
97        boolean addResult;;
98
99        switch(s) {
100        case "foo":
101            failures = 0;
102            addResult = stringSet.add(s);
103            if (addResult != expected) {
104                failures++;
105                System.err.println("oneCaseNoDefault: Expectedly got add result of " + addResult +
106                                   " on string " + s);
107            }
108            break;
109        default:
110            break;
111        }
112
113        return failures;
114    }
115
116    @TestMeForNull
117    public static int oneCaseBreakOnly(String s, Set<String> stringSet, boolean expected) {
118        int failures = 1;
119        switch(s) {
120        case "foo":
121            break;
122        }
123        failures = 0;
124        return failures;
125    }
126
127    @TestMeForNull
128    public static int oneCaseDefaultBreakOnly(String s, Set<String> stringSet, boolean expected) {
129        int failures = 1;
130        switch(s) {
131        default:
132            break;
133        }
134        failures = 0;
135        return failures;
136    }
137
138
139    static int testNullBehavior() {
140        int failures = 0;
141        int count = 0;
142
143        Method[] methods = OneCaseSwitches.class.getDeclaredMethods();
144
145        try {
146            for(Method method : methods) {
147                count++;
148                try {
149                    if (method.isAnnotationPresent(TestMeForNull.class)) {
150                        System.out.println("Testing method " + method);
151                        method.invoke(null, (String)null, emptyStringSet, false);
152                        failures++;
153                        System.err.println("Didn't get NPE as expected from " + method);
154                    }
155                } catch (InvocationTargetException ite) { // Expected
156                    Throwable targetException = ite.getTargetException();
157                    if (! (targetException instanceof NullPointerException)) {
158                        failures++; // Wrong exception thrown
159                        System.err.println("Didn't get expected target exception NPE, got " +
160                                           ite.getClass().getName());
161                    }
162                }
163            }
164        } catch (Exception e) {
165            throw new RuntimeException(e);
166        }
167
168        if (count == 0) {
169            failures++;
170            System.err.println("Did not find any annotated methods.");
171        }
172        return failures;
173    }
174
175    static int testZeroCases() {
176        int failures = 0;
177        Set<String> noDefaultSet = new HashSet<String>();
178        Set<String> defaultSet   = new HashSet<String>();
179
180        zeroCasesNoDefault(FOO, noDefaultSet, false);
181        for(String word : words) {
182            zeroCasesNoDefault(word, noDefaultSet, false);
183        }
184
185        if (!noDefaultSet.isEmpty()) {
186            failures++;
187            System.err.println("Non-empty set after zeroCasesNoDefault");
188        }
189
190        for(String word : words) {
191            zeroCasesWithDefault(word, defaultSet, true);
192        }
193        if (defaultSet.size() != words.length) {
194            failures++;
195            System.err.println("Missing strings after zeroCasesWithDefault");
196        }
197
198        return failures;
199    }
200
201    static int testOneCaseNoDefault() {
202        int failures = 0;
203        Set<String> s = new HashSet<String>();
204        s.add("foo");
205        Set<String> fooSet = Collections.unmodifiableSet(s);
206        Set<String> testSet   = new HashSet<String>();
207
208        oneCaseNoDefault(FOO, testSet, true);
209        if (!testSet.equals(fooSet)) {
210            failures++;
211            System.err.println("Unexpected result from oneCaseNoDefault: didn't get {\"Foo\"}");
212        }
213
214        for(String word : words) {
215            oneCaseNoDefault(word, testSet, false);
216        }
217        if (!testSet.equals(fooSet)) {
218            failures++;
219            System.err.println("Unexpected result from oneCaseNoDefault: didn't get {\"Foo\"}");
220        }
221
222        return failures;
223    }
224
225    static int testBreakOnly() {
226        int failures = 0;
227
228        for(String word : words) {
229            failures += oneCaseBreakOnly(word, emptyStringSet, true);
230            failures += oneCaseDefaultBreakOnly(word, emptyStringSet, true);
231        }
232
233        return failures;
234    }
235
236    static int testExpressionEval() {
237        String s = "a";
238        int errors = 2;
239
240        System.out.println("Testing expression evaluation.");
241
242        switch (s + s) {
243        case "aa":
244            errors = 0;
245            break;
246
247        case "aaaa":
248            errors = 1;
249            System.err.println("Suspected bad expression evaluation.");
250            break;
251
252        default:
253             throw new RuntimeException("Should not reach here.");
254        }
255        return errors;
256    }
257
258    static final String FOO = "foo";
259
260    static final String[] words = {"baz",
261                                   "quux",
262                                   "wombat",
263                                   "\u0ccc\u0012"}; // hash collision with "foo"
264
265    final static Set<String> emptyStringSet = Collections.emptySet();
266
267    public static void main(String... args) {
268        int failures = 0;
269
270        failures += testNullBehavior();
271        failures += testZeroCases();
272        failures += testOneCaseNoDefault();
273        failures += testBreakOnly();
274        failures += testExpressionEval();
275
276        if (failures > 0) {
277            throw new RuntimeException();
278        }
279    }
280}
281