aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/vfs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/vfs')
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java180
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java48
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java169
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java164
4 files changed, 561 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java b/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java
new file mode 100644
index 0000000000..93869521ad
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/vfs/LocalPathAbstractTest.java
@@ -0,0 +1,180 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.vfs;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
+import static java.util.stream.Collectors.toList;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+
+/** Tests for {@link LocalPath}. */
+public abstract class LocalPathAbstractTest {
+
+ private OsPathPolicy os;
+
+ @Before
+ public void setup() {
+ os = getFilePathOs();
+ }
+
+ @Test
+ public void testEqualsAndHashCode() {
+ new EqualsTester()
+ .addEqualityGroup(
+ create("../relative/path"), create("..").getRelative("relative").getRelative("path"))
+ .addEqualityGroup(create("something/else"))
+ .addEqualityGroup(create(""), LocalPath.EMPTY)
+ .testEquals();
+ }
+
+ @Test
+ public void testRelativeTo() {
+ assertThat(create("").relativeTo(create("")).getPathString()).isEmpty();
+ assertThat(create("foo").relativeTo(create("foo")).getPathString()).isEmpty();
+ assertThat(create("foo/bar/baz").relativeTo(create("foo")).getPathString())
+ .isEqualTo("bar/baz");
+ assertThat(create("foo/bar/baz").relativeTo(create("foo/bar")).getPathString())
+ .isEqualTo("baz");
+ assertThat(create("foo").relativeTo(create("")).getPathString()).isEqualTo("foo");
+
+ // Cannot relativize non-ancestors
+ assertThrows(IllegalArgumentException.class, () -> create("foo/bar").relativeTo(create("fo")));
+
+ // Make sure partial directory matches aren't reported
+ assertThrows(
+ IllegalArgumentException.class, () -> create("foo/bar").relativeTo(create("foo/ba")));
+ }
+
+ @Test
+ public void testGetRelative() {
+ assertThat(create("a").getRelative("b").getPathString()).isEqualTo("a/b");
+ assertThat(create("a/b").getRelative("c/d").getPathString()).isEqualTo("a/b/c/d");
+ assertThat(create("a").getRelative("").getPathString()).isEqualTo("a");
+ assertThat(create("a/b").getRelative("../c").getPathString()).isEqualTo("a/c");
+ assertThat(create("a/b").getRelative("..").getPathString()).isEqualTo("a");
+ }
+
+ @Test
+ public void testEmptyPathToEmptyPath() {
+ // compare string forms
+ assertThat(create("").getPathString()).isEmpty();
+ // compare fragment forms
+ assertThat(create("")).isEqualTo(create(""));
+ }
+
+ @Test
+ public void testSimpleNameToSimpleName() {
+ // compare string forms
+ assertThat(create("foo").getPathString()).isEqualTo("foo");
+ // compare fragment forms
+ assertThat(create("foo")).isEqualTo(create("foo"));
+ }
+
+ @Test
+ public void testSimplePathToSimplePath() {
+ // compare string forms
+ assertThat(create("foo/bar").getPathString()).isEqualTo("foo/bar");
+ // compare fragment forms
+ assertThat(create("foo/bar")).isEqualTo(create("foo/bar"));
+ }
+
+ @Test
+ public void testStripsTrailingSlash() {
+ // compare string forms
+ assertThat(create("foo/bar/").getPathString()).isEqualTo("foo/bar");
+ // compare fragment forms
+ assertThat(create("foo/bar/")).isEqualTo(create("foo/bar"));
+ }
+
+ @Test
+ public void testGetParentDirectory() {
+ LocalPath fooBarWiz = create("foo/bar/wiz");
+ LocalPath fooBar = create("foo/bar");
+ LocalPath foo = create("foo");
+ LocalPath empty = create("");
+ assertThat(fooBarWiz.getParentDirectory()).isEqualTo(fooBar);
+ assertThat(fooBar.getParentDirectory()).isEqualTo(foo);
+ assertThat(foo.getParentDirectory()).isEqualTo(empty);
+ assertThat(empty.getParentDirectory()).isNull();
+ }
+
+ @Test
+ public void testBasename() throws Exception {
+ assertThat(create("foo/bar").getBaseName()).isEqualTo("bar");
+ assertThat(create("foo/").getBaseName()).isEqualTo("foo");
+ assertThat(create("foo").getBaseName()).isEqualTo("foo");
+ assertThat(create("").getBaseName()).isEmpty();
+ }
+
+ @Test
+ public void testStartsWith() {
+ // (relative path, relative prefix) => true
+ assertThat(create("foo/bar").startsWith(create("foo/bar"))).isTrue();
+ assertThat(create("foo/bar").startsWith(create("foo"))).isTrue();
+ assertThat(create("foot/bar").startsWith(create("foo"))).isFalse();
+ }
+
+ @Test
+ public void testNormalize() {
+ assertThat(create("a/b")).isEqualTo(create("a/b"));
+ assertThat(create("a/../../b")).isEqualTo(create("../b"));
+ assertThat(create("a/../..")).isEqualTo(create(".."));
+ assertThat(create("a/../b")).isEqualTo(create("b"));
+ assertThat(create("a/b/../b")).isEqualTo(create("a/b"));
+ }
+
+ @Test
+ public void testNormalStringsDoNotAllocate() {
+ String normal1 = "a/b/hello.txt";
+ assertThat(create(normal1).getPathString()).isSameAs(normal1);
+
+ // Sanity check our testing strategy
+ String notNormal = "a/../b";
+ assertThat(create(notNormal).getPathString()).isNotSameAs(notNormal);
+ }
+
+ @Test
+ public void testComparableSortOrder() {
+ List<LocalPath> list =
+ Lists.newArrayList(
+ create("zzz"),
+ create("ZZZ"),
+ create("ABC"),
+ create("aBc"),
+ create("AbC"),
+ create("abc"));
+ Collections.sort(list);
+ List<String> result = list.stream().map(LocalPath::getPathString).collect(toList());
+
+ if (os.isCaseSensitive()) {
+ assertThat(result).containsExactly("ABC", "AbC", "ZZZ", "aBc", "abc", "zzz").inOrder();
+ } else {
+ // Partial ordering among case-insensitive items guaranteed by Collections.sort stability
+ assertThat(result).containsExactly("ABC", "aBc", "AbC", "abc", "zzz", "ZZZ").inOrder();
+ }
+ }
+
+ protected abstract OsPathPolicy getFilePathOs();
+
+ protected LocalPath create(String path) {
+ return LocalPath.createWithOs(path, os);
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java
new file mode 100644
index 0000000000..c99ad487ee
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/vfs/MacOsLocalPathTest.java
@@ -0,0 +1,48 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.vfs;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.vfs.LocalPath.MacOsPathPolicy;
+import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests Mac-specific parts of {@link LocalPath}. */
+@RunWith(JUnit4.class)
+public class MacOsLocalPathTest extends UnixLocalPathTest {
+
+ @Override
+ protected OsPathPolicy getFilePathOs() {
+ return new MacOsPathPolicy();
+ }
+
+ @Test
+ public void testMacEqualsAndHashCode() {
+ new EqualsTester()
+ .addEqualityGroup(create("a/b"), create("A/B"))
+ .addEqualityGroup(create("/a/b"), create("/A/B"))
+ .addEqualityGroup(create("something/else"))
+ .addEqualityGroup(create("/something/else"))
+ .testEquals();
+ }
+
+ @Test
+ public void testCaseIsPreserved() {
+ assertThat(create("a/B").getPathString()).isEqualTo("a/B");
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java
new file mode 100644
index 0000000000..2cdb4014ae
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/vfs/UnixLocalPathTest.java
@@ -0,0 +1,169 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.vfs;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
+
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy;
+import com.google.devtools.build.lib.vfs.LocalPath.UnixOsPathPolicy;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests the unix implementation of {@link LocalPath}. */
+@RunWith(JUnit4.class)
+public class UnixLocalPathTest extends LocalPathAbstractTest {
+
+ @Test
+ public void testEqualsAndHashCodeUnix() {
+ new EqualsTester()
+ .addEqualityGroup(create("/something/else"))
+ .addEqualityGroup(create("/"), create("//////"))
+ .testEquals();
+ }
+
+ @Test
+ public void testRelativeToUnix() {
+ // Cannot relativize absolute and non-absolute
+ assertThat(create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b");
+ assertThat(create("/").relativeTo(create("/")).getPathString()).isEmpty();
+ assertThat(create("/foo").relativeTo(create("/foo")).getPathString()).isEmpty();
+ assertThat(create("/foo/bar/baz").relativeTo(create("/foo")).getPathString())
+ .isEqualTo("bar/baz");
+ assertThat(create("/foo/bar/baz").relativeTo(create("/foo/bar")).getPathString())
+ .isEqualTo("baz");
+ assertThat(create("/foo").relativeTo(create("/")).getPathString()).isEqualTo("foo");
+ assertThrows(
+ IllegalArgumentException.class, () -> create("/foo/bar/baz").relativeTo(create("foo")));
+ assertThrows(
+ IllegalArgumentException.class, () -> create("/foo").relativeTo(create("/foo/bar/baz")));
+ }
+
+ @Test
+ public void testIsAbsoluteUnix() {
+ assertThat(create("/absolute/test").isAbsolute()).isTrue();
+ assertThat(create("relative/test").isAbsolute()).isFalse();
+ }
+
+ @Test
+ public void testGetRelativeUnix() {
+ assertThat(create("/a").getRelative("b").getPathString()).isEqualTo("/a/b");
+ assertThat(create("/").getRelative("").getPathString()).isEqualTo("/");
+ assertThat(create("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b");
+ }
+
+ @Test
+ public void testEmptyPathToEmptyPathUnix() {
+ // compare string forms
+ assertThat(create("/").getPathString()).isEqualTo("/");
+ // compare fragment forms
+ assertThat(create("/")).isEqualTo(create("/"));
+ }
+
+ @Test
+ public void testRedundantSlashes() {
+ // compare string forms
+ assertThat(create("///").getPathString()).isEqualTo("/");
+ // compare fragment forms
+ assertThat(create("///")).isEqualTo(create("/"));
+ // compare string forms
+ assertThat(create("/foo///bar").getPathString()).isEqualTo("/foo/bar");
+ // compare fragment forms
+ assertThat(create("/foo///bar")).isEqualTo(create("/foo/bar"));
+ // compare string forms
+ assertThat(create("////foo//bar").getPathString()).isEqualTo("/foo/bar");
+ // compare fragment forms
+ assertThat(create("////foo//bar")).isEqualTo(create("/foo/bar"));
+ }
+
+ @Test
+ public void testSimpleNameToSimpleNameUnix() {
+ // compare string forms
+ assertThat(create("/foo").getPathString()).isEqualTo("/foo");
+ // compare fragment forms
+ assertThat(create("/foo")).isEqualTo(create("/foo"));
+ }
+
+ @Test
+ public void testSimplePathToSimplePathUnix() {
+ // compare string forms
+ assertThat(create("/foo/bar").getPathString()).isEqualTo("/foo/bar");
+ // compare fragment forms
+ assertThat(create("/foo/bar")).isEqualTo(create("/foo/bar"));
+ }
+
+ @Test
+ public void testGetParentDirectoryUnix() {
+ LocalPath fooBarWizAbs = create("/foo/bar/wiz");
+ LocalPath fooBarAbs = create("/foo/bar");
+ LocalPath fooAbs = create("/foo");
+ LocalPath rootAbs = create("/");
+ assertThat(fooBarWizAbs.getParentDirectory()).isEqualTo(fooBarAbs);
+ assertThat(fooBarAbs.getParentDirectory()).isEqualTo(fooAbs);
+ assertThat(fooAbs.getParentDirectory()).isEqualTo(rootAbs);
+ assertThat(rootAbs.getParentDirectory()).isNull();
+ }
+
+ @Test
+ public void testBasenameUnix() throws Exception {
+ assertThat(create("/foo/bar").getBaseName()).isEqualTo("bar");
+ assertThat(create("/foo/").getBaseName()).isEqualTo("foo");
+ assertThat(create("/foo").getBaseName()).isEqualTo("foo");
+ assertThat(create("/").getBaseName()).isEmpty();
+ }
+
+ @Test
+ public void testStartsWithUnix() {
+ LocalPath foobar = create("/foo/bar");
+ LocalPath foobarRelative = create("foo/bar");
+
+ // (path, prefix) => true
+ assertThat(foobar.startsWith(foobar)).isTrue();
+ assertThat(foobar.startsWith(create("/"))).isTrue();
+ assertThat(foobar.startsWith(create("/foo"))).isTrue();
+ assertThat(foobar.startsWith(create("/foo/"))).isTrue();
+ assertThat(foobar.startsWith(create("/foo/bar/"))).isTrue(); // Includes trailing slash.
+
+ // (prefix, path) => false
+ assertThat(create("/foo").startsWith(foobar)).isFalse();
+ assertThat(create("/").startsWith(foobar)).isFalse();
+
+ // (absolute, relative) => false
+ assertThat(foobar.startsWith(foobarRelative)).isFalse();
+ assertThat(foobarRelative.startsWith(foobar)).isFalse();
+
+ // relative paths start with nothing, absolute paths do not
+ assertThat(foobar.startsWith(create(""))).isFalse();
+
+ // (path, sibling) => false
+ assertThat(create("/foo/wiz").startsWith(foobar)).isFalse();
+ assertThat(foobar.startsWith(create("/foo/wiz"))).isFalse();
+ }
+
+ @Test
+ public void testNormalizeUnix() {
+ assertThat(create("/a/b")).isEqualTo(create("/a/b"));
+ assertThat(create("/a/b/")).isEqualTo(create("/a/b"));
+ assertThat(create("/a/./b")).isEqualTo(create("/a/b"));
+ assertThat(create("/a/../b")).isEqualTo(create("/b"));
+ assertThat(create("/..")).isEqualTo(create("/.."));
+ }
+
+ @Override
+ protected OsPathPolicy getFilePathOs() {
+ return new UnixOsPathPolicy();
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java b/src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java
new file mode 100644
index 0000000000..ac5acef1f4
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/vfs/WindowsLocalPathTest.java
@@ -0,0 +1,164 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.vfs;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.testutil.MoreAsserts;
+import com.google.devtools.build.lib.vfs.LocalPath.OsPathPolicy;
+import com.google.devtools.build.lib.vfs.LocalPath.WindowsOsPathPolicy;
+import com.google.devtools.build.lib.vfs.LocalPath.WindowsOsPathPolicy.ShortPathResolver;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests windows-specific parts of {@link LocalPath} */
+@RunWith(JUnit4.class)
+public class WindowsLocalPathTest extends LocalPathAbstractTest {
+
+ private static final class MockShortPathResolver implements ShortPathResolver {
+ // Full path to resolved child mapping.
+ private Map<String, String> resolutions = new HashMap<>();
+
+ @Override
+ public String resolveShortPath(String path) {
+ String[] segments = path.split("[\\\\/]+");
+ String result = "";
+ for (int i = 0; i < segments.length; ) {
+ String segment = segments[i];
+ String queryString = (result + segment).toLowerCase();
+ segment = resolutions.getOrDefault(queryString, segment);
+ result = result + segment;
+ ++i;
+ if (i != segments.length) {
+ result += "/";
+ }
+ }
+ return result;
+ }
+ }
+
+ private final MockShortPathResolver shortPathResolver = new MockShortPathResolver();
+
+ @Override
+ protected OsPathPolicy getFilePathOs() {
+ return new WindowsOsPathPolicy(shortPathResolver);
+ }
+
+ @Test
+ public void testEqualsAndHashcodeWindows() {
+ new EqualsTester()
+ .addEqualityGroup(create("a/b"), create("A/B"))
+ .addEqualityGroup(create("/a/b"), create("/A/B"))
+ .addEqualityGroup(create("c:/a/b"), create("C:\\A\\B"))
+ .addEqualityGroup(create("something/else"))
+ .testEquals();
+ }
+
+ @Test
+ public void testCaseIsPreserved() {
+ assertThat(create("a/B").getPathString()).isEqualTo("a/B");
+ }
+
+ @Test
+ public void testNormalizeWindows() {
+ assertThat(create("C:/")).isEqualTo(create("C:/"));
+ assertThat(create("c:/")).isEqualTo(create("C:/"));
+ assertThat(create("c:\\")).isEqualTo(create("C:/"));
+ assertThat(create("c:\\foo\\..\\bar\\")).isEqualTo(create("C:/bar"));
+ }
+
+ @Test
+ public void testStartsWithWindows() {
+ assertThat(create("C:/").startsWith(create("C:/"))).isTrue();
+ assertThat(create("C:/foo").startsWith(create("C:/"))).isTrue();
+ assertThat(create("C:/foo").startsWith(create("D:/"))).isFalse();
+
+ // Case insensitivity test
+ assertThat(create("C:/foo/bar").startsWith(create("C:/FOO"))).isTrue();
+ }
+
+ @Test
+ public void testGetParentDirectoryWindows() {
+ assertThat(create("C:/foo").getParentDirectory()).isEqualTo(create("C:/"));
+ assertThat(create("C:/").getParentDirectory()).isNull();
+ }
+
+ @Test
+ public void testisAbsoluteWindows() {
+ assertThat(create("C:/").isAbsolute()).isTrue();
+ // test that msys paths turn into absolute paths
+ assertThat(create("/").isAbsolute()).isTrue();
+ }
+
+ @Test
+ public void testRelativeToWindows() {
+ assertThat(create("C:/foo").relativeTo(create("C:/"))).isEqualTo(create("foo"));
+ // Case insensitivity test
+ assertThat(create("C:/foo/bar").relativeTo(create("C:/FOO"))).isEqualTo(create("bar"));
+ MoreAsserts.assertThrows(
+ IllegalArgumentException.class, () -> create("D:/foo").relativeTo(create("C:/")));
+ }
+
+ @Test
+ public void testAbsoluteUnixPathIsRelativeToWindowsUnixRoot() {
+ assertThat(create("/").getPathString()).isEqualTo("C:/fake/msys");
+ assertThat(create("/foo/bar").getPathString()).isEqualTo("C:/fake/msys/foo/bar");
+ assertThat(create("/foo/bar").getPathString()).isEqualTo("C:/fake/msys/foo/bar");
+ }
+
+ @Test
+ public void testAbsoluteUnixPathReferringToDriveIsRecognized() {
+ assertThat(create("/c/foo").getPathString()).isEqualTo("C:/foo");
+ assertThat(create("/c/foo").getPathString()).isEqualTo("C:/foo");
+ assertThat(create("/c:").getPathString()).isNotEqualTo("C:/foo");
+ }
+
+ @Test
+ public void testResolvesShortenedPaths() {
+ shortPathResolver.resolutions.put("d:/progra~1", "program files");
+ shortPathResolver.resolutions.put("d:/program files/micros~1", "microsoft something");
+ shortPathResolver.resolutions.put(
+ "d:/program files/microsoft something/foo/~bar~1", "~bar_hello");
+
+ // Assert normal shortpath resolution.
+ LocalPath normal = create("d:/progra~1/micros~1/foo/~bar~1/baz");
+ // The path string has an upper-case drive letter because that's how path printing works.
+ assertThat(normal.getPathString())
+ .isEqualTo("D:/program files/microsoft something/foo/~bar_hello/baz");
+ LocalPath notYetExistent = create("d:/progra~1/micros~1/foo/will~1.exi/bar");
+ // The path string has an upper-case drive letter because that's how path printing works.
+ assertThat(notYetExistent.getPathString())
+ .isEqualTo("D:/program files/microsoft something/foo/will~1.exi/bar");
+
+ LocalPath msRoot = create("d:/progra~1/micros~1");
+ assertThat(msRoot.getPathString()).isEqualTo("D:/program files/microsoft something");
+
+ // Pretend that a path we already failed to resolve once came into existence.
+ shortPathResolver.resolutions.put(
+ "d:/program files/microsoft something/foo/will~1.exi", "will.exist");
+
+ // Assert that this time we can resolve the previously non-existent path.
+ LocalPath nowExists = create("d:/progra~1/micros~1/foo/will~1.exi/bar");
+ // The path string has an upper-case drive letter because that's how path printing works.
+ assertThat(nowExists.getPathString())
+ .isEqualTo("D:/program files/microsoft something/foo/will.exist/bar");
+
+ // Assert relative paths that look like short paths are untouched
+ assertThat(create("progra~1").getPathString()).isEqualTo("progra~1");
+ }
+}