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