ImmutableListPathCore implements PathCore<ImmutableListPathCore> { @Override public ImmutableListPathCore normalize() { boolean[] ignore = new boolean[path.size()]; int ignoreCount = 0; for (int i = 0; i < path.size(); i++) { if (path.get(i).equals(CURRENT_DIR)) { ignore[i] = true; ignoreCount++; } else if (path.get(i).equals(PARENT_DIR)) { int j = i - 1; while (j >= 0 && ignore[j]) { j--; } if (j >= 0 && !path.get(j).equals(PARENT_DIR)) { ignore[i] = true; ignore[j] = true; ignoreCount += 2; } else if (j < 0 && isAbsolute()) { ignore[i] = true; ignoreCount++; } } } if (ignoreCount == 0) { return this; } else { ImmutableList.Builder<String> normalized = ImmutableList.builder(); for (int i = 0; i < path.size(); i++) { if (!ignore[i]) { normalized.add(path.get(i)); } } return new ImmutableListPathCore(root, normalized.build()); } } ImmutableListPathCore(@Nullable String root, Iterable<String> path); static Parser parser(String separator); static Parser namedRootParser(String separator, NamedRootFormat format, String rootId); @Override boolean isAbsolute(); @Override ImmutableListPathCore getRoot(); @Override ImmutableListPathCore getFileName(); @Override ImmutableListPathCore getParent(); @Override int getNameCount(); @Override ImmutableListPathCore getName(int index); @Override ImmutableListPathCore subpath(int beginIndex, int endIndex); @Override boolean startsWith(ImmutableListPathCore other); @Override boolean endsWith(ImmutableListPathCore other); @Override ImmutableListPathCore normalize(); @Override ImmutableListPathCore resolve(ImmutableListPathCore other); @Override ImmutableListPathCore resolveSibling(ImmutableListPathCore other); @Override ImmutableListPathCore relativize(ImmutableListPathCore other); @Override String toPathString(String separator); @Override String toString(); @Override int compareTo(ImmutableListPathCore other); @Override boolean equals(Object obj); @Override int hashCode(); @Nullable String getRootString(); ImmutableList<String> getPathSegments();  }
@Test public void normalizeNormalPathIsIdentity() { ImmutableListPathCore normal = relative.normalize(); assertThat("normalized normal path is not identity", normal, sameInstance(relative)); }
@Test public void normalizeCollapsesParents() { ImmutableListPathCore input = core(null, "a", "b", "..", "c", "d", "..", "..", "e"); assertThat(input.normalize(), hasPath("a", "e")); }
@Test public void normalizeCollapsesCurrent() { ImmutableListPathCore input = core(null, ".", "a", "b", ".", "c", "d", ".", ".", "e"); assertThat(input.normalize(), hasPath("a", "b", "c", "d", "e")); }
@Test public void normalizeCollapsesMixed() { ImmutableListPathCore input = core(null, "a", ".", "b", "..", "c", "d", ".", "..", "e"); assertThat(input.normalize(), hasPath("a", "c", "e")); }
@Test public void normalizePreservesLeadingParents() { ImmutableListPathCore input = core(null, "..", "..", "c", "d", "..", "e"); assertThat(input.normalize(), hasPath("..", "..", "c", "e")); }
@Test public void normalizePreserversInnerParentsThatBecomeLeading() { ImmutableListPathCore input = core(null, "a", "b", "..", "..", "d", "..", "..", "e"); assertThat(input.normalize(), hasPath("..", "e")); }