// Copyright 2014 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.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
import static com.google.devtools.build.lib.vfs.PathFragment.create;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.File;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * This class tests the functionality of the PathFragment.
 */
@RunWith(JUnit4.class)
public class PathFragmentTest {

  @Test
  public void testEqualsAndHashCode() {
    InMemoryFileSystem filesystem = new InMemoryFileSystem();

    new EqualsTester()
        .addEqualityGroup(
            create("../relative/path"),
            create("..").getRelative("relative").getRelative("path"),
            create(new File("../relative/path").getPath()))
        .addEqualityGroup(create("something/else"))
        .addEqualityGroup(create("/something/else"))
        .addEqualityGroup(create("/"), create("//////"))
        .addEqualityGroup(create(""), PathFragment.EMPTY_FRAGMENT)
        .addEqualityGroup(filesystem.getPath("/")) // A Path object.
        .testEquals();
  }

  @Test
  public void testHashCodeCache() {
    PathFragment relativePath = create("../relative/path");
    PathFragment rootPath = create("/");

    int oldResult = relativePath.hashCode();
    int rootResult = rootPath.hashCode();
    assertThat(relativePath.hashCode()).isEqualTo(oldResult);
    assertThat(rootPath.hashCode()).isEqualTo(rootResult);
  }

  @Test
  public void testRelativeTo() {
    assertThat(create("foo/bar/baz").relativeTo("foo").getPathString()).isEqualTo("bar/baz");
    assertThat(create("/foo/bar/baz").relativeTo("/foo").getPathString()).isEqualTo("bar/baz");
    assertThat(create("foo/bar/baz").relativeTo("foo/bar").getPathString()).isEqualTo("baz");
    assertThat(create("/foo/bar/baz").relativeTo("/foo/bar").getPathString()).isEqualTo("baz");
    assertThat(create("/foo").relativeTo("/").getPathString()).isEqualTo("foo");
    assertThat(create("foo").relativeTo("").getPathString()).isEqualTo("foo");
    assertThat(create("foo/bar").relativeTo("").getPathString()).isEqualTo("foo/bar");
  }

  @Test
  public void testIsAbsolute() {
    assertThat(create("/absolute/test").isAbsolute()).isTrue();
    assertThat(create("relative/test").isAbsolute()).isFalse();
    assertThat(create(new File("/absolute/test").getPath()).isAbsolute()).isTrue();
    assertThat(create(new File("relative/test").getPath()).isAbsolute()).isFalse();
  }

  @Test
  public void testIsNormalized() {
    assertThat(PathFragment.isNormalized("/absolute/path")).isTrue();
    assertThat(PathFragment.isNormalized("some//path")).isTrue();
    assertThat(PathFragment.isNormalized("some/./path")).isFalse();
    assertThat(PathFragment.isNormalized("../some/path")).isFalse();
    assertThat(PathFragment.isNormalized("./some/path")).isFalse();
    assertThat(PathFragment.isNormalized("some/path/..")).isFalse();
    assertThat(PathFragment.isNormalized("some/path/.")).isFalse();
    assertThat(PathFragment.isNormalized("some/other/../path")).isFalse();
    assertThat(PathFragment.isNormalized("some/other//tricky..path..")).isTrue();
    assertThat(PathFragment.isNormalized("/some/other//tricky..path..")).isTrue();
  }

  @Test
  public void testContainsUpLevelReferences() {
    assertThat(PathFragment.containsUplevelReferences("/absolute/path")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("some//path")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("some/./path")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("../some/path")).isTrue();
    assertThat(PathFragment.containsUplevelReferences("./some/path")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("some/path/..")).isTrue();
    assertThat(PathFragment.containsUplevelReferences("some/path/.")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("some/other/../path")).isTrue();
    assertThat(PathFragment.containsUplevelReferences("some/other//tricky..path..")).isFalse();
    assertThat(PathFragment.containsUplevelReferences("/some/other//tricky..path..")).isFalse();

    // Normalization cannot remove leading uplevel references, so this will be true
    assertThat(create("../some/path").containsUplevelReferences()).isTrue();
    // Normalization will remove these, so no uplevel references left
    assertThat(create("some/path/..").containsUplevelReferences()).isFalse();
  }

  @Test
  public void testRootNodeReturnsRootString() {
    PathFragment rootFragment = create("/");
    assertThat(rootFragment.getPathString()).isEqualTo("/");
  }

  @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("c/d").getRelative("/a/b").getPathString()).isEqualTo("/a/b");
    assertThat(create("a").getRelative("").getPathString()).isEqualTo("a");
    assertThat(create("/").getRelative("").getPathString()).isEqualTo("/");
    assertThat(create("a/b").getRelative("../foo").getPathString()).isEqualTo("a/foo");
    assertThat(create("/a/b").getRelative("../foo").getPathString()).isEqualTo("/a/foo");

    // Make sure any fast path of PathFragment#getRelative(PathFragment) works
    assertThat(create("a/b").getRelative(create("../foo")).getPathString()).isEqualTo("a/foo");
    assertThat(create("/a/b").getRelative(create("../foo")).getPathString()).isEqualTo("/a/foo");

    // Make sure any fast path of PathFragment#getRelative(PathFragment) works
    assertThat(create("c/d").getRelative(create("/a/b")).getPathString()).isEqualTo("/a/b");

    // Test normalization
    assertThat(create("a").getRelative(".").getPathString()).isEqualTo("a");
  }

  @Test
  public void testIsNormalizedRelativePath() {
    assertThat(PathFragment.isNormalizedRelativePath("/a")).isFalse();
    assertThat(PathFragment.isNormalizedRelativePath("a///b")).isFalse();
    assertThat(PathFragment.isNormalizedRelativePath("../a")).isFalse();
    assertThat(PathFragment.isNormalizedRelativePath("a/../b")).isFalse();
    assertThat(PathFragment.isNormalizedRelativePath("a/b")).isTrue();
    assertThat(PathFragment.isNormalizedRelativePath("ab")).isTrue();
  }

  @Test
  public void testContainsSeparator() {
    assertThat(PathFragment.containsSeparator("/a")).isTrue();
    assertThat(PathFragment.containsSeparator("a///b")).isTrue();
    assertThat(PathFragment.containsSeparator("../a")).isTrue();
    assertThat(PathFragment.containsSeparator("a/../b")).isTrue();
    assertThat(PathFragment.containsSeparator("a/b")).isTrue();
    assertThat(PathFragment.containsSeparator("ab")).isFalse();
  }

  @Test
  public void testGetChildWorks() {
    PathFragment pf = create("../some/path");
    assertThat(pf.getChild("hi")).isEqualTo(create("../some/path/hi"));
  }

  @Test
  public void testGetChildRejectsInvalidBaseNames() {
    PathFragment pf = create("../some/path");
    assertThrows(IllegalArgumentException.class, () -> pf.getChild("."));
    assertThrows(IllegalArgumentException.class, () -> pf.getChild(".."));
    assertThrows(IllegalArgumentException.class, () -> pf.getChild("x/y"));
    assertThrows(IllegalArgumentException.class, () -> pf.getChild("/y"));
    assertThrows(IllegalArgumentException.class, () -> pf.getChild("y/"));
    assertThrows(IllegalArgumentException.class, () -> pf.getChild(""));
  }

  @Test
  public void testEmptyPathToEmptyPath() {
    assertThat(create("/").getPathString()).isEqualTo("/");
    assertThat(create("").getPathString()).isEqualTo("");
  }

  @Test
  public void testRedundantSlashes() {
    assertThat(create("///").getPathString()).isEqualTo("/");
    assertThat(create("/foo///bar").getPathString()).isEqualTo("/foo/bar");
    assertThat(create("////foo//bar").getPathString()).isEqualTo("/foo/bar");
  }

  @Test
  public void testSimpleNameToSimpleName() {
    assertThat(create("/foo").getPathString()).isEqualTo("/foo");
    assertThat(create("foo").getPathString()).isEqualTo("foo");
  }

  @Test
  public void testSimplePathToSimplePath() {
    assertThat(create("/foo/bar").getPathString()).isEqualTo("/foo/bar");
    assertThat(create("foo/bar").getPathString()).isEqualTo("foo/bar");
  }

  @Test
  public void testStripsTrailingSlash() {
    assertThat(create("/foo/bar/").getPathString()).isEqualTo("/foo/bar");
  }

  @Test
  public void testGetParentDirectory() {
    PathFragment fooBarWiz = create("foo/bar/wiz");
    PathFragment fooBar = create("foo/bar");
    PathFragment foo = create("foo");
    PathFragment empty = create("");
    assertThat(fooBarWiz.getParentDirectory()).isEqualTo(fooBar);
    assertThat(fooBar.getParentDirectory()).isEqualTo(foo);
    assertThat(foo.getParentDirectory()).isEqualTo(empty);
    assertThat(empty.getParentDirectory()).isNull();

    PathFragment fooBarWizAbs = create("/foo/bar/wiz");
    PathFragment fooBarAbs = create("/foo/bar");
    PathFragment fooAbs = create("/foo");
    PathFragment rootAbs = create("/");
    assertThat(fooBarWizAbs.getParentDirectory()).isEqualTo(fooBarAbs);
    assertThat(fooBarAbs.getParentDirectory()).isEqualTo(fooAbs);
    assertThat(fooAbs.getParentDirectory()).isEqualTo(rootAbs);
    assertThat(rootAbs.getParentDirectory()).isNull();
  }

  @Test
  public void testSegmentsCount() {
    assertThat(create("foo/bar").segmentCount()).isEqualTo(2);
    assertThat(create("/foo/bar").segmentCount()).isEqualTo(2);
    assertThat(create("foo//bar").segmentCount()).isEqualTo(2);
    assertThat(create("/foo//bar").segmentCount()).isEqualTo(2);
    assertThat(create("foo/").segmentCount()).isEqualTo(1);
    assertThat(create("/foo/").segmentCount()).isEqualTo(1);
    assertThat(create("foo").segmentCount()).isEqualTo(1);
    assertThat(create("/foo").segmentCount()).isEqualTo(1);
    assertThat(create("/").segmentCount()).isEqualTo(0);
    assertThat(create("").segmentCount()).isEqualTo(0);
  }


  @Test
  public void testGetSegment() {
    assertThat(create("foo/bar").getSegment(0)).isEqualTo("foo");
    assertThat(create("foo/bar").getSegment(1)).isEqualTo("bar");
    assertThat(create("/foo/bar").getSegment(0)).isEqualTo("foo");
    assertThat(create("/foo/bar").getSegment(1)).isEqualTo("bar");
    assertThat(create("foo/").getSegment(0)).isEqualTo("foo");
    assertThat(create("/foo/").getSegment(0)).isEqualTo("foo");
    assertThat(create("foo").getSegment(0)).isEqualTo("foo");
    assertThat(create("/foo").getSegment(0)).isEqualTo("foo");
  }

  @Test
  public void testBasename() throws Exception {
    assertThat(create("foo/bar").getBaseName()).isEqualTo("bar");
    assertThat(create("/foo/bar").getBaseName()).isEqualTo("bar");
    assertThat(create("foo/").getBaseName()).isEqualTo("foo");
    assertThat(create("/foo/").getBaseName()).isEqualTo("foo");
    assertThat(create("foo").getBaseName()).isEqualTo("foo");
    assertThat(create("/foo").getBaseName()).isEqualTo("foo");
    assertThat(create("/").getBaseName()).isEmpty();
    assertThat(create("").getBaseName()).isEmpty();
  }

  @Test
  public void testFileExtension() throws Exception {
    assertThat(create("foo.bar").getFileExtension()).isEqualTo("bar");
    assertThat(create("foo.barr").getFileExtension()).isEqualTo("barr");
    assertThat(create("foo.b").getFileExtension()).isEqualTo("b");
    assertThat(create("foo.").getFileExtension()).isEmpty();
    assertThat(create("foo").getFileExtension()).isEmpty();
    assertThat(create(".").getFileExtension()).isEmpty();
    assertThat(create("").getFileExtension()).isEmpty();
    assertThat(create("foo/bar.baz").getFileExtension()).isEqualTo("baz");
    assertThat(create("foo.bar.baz").getFileExtension()).isEqualTo("baz");
    assertThat(create("foo.bar/baz").getFileExtension()).isEmpty();
  }

  @Test
  public void testReplaceName() throws Exception {
    assertThat(create("foo/bar").replaceName("baz").getPathString()).isEqualTo("foo/baz");
    assertThat(create("/foo/bar").replaceName("baz").getPathString()).isEqualTo("/foo/baz");
    assertThat(create("foo/bar").replaceName("").getPathString()).isEqualTo("foo");
    assertThat(create("foo/").replaceName("baz").getPathString()).isEqualTo("baz");
    assertThat(create("/foo/").replaceName("baz").getPathString()).isEqualTo("/baz");
    assertThat(create("foo").replaceName("baz").getPathString()).isEqualTo("baz");
    assertThat(create("/foo").replaceName("baz").getPathString()).isEqualTo("/baz");
    assertThat(create("/").replaceName("baz")).isNull();
    assertThat(create("/").replaceName("")).isNull();
    assertThat(create("").replaceName("baz")).isNull();
    assertThat(create("").replaceName("")).isNull();

    assertThat(create("foo/bar").replaceName("bar/baz").getPathString()).isEqualTo("foo/bar/baz");
    assertThat(create("foo/bar").replaceName("bar/baz/").getPathString()).isEqualTo("foo/bar/baz");

    // Absolute path arguments will clobber the original path.
    assertThat(create("foo/bar").replaceName("/absolute").getPathString()).isEqualTo("/absolute");
    assertThat(create("foo/bar").replaceName("/").getPathString()).isEqualTo("/");
  }
  @Test
  public void testSubFragment() throws Exception {
    assertThat(create("/foo/bar/baz").subFragment(0, 3).getPathString()).isEqualTo("/foo/bar/baz");
    assertThat(create("foo/bar/baz").subFragment(0, 3).getPathString()).isEqualTo("foo/bar/baz");
    assertThat(create("/foo/bar/baz").subFragment(0, 2).getPathString()).isEqualTo("/foo/bar");
    assertThat(create("/foo/bar/baz").subFragment(1, 3).getPathString()).isEqualTo("bar/baz");
    assertThat(create("/foo/bar/baz").subFragment(0, 1).getPathString()).isEqualTo("/foo");
    assertThat(create("/foo/bar/baz").subFragment(1, 2).getPathString()).isEqualTo("bar");
    assertThat(create("/foo/bar/baz").subFragment(2, 3).getPathString()).isEqualTo("baz");
    assertThat(create("/foo/bar/baz").subFragment(0, 0).getPathString()).isEqualTo("/");
    assertThat(create("foo/bar/baz").subFragment(0, 0).getPathString()).isEqualTo("");
    assertThat(create("foo/bar/baz").subFragment(1, 1).getPathString()).isEqualTo("");

    assertThat(create("/foo/bar/baz").subFragment(0).getPathString()).isEqualTo("/foo/bar/baz");
    assertThat(create("foo/bar/baz").subFragment(0).getPathString()).isEqualTo("foo/bar/baz");
    assertThat(create("/foo/bar/baz").subFragment(1).getPathString()).isEqualTo("bar/baz");
    assertThat(create("foo/bar/baz").subFragment(1).getPathString()).isEqualTo("bar/baz");
    assertThat(create("foo/bar/baz").subFragment(2).getPathString()).isEqualTo("baz");
    assertThat(create("foo/bar/baz").subFragment(3).getPathString()).isEqualTo("");

    assertThrows(IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(3, 2));
    assertThrows(IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(4, 4));
    assertThrows(IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(3, 2));
    assertThrows(IndexOutOfBoundsException.class, () -> create("foo/bar/baz").subFragment(4));
  }

  @Test
  public void testStartsWith() {
    PathFragment foobar = create("/foo/bar");
    PathFragment 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 path, relative prefix) => true
    assertThat(foobarRelative.startsWith(foobarRelative)).isTrue();
    assertThat(foobarRelative.startsWith(create("foo"))).isTrue();
    assertThat(foobarRelative.startsWith(create(""))).isTrue();

    // (path, sibling) => false
    assertThat(create("/foo/wiz").startsWith(foobar)).isFalse();
    assertThat(foobar.startsWith(create("/foo/wiz"))).isFalse();
  }

  @Test
  public void testCheckAllPathsStartWithButAreNotEqualTo() {
    // Check passes:
    PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a/c"), create("a"));

    // Check trivially passes:
    PathFragment.checkAllPathsAreUnder(ImmutableList.<PathFragment>of(), create("a"));

    // Check fails when some path does not start with startingWithPath:
    assertThrows(
        IllegalArgumentException.class,
        () -> PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "b/c"), create("a")));

    // Check fails when some path is equal to startingWithPath:
    assertThrows(
        IllegalArgumentException.class,
        () -> PathFragment.checkAllPathsAreUnder(toPathsSet("a/b", "a"), create("a")));
  }

  @Test
  public void testEndsWith() {
    PathFragment foobar = create("/foo/bar");
    PathFragment foobarRelative = create("foo/bar");

    // (path, suffix) => true
    assertThat(foobar.endsWith(foobar)).isTrue();
    assertThat(foobar.endsWith(create("bar"))).isTrue();
    assertThat(foobar.endsWith(create("foo/bar"))).isTrue();
    assertThat(foobar.endsWith(create("/foo/bar"))).isTrue();
    assertThat(foobar.endsWith(create("/bar"))).isFalse();

    // (prefix, path) => false
    assertThat(create("/foo").endsWith(foobar)).isFalse();
    assertThat(create("/").endsWith(foobar)).isFalse();

    // (suffix, path) => false
    assertThat(create("/bar").endsWith(foobar)).isFalse();
    assertThat(create("bar").endsWith(foobar)).isFalse();
    assertThat(create("").endsWith(foobar)).isFalse();

    // (absolute, relative) => true
    assertThat(foobar.endsWith(foobarRelative)).isTrue();

    // (relative, absolute) => false
    assertThat(foobarRelative.endsWith(foobar)).isFalse();

    // (relative path, relative prefix) => true
    assertThat(foobarRelative.endsWith(foobarRelative)).isTrue();
    assertThat(foobarRelative.endsWith(create("bar"))).isTrue();
    assertThat(foobarRelative.endsWith(create(""))).isTrue();

    // (path, sibling) => false
    assertThat(create("/foo/wiz").endsWith(foobar)).isFalse();
    assertThat(foobar.endsWith(create("/foo/wiz"))).isFalse();
  }

  @Test
  public void testToRelative() {
    assertThat(create("/foo/bar").toRelative()).isEqualTo(create("foo/bar"));
    assertThat(create("/").toRelative()).isEqualTo(create(""));
    assertThrows(IllegalArgumentException.class, () -> create("foo").toRelative());
  }

  @Test
  public void testGetDriveStr() {
    assertThat(create("/foo/bar").getDriveStr()).isEqualTo("/");
    assertThat(create("/").getDriveStr()).isEqualTo("/");
    assertThrows(IllegalArgumentException.class, () -> create("foo").getDriveStr());
  }

  static List<PathFragment> toPaths(List<String> strs) {
    List<PathFragment> paths = Lists.newArrayList();
    for (String s : strs) {
      paths.add(create(s));
    }
    return paths;
  }

  static ImmutableSet<PathFragment> toPathsSet(String... strs) {
    ImmutableSet.Builder<PathFragment> builder = ImmutableSet.builder();
    for (String str : strs) {
      builder.add(create(str));
    }
    return builder.build();
  }

  @Test
  public void testCompareTo() throws Exception {
    List<String> pathStrs =
        ImmutableList.of(
            "",
            "/",
            "foo",
            "/foo",
            "foo/bar",
            "foo.bar",
            "foo/bar.baz",
            "foo/bar/baz",
            "foo/barfile",
            "foo/Bar",
            "Foo/bar");
    List<PathFragment> paths = toPaths(pathStrs);
    // First test that compareTo is self-consistent.
    for (PathFragment x : paths) {
      for (PathFragment y : paths) {
        for (PathFragment z : paths) {
          // Anti-symmetry
          assertThat(-1 * Integer.signum(y.compareTo(x))).isEqualTo(Integer.signum(x.compareTo(y)));
          // Transitivity
          if (x.compareTo(y) > 0 && y.compareTo(z) > 0) {
            assertThat(x.compareTo(z)).isGreaterThan(0);
          }
          // "Substitutability"
          if (x.compareTo(y) == 0) {
            assertThat(Integer.signum(y.compareTo(z))).isEqualTo(Integer.signum(x.compareTo(z)));
          }
          // Consistency with equals
          assertThat(x.equals(y)).isEqualTo((x.compareTo(y) == 0));
        }
      }
    }
    // Now test that compareTo does what we expect.  The exact ordering here doesn't matter much.
    Collections.shuffle(paths);
    Collections.sort(paths);
    List<PathFragment> expectedOrder =
        toPaths(
            ImmutableList.of(
                "",
                "/",
                "/foo",
                "Foo/bar",
                "foo",
                "foo.bar",
                "foo/Bar",
                "foo/bar",
                "foo/bar.baz",
                "foo/bar/baz",
                "foo/barfile"));
    assertThat(paths).isEqualTo(expectedOrder);
  }

  @Test
  public void testGetSafePathString() {
    assertThat(create("/").getSafePathString()).isEqualTo("/");
    assertThat(create("/abc").getSafePathString()).isEqualTo("/abc");
    assertThat(create("").getSafePathString()).isEqualTo(".");
    assertThat(PathFragment.EMPTY_FRAGMENT.getSafePathString()).isEqualTo(".");
    assertThat(create("abc/def").getSafePathString()).isEqualTo("abc/def");
  }

  @Test
  public void testNormalize() {
    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("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"));
    assertThat(create("/..")).isEqualTo(create("/.."));
    assertThat(create("..")).isEqualTo(create(".."));
  }

  @Test
  public void testSegments() {
    assertThat(create("").segmentCount()).isEqualTo(0);
    assertThat(create("a").segmentCount()).isEqualTo(1);
    assertThat(create("a/b").segmentCount()).isEqualTo(2);
    assertThat(create("a/b/c").segmentCount()).isEqualTo(3);
    assertThat(create("/").segmentCount()).isEqualTo(0);
    assertThat(create("/a").segmentCount()).isEqualTo(1);
    assertThat(create("/a/b").segmentCount()).isEqualTo(2);
    assertThat(create("/a/b/c").segmentCount()).isEqualTo(3);

    assertThat(create("").getSegments()).isEmpty();
    assertThat(create("a").getSegments()).containsExactly("a").inOrder();
    assertThat(create("a/b").getSegments()).containsExactly("a", "b").inOrder();
    assertThat(create("a/b/c").getSegments()).containsExactly("a", "b", "c").inOrder();
    assertThat(create("/").getSegments()).isEmpty();
    assertThat(create("/a").getSegments()).containsExactly("a").inOrder();
    assertThat(create("/a/b").getSegments()).containsExactly("a", "b").inOrder();
    assertThat(create("/a/b/c").getSegments()).containsExactly("a", "b", "c").inOrder();

    assertThat(create("a").getSegment(0)).isEqualTo("a");
    assertThat(create("a/b").getSegment(0)).isEqualTo("a");
    assertThat(create("a/b").getSegment(1)).isEqualTo("b");
    assertThat(create("a/b/c").getSegment(2)).isEqualTo("c");
    assertThat(create("/a").getSegment(0)).isEqualTo("a");
    assertThat(create("/a/b").getSegment(0)).isEqualTo("a");
    assertThat(create("/a/b").getSegment(1)).isEqualTo("b");
    assertThat(create("/a/b/c").getSegment(2)).isEqualTo("c");

    assertThrows(IllegalArgumentException.class, () -> create("").getSegment(0));
    assertThrows(IllegalArgumentException.class, () -> create("a/b").getSegment(2));
  }

  @Test
  public void testCodec() throws Exception {
    new SerializationTester(
            ImmutableList.of("", "a", "/foo", "foo/bar/baz", "/a/path/fragment/with/lots/of/parts")
                .stream()
                .map(PathFragment::create)
                .collect(toImmutableList()))
        .runTests();
  }

  @Test
  public void testSerializationSimple() throws Exception {
   checkSerialization("a", 91);
  }

  @Test
  public void testSerializationAbsolute() throws Exception {
    checkSerialization("/foo", 94);
   }

  @Test
  public void testSerializationNested() throws Exception {
    checkSerialization("foo/bar/baz", 101);
  }

  private void checkSerialization(String pathFragmentString, int expectedSize) throws Exception {
    PathFragment a = create(pathFragmentString);
    byte[] sa = TestUtils.serializeObject(a);
    assertThat(sa).hasLength(expectedSize);

    PathFragment a2 = (PathFragment) TestUtils.deserializeObject(sa);
    assertThat(a2).isEqualTo(a);
  }
}
