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