1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.jimfs; 18 19 import static com.google.common.base.Functions.toStringFunction; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 26 import com.google.common.base.Joiner; 27 import com.google.common.base.Splitter; 28 import com.google.common.collect.FluentIterable; 29 import com.google.common.collect.ImmutableList; 30 import java.nio.file.Path; 31 import java.util.Arrays; 32 import java.util.List; 33 34 /** @author Colin Decker */ 35 public final class PathTester { 36 37 private final PathService pathService; 38 private final String string; 39 private String root; 40 private ImmutableList<String> names = ImmutableList.of(); 41 PathTester(PathService pathService, String string)42 public PathTester(PathService pathService, String string) { 43 this.pathService = pathService; 44 this.string = string; 45 } 46 root(String root)47 public PathTester root(String root) { 48 this.root = root; 49 return this; 50 } 51 names(Iterable<String> names)52 public PathTester names(Iterable<String> names) { 53 this.names = ImmutableList.copyOf(names); 54 return this; 55 } 56 names(String... names)57 public PathTester names(String... names) { 58 return names(Arrays.asList(names)); 59 } 60 test(String first, String... more)61 public void test(String first, String... more) { 62 Path path = pathService.parsePath(first, more); 63 test(path); 64 } 65 test(Path path)66 public void test(Path path) { 67 assertEquals(string, path.toString()); 68 69 testRoot(path); 70 testNames(path); 71 testParents(path); 72 testStartsWith(path); 73 testEndsWith(path); 74 testSubpaths(path); 75 } 76 testRoot(Path path)77 private void testRoot(Path path) { 78 if (root != null) { 79 assertTrue(path + ".isAbsolute() should be true", path.isAbsolute()); 80 assertNotNull(path + ".getRoot() should not be null", path.getRoot()); 81 assertEquals(root, path.getRoot().toString()); 82 } else { 83 assertFalse(path + ".isAbsolute() should be false", path.isAbsolute()); 84 assertNull(path + ".getRoot() should be null", path.getRoot()); 85 } 86 } 87 testNames(Path path)88 private void testNames(Path path) { 89 assertEquals(names.size(), path.getNameCount()); 90 assertEquals(names, names(path)); 91 for (int i = 0; i < names.size(); i++) { 92 assertEquals(names.get(i), path.getName(i).toString()); 93 // don't test individual names if this is an individual name 94 if (names.size() > 1) { 95 new PathTester(pathService, names.get(i)).names(names.get(i)).test(path.getName(i)); 96 } 97 } 98 if (names.size() > 0) { 99 String fileName = names.get(names.size() - 1); 100 assertEquals(fileName, path.getFileName().toString()); 101 // don't test individual names if this is an individual name 102 if (names.size() > 1) { 103 new PathTester(pathService, fileName).names(fileName).test(path.getFileName()); 104 } 105 } 106 } 107 testParents(Path path)108 private void testParents(Path path) { 109 Path parent = path.getParent(); 110 111 if (root != null && names.size() >= 1 || names.size() > 1) { 112 assertNotNull(parent); 113 } 114 115 if (parent != null) { 116 String parentName = names.size() == 1 ? root : string.substring(0, string.lastIndexOf('/')); 117 new PathTester(pathService, parentName) 118 .root(root) 119 .names(names.subList(0, names.size() - 1)) 120 .test(parent); 121 } 122 } 123 testSubpaths(Path path)124 private void testSubpaths(Path path) { 125 if (path.getRoot() == null) { 126 assertEquals(path, path.subpath(0, path.getNameCount())); 127 } 128 129 if (path.getNameCount() > 1) { 130 String stringWithoutRoot = root == null ? string : string.substring(root.length()); 131 132 // test start + 1 to end and start to end - 1 subpaths... this recursively tests all subpaths 133 // actually tests most possible subpaths multiple times but... eh 134 Path startSubpath = path.subpath(1, path.getNameCount()); 135 List<String> startNames = 136 ImmutableList.copyOf(Splitter.on('/').split(stringWithoutRoot)) 137 .subList(1, path.getNameCount()); 138 139 new PathTester(pathService, Joiner.on('/').join(startNames)) 140 .names(startNames) 141 .test(startSubpath); 142 143 Path endSubpath = path.subpath(0, path.getNameCount() - 1); 144 List<String> endNames = 145 ImmutableList.copyOf(Splitter.on('/').split(stringWithoutRoot)) 146 .subList(0, path.getNameCount() - 1); 147 148 new PathTester(pathService, Joiner.on('/').join(endNames)).names(endNames).test(endSubpath); 149 } 150 } 151 testStartsWith(Path path)152 private void testStartsWith(Path path) { 153 // empty path doesn't start with any path 154 if (root != null || !names.isEmpty()) { 155 Path other = path; 156 while (other != null) { 157 assertTrue(path + ".startsWith(" + other + ") should be true", path.startsWith(other)); 158 assertTrue( 159 path + ".startsWith(" + other + ") should be true", path.startsWith(other.toString())); 160 other = other.getParent(); 161 } 162 } 163 } 164 testEndsWith(Path path)165 private void testEndsWith(Path path) { 166 // empty path doesn't start with any path 167 if (root != null || !names.isEmpty()) { 168 Path other = path; 169 while (other != null) { 170 assertTrue(path + ".endsWith(" + other + ") should be true", path.endsWith(other)); 171 assertTrue( 172 path + ".endsWith(" + other + ") should be true", path.endsWith(other.toString())); 173 if (other.getRoot() != null && other.getNameCount() > 0) { 174 other = other.subpath(0, other.getNameCount()); 175 } else if (other.getNameCount() > 1) { 176 other = other.subpath(1, other.getNameCount()); 177 } else { 178 other = null; 179 } 180 } 181 } 182 } 183 names(Path path)184 private static List<String> names(Path path) { 185 return FluentIterable.from(path).transform(toStringFunction()).toList(); 186 } 187 } 188