1 /*
   2  * Copyright (c) 2003, 2015, 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 4313885 4926319 4927634 5032610 5032622 5049968 5059533 6223711 6277261 6269946 6288823
  27  * @summary Basic tests of java.util.Scanner methods
  28  * @key randomness
  29  * @run main/othervm ScanTest
  30  */
  31 
  32 import java.util.*;
  33 import java.text.*;
  34 import java.io.*;
  35 import java.nio.*;
  36 import java.util.regex.*;
  37 import java.math.*;
  38 
  39 public class ScanTest {
  40 
  41     private static boolean failure = false;
  42     private static int failCount = 0;
  43     private static int NUM_SOURCE_TYPES = 2;
  44 
  45     public static void main(String[] args) throws Exception {
  46         Locale reservedLocale = Locale.getDefault();
  47         String lang = reservedLocale.getLanguage();
  48         try {
  49             if (!"en".equals(lang) &&
  50                 !"zh".equals(lang) &&
  51                 !"ko".equals(lang) &&
  52                 !"ja".equals(lang)) {
  53                 //Before we have resource to improve the test to be ready for
  54                 //arbitrary locale, force the default locale to be "English"
  55                 //for now.
  56                 Locale.setDefault(Locale.ENGLISH);
  57             }
  58             skipTest();
  59             findInLineTest();
  60             findWithinHorizonTest();
  61             findInEmptyLineTest();
  62             removeTest();
  63             fromFileTest();
  64             ioExceptionTest();
  65             matchTest();
  66             delimiterTest();
  67             useLocaleTest();
  68             closeTest();
  69             cacheTest();
  70             cacheTest2();
  71             nonASCIITest();
  72             resetTest();
  73 
  74             for (int j=0; j<NUM_SOURCE_TYPES; j++) {
  75                 hasNextTest(j);
  76                 nextTest(j);
  77                 hasNextPatternTest(j);
  78                 nextPatternTest(j);
  79                 booleanTest(j);
  80                 byteTest(j);
  81                 shortTest(j);
  82                 intTest(j);
  83                 longTest(j);
  84                 floatTest(j);
  85                 doubleTest(j);
  86                 integerPatternTest(j);
  87                 floatPatternTest(j);
  88                 bigIntegerPatternTest(j);
  89                 bigDecimalPatternTest(j);
  90                 hasNextLineTest(j);
  91                 nextLineTest(j);
  92                 singleDelimTest(j);
  93             }
  94 
  95             // Examples
  96             //example1();
  97             //example2();
  98             //example3();
  99 
 100             // Usage cases
 101             useCase1();
 102             useCase2();
 103             useCase3();
 104             useCase4();
 105             useCase5();
 106 
 107             if (failure)
 108                 throw new RuntimeException("Failure in the scanning tests.");
 109             else
 110                 System.err.println("OKAY: All tests passed.");
 111         } finally {
 112             // restore the default locale
 113             Locale.setDefault(reservedLocale);
 114         }
 115     }
 116 
 117     public static void useCase1() throws Exception {
 118         File f = new File(System.getProperty("test.src", "."), "input.txt");
 119         Scanner sc = new Scanner(f);
 120         sc.findWithinHorizon("usage case 1", 0);
 121         String[] names = new String[4];
 122         for (int i=0; i<4; i++) {
 123             while(sc.hasNextFloat())
 124                 sc.nextFloat();
 125             names[i] = sc.next();
 126             sc.nextLine();
 127         }
 128         if (!names[0].equals("Frank"))
 129             failCount++;
 130         if (!names[1].equals("Joe"))
 131             failCount++;
 132         if (!names[2].equals("Mary"))
 133             failCount++;
 134         if (!names[3].equals("Michelle"))
 135             failCount++;
 136         sc.close();
 137         report("Use case 1");
 138     }
 139 
 140     public static void useCase2() throws Exception {
 141         File f = new File(System.getProperty("test.src", "."), "input.txt");
 142         Scanner sc = new Scanner(f).useDelimiter("-");
 143         String testDataTag = sc.findWithinHorizon("usage case 2\n", 0);
 144         if (!testDataTag.equals("usage case 2\n"))
 145             failCount++;
 146         if (!sc.next().equals("cat"))
 147             failCount++;
 148         if (sc.nextInt() != 9)
 149             failCount++;
 150         if (!sc.next().equals("dog"))
 151             failCount++;
 152         if (sc.nextInt() != 6)
 153             failCount++;
 154         if (!sc.next().equals("pig"))
 155             failCount++;
 156         if (sc.nextInt() != 2)
 157             failCount++;
 158         if (!sc.next().equals(""))
 159             failCount++;
 160         if (sc.nextInt() != 5)
 161             failCount++;
 162         sc.close();
 163         report("Use case 2");
 164     }
 165 
 166     public static void useCase3() throws Exception {
 167         File f = new File(System.getProperty("test.src", "."), "input.txt");
 168         Scanner sc = new Scanner(f);
 169         String testDataTag = sc.findWithinHorizon("usage case 3\n", 0);
 170         if (!testDataTag.equals("usage case 3\n"))
 171             failCount++;
 172         Pattern tagPattern = Pattern.compile("@[a-z]+");
 173         Pattern endPattern = Pattern.compile("\\*\\/");
 174         String tag;
 175         String end = sc.findInLine(endPattern);
 176 
 177         while (end == null) {
 178             if ((tag = sc.findInLine(tagPattern)) != null) {
 179                 String text = sc.nextLine();
 180                 text = text.substring(0, text.length() - 1);
 181                 //System.out.println(text);
 182             } else {
 183                 sc.nextLine();
 184             }
 185             end = sc.findInLine(endPattern);
 186         }
 187         report("Use case 3");
 188     }
 189 
 190     public static void useCase4() throws Exception {
 191         File f = new File(System.getProperty("test.src", "."), "input.txt");
 192         Scanner sc = new Scanner(f);
 193         String testDataTag = sc.findWithinHorizon("usage case 4\n", 0);
 194         if (!testDataTag.equals("usage case 4\n"))
 195             failCount++;
 196 
 197         // Read some text parts of four hrefs
 198         String[] expected = { "Diffs", "Sdiffs", "Old", "New" };
 199         for (int i=0; i<4; i++) {
 200             sc.findWithinHorizon("<a href", 1000);
 201             sc.useDelimiter("[<>\n]+");
 202             sc.next();
 203             String textOfRef = sc.next();
 204             if (!textOfRef.equals(expected[i]))
 205                 failCount++;
 206         }
 207         // Read some html tags using < and > as delimiters
 208         if (!sc.next().equals("/a"))
 209             failCount++;
 210         if (!sc.next().equals("b"))
 211             failCount++;
 212 
 213         // Scan some html tags using skip and next
 214         Pattern nonTagStart = Pattern.compile("[^<]+");
 215         Pattern tag = Pattern.compile("<[^>]+?>");
 216         Pattern spotAfterTag = Pattern.compile("(?<=>)");
 217         String[] expected2 = { "</b>", "<p>", "<ul>", "<li>" };
 218         sc.useDelimiter(spotAfterTag);
 219         int tagsFound = 0;
 220         while(tagsFound < 4) {
 221             if (!sc.hasNext(tag)) {
 222                 // skip text between tags
 223                 sc.skip(nonTagStart);
 224             }
 225             String tagContents = sc.next(tag);
 226             if (!tagContents.equals(expected2[tagsFound]))
 227                 failCount++;
 228             tagsFound++;
 229         }
 230 
 231         report("Use case 4");
 232     }
 233 
 234     public static void useCase5() throws Exception {
 235         File f = new File(System.getProperty("test.src", "."), "input.txt");
 236         Scanner sc = new Scanner(f);
 237         String testDataTag = sc.findWithinHorizon("usage case 5\n", 0);
 238         if (!testDataTag.equals("usage case 5\n"))
 239             failCount++;
 240 
 241         sc.findWithinHorizon("Share Definitions", 0);
 242         sc.nextLine();
 243         sc.next("\\[([a-z]+)\\]");
 244         String shareName = sc.match().group(1);
 245         if (!shareName.equals("homes"))
 246             failCount++;
 247 
 248         String[] keys = { "comment", "browseable", "writable", "valid users" };
 249         String[] vals = { "Home Directories", "no", "yes", "%S" };
 250         for (int i=0; i<4; i++) {
 251             sc.useDelimiter("=");
 252             String key = sc.next().trim();
 253             if (!key.equals(keys[i]))
 254                 failCount++;
 255             sc.skip("[ =]+");
 256             sc.useDelimiter("\n");
 257             String value = sc.next();
 258             if (!value.equals(vals[i]))
 259                 failCount++;
 260             sc.nextLine();
 261         }
 262 
 263         report("Use case 5");
 264     }
 265 
 266     public static void nonASCIITest() throws Exception {
 267         String yourBasicTibetanNumberZero = "\u0f20";
 268         String yourBasicTibetanFloatingNumber = "\u0f23.\u0f27";
 269         String weirdMixtureOfTibetanAndASCII = "\u0f23.7";
 270         String weirdMixtureOfASCIIAndTibetan = "3.\u0f27";
 271         Scanner sc = new Scanner(yourBasicTibetanNumberZero);
 272         int i = sc.nextInt();
 273         if (i != 0)
 274             failCount++;
 275         sc = new Scanner(yourBasicTibetanFloatingNumber);
 276         float f = sc.nextFloat();
 277         if (f != Float.parseFloat("3.7"))
 278             failCount++;
 279         sc = new Scanner(weirdMixtureOfTibetanAndASCII);
 280         f = sc.nextFloat();
 281         if (f != Float.parseFloat("3.7"))
 282             failCount++;
 283         sc = new Scanner(weirdMixtureOfASCIIAndTibetan);
 284         f = sc.nextFloat();
 285         if (f != Float.parseFloat("3.7"))
 286             failCount++;
 287         report("Scanning non ASCII digits");
 288     }
 289 
 290     public static void findWithinHorizonTest() throws Exception {
 291         // Test with a string source
 292         Scanner sc = new Scanner("dog  cat     cat    dog     cat");
 293         try {
 294             sc.findWithinHorizon("dog", -1);
 295             failCount++;
 296         } catch (IllegalArgumentException iae) {
 297             // Correct result
 298         }
 299         if (sc.findWithinHorizon("dog", 2) != null)
 300             failCount++;
 301         if (!sc.findWithinHorizon("dog", 3).equals("dog"))
 302             failCount++;
 303         if (sc.findWithinHorizon("cat", 4) != null)
 304             failCount++;
 305         if (!sc.findWithinHorizon("cat", 5).equals("cat"))
 306             failCount++;
 307          if (sc.findWithinHorizon("cat", 7) != null)
 308             failCount++;
 309         if (sc.findWithinHorizon("dog", 7) != null)
 310             failCount++;
 311         if (!sc.findWithinHorizon("cat", 0).equals("cat"))
 312             failCount++;
 313         if (!sc.findWithinHorizon("dog", 0).equals("dog"))
 314             failCount++;
 315         if (!sc.findWithinHorizon("cat", 0).equals("cat"))
 316             failCount++;
 317 
 318         // Test with a stream source
 319         StutteringInputStream stutter = new StutteringInputStream();
 320         for (int index=0; index<stutter.length(); index++) {
 321             //System.out.println("index is now "+index);
 322             sc = new Scanner(stutter);
 323             String word = stutter.wordInIndex(index);
 324             if (word != null) {
 325                 String result = sc.findWithinHorizon(word, index);
 326                 if ((result == null) || (!result.equals(word)))
 327                     failCount++;
 328             }
 329             stutter.reset();
 330             word = stutter.wordBeyondIndex(index);
 331             sc = new Scanner(stutter);
 332             String result = sc.findWithinHorizon(word, index);
 333             if ((result != null) && (index > 0))
 334                 failCount++;
 335             stutter.reset();
 336         }
 337 
 338         // We must loop to let StutteringInputStream do its magic
 339         for (int j=0; j<10; j++) {
 340             // An anchor at the end of stream should work
 341             stutter.reset();
 342             sc = new Scanner(stutter);
 343             String result = sc.findWithinHorizon("phant$", 0);
 344             if (!result.equals("phant"))
 345                 failCount++;
 346             stutter.reset();
 347             sc = new Scanner(stutter);
 348             result = sc.findWithinHorizon("phant$", 54);
 349             if (!result.equals("phant"))
 350                 failCount++;
 351             // An anchor at the end of horizon should not
 352             stutter.reset();
 353             sc = new Scanner(stutter);
 354             result = sc.findWithinHorizon("brummer$", 7);
 355             if (result != null)
 356                 failCount++;
 357             // An anchor at start should work
 358             stutter.reset();
 359             sc = new Scanner(stutter);
 360             result = sc.findWithinHorizon("^brummer", 0);
 361             if (!result.equals("brummer"))
 362                 failCount++;
 363         }
 364 
 365         report("Find to horizon test");
 366     }
 367 
 368     // StutteringInputStream returns 1 to 3 characters at a time
 369     static class StutteringInputStream implements Readable {
 370         StutteringInputStream() {
 371             text = "brummer hisser tort zardzard rantrant caimagator phant";
 372             datalen = 54;
 373         }
 374         StutteringInputStream(String text) {
 375             this.text = text;
 376             datalen = text.length();
 377         }
 378         Random generator = new Random();
 379         String text;
 380         int datalen;
 381         int index = 0;
 382         public int length() {
 383             return datalen;
 384         }
 385         public void reset() {
 386             index = 0;
 387         }
 388         public String wordInIndex(int index) {
 389             if (index < 7)  return null;
 390             if (index < 14) return "brummer";
 391             if (index < 19) return "hisser";
 392             if (index < 28) return "tort";
 393             if (index < 37) return "zardzard";
 394             if (index < 48) return "rantrant";
 395             return "caimagator";
 396         }
 397         public String wordBeyondIndex(int index) {
 398             if (index < 7)  return "brummer";
 399             if (index < 14) return "hisser";
 400             if (index < 19) return "tort";
 401             if (index < 28) return "zardzard";
 402             if (index < 37) return "rantrant";
 403             if (index < 48) return "caimagator";
 404             return "phantphant";
 405         }
 406         public int read(java.nio.CharBuffer target) throws IOException {
 407             if (index > datalen-1)
 408                 return -1; // EOS
 409             int len = target.remaining();
 410             if (len > 4) // return 1 to 3 characters
 411                 len = generator.nextInt(3) + 1;
 412             while ((index + len) > datalen)
 413                 len--;
 414             for (int i=0; i<len; i++)
 415                 target.put(text.charAt(index++));
 416             return len;
 417         }
 418     }
 419 
 420     public static void hasNextLineTest(int sourceType) throws Exception {
 421         Scanner sc = scannerFor("1\n2\n3 3\r\n4 4 4\r5", sourceType);
 422         if (!sc.hasNextLine()) failCount++;
 423         if (!sc.nextLine().equals("1")) failCount++;
 424         if (!sc.hasNextLine()) failCount++;
 425         if (sc.nextInt() != 2) failCount++;
 426         if (!sc.hasNextLine()) failCount++;
 427         if (!sc.nextLine().equals("")) failCount++;
 428         if (!sc.hasNextLine()) failCount++;
 429         if (sc.nextInt() != 3) failCount++;
 430         if (!sc.hasNextLine()) failCount++;
 431         if (!sc.nextLine().equals(" 3")) failCount++;
 432         if (!sc.hasNextLine()) failCount++;
 433         if (sc.nextInt() != 4) failCount++;
 434         if (!sc.hasNextLine()) failCount++;
 435         if (sc.nextInt() != 4) failCount++;
 436         if (!sc.hasNextLine()) failCount++;
 437         if (!sc.nextLine().equals(" 4")) failCount++;
 438         if (!sc.hasNextLine()) failCount++;
 439         if (!sc.nextLine().equals("5")) failCount++;
 440         if (sc.hasNextLine()) failCount++;
 441         sc = new Scanner("blah blah blah blah blah blah");
 442         if (!sc.hasNextLine()) failCount++;
 443         if (!sc.nextLine().equals("blah blah blah blah blah blah"))
 444            failCount++;
 445         if (sc.hasNextLine()) failCount++;
 446 
 447         // Go through all the lines in a file
 448         File f = new File(System.getProperty("test.src", "."), "input.txt");
 449         sc = new Scanner(f);
 450         String lastLine = "blah";
 451         while(sc.hasNextLine())
 452             lastLine = sc.nextLine();
 453         if (!lastLine.equals("# Data for usage case 6")) failCount++;
 454 
 455         report("Has next line test");
 456     }
 457 
 458     public static void nextLineTest(int sourceType) throws Exception {
 459         Scanner sc = scannerFor("1\n2\n3 3\r\n4 4 4\r5", sourceType);
 460         if (!sc.nextLine().equals("1"))
 461             failCount++;
 462         if (sc.nextInt() != 2)
 463             failCount++;
 464         if (!sc.nextLine().equals(""))
 465            failCount++;
 466         if (sc.nextInt() != 3)
 467             failCount++;
 468         if (!sc.nextLine().equals(" 3"))
 469            failCount++;
 470         if (sc.nextInt() != 4)
 471             failCount++;
 472         if (sc.nextInt() != 4)
 473             failCount++;
 474         if (!sc.nextLine().equals(" 4"))
 475            failCount++;
 476         if (!sc.nextLine().equals("5"))
 477            failCount++;
 478         sc = new Scanner("blah blah blah blah blah blah");
 479         if (!sc.nextLine().equals("blah blah blah blah blah blah"))
 480            failCount++;
 481         report("Next line test");
 482     }
 483 
 484     public static void singleDelimTest(int sourceType) throws Exception {
 485         Scanner sc = scannerFor("12 13  14   15    16     17      ",
 486                                 sourceType);
 487         sc.useDelimiter(" ");
 488         for (int i=0; i<6; i++) {
 489             int j = sc.nextInt();
 490             if (j != 12 + i)
 491                 failCount++;
 492             for (int k=0; k<i; k++) {
 493                 String empty = sc.next();
 494                 if (!empty.equals(""))
 495                     failCount++;
 496             }
 497         }
 498         report("Single delim test");
 499     }
 500 
 501     /*
 502      * The hasNextPattern caches a match of a pattern called the regular cache
 503      * The hasNextType caches a match of that type called the type cache
 504      * Any next must clear the caches whether it uses them or not, because
 505      * it advances past a token thus invalidating any cached token; any
 506      * hasNext must set a cache to what it finds.
 507      */
 508     public static void cacheTest() throws Exception {
 509         // Test clearing of the type cache
 510         Scanner scanner = new Scanner("777 dog");
 511         scanner.hasNextInt();
 512         scanner.findInLine("777");
 513         try {
 514             scanner.nextInt();
 515             System.out.println("type cache not cleared by find");
 516             failCount++;
 517         } catch (InputMismatchException ime) {
 518             // Correct
 519         }
 520 
 521         scanner = new Scanner("777 dog");
 522         scanner.hasNextInt();
 523         scanner.skip("777");
 524         try {
 525             scanner.nextInt();
 526             System.out.println("type cache not cleared by skip");
 527             failCount++;
 528         } catch (InputMismatchException ime) {
 529             // Correct
 530         }
 531 
 532         // Test clearing of the regular cache
 533         scanner = new Scanner("777 dog");
 534         scanner.hasNext("777");
 535         scanner.findInLine("777");
 536         try {
 537             scanner.next("777");
 538             System.out.println("regular cache not cleared by find");
 539             failCount++;
 540         } catch (InputMismatchException ime) {
 541             // Correct
 542         }
 543 
 544         // Test two primitive next clearing of type cache
 545         scanner = new Scanner("777 dog");
 546         scanner.hasNextInt();
 547         scanner.nextLong();
 548         try {
 549             scanner.nextInt();
 550             System.out.println("type cache not cleared by primitive next");
 551             failCount++;
 552         } catch (InputMismatchException ime) {
 553             // Correct
 554         }
 555 
 556         // Test using both of them, type first
 557         scanner = new Scanner("777 dog");
 558         scanner.hasNext("777");
 559         scanner.nextInt();
 560         try {
 561             scanner.next("777");
 562             System.out.println("regular cache not cleared by primitive next");
 563             failCount++;
 564         } catch (InputMismatchException ime) {
 565             // Correct
 566         }
 567 
 568         // Test using both of them, regular first
 569         scanner = new Scanner("777 dog");
 570         scanner.hasNext("777");
 571         scanner.hasNextInt();
 572         scanner.next("777");
 573         try {
 574             scanner.nextInt();
 575             System.out.println("type cache not cleared by regular next");
 576             failCount++;
 577         } catch (InputMismatchException ime) {
 578             // Correct
 579         }
 580         report("Cache test");
 581     }
 582 
 583     /*
 584      * The hasNext<IntegerType>(radix) method caches a matched integer type
 585      * with specified radix for the next next<IntegerType>(radix) invoke.
 586      * The cache value should not be used if the next<IntegerType>(radix)
 587      * has different radix value with the last hasNext<IntegerType>(radix).
 588      */
 589     public static void cacheTest2() throws Exception {
 590         // Test clearing of the type cache
 591         Scanner scanner = new Scanner("10");
 592         scanner.hasNextByte(16);
 593         if (scanner.nextByte(10) != 10) {
 594             System.out.println("wrong radix cache is used");
 595             failCount++;
 596         }
 597         scanner = new Scanner("10");
 598         scanner.hasNextShort(16);
 599         if (scanner.nextShort(10) != 10) {
 600             System.out.println("wrong radix cache is used");
 601             failCount++;
 602         }
 603         scanner = new Scanner("10");
 604         scanner.hasNextInt(16);
 605         if (scanner.nextInt(10) != 10) {
 606             System.out.println("wrong radix cache is used");
 607             failCount++;
 608         }
 609         scanner = new Scanner("10");
 610         scanner.hasNextLong(16);
 611         if (scanner.nextLong(10) != 10) {
 612             System.out.println("wrong radix cache is used");
 613             failCount++;
 614         }
 615         scanner = new Scanner("10");
 616         scanner.hasNextBigInteger(16);
 617         if (scanner.nextBigInteger(10).intValue() != 10) {
 618             System.out.println("wrong radix cache is used");
 619             failCount++;
 620         }
 621         report("Cache test2");
 622     }
 623 
 624 
 625     public static void closeTest() throws Exception {
 626         Scanner sc = new Scanner("testing");
 627         sc.close();
 628         sc.ioException();
 629         sc.delimiter();
 630         sc.useDelimiter("blah");
 631         sc.useDelimiter(Pattern.compile("blah"));
 632         for (int i=0; i<NUM_METHODS; i++) {
 633             try {
 634                 methodCall(sc, i);
 635                 failCount++;
 636             } catch (IllegalStateException ise) {
 637                 // Correct
 638             }
 639         }
 640         report("Close test");
 641     }
 642 
 643     private static int NUM_METHODS = 23;
 644 
 645     private static void methodCall(Scanner sc, int i) {
 646         switch(i) {
 647             case 0: sc.hasNext(); break;
 648             case 1: sc.next(); break;
 649             case 2: sc.hasNext(Pattern.compile("blah")); break;
 650             case 3: sc.next(Pattern.compile("blah")); break;
 651             case 4: sc.hasNextBoolean(); break;
 652             case 5: sc.nextBoolean(); break;
 653             case 6: sc.hasNextByte(); break;
 654             case 7: sc.nextByte(); break;
 655             case 8: sc.hasNextShort(); break;
 656             case 9: sc.nextShort(); break;
 657             case 10: sc.hasNextInt(); break;
 658             case 11: sc.nextInt(); break;
 659             case 12: sc.hasNextLong(); break;
 660             case 13: sc.nextLong(); break;
 661             case 14: sc.hasNextFloat(); break;
 662             case 15: sc.nextFloat(); break;
 663             case 16: sc.hasNextDouble(); break;
 664             case 17: sc.nextDouble(); break;
 665             case 18: sc.hasNextBigInteger(); break;
 666             case 19: sc.nextBigInteger(); break;
 667             case 20: sc.hasNextBigDecimal(); break;
 668             case 21: sc.nextBigDecimal(); break;
 669             case 22: sc.hasNextLine(); break;
 670             default:
 671                 break;
 672         }
 673     }
 674 
 675     public static void removeTest() throws Exception {
 676         Scanner sc = new Scanner("testing");
 677         try {
 678             sc.remove();
 679             failCount++;
 680         } catch (UnsupportedOperationException uoe) {
 681             // Correct result
 682         }
 683         report("Remove test");
 684     }
 685 
 686     public static void delimiterTest() throws Exception {
 687         Scanner sc = new Scanner("blah");
 688         Pattern test = sc.delimiter();
 689         if (!test.toString().equals("\\p{javaWhitespace}+"))
 690             failCount++;
 691         sc.useDelimiter("a");
 692         test = sc.delimiter();
 693         if (!test.toString().equals("a"))
 694             failCount++;
 695         sc.useDelimiter(Pattern.compile("b"));
 696         test = sc.delimiter();
 697         if (!test.toString().equals("b"))
 698             failCount++;
 699         report("Delimiter test");
 700     }
 701 
 702     public static void ioExceptionTest() throws Exception {
 703         Readable thrower = new ThrowingReadable();
 704         Scanner sc = new Scanner(thrower);
 705         try {
 706             sc.nextInt();
 707             failCount++;
 708         } catch (NoSuchElementException nsee) {
 709             // Correct result
 710         }
 711         Exception thrown = sc.ioException();
 712         String detail = thrown.getMessage();
 713         if (!detail.equals("ThrowingReadable always throws"))
 714             failCount++;
 715 
 716         report("IOException test");
 717     }
 718 
 719     public static void bigIntegerPatternTest(int sourceType) throws Exception {
 720         Scanner sc = scannerFor("23 9223372036854775817", sourceType);
 721         if (!sc.nextBigInteger().equals(BigInteger.valueOf(23)))
 722             failCount++;
 723         if (!sc.nextBigInteger().equals(new BigInteger(
 724             "9223372036854775817", 10)))
 725             failCount++;
 726 
 727         // Test another radix
 728         sc = new Scanner("4a4 4A4").useRadix(16);
 729         if (!sc.nextBigInteger().equals(new BigInteger("4a4", 16)))
 730             failCount++;
 731         if (!sc.nextBigInteger().equals(new BigInteger("4A4", 16)))
 732             failCount++;
 733 
 734         // Test alternating radices
 735         sc = new Scanner("12 4a4 14 4f4");
 736         if (!sc.nextBigInteger(10).equals(new BigInteger("12", 10)))
 737             failCount++;
 738         if (!sc.nextBigInteger(16).equals(new BigInteger("4a4", 16)))
 739             failCount++;
 740         if (!sc.nextBigInteger(10).equals(new BigInteger("14", 10)))
 741             failCount++;
 742         if (!sc.nextBigInteger(16).equals(new BigInteger("4f4", 16)))
 743             failCount++;
 744 
 745         // Test use of a lot of radices
 746         for (int i=2; i<17; i++) {
 747             sc = new Scanner("1111");
 748             if (!sc.nextBigInteger(i).equals(new BigInteger("1111", i)))
 749                 failCount++;
 750         }
 751 
 752         report("BigInteger pattern");
 753     }
 754 
 755     public static void bigDecimalPatternTest(int sourceType) throws Exception {
 756         Scanner sc = scannerFor("23 45.99 -45,067.444 3.4e10", sourceType);
 757         if (!sc.nextBigDecimal().equals(BigDecimal.valueOf(23)))
 758             failCount++;
 759         if (!sc.nextBigDecimal().equals(new BigDecimal("45.99")))
 760             failCount++;
 761         if (!sc.nextBigDecimal().equals(new BigDecimal("-45067.444")))
 762             failCount++;
 763         if (!sc.nextBigDecimal().equals(new BigDecimal("3.4e10")))
 764             failCount++;
 765         report("BigDecimal pattern");
 766     }
 767 
 768     public static void integerPatternTest(int sourceType) throws Exception {
 769         String input =
 770             "1 22 f FF Z -3 -44 123 1,200 -123 -3,400,000 5,40 ,500 ";
 771         Scanner sc = scannerFor(input, sourceType);
 772         integerPatternBody(sc);
 773         CharBuffer cb = CharBuffer.wrap(input);
 774         sc = new Scanner(cb);
 775         integerPatternBody(sc);
 776         report("Integer pattern");
 777     }
 778 
 779     public static void integerPatternBody(Scanner sc) throws Exception {
 780         if (sc.nextInt() != 1)        failCount++;
 781         if (sc.nextShort() != 22)     failCount++;
 782         if (sc.nextShort(16) != 15)   failCount++;
 783         if (sc.nextShort(16) != 255)  failCount++;
 784         if (sc.nextShort(36) != 35)   failCount++;
 785         if (!sc.hasNextInt())         failCount++;
 786         if (sc.nextInt() != -3)       failCount++;
 787         if (sc.nextInt() != -44)      failCount++;
 788         if (sc.nextLong() != 123)     failCount++;
 789         if (!sc.hasNextInt())         failCount++;
 790         if (sc.nextInt() != 1200)     failCount++;
 791         if (sc.nextInt() != -123)     failCount++;
 792         if (sc.nextInt() != -3400000) failCount++;
 793         try {
 794             sc.nextInt();
 795             failCount++;
 796         } catch (InputMismatchException ime) {
 797             // Correct result
 798         }
 799         sc.next();
 800         try {
 801             sc.nextLong();
 802             failCount++;
 803         } catch (InputMismatchException ime) {
 804             // Correct result
 805         }
 806         sc.next();
 807         try {
 808             sc.next();
 809             failCount++;
 810         } catch (InputMismatchException ime) {
 811             failCount++;
 812         } catch (NoSuchElementException nse) {
 813             // Correct result
 814         }
 815     }
 816 
 817     public static void floatPatternTest(int sourceType) throws Exception {
 818         String input =
 819             "090.090 1 22.0 -3 -44.05 +.123 -.1234 -3400000 56,566.6 " +
 820             "Infinity +Infinity -Infinity NaN -NaN +NaN 5.4.0 5-.00 ++6.07";
 821         Scanner sc = scannerFor(input, sourceType);
 822         floatPatternBody(sc);
 823         CharBuffer cb = CharBuffer.wrap(input);
 824         sc = new Scanner(cb);
 825         floatPatternBody(sc);
 826         report("Float pattern");
 827     }
 828 
 829     public static void floatPatternBody(Scanner sc) throws Exception {
 830         if (sc.nextFloat() != 090.090f)                   failCount++;
 831         if (sc.nextFloat() != 1f)                         failCount++;
 832         if (sc.nextFloat() != 22.0f)                      failCount++;
 833         if (sc.nextDouble() != -3d)                       failCount++;
 834         if (sc.nextDouble() != -44.05d)                   failCount++;
 835         if (sc.nextFloat() != .123f)                      failCount++;
 836         if (sc.nextFloat() != -.1234f)                    failCount++;
 837         if (sc.nextDouble() != -3400000d)                 failCount++;
 838         if (sc.nextDouble() != 56566.6d)                  failCount++;
 839         if (sc.nextDouble() != Double.POSITIVE_INFINITY)  failCount++;
 840         if (sc.nextDouble() != Double.POSITIVE_INFINITY)  failCount++;
 841         if (sc.nextDouble() != Double.NEGATIVE_INFINITY)  failCount++;
 842         if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
 843         if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
 844         if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
 845         try {
 846             sc.nextFloat();
 847             failCount++;
 848         } catch (NoSuchElementException nse) {
 849             // Correct result
 850         }
 851         try {
 852             sc.nextDouble();
 853             failCount++;
 854         } catch (NoSuchElementException nse) {
 855             // Correct result
 856         }
 857         try {
 858             sc.nextDouble();
 859             failCount++;
 860         } catch (NoSuchElementException nse) {
 861             // Correct result
 862         }
 863     }
 864 
 865     public static void fromFileTest() throws Exception {
 866         File f = new File(System.getProperty("test.src", "."), "input.txt");
 867         Scanner sc = new Scanner(f).useDelimiter("\n+");
 868         String testDataTag = sc.findWithinHorizon("fromFileTest", 0);
 869         if (!testDataTag.equals("fromFileTest"))
 870             failCount++;
 871 
 872         int count = 0;
 873         while (sc.hasNextLong()) {
 874             long blah = sc.nextLong();
 875             count++;
 876         }
 877         if (count != 7)
 878             failCount++;
 879         sc.close();
 880         report("From file");
 881     }
 882 
 883     private static void example1() throws Exception {
 884         Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
 885         s.useDelimiter("\\s*fish\\s*");
 886         List <String> results = new ArrayList<String>();
 887         while(s.hasNext())
 888             results.add(s.next());
 889         System.out.println(results);
 890     }
 891 
 892     private static void example2() throws Exception {
 893         Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
 894         s.useDelimiter("\\s*fish\\s*");
 895         System.out.println(s.nextInt());
 896         System.out.println(s.nextInt());
 897         System.out.println(s.next());
 898         System.out.println(s.next());
 899     }
 900 
 901     private static void example3() throws Exception {
 902         Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
 903         s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 904         for (int i=1; i<=s.match().groupCount(); i++)
 905             System.out.println(s.match().group(i));
 906     }
 907 
 908     private static void findInLineTest() throws Exception {
 909         Scanner s = new Scanner("abc def ghi jkl mno");
 910         Pattern letters = Pattern.compile("[a-z]+");
 911         Pattern frogs = Pattern.compile("frogs");
 912         String str = s.findInLine(letters);
 913         if (!str.equals("abc"))
 914             failCount++;
 915         if (!s.hasNext(letters))
 916             failCount++;
 917         try {
 918             str = s.findInLine(frogs);
 919         } catch (NoSuchElementException nsee) {
 920             // Correct
 921         }
 922         if (!s.hasNext())
 923             failCount++;
 924         if (!s.hasNext(letters))
 925             failCount++;
 926         str = s.findInLine(letters);
 927         if (!str.equals("def"))
 928             failCount++;
 929 
 930         report("Find patterns");
 931     }
 932 
 933     private static void findInEmptyLineTest() throws Exception {
 934         String eol = System.getProperty("line.separator");
 935         Scanner s = new Scanner("line 1" + eol + "" + eol + "line 3" + eol);
 936         int lineNo = 0;
 937         while (s.hasNextLine()) {
 938             lineNo++;
 939             s.findInLine("3");
 940             s.nextLine();
 941         }
 942         if (lineNo != 3)
 943             failCount++;
 944         report("findInEmptyLine test");
 945     }
 946 
 947     private static void matchTest() throws Exception {
 948         Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
 949         s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 950 
 951         MatchResult result = s.match();
 952         if (!result.group(1).equals("1"))
 953             failCount++;
 954         if (!result.group(2).equals("2"))
 955             failCount++;
 956         if (!result.group(3).equals("red"))
 957             failCount++;
 958         if (!result.group(4).equals("blue"))
 959             failCount++;
 960 
 961         report("Match patterns");
 962     }
 963 
 964     private static void skipTest() throws Exception {
 965         Scanner s = new Scanner("abc def ghi jkl mno");
 966         Pattern letters = Pattern.compile("[a-z]+");
 967         Pattern spaceLetters = Pattern.compile(" [a-z]+");
 968         Pattern frogs = Pattern.compile("frogs");
 969         try {
 970             s.skip(letters);
 971         } catch (NoSuchElementException ime) {
 972             failCount++;
 973         }
 974         String token = s.next(letters);
 975         if (!token.equals("def")) {
 976             System.out.println("expected def");
 977             System.out.println("I found "+token);
 978             failCount++;
 979         }
 980         try {
 981             s.skip(letters);
 982             failCount++;
 983         } catch (NoSuchElementException ime) {
 984             // Correct result
 985         }
 986         token = s.next(letters);
 987         if (!token.equals("ghi")) {
 988             System.out.println("expected ghi");
 989             System.out.println("I found "+token);
 990             failCount++;
 991         }
 992         try {
 993             s.skip(letters);
 994             failCount++;
 995         } catch (NoSuchElementException ime) {
 996             // Correct result because skip ignores delims
 997         }
 998         try {
 999             s.skip(spaceLetters);
1000         } catch (NoSuchElementException ime) {
1001             failCount++;
1002         }
1003         token = s.next(letters);
1004         if (!token.equals("mno")) {
1005             System.out.println("expected mno");
1006             System.out.println("I found "+token);
1007             failCount++;
1008         }
1009         try {
1010             s.skip(letters);
1011             failCount++;
1012         } catch (NoSuchElementException ime) {
1013             // Correct result
1014         }
1015         report("Skip patterns");
1016     }
1017 
1018     private static void byteTest(int sourceType) throws Exception {
1019         String input = " 3 0 00 b -B 012 44 -55 12 127 129 -131 dog 0x12";
1020         Scanner s = scannerFor(input, sourceType);
1021         if (!s.hasNextByte())          failCount++;
1022         if (s.nextByte() != (byte)3)   failCount++;
1023         if (!s.hasNextByte())          failCount++;
1024         if (s.nextByte() != (byte)0)   failCount++;
1025         if (!s.hasNextByte())          failCount++;
1026         if (s.nextByte() != (byte)0)   failCount++;
1027         if (!s.hasNextByte(16))        failCount++;
1028         if (s.nextByte(16) != (byte)11)failCount++;
1029         if (!s.hasNextByte(16))        failCount++;
1030         if (s.nextByte(16) != (byte)-11) failCount++;
1031         if (!s.hasNextByte())          failCount++;
1032         if (s.nextByte() != (byte)12)  failCount++;
1033         if (!s.hasNextByte())          failCount++;
1034         if (s.nextByte() != (byte)44)  failCount++;
1035         if (!s.hasNextByte())          failCount++;
1036         if (s.nextByte() != (byte)-55) failCount++;
1037         if (!s.hasNextByte())          failCount++;
1038         if (s.nextByte() != (byte)12)  failCount++;
1039         if (!s.hasNextByte())          failCount++;
1040         if (s.nextByte() != (byte)127) failCount++;
1041         if (s.hasNextByte())           failCount++;
1042 
1043         try {
1044             s.nextByte();
1045             failCount++;
1046         } catch (InputMismatchException ime) {
1047             // Correct result
1048         }
1049         if (s.hasNextByte())           failCount++;
1050         if (s.nextInt() != 129)        failCount++;
1051         if (s.hasNextByte())           failCount++;
1052         try {
1053             s.nextByte();
1054             failCount++;
1055         } catch (InputMismatchException ime) {
1056             // Correct result
1057         }
1058         if (s.nextInt() != -131)       failCount++;
1059         if (s.hasNextByte())           failCount++;
1060         try {
1061             s.nextByte();
1062             failCount++;
1063         } catch (InputMismatchException ime) {
1064             // Correct result
1065         }
1066         s.next(Pattern.compile("\\w+"));
1067         if (s.hasNextByte())
1068             failCount++;
1069         try {
1070             s.nextByte();
1071             failCount++;
1072         } catch (NoSuchElementException nsee) {
1073             // Correct result
1074         }
1075         s.next();
1076         if (s.hasNextByte())
1077             failCount++;
1078         try {
1079             byte bb = s.nextByte();
1080             failCount++;
1081         } catch (NoSuchElementException nsee) {
1082             // Correct result
1083         }
1084         report("Scan bytes");
1085     }
1086 
1087     private static void shortTest(int sourceType) throws Exception {
1088         String input = "  017 22 00E -34 44,333 -53999 0x19 dog";
1089         Scanner s = scannerFor(input, sourceType);
1090         if (!s.hasNextShort())             failCount++;
1091         if (s.nextShort() != (short)17)   failCount++;
1092         if (!s.hasNextShort())            failCount++;
1093         if (s.nextShort() != (short)22)   failCount++;
1094         if (!s.hasNextShort(16))          failCount++;
1095         if (s.nextShort(16) != (short)14) failCount++;
1096         if (!s.hasNextShort())            failCount++;
1097         if (s.nextShort() != (short)-34)  failCount++;
1098         for (int i=0; i<4; i++) {
1099             if (s.hasNextShort())
1100                 failCount++;
1101             try {
1102                 s.nextShort();
1103                 failCount++;
1104             } catch (InputMismatchException ime) {
1105                 // Correct result
1106             }
1107             s.next();
1108         }
1109         try {
1110             s.next();
1111             failCount++;
1112         } catch (InputMismatchException ime) {
1113             failCount++;
1114         } catch (NoSuchElementException nse) {
1115             // Correct result
1116         }
1117         report("Scan shorts");
1118     }
1119 
1120     private static void intTest(int sourceType) throws Exception {
1121         Scanner s = scannerFor(
1122             "22 022 C -34 0x80000000 -2147483649 dog ", sourceType);
1123         if (!s.hasNextInt())      failCount++;
1124         if (s.nextInt() != 22)    failCount++;
1125         if (!s.hasNextInt())      failCount++;
1126         if (s.nextInt() != 22)    failCount++;
1127         if (!s.hasNextInt(16))    failCount++;
1128         if (s.nextInt(16) != 12)  failCount++;
1129         if (!s.hasNextInt())      failCount++;
1130         if (s.nextInt() != -34)   failCount++;
1131         for (int i=0; i<3; i++) {
1132             if (s.hasNextInt())
1133                 failCount++;
1134             try {
1135                 s.nextInt();
1136                 failCount++;
1137             } catch (InputMismatchException ime) {
1138                 // Correct result
1139             }
1140             s.next();
1141         }
1142         try {
1143             s.next();
1144             failCount++;
1145         } catch (InputMismatchException ime) {
1146             failCount++;
1147         } catch (NoSuchElementException nse) {
1148             // Correct result
1149         }
1150         report("Scan ints");
1151     }
1152 
1153     private static void longTest(int sourceType) throws Exception {
1154         Scanner s = scannerFor(
1155         "022 9223372036854775807 0x8000000000000000 9223372036854775808 dog ",
1156               sourceType);
1157         if (!s.hasNextLong())                        failCount++;
1158         if (s.nextLong() != (long)22)                failCount++;
1159         if (!s.hasNextLong())                        failCount++;
1160         if (s.nextLong() != 9223372036854775807L)    failCount++;
1161         for (int i=0; i<3; i++) {
1162             if (s.hasNextLong())
1163                 failCount++;
1164             try {
1165                 s.nextLong();
1166                 failCount++;
1167             } catch (InputMismatchException ime) {
1168                 // Correct result
1169             }
1170             s.next();
1171         }
1172         try {
1173             s.next();
1174             failCount++;
1175         } catch (InputMismatchException ime) {
1176             failCount++;
1177         } catch (NoSuchElementException nse) {
1178             // Correct result
1179         }
1180         report("Scan longs");
1181     }
1182 
1183     private static void floatTest(int sourceType) throws Exception {
1184         Scanner s = scannerFor(
1185             "0 0. 0.0 2 2. 2.0 2.3 -2 -2.0 -2.3 -. 2-. 2..3", sourceType);
1186         if (!s.hasNextFloat())      failCount++;
1187         if (s.nextFloat() != 0f)    failCount++;
1188         if (!s.hasNextFloat())      failCount++;
1189         if (s.nextFloat() != 0f)    failCount++;
1190         if (!s.hasNextFloat())      failCount++;
1191         if (s.nextFloat() != 0f)    failCount++;
1192         if (!s.hasNextFloat())      failCount++;
1193         if (s.nextFloat() != 2f)    failCount++;
1194         if (!s.hasNextFloat())      failCount++;
1195         if (s.nextFloat() != 2f)    failCount++;
1196         if (!s.hasNextFloat())      failCount++;
1197         if (s.nextFloat() != 2f)    failCount++;
1198         if (!s.hasNextFloat())      failCount++;
1199         if (s.nextFloat() != 2.3f)  failCount++;
1200         if (!s.hasNextFloat())      failCount++;
1201         if (s.nextFloat() != -2f)   failCount++;
1202         if (!s.hasNextFloat())      failCount++;
1203         if (s.nextFloat() != -2f)   failCount++;
1204         if (!s.hasNextFloat())      failCount++;
1205         if (s.nextFloat() != -2.3f) failCount++;
1206         for (int i=0; i<3; i++) {
1207             if (s.hasNextLong())
1208                 failCount++;
1209             try {
1210                 s.nextFloat();
1211                 failCount++;
1212             } catch (InputMismatchException ime) {
1213                 // Correct result
1214             }
1215             s.next();
1216         }
1217         try {
1218             s.next();
1219             failCount++;
1220         } catch (InputMismatchException ime) {
1221             failCount++;
1222         } catch (NoSuchElementException nse) {
1223             // Correct result
1224         }
1225         report("Scan floats");
1226     }
1227 
1228     private static void doubleTest(int sourceType) throws Exception {
1229         Scanner s = scannerFor(
1230             "0 0. 0.0 2 2. 2.0 2.3 -2 -2.0 -2.3 -. 2-. 2..3", sourceType);
1231         if (!s.hasNextDouble())             failCount++;
1232         if (s.nextDouble() != 0d)           failCount++;
1233         if (!s.hasNextDouble())             failCount++;
1234         if (s.nextDouble() != 0d)           failCount++;
1235         if (!s.hasNextDouble())             failCount++;
1236         if (s.nextDouble() != 0d)           failCount++;
1237         if (!s.hasNextDouble())             failCount++;
1238         if (s.nextDouble() != 2d)           failCount++;
1239         if (!s.hasNextDouble())             failCount++;
1240         if (s.nextDouble() != 2d)           failCount++;
1241         if (!s.hasNextDouble())             failCount++;
1242         if (s.nextDouble() != 2d)           failCount++;
1243         if (!s.hasNextDouble())             failCount++;
1244         if (s.nextDouble() != 2.3d)         failCount++;
1245         if (!s.hasNextDouble())             failCount++;
1246         if (s.nextDouble() != -2d)          failCount++;
1247         if (!s.hasNextDouble())             failCount++;
1248         if (s.nextDouble() != -2d)          failCount++;
1249         if (!s.hasNextDouble())             failCount++;
1250         if (s.nextDouble() != -2.3d)        failCount++;
1251         for (int i=0; i<3; i++) {
1252             if (s.hasNextLong())
1253                 failCount++;
1254             try {
1255                 s.nextDouble();
1256                 failCount++;
1257             } catch (InputMismatchException ime) {
1258                 // Correct result
1259             }
1260             s.next();
1261         }
1262         try {
1263             s.next();
1264             failCount++;
1265         } catch (InputMismatchException ime) {
1266             failCount++;
1267         } catch (NoSuchElementException nse) {
1268             // Correct result
1269         }
1270         report("Scan doubles");
1271     }
1272 
1273     private static void booleanTest(int sourceType) throws Exception {
1274         Scanner s = scannerFor(
1275             " true false\t \r\n true FaLse \n  True Tru", sourceType);
1276         if (!s.nextBoolean())     failCount++;
1277         if (!s.hasNextBoolean())  failCount++;
1278         if (s.nextBoolean())      failCount++;
1279         if (!s.nextBoolean())     failCount++;
1280         if (s.nextBoolean())      failCount++;
1281         if (!s.nextBoolean())     failCount++;
1282         if (s.hasNextBoolean())   failCount++;
1283         try {
1284             s.nextBoolean();
1285             failCount++;
1286         } catch (NoSuchElementException nsee) {
1287             // Expected result
1288         }
1289         report("Scan booleans");
1290     }
1291 
1292     private static void hasNextTest(int sourceType) throws Exception {
1293         Scanner s = scannerFor(
1294             " blah blech\t blather  alongblatherindeed", sourceType);
1295         if (!s.hasNext())            failCount++;
1296         if (!s.hasNext())            failCount++;
1297         String result = s.next();
1298         if (!result.equals("blah"))  failCount++;
1299         if (!s.hasNext())            failCount++;
1300         if (!s.hasNext())            failCount++;
1301         result = s.next();
1302         if (!result.equals("blech")) failCount++;
1303         if (!s.hasNext())            failCount++;
1304         result = s.next();
1305         if (!result.equals("blather")) failCount++;
1306         if (!s.hasNext())              failCount++;
1307         if (!s.hasNext())              failCount++;
1308         result = s.next();
1309         if (!result.equals("alongblatherindeed")) failCount++;
1310         if (s.hasNext())                          failCount++;
1311         try {
1312             result = s.next();
1313             failCount++;
1314         } catch (NoSuchElementException nsee) {
1315             // Correct result
1316         }
1317         report("Has next test");
1318     }
1319 
1320     private static void nextTest(int sourceType) throws Exception {
1321         Scanner s = scannerFor(
1322             " blah blech\t blather  alongblatherindeed", sourceType);
1323         String result = (String)s.next();
1324         if (!result.equals("blah"))    failCount++;
1325         result = (String)s.next();
1326         if (!result.equals("blech"))   failCount++;
1327         result = (String)s.next();
1328         if (!result.equals("blather")) failCount++;
1329         result = (String)s.next();
1330         if (!result.equals("alongblatherindeed"))
1331             failCount++;
1332         try {
1333             result = (String)s.next();
1334             failCount++;
1335         } catch (NoSuchElementException nsee) {
1336             // Correct result
1337         }
1338         report("Next test");
1339     }
1340 
1341     private static void hasNextPatternTest(int sourceType) throws Exception {
1342         Scanner s = scannerFor(
1343             " blah blech\t blather  alongblatherindeed", sourceType);
1344         Pattern p1 = Pattern.compile("\\w+");
1345         Pattern p2 = Pattern.compile("blech");
1346         if (!s.hasNext(p1))    failCount++;
1347         if (!s.hasNext(p1))    failCount++;
1348         if (s.hasNext(p2))     failCount++;
1349         String result = (String)s.next();
1350         if (!result.equals("blah"))  failCount++;
1351         if (!s.hasNext(p1))          failCount++;
1352         if (!s.hasNext(p2))          failCount++;
1353         result = (String)s.next();
1354         if (!result.equals("blech")) failCount++;
1355         if (!s.hasNext(p1))          failCount++;
1356         if (s.hasNext(p2))           failCount++;
1357         result = (String)s.next();
1358         if (!result.equals("blather")) failCount++;
1359         if (!s.hasNext(p1))            failCount++;
1360         if (s.hasNext(p2))             failCount++;
1361         result = (String)s.next();
1362         if (!result.equals("alongblatherindeed")) failCount++;
1363         if (s.hasNext(p1))  failCount++;
1364         if (s.hasNext(p2))  failCount++;
1365         report("Has Next Pattern test");
1366     }
1367 
1368     private static void nextPatternTest(int sourceType) throws Exception {
1369         Scanner s = scannerFor(
1370             " blah blech\t blather  alongblatherindeed", sourceType);
1371         Pattern p1 = Pattern.compile("blah");
1372         Pattern p2 = Pattern.compile("blech");
1373         Pattern p3 = Pattern.compile("blather");
1374         Pattern p4 = Pattern.compile("alongblatherindeed");
1375         String result = null;
1376         try {
1377             result = (String)s.next(p2);
1378             failCount++;
1379         } catch (NoSuchElementException nsee) {
1380             // Correct result
1381         }
1382         result = (String)s.next(p1);
1383         if (!result.equals("blah"))
1384             failCount++;
1385         try {
1386             result = (String)s.next(p1);
1387             failCount++;
1388         } catch (NoSuchElementException nsee) {
1389             // Correct result
1390         }
1391         result = (String)s.next(p2);
1392         if (!result.equals("blech"))
1393             failCount++;
1394         try {
1395             result = (String)s.next(p4);
1396             failCount++;
1397         } catch (NoSuchElementException nsee) {
1398             // Correct result
1399         }
1400         result = (String)s.next(p3);
1401         if (!result.equals("blather"))
1402             failCount++;
1403         try {
1404             result = (String)s.next(p3);
1405             failCount++;
1406         } catch (NoSuchElementException nsee) {
1407             // Correct result
1408         }
1409         result = (String)s.next(p4);
1410         if (!result.equals("alongblatherindeed"))
1411             failCount++;
1412         try {
1413             result = (String)s.next();
1414             failCount++;
1415         } catch (NoSuchElementException nsee) {
1416             // Correct result
1417         }
1418         report("Next pattern test");
1419     }
1420 
1421     private static void useLocaleTest() throws Exception {
1422         Scanner s = new Scanner("334.65").useLocale(Locale.ENGLISH);
1423         if (!s.hasNextFloat())           failCount++;
1424         if (s.nextFloat() != 334.65f)    failCount++;
1425 
1426         s = new Scanner("334,65").useLocale(Locale.FRENCH);
1427         if (!s.hasNextFloat())           failCount++;
1428         if (s.nextFloat() != 334.65f)    failCount++;
1429 
1430         s = new Scanner("4.334,65").useLocale(Locale.GERMAN);
1431         if (!s.hasNextFloat())           failCount++;
1432         if (s.nextFloat() != 4334.65f)    failCount++;
1433 
1434         // Test case reported from India
1435         try {
1436             String Message = "123978.90 $";
1437             Locale locale = new Locale("hi","IN");
1438             NumberFormat form = NumberFormat.getInstance(locale);
1439             double myNumber = 1902.09;
1440             Scanner scanner = new Scanner(form.format(myNumber).toString());
1441             scanner.useLocale(locale);
1442             double d = scanner.nextDouble();
1443         } catch (InputMismatchException ime) {
1444             failCount++;
1445         }
1446         report("Use locale test");
1447     }
1448 
1449     public static void resetTest() throws Exception {
1450         Scanner sc = new Scanner("");
1451         int radix = sc.radix();
1452         Locale locale = sc.locale();
1453         Pattern delimiter = sc.delimiter();
1454         Pattern a = Pattern.compile("A");
1455         sc.useDelimiter(a);
1456         Locale dummy = new Locale("en", "US", "dummy");
1457         sc.useLocale(dummy);
1458         sc.useRadix(16);
1459         if (sc.radix() != 16 ||
1460             !sc.locale().equals(dummy) ||
1461             !sc.delimiter().pattern().equals(a.pattern())) {
1462             failCount++;
1463         } else {
1464             sc.reset();
1465             if (sc.radix() != radix ||
1466                 !sc.locale().equals(locale) ||
1467                 !sc.delimiter().pattern().equals(delimiter.pattern())) {
1468                 failCount++;
1469             }
1470         }
1471         sc.close();
1472         report("Reset test");
1473     }
1474 
1475     private static void report(String testName) {
1476         int spacesToAdd = 30 - testName.length();
1477         StringBuffer paddedNameBuffer = new StringBuffer(testName);
1478         for (int i=0; i<spacesToAdd; i++)
1479             paddedNameBuffer.append(" ");
1480         String paddedName = paddedNameBuffer.toString();
1481         System.err.println(paddedName + ": " +
1482                            (failCount==0 ? "Passed":"Failed("+failCount+")"));
1483         if (failCount > 0)
1484             failure = true;
1485         failCount = 0;
1486     }
1487 
1488     static Scanner scannerFor(String input, int sourceType) {
1489         if (sourceType == 1)
1490             return new Scanner(input);
1491         else
1492             return new Scanner(new StutteringInputStream(input));
1493     }
1494 
1495     static class ThrowingReadable implements Readable {
1496         ThrowingReadable() {
1497         }
1498         public int read(java.nio.CharBuffer cb) throws IOException {
1499             throw new IOException("ThrowingReadable always throws");
1500         }
1501     }
1502 }