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