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 
  11 import java.lang.reflect.*;
  12 import java.lang.annotation.*;
  13 import java.util.*;
  14 import static java.lang.annotation.RetentionPolicy.*;
  15 
  16 public 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 }