/* * Copyright 2013 Google Inc. * * 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.common.jimfs; import static com.google.common.jimfs.PathNormalization.CASE_FOLD_ASCII; import static com.google.common.jimfs.PathSubject.paths; import static com.google.common.truth.Truth.assertAbout; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.PathMatcher; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for {@link PathService}. * * @author Colin Decker */ @RunWith(JUnit4.class) public class PathServiceTest { private static final ImmutableSet NO_NORMALIZATIONS = ImmutableSet.of(); private final PathService service = fakeUnixPathService(); @Test public void testBasicProperties() { assertThat(service.getSeparator()).isEqualTo("/"); assertThat(fakeWindowsPathService().getSeparator()).isEqualTo("\\"); } @Test public void testPathCreation() { assertAbout(paths()) .that(service.emptyPath()) .hasRootComponent(null) .and() .hasNameComponents(""); assertAbout(paths()) .that(service.createRoot(service.name("/"))) .isAbsolute() .and() .hasRootComponent("/") .and() .hasNoNameComponents(); assertAbout(paths()) .that(service.createFileName(service.name("foo"))) .hasRootComponent(null) .and() .hasNameComponents("foo"); JimfsPath relative = service.createRelativePath(service.names(ImmutableList.of("foo", "bar"))); assertAbout(paths()) .that(relative) .hasRootComponent(null) .and() .hasNameComponents("foo", "bar"); JimfsPath absolute = service.createPath(service.name("/"), service.names(ImmutableList.of("foo", "bar"))); assertAbout(paths()) .that(absolute) .isAbsolute() .and() .hasRootComponent("/") .and() .hasNameComponents("foo", "bar"); } @Test public void testPathCreation_emptyPath() { // normalized to empty path with single empty string name assertAbout(paths()) .that(service.createPath(null, ImmutableList.of())) .hasRootComponent(null) .and() .hasNameComponents(""); } @Test public void testPathCreation_parseIgnoresEmptyString() { // if the empty string wasn't ignored, the resulting path would be "/foo" since the empty // string would be joined with foo assertAbout(paths()) .that(service.parsePath("", "foo")) .hasRootComponent(null) .and() .hasNameComponents("foo"); } @Test public void testToString() { // not much to test for this since it just delegates to PathType anyway JimfsPath path = new JimfsPath(service, null, ImmutableList.of(Name.simple("foo"), Name.simple("bar"))); assertThat(service.toString(path)).isEqualTo("foo/bar"); path = new JimfsPath(service, Name.simple("/"), ImmutableList.of(Name.simple("foo"))); assertThat(service.toString(path)).isEqualTo("/foo"); } @Test public void testHash_usingDisplayForm() { PathService pathService = fakePathService(PathType.unix(), false); JimfsPath path1 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("FOO", "foo"))); JimfsPath path2 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("FOO", "FOO"))); JimfsPath path3 = new JimfsPath( pathService, null, ImmutableList.of(Name.create("FOO", "9874238974897189741"))); assertThat(pathService.hash(path1)).isEqualTo(pathService.hash(path2)); assertThat(pathService.hash(path2)).isEqualTo(pathService.hash(path3)); } @Test public void testHash_usingCanonicalForm() { PathService pathService = fakePathService(PathType.unix(), true); JimfsPath path1 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("foo", "foo"))); JimfsPath path2 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("FOO", "foo"))); JimfsPath path3 = new JimfsPath( pathService, null, ImmutableList.of(Name.create("28937497189478912374897", "foo"))); assertThat(pathService.hash(path1)).isEqualTo(pathService.hash(path2)); assertThat(pathService.hash(path2)).isEqualTo(pathService.hash(path3)); } @Test public void testCompareTo_usingDisplayForm() { PathService pathService = fakePathService(PathType.unix(), false); JimfsPath path1 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("a", "z"))); JimfsPath path2 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("b", "y"))); JimfsPath path3 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("c", "x"))); assertThat(pathService.compare(path1, path2)).isEqualTo(-1); assertThat(pathService.compare(path2, path3)).isEqualTo(-1); } @Test public void testCompareTo_usingCanonicalForm() { PathService pathService = fakePathService(PathType.unix(), true); JimfsPath path1 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("a", "z"))); JimfsPath path2 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("b", "y"))); JimfsPath path3 = new JimfsPath(pathService, null, ImmutableList.of(Name.create("c", "x"))); assertThat(pathService.compare(path1, path2)).isEqualTo(1); assertThat(pathService.compare(path2, path3)).isEqualTo(1); } @Test public void testPathMatcher() { assertThat(service.createPathMatcher("regex:foo")) .isInstanceOf(PathMatchers.RegexPathMatcher.class); assertThat(service.createPathMatcher("glob:foo")) .isInstanceOf(PathMatchers.RegexPathMatcher.class); } @Test public void testPathMatcher_usingCanonicalForm_usesCanonicalNormalizations() { // https://github.com/google/jimfs/issues/91 // This matches the behavior of Windows (the only built-in configuration that uses canonical // form for equality). There, PathMatchers should do case-insensitive matching despite Windows // not normalizing case for display. assertCaseInsensitiveMatches( new PathService( PathType.unix(), NO_NORMALIZATIONS, ImmutableSet.of(CASE_FOLD_ASCII), true)); assertCaseSensitiveMatches( new PathService( PathType.unix(), ImmutableSet.of(CASE_FOLD_ASCII), NO_NORMALIZATIONS, true)); } @Test public void testPathMatcher_usingDisplayForm_usesDisplayNormalizations() { assertCaseInsensitiveMatches( new PathService( PathType.unix(), ImmutableSet.of(CASE_FOLD_ASCII), NO_NORMALIZATIONS, false)); assertCaseSensitiveMatches( new PathService( PathType.unix(), NO_NORMALIZATIONS, ImmutableSet.of(CASE_FOLD_ASCII), false)); } private static void assertCaseInsensitiveMatches(PathService service) { ImmutableList matchers = ImmutableList.of( service.createPathMatcher("glob:foo"), service.createPathMatcher("glob:FOO")); JimfsPath lowerCasePath = singleNamePath(service, "foo"); JimfsPath upperCasePath = singleNamePath(service, "FOO"); JimfsPath nonMatchingPath = singleNamePath(service, "bar"); for (PathMatcher matcher : matchers) { assertThat(matcher.matches(lowerCasePath)).isTrue(); assertThat(matcher.matches(upperCasePath)).isTrue(); assertThat(matcher.matches(nonMatchingPath)).isFalse(); } } private static void assertCaseSensitiveMatches(PathService service) { PathMatcher matcher = service.createPathMatcher("glob:foo"); JimfsPath lowerCasePath = singleNamePath(service, "foo"); JimfsPath upperCasePath = singleNamePath(service, "FOO"); assertThat(matcher.matches(lowerCasePath)).isTrue(); assertThat(matcher.matches(upperCasePath)).isFalse(); } public static PathService fakeUnixPathService() { return fakePathService(PathType.unix(), false); } public static PathService fakeWindowsPathService() { return fakePathService(PathType.windows(), false); } public static PathService fakePathService(PathType type, boolean equalityUsesCanonicalForm) { PathService service = new PathService(type, NO_NORMALIZATIONS, NO_NORMALIZATIONS, equalityUsesCanonicalForm); service.setFileSystem(FILE_SYSTEM); return service; } private static JimfsPath singleNamePath(PathService service, String name) { return new JimfsPath(service, null, ImmutableList.of(Name.create(name, name))); } private static final FileSystem FILE_SYSTEM; static { try { FILE_SYSTEM = JimfsFileSystems.newFileSystem( new JimfsFileSystemProvider(), URI.create("jimfs://foo"), Configuration.unix()); } catch (IOException e) { throw new AssertionError(e); } } }