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