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