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