1 /*
   2  * Copyright (c) 2018, 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 import java.lang.System;
  25 import java.io.File;
  26 import java.nio.file.Path;
  27 import java.util.List;
  28 import java.util.stream.Collectors;
  29 
  30 import java.nio.file.Paths;
  31 
  32 import jdk.internal.util.PathParser;
  33 import org.testng.Assert;
  34 import org.testng.IMethodInstance;
  35 import org.testng.IMethodInterceptor;
  36 import org.testng.TestListenerAdapter;
  37 import org.testng.TestNG;
  38 import org.testng.annotations.BeforeTest;
  39 import org.testng.annotations.DataProvider;
  40 import org.testng.annotations.Test;
  41 
  42 /*
  43  * @test
  44  * @bug 4463345 4244670 8030781
  45  * @summary Tests of parsing paths via public and internal APIs
  46  * @modules java.base/jdk.internal.util:+open
  47  * @run testng/othervm ParsePathTest
  48  */
  49 
  50 @Test
  51 public class ParsePathTest {
  52 
  53     static final String SP = File.pathSeparator;
  54 
  55     @DataProvider(name = "pathData")
  56     static Object[][] pathData() {
  57         if (System.getProperty("os.name").contains("Windows")) {
  58             return new Object[][]{
  59                     // Common path lists
  60                     {"", List.of(".")},
  61                     {SP, List.of(".", ".")},
  62                     {"a" + SP, List.of("a", ".")},
  63                     {SP + "b", List.of(".", "b")},
  64                     {"a" + SP + SP + "b", List.of("a", ".", "b")},
  65 
  66                     // on Windows parts of paths may be quoted
  67                     {"\"\"", List.of(".")},
  68                     {"\"\"" + SP, List.of(".", ".")},
  69                     {SP + "\"\"", List.of(".", ".")},
  70                     {"a" + SP + "\"b\"" + SP, List.of("a", "b", ".")},
  71                     {SP + "\"a\"" + SP + SP + "b", List.of(".", "a", ".", "b")},
  72                     {"\"a\"" + SP + "\"b\"", List.of("a", "b")},
  73                     {"\"/a/\"b" + SP + "c", List.of("/a/b", "c")},
  74                     {"\"/a;b\"" + SP + "c", List.of("/a;b", "c")},
  75                     {"\"/a" + SP + "b\"" + SP + "c", List.of("/a" + SP + "b", "c")},
  76                     {"/\"a\"\";\"\"b\"" + SP + "\"c\"", List.of("/a;b", "c")},
  77 
  78                     // Unmatched trailing quotes
  79                     {"\"c\"" + SP +  "/\"a\"\";\"\"b",  List.of("c", "/a;b")},
  80                     {"\"c\"" + SP +  "/\"a\"\";b",  List.of("c", "/a;b")},
  81 
  82             };
  83         } else {
  84             return new Object[][]{
  85                     {"", List.of(".")},
  86                     {SP, List.of(".", ".")},
  87                     {"a" + SP, List.of("a", ".")},
  88                     {SP + "b", List.of(".", "b")},
  89                     {"a" + SP + SP + "b", List.of("a", ".", "b")},
  90             };
  91         }
  92     }
  93 
  94     /**
  95      * Test public API that produces lists of Path.
  96      */
  97     @Test(dataProvider = "pathData")
  98     static void checkPathToPaths(String path, List<String>expected) {
  99         List<Path> newExpected = expected.stream()
 100                 .filter(s -> !s.equals("."))
 101                 .map( s -> Path.of(s))
 102                 .collect(Collectors.toList());
 103         List<Path> s = Paths.pathToPaths(path);
 104         Assert.assertEquals(s, newExpected, path + " as " + newExpected.toString());
 105     }
 106 
 107     /**
 108      * Test public API that produces lists of String.
 109      */
 110     @Test(dataProvider = "pathData")
 111     static void checkpathToStrings(String path, List<String>expected) {
 112         List<String> newExpected = expected.stream()
 113                 .filter(s -> !s.equals("."))
 114                 .collect(Collectors.toList());
 115         List<String> s = Paths.pathToStrings(path);
 116         Assert.assertEquals(s, newExpected, path + " as " + newExpected.toString());
 117     }
 118 
 119     /**
 120      * Test internal API that parses to arrays of String with replaced empty path.
 121      * @param path  a path
 122      * @param expected a list of the expected path strings
 123      */
 124     @Test(dataProvider = "pathData")
 125     static void checkpathToStringsRepl(String path, List<String> expected) {
 126         List<String> s = List.of(PathParser.parsePath(path, "."));
 127         Assert.assertEquals(s, expected, path + " as " + expected.toString());
 128     }
 129 
 130     /**
 131      * Test internal API that parses to arrays of String omitting empty paths.
 132      * @param path  a path
 133      * @param expected a list of the expected path strings
 134      */
 135     @Test(dataProvider = "pathData")
 136     static void checkpathToStringsNoRepl(String path, List<String>expected) {
 137         List<String> newExpected = expected.stream()
 138                 .filter(s -> !s.equals("."))
 139                 .collect(Collectors.toList());
 140         List<String> s = List.of(PathParser.parsePath(path, null));
 141         Assert.assertEquals(s, newExpected, path + " as " + newExpected.toString());
 142     }
 143 
 144 
 145     /**
 146      * Main to allow stand alone execution.
 147      * @param args command line args - none expected
 148      */
 149     @SuppressWarnings("raw_types")
 150     @Test(enabled=false)
 151     public static void main(String[] args) {
 152         TestListenerAdapter tla = new TestListenerAdapter();
 153 
 154         Class<?>[] testclass = {ParsePathTest.class};
 155         TestNG testng = new TestNG();
 156         testng.setTestClasses(testclass);
 157         testng.addListener(tla);
 158         if (args.length > 0) {
 159             IMethodInterceptor intercept = (m, c) -> {
 160                 List<IMethodInstance> x = m.stream()
 161                         .filter(m1 -> m1.getMethod().getMethodName().contains(args[0]))
 162                         .collect(Collectors.toList());
 163                 return x;
 164             };
 165             testng.setMethodInterceptor(intercept);
 166         }
 167         testng.run();
 168         tla.getPassedTests()
 169                 .stream().forEach(t -> System.out.printf("Passed: %s%s%n", t.getName(),
 170                 List.of(t.getParameters())));
 171         tla.getFailedTests()
 172                 .stream().forEach(t -> System.out.printf("Failed: %s%s%n", t.getName(),
 173                 List.of(t.getParameters())));
 174     }
 175 }