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