< prev index next >

test/java/util/Scanner/ScanTest.java

Print this page
rev 12670 : 8072722: add stream support to Scanner
Reviewed-by: psandoz, chegar

@@ -22,29 +22,34 @@
  */
 
 /**
  * @test
  * @bug 4313885 4926319 4927634 5032610 5032622 5049968 5059533 6223711 6277261 6269946 6288823
+ *      8072722
  * @summary Basic tests of java.util.Scanner methods
  * @key randomness
  * @run main/othervm ScanTest
  */
 
-import java.util.*;
-import java.text.*;
 import java.io.*;
+import java.math.*;
 import java.nio.*;
+import java.text.*;
+import java.util.*;
+import java.util.function.Consumer;
 import java.util.regex.*;
-import java.math.*;
+import java.util.stream.*;
 
 public class ScanTest {
 
     private static boolean failure = false;
     private static int failCount = 0;
     private static int NUM_SOURCE_TYPES = 2;
+    private static File inputFile = new File(System.getProperty("test.src", "."), "input.txt");
 
     public static void main(String[] args) throws Exception {
+
         Locale reservedLocale = Locale.getDefault();
         String lang = reservedLocale.getLanguage();
         try {
             if (!"en".equals(lang) &&
                 !"zh".equals(lang) &&

@@ -68,12 +73,14 @@
             closeTest();
             cacheTest();
             cacheTest2();
             nonASCIITest();
             resetTest();
+            streamCloseTest();
+            streamComodTest();
 
-            for (int j=0; j<NUM_SOURCE_TYPES; j++) {
+            for (int j = 0; j < NUM_SOURCE_TYPES; j++) {
                 hasNextTest(j);
                 nextTest(j);
                 hasNextPatternTest(j);
                 nextPatternTest(j);
                 booleanTest(j);

@@ -113,16 +120,15 @@
             Locale.setDefault(reservedLocale);
         }
     }
 
     public static void useCase1() throws Exception {
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f);
+        try (Scanner sc = new Scanner(inputFile)) {
         sc.findWithinHorizon("usage case 1", 0);
         String[] names = new String[4];
         for (int i=0; i<4; i++) {
-            while(sc.hasNextFloat())
+                while (sc.hasNextFloat())
                 sc.nextFloat();
             names[i] = sc.next();
             sc.nextLine();
         }
         if (!names[0].equals("Frank"))

@@ -131,17 +137,16 @@
             failCount++;
         if (!names[2].equals("Mary"))
             failCount++;
         if (!names[3].equals("Michelle"))
             failCount++;
-        sc.close();
+        }
         report("Use case 1");
     }
 
     public static void useCase2() throws Exception {
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f).useDelimiter("-");
+        try (Scanner sc = new Scanner(inputFile).useDelimiter("-")) {
         String testDataTag = sc.findWithinHorizon("usage case 2\n", 0);
         if (!testDataTag.equals("usage case 2\n"))
             failCount++;
         if (!sc.next().equals("cat"))
             failCount++;

@@ -157,17 +162,16 @@
             failCount++;
         if (!sc.next().equals(""))
             failCount++;
         if (sc.nextInt() != 5)
             failCount++;
-        sc.close();
+        }
         report("Use case 2");
     }
 
     public static void useCase3() throws Exception {
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f);
+        try (Scanner sc = new Scanner(inputFile)) {
         String testDataTag = sc.findWithinHorizon("usage case 3\n", 0);
         if (!testDataTag.equals("usage case 3\n"))
             failCount++;
         Pattern tagPattern = Pattern.compile("@[a-z]+");
         Pattern endPattern = Pattern.compile("\\*\\/");

@@ -182,16 +186,16 @@
             } else {
                 sc.nextLine();
             }
             end = sc.findInLine(endPattern);
         }
+        }
         report("Use case 3");
     }
 
     public static void useCase4() throws Exception {
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f);
+        try (Scanner sc = new Scanner(inputFile)) {
         String testDataTag = sc.findWithinHorizon("usage case 4\n", 0);
         if (!testDataTag.equals("usage case 4\n"))
             failCount++;
 
         // Read some text parts of four hrefs

@@ -215,27 +219,27 @@
         Pattern tag = Pattern.compile("<[^>]+?>");
         Pattern spotAfterTag = Pattern.compile("(?<=>)");
         String[] expected2 = { "</b>", "<p>", "<ul>", "<li>" };
         sc.useDelimiter(spotAfterTag);
         int tagsFound = 0;
-        while(tagsFound < 4) {
+            while (tagsFound < 4) {
             if (!sc.hasNext(tag)) {
                 // skip text between tags
                 sc.skip(nonTagStart);
             }
             String tagContents = sc.next(tag);
             if (!tagContents.equals(expected2[tagsFound]))
                 failCount++;
             tagsFound++;
         }
+        }
 
         report("Use case 4");
     }
 
     public static void useCase5() throws Exception {
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f);
+        try (Scanner sc = new Scanner(inputFile)) {
         String testDataTag = sc.findWithinHorizon("usage case 5\n", 0);
         if (!testDataTag.equals("usage case 5\n"))
             failCount++;
 
         sc.findWithinHorizon("Share Definitions", 0);

@@ -257,10 +261,11 @@
             String value = sc.next();
             if (!value.equals(vals[i]))
                 failCount++;
             sc.nextLine();
         }
+        }
 
         report("Use case 5");
     }
 
     public static void nonASCIITest() throws Exception {

@@ -443,16 +448,16 @@
         if (!sc.nextLine().equals("blah blah blah blah blah blah"))
            failCount++;
         if (sc.hasNextLine()) failCount++;
 
         // Go through all the lines in a file
-        File f = new File(System.getProperty("test.src", "."), "input.txt");
-        sc = new Scanner(f);
+        try (Scanner sc2 = new Scanner(inputFile)) {
         String lastLine = "blah";
-        while(sc.hasNextLine())
-            lastLine = sc.nextLine();
+            while (sc2.hasNextLine())
+                lastLine = sc2.nextLine();
         if (!lastLine.equals("# Data for usage case 6")) failCount++;
+        }
 
         report("Has next line test");
     }
 
     public static void nextLineTest(int sourceType) throws Exception {

@@ -627,52 +632,51 @@
         sc.close();
         sc.ioException();
         sc.delimiter();
         sc.useDelimiter("blah");
         sc.useDelimiter(Pattern.compile("blah"));
-        for (int i=0; i<NUM_METHODS; i++) {
+
+        for (Consumer<Scanner> method : methodList) {
             try {
-                methodCall(sc, i);
+                method.accept(sc);
                 failCount++;
             } catch (IllegalStateException ise) {
                 // Correct
             }
         }
+
         report("Close test");
     }
 
-    private static int NUM_METHODS = 23;
-
-    private static void methodCall(Scanner sc, int i) {
-        switch(i) {
-            case 0: sc.hasNext(); break;
-            case 1: sc.next(); break;
-            case 2: sc.hasNext(Pattern.compile("blah")); break;
-            case 3: sc.next(Pattern.compile("blah")); break;
-            case 4: sc.hasNextBoolean(); break;
-            case 5: sc.nextBoolean(); break;
-            case 6: sc.hasNextByte(); break;
-            case 7: sc.nextByte(); break;
-            case 8: sc.hasNextShort(); break;
-            case 9: sc.nextShort(); break;
-            case 10: sc.hasNextInt(); break;
-            case 11: sc.nextInt(); break;
-            case 12: sc.hasNextLong(); break;
-            case 13: sc.nextLong(); break;
-            case 14: sc.hasNextFloat(); break;
-            case 15: sc.nextFloat(); break;
-            case 16: sc.hasNextDouble(); break;
-            case 17: sc.nextDouble(); break;
-            case 18: sc.hasNextBigInteger(); break;
-            case 19: sc.nextBigInteger(); break;
-            case 20: sc.hasNextBigDecimal(); break;
-            case 21: sc.nextBigDecimal(); break;
-            case 22: sc.hasNextLine(); break;
-            default:
-                break;
-        }
-    }
+    static List<Consumer<Scanner>> methodList = Arrays.asList(
+        Scanner::hasNext,
+        Scanner::next,
+        sc -> sc.hasNext(Pattern.compile("blah")),
+        sc -> sc.next(Pattern.compile("blah")),
+        Scanner::hasNextBoolean,
+        Scanner::nextBoolean,
+        Scanner::hasNextByte,
+        Scanner::nextByte,
+        Scanner::hasNextShort,
+        Scanner::nextShort,
+        Scanner::hasNextInt,
+        Scanner::nextInt,
+        Scanner::hasNextLong,
+        Scanner::nextLong,
+        Scanner::hasNextFloat,
+        Scanner::nextFloat,
+        Scanner::hasNextDouble,
+        Scanner::nextDouble,
+        Scanner::hasNextBigInteger,
+        Scanner::nextBigInteger,
+        Scanner::hasNextBigDecimal,
+        Scanner::nextBigDecimal,
+        Scanner::hasNextLine,
+        Scanner::tokens,
+        sc -> sc.findAll(Pattern.compile("blah")),
+        sc -> sc.findAll("blah")
+    );
 
     public static void removeTest() throws Exception {
         Scanner sc = new Scanner("testing");
         try {
             sc.remove();

@@ -862,11 +866,12 @@
         }
     }
 
     public static void fromFileTest() throws Exception {
         File f = new File(System.getProperty("test.src", "."), "input.txt");
-        Scanner sc = new Scanner(f).useDelimiter("\n+");
+        try (Scanner sc = new Scanner(f)) {
+            sc.useDelimiter("\n+");
         String testDataTag = sc.findWithinHorizon("fromFileTest", 0);
         if (!testDataTag.equals("fromFileTest"))
             failCount++;
 
         int count = 0;

@@ -874,19 +879,19 @@
             long blah = sc.nextLong();
             count++;
         }
         if (count != 7)
             failCount++;
-        sc.close();
+        }
         report("From file");
     }
 
     private static void example1() throws Exception {
         Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
         s.useDelimiter("\\s*fish\\s*");
         List <String> results = new ArrayList<String>();
-        while(s.hasNext())
+        while (s.hasNext())
             results.add(s.next());
         System.out.println(results);
     }
 
     private static void example2() throws Exception {

@@ -1470,18 +1475,116 @@
         }
         sc.close();
         report("Reset test");
     }
 
+    /*
+     * Test that closing the stream also closes the underlying Scanner.
+     * The cases of attempting to open streams on a closed Scanner are
+     * covered by closeTest().
+     */
+    public static void streamCloseTest() throws Exception {
+        Scanner sc;
+
+        Scanner sc1 = new Scanner("xyzzy");
+        sc1.tokens().close();
+        try {
+            sc1.hasNext();
+            failCount++;
+        } catch (IllegalStateException ise) {
+            // Correct result
+        }
+
+        Scanner sc2 = new Scanner("a b c d e f");
+        try {
+            sc2.tokens()
+               .peek(s -> sc2.close())
+               .count();
+        } catch (IllegalStateException ise) {
+            // Correct result
+        }
+
+        Scanner sc3 = new Scanner("xyzzy");
+        sc3.findAll("q").close();
+        try {
+            sc3.hasNext();
+            failCount++;
+        } catch (IllegalStateException ise) {
+            // Correct result
+        }
+
+        try (Scanner sc4 = new Scanner(inputFile)) {
+            sc4.findAll("[0-9]+")
+               .peek(s -> sc4.close())
+               .count();
+            failCount++;
+        } catch (IllegalStateException ise) {
+            // Correct result
+        }
+
+        report("Streams Close test");
+    }
+
+    /*
+     * Test ConcurrentModificationException
+     */
+    public static void streamComodTest() {
+        try {
+            Scanner sc = new Scanner("a b c d e f");
+            sc.tokens()
+              .peek(s -> sc.hasNext())
+              .count();
+            failCount++;
+        } catch (ConcurrentModificationException cme) {
+            // Correct result
+        }
+
+        try {
+            Scanner sc = new Scanner("a b c d e f");
+            Iterator<String> it = sc.tokens().iterator();
+            it.next();
+            sc.next();
+            it.next();
+            failCount++;
+        } catch (ConcurrentModificationException cme) {
+            // Correct result
+        }
+
+        try {
+            String input = IntStream.range(0, 100)
+                                    .mapToObj(String::valueOf)
+                                    .collect(Collectors.joining(" "));
+            Scanner sc = new Scanner(input);
+            sc.findAll("[0-9]+")
+              .peek(s -> sc.hasNext())
+              .count();
+            failCount++;
+        } catch (ConcurrentModificationException cme) {
+            // Correct result
+        }
+
+        try {
+            String input = IntStream.range(0, 100)
+                                    .mapToObj(String::valueOf)
+                                    .collect(Collectors.joining(" "));
+            Scanner sc = new Scanner(input);
+            Iterator<MatchResult> it = sc.findAll("[0-9]+").iterator();
+            it.next();
+            sc.next();
+            it.next();
+            failCount++;
+        } catch (ConcurrentModificationException cme) {
+            // Correct result
+        }
+
+        report("Streams Comod test");
+    }
+
     private static void report(String testName) {
-        int spacesToAdd = 30 - testName.length();
-        StringBuffer paddedNameBuffer = new StringBuffer(testName);
-        for (int i=0; i<spacesToAdd; i++)
-            paddedNameBuffer.append(" ");
-        String paddedName = paddedNameBuffer.toString();
-        System.err.println(paddedName + ": " +
-                           (failCount==0 ? "Passed":"Failed("+failCount+")"));
+        System.err.printf("%-30s: %s%n", testName,
+                          (failCount == 0) ? "Passed" : String.format("Failed(%d)", failCount));
+
         if (failCount > 0)
             failure = true;
         failCount = 0;
     }
 
< prev index next >