/*
* ModeShape (http://www.modeshape.org)
*
* 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 org.modeshape.jcr.value.basic;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertThat;
import static org.modeshape.jcr.value.basic.IsPathContaining.hasSegments;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.common.text.Jsr283Encoder;
import org.modeshape.common.text.TextEncoder;
import org.modeshape.jcr.ModeShapeLexicon;
import org.modeshape.jcr.value.InvalidPathException;
import org.modeshape.jcr.value.Name;
import org.modeshape.jcr.value.Path;
import org.modeshape.jcr.value.ValueFormatException;
/**
* @author Randall Hauch
* @author John Verhaeg
*/
public class BasicPathOldTest extends BaseValueFactoryTest {
public static final TextEncoder NO_OP_ENCODER = Path.NO_OP_ENCODER;
public static final Path ROOT = RootPath.INSTANCE;
private String validNamespaceUri;
private Path path;
private Path path2;
private Path.Segment[] validSegments;
private List<Path.Segment> validSegmentsList;
private Name[] validSegmentNames;
private String validNamespacePrefix;
private PathValueFactory pathFactory;
@Before
@Override
public void beforeEach() {
super.beforeEach();
validNamespacePrefix = ModeShapeLexicon.Namespace.PREFIX;
validNamespaceUri = ModeShapeLexicon.Namespace.URI;
validSegmentNames = new Name[] {new BasicName(validNamespaceUri, "a"), new BasicName(validNamespaceUri, "b"),
new BasicName(validNamespaceUri, "c")};
validSegments = new Path.Segment[] {new BasicPathSegment(validSegmentNames[0]),
new BasicPathSegment(validSegmentNames[1]), new BasicPathSegment(validSegmentNames[1])};
validSegmentsList = new ArrayList<Path.Segment>();
for (Path.Segment segment : validSegments) {
validSegmentsList.add(segment);
}
path = new BasicPath(validSegmentsList, true);
registry.register(validNamespacePrefix, validNamespaceUri);
pathFactory = new PathValueFactory(Path.DEFAULT_DECODER, valueFactories);
}
@Test
public void shouldCreateAbsolutePathFromListOfValidSegments() {
path = new BasicPath(validSegmentsList, true);
assertThat(path.isAbsolute(), is(true));
assertThat(path.isNormalized(), is(true));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreateRelativePathFromListOfValidSegments() {
path = new BasicPath(validSegmentsList, false);
assertThat(path.isAbsolute(), is(false));
assertThat(path.isNormalized(), is(true));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreateAbsolutePathWithParentSegment() {
validSegmentsList.add(Path.PARENT_SEGMENT);
path = new BasicPath(validSegmentsList, true);
assertThat(path.isAbsolute(), is(true));
assertThat(path.isNormalized(), is(false));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreateRelativePathWithParentSegment() {
validSegmentsList.add(Path.PARENT_SEGMENT);
path = new BasicPath(validSegmentsList, false);
assertThat(path.isAbsolute(), is(false));
assertThat(path.isNormalized(), is(false));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreateAbsolutePathWithSelfSegment() {
validSegmentsList.add(Path.SELF_SEGMENT);
path = new BasicPath(validSegmentsList, true);
assertThat(path.isAbsolute(), is(true));
assertThat(path.isNormalized(), is(false));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreateRelativePathWithSelfSegment() {
validSegmentsList.add(Path.SELF_SEGMENT);
path = new BasicPath(validSegmentsList, false);
assertThat(path.isAbsolute(), is(false));
assertThat(path.isNormalized(), is(false));
assertThat(path.getSegmentsList(), is(validSegmentsList));
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldCreatePathWithNoNamespacePrefixes() {
path = pathFactory.create("/a/b/c/");
assertThat(path.size(), is(3));
assertThat(path, hasSegments(pathFactory, "a", "b", "c"));
}
@Test
public void shouldConstructRelativePath() {
assertThat(pathFactory.create("a/b/c").isAbsolute(), is(false));
assertThat(pathFactory.create("a/b/c").isNormalized(), is(true));
assertThat(pathFactory.create("a/b/c").size(), is(3));
assertThat(pathFactory.create("a/b/c").getString(registry), is("a/b/c"));
}
@Test
public void shouldConstructRelativePathToSelf() {
assertThat(pathFactory.create(".").isAbsolute(), is(false));
assertThat(pathFactory.create(".").size(), is(1));
assertThat(pathFactory.create("."), hasSegments(pathFactory, Path.SELF));
assertThat(pathFactory.create("./").isAbsolute(), is(false));
assertThat(pathFactory.create("./").size(), is(1));
assertThat(pathFactory.create("./"), hasSegments(pathFactory, Path.SELF));
}
@Test
public void shouldConstructRelativePathToParent() {
assertThat(pathFactory.create("..").isAbsolute(), is(false));
assertThat(pathFactory.create("..").size(), is(1));
assertThat(pathFactory.create(".."), hasSegments(pathFactory, Path.PARENT));
assertThat(pathFactory.create("../").isAbsolute(), is(false));
assertThat(pathFactory.create("../").size(), is(1));
assertThat(pathFactory.create("../"), hasSegments(pathFactory, Path.PARENT));
}
@Test
public void shouldConstructRootPathFromStringWithSingleDelimiter() {
assertThat(pathFactory.create("/"), is(ROOT));
assertThat(pathFactory.create("/").isRoot(), is(true));
}
@Test( expected = ValueFormatException.class )
public void shouldNotConstructPathWithSuccessiveDelimiters() {
pathFactory.create("///a/b///c//d//");
}
@Test( expected = ValueFormatException.class )
public void shouldNotConstructPathWithOnlyDelimiters() {
pathFactory.create("///");
}
@Test
public void shouldConstructPathFromStringAndShouldIgnoreLeadingAndTrailingWhitespace() {
assertThat(pathFactory.create(" \t / \t").toString(), is("/"));
}
@Test
public void shouldConstructRelativePathIfSuppliedPathHasNoLeadingDelimiter() {
assertThat(pathFactory.create("a"), hasSegments(pathFactory, "a"));
}
@Test
public void shouldHaveSizeThatReflectsNumberOfSegments() {
assertThat(path.size(), is(validSegmentsList.size()));
}
@Test
public void shouldIterateOverAllSegmentsReturnedByList() {
Iterator<Path.Segment> expectedIter = validSegmentsList.iterator();
for (Path.Segment segment : path) {
assertThat(segment, is(expectedIter.next()));
}
expectedIter = path.getSegmentsList().iterator();
for (Path.Segment segment : path) {
assertThat(segment, is(expectedIter.next()));
}
}
@Test
public void shouldReturnNoAncestorForRoot() {
assertThat(RootPath.INSTANCE.getParent(), nullValue());
}
@Test
public void shouldReturnAncestorForNodeOtherThanRoot() {
assertThat(path.getParent(), is(pathFactory.create("/mode:a/mode:b")));
assertThat(path.getParent().getParent(), is(pathFactory.create("/mode:a")));
assertThat(path.getParent().getParent().getParent(), is(ROOT));
}
@Test
public void shouldReturnNthDegreeAncestor() {
assertThat(path.getAncestor(1), is(pathFactory.create("/mode:a/mode:b")));
assertThat(path.getAncestor(2), is(pathFactory.create("/mode:a")));
assertThat(path.getAncestor(3), is(ROOT));
}
@Test( expected = InvalidPathException.class )
public void shouldNotAllowAncestorDegreeLargerThanSize() {
path.getAncestor(path.size() + 1);
}
@Test( expected = IllegalArgumentException.class )
public void shouldNotAllowNegativeAncestorDegree() {
path.getAncestor(-1);
}
@Test
public void shouldReturnRootForAnyAncestorExactDegreeFromRoot() {
assertThat(path.getAncestor(path.size()), is(ROOT));
assertThat(ROOT.getAncestor(0), is(ROOT));
}
@Test
public void shouldConsiderRootTheLowestCommonAncestorOfAnyNodeAndRoot() {
assertThat(path.getCommonAncestor(ROOT), is(ROOT));
assertThat(ROOT.getCommonAncestor(path), is(ROOT));
}
@Test( expected = IllegalArgumentException.class )
public void shouldReturnNullForLowestCommonAncestorWithNullPath() {
path.getCommonAncestor(null);
}
@Test
public void shouldFindLowestCommonAncestorBetweenTwoNonRootNodesOnCommonBranch() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path common = pathFactory.create("/a");
assertThat(path1.getCommonAncestor(path2), is(common));
path1 = pathFactory.create("/a/b/c");
path2 = pathFactory.create("/a/b/c/d");
common = path1;
assertThat(path1.getCommonAncestor(path2), is(common));
path1 = pathFactory.create("/a/b/c/x/y/");
path2 = pathFactory.create("/a/b/c/d/e/f/");
common = pathFactory.create("/a/b/c");
assertThat(path1.getCommonAncestor(path2), is(common));
}
@Test
public void shouldConsiderRootTheLowestCommonAncestorOfAnyNodesOnSeparateBrances() {
Path path1 = pathFactory.create("/x/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path common = ROOT;
assertThat(path1.getCommonAncestor(path2), is(common));
}
@Test
public void shouldConsiderNodeToBeAncestorOfEveryDecendantNode() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
Path common = pathFactory.create("/a");
assertThat(common.isAncestorOf(path1), is(true));
assertThat(common.isAncestorOf(path2), is(true));
assertThat(common.isAncestorOf(path3), is(false));
assertThat(path1.getParent().isAncestorOf(path1), is(true));
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.getAncestor(i).isAncestorOf(path1), is(true));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.getAncestor(i).isAncestorOf(path2), is(true));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.getAncestor(i).isAncestorOf(path3), is(true));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.getAncestor(i).isAncestorOf(path4), is(true));
}
}
@Test
public void shouldConsiderNodeToBeDecendantOfEveryAncestorNode() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
Path common = pathFactory.create("/a");
assertThat(path1.isDescendantOf(common), is(true));
assertThat(path2.isDescendantOf(common), is(true));
assertThat(path3.isDescendantOf(common), is(false));
assertThat(path1.getParent().isAncestorOf(path1), is(true));
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.isDescendantOf(path1.getAncestor(i)), is(true));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.isDescendantOf(path2.getAncestor(i)), is(true));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.isDescendantOf(path3.getAncestor(i)), is(true));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.isDescendantOf(path4.getAncestor(i)), is(true));
}
}
@Test
public void shouldNotConsiderNodeToBeAncestorOfItself() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
assertThat(path1.isAncestorOf(path1), is(false));
assertThat(path2.isAncestorOf(path2), is(false));
assertThat(path3.isAncestorOf(path3), is(false));
assertThat(ROOT.isAncestorOf(ROOT), is(false));
}
@Test
public void shouldNotConsiderNodeToBeDecendantOfItself() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
assertThat(path1.isDescendantOf(path1), is(false));
assertThat(path2.isDescendantOf(path2), is(false));
assertThat(path3.isDescendantOf(path3), is(false));
assertThat(ROOT.isDescendantOf(ROOT), is(false));
}
@Test
public void shouldNotConsiderRootToBeDecendantOfAnyNode() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path common = pathFactory.create("/a");
assertThat(ROOT.isDescendantOf(path1), is(false));
assertThat(ROOT.isDescendantOf(path2), is(false));
assertThat(ROOT.isDescendantOf(path3), is(false));
assertThat(ROOT.isDescendantOf(common), is(false));
}
@Test
public void shouldConsiderRootToBeAncestorOfAnyNode() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path common = pathFactory.create("/a");
assertThat(ROOT.isAncestorOf(path1), is(true));
assertThat(ROOT.isAncestorOf(path2), is(true));
assertThat(ROOT.isAncestorOf(path3), is(true));
assertThat(ROOT.isAncestorOf(common), is(true));
}
@Test
public void shouldNotConsiderRootToBeAncestorOfItself() {
assertThat(ROOT.isAncestorOf(ROOT), is(false));
}
@Test
public void shouldNotConsiderRootToBeDecendantOfItself() {
assertThat(ROOT.isDescendantOf(ROOT), is(false));
}
@Test
public void shouldConsiderTwoRootNodesToHaveSameAncestor() {
assertThat(ROOT.hasSameAncestor(ROOT), is(true));
}
@Test
public void shouldConsiderTwoNotRootSiblingNodesToHaveSameAncestor() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/y/c");
assertThat(path1.hasSameAncestor(path2), is(true));
path1 = pathFactory.create("/a/z");
path2 = pathFactory.create("/a/c");
assertThat(path1.hasSameAncestor(path2), is(true));
path1 = pathFactory.create("/z");
path2 = pathFactory.create("/c");
assertThat(path1.hasSameAncestor(path2), is(true));
}
@Test
public void shouldNotConsiderTwoNonSiblingNodesToHaveSameAncestor() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/x/c");
assertThat(path1.hasSameAncestor(path2), is(false));
path1 = pathFactory.create("/a/z");
path2 = pathFactory.create("/b/c");
assertThat(path1.hasSameAncestor(path2), is(false));
path1 = pathFactory.create("/z");
path2 = pathFactory.create("/a/c");
assertThat(path1.hasSameAncestor(path2), is(false));
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailForSameAncestorOfNullPath() {
path.hasSameAncestor(null);
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailForDecendantOfNullPath() {
path.isDescendantOf(null);
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailForAtOrAboveNullPath() {
path.isAtOrAbove(null);
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailForAtOrBelowNullPath() {
path.isAtOrBelow(null);
}
@Test( expected = IndexOutOfBoundsException.class )
public void shouldFailToReturnSegmentAtIndexGreatherThanSize() {
path.getSegment(path.size() + 1);
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailToReturnSegmentAtNegativeIndex() {
path.getSegment(-1);
}
@Test
public void shouldConsiderNodeToBeAtOrAboveItself() {
assertThat(path.isAtOrAbove(path), is(true));
}
@Test
public void shouldConsiderNodeToBeAtOrBelowItself() {
assertThat(path.isAtOrBelow(path), is(true));
}
@Test
public void shouldConsiderAncestorToBeAtOrAboveTheDecendant() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.getAncestor(i).isAtOrAbove(path1), is(true));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.getAncestor(i).isAtOrAbove(path2), is(true));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.getAncestor(i).isAtOrAbove(path3), is(true));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.getAncestor(i).isAtOrAbove(path4), is(true));
}
}
@Test
public void shouldConsiderDecendantToBeAtOrBelowTheAncestor() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.isAtOrBelow(path1.getAncestor(i)), is(true));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.isAtOrBelow(path2.getAncestor(i)), is(true));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.isAtOrBelow(path3.getAncestor(i)), is(true));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.isAtOrBelow(path4.getAncestor(i)), is(true));
}
}
@Test
public void shouldNotConsiderAncestorToBeAtOrBelowTheDecendant() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.getAncestor(i).isAtOrBelow(path1), is(false));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.getAncestor(i).isAtOrBelow(path2), is(false));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.getAncestor(i).isAtOrBelow(path3), is(false));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.getAncestor(i).isAtOrBelow(path4), is(false));
}
}
@Test
public void shouldNotConsiderDecendantToBeAtOrAboveTheAncestor() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
for (int i = 1; i < path1.size(); ++i) {
assertThat(path1.isAtOrAbove(path1.getAncestor(i)), is(false));
}
for (int i = 1; i < path2.size(); ++i) {
assertThat(path2.isAtOrAbove(path2.getAncestor(i)), is(false));
}
for (int i = 1; i < path3.size(); ++i) {
assertThat(path3.isAtOrAbove(path3.getAncestor(i)), is(false));
}
for (int i = 1; i < path4.size(); ++i) {
assertThat(path4.isAtOrAbove(path4.getAncestor(i)), is(false));
}
}
@Test
public void shouldReturnNullForLastSegmentOfRoot() {
assertThat(ROOT.getLastSegment(), is(nullValue()));
}
@Test
public void shouldReturnLastSegmentOfNonRootPath() {
Path path1 = pathFactory.create("/a/y/z");
Path path2 = pathFactory.create("/a/b/c");
Path path3 = pathFactory.create("/x/b/c");
Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x");
assertThat(path1.getLastSegment().getName().getLocalName(), is("z"));
assertThat(path2.getLastSegment().getName().getLocalName(), is("c"));
assertThat(path3.getLastSegment().getName().getLocalName(), is("c"));
assertThat(path4.getLastSegment().getName().getLocalName(), is("x"));
}
@Test
public void shouldNormalizePathWithSelfAndParentReferences() {
path = pathFactory.create("/a/b/c/../d/./e/../..");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
assertThat(path.getNormalizedPath().isAbsolute(), is(true));
assertThat(path.getNormalizedPath().isNormalized(), is(true));
path = pathFactory.create("a/b/c/../d/./e/../..");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
assertThat(path.getNormalizedPath().isAbsolute(), is(false));
assertThat(path.getNormalizedPath().isNormalized(), is(true));
}
@Test
public void shouldAlreadyBeNormalizedIfPathContainsNoParentOrSelfReferences() {
assertThat(pathFactory.create("/a/b/c/d/e").isNormalized(), is(true));
assertThat(pathFactory.create("a/b/c/d/e").isNormalized(), is(true));
assertThat(pathFactory.create("a").isNormalized(), is(true));
assertThat(pathFactory.create("/a").isNormalized(), is(true));
assertThat(ROOT.isNormalized(), is(true));
}
@Test
public void shouldNotBeNormalizedIfPathContainsParentOrSelfReferences() {
assertThat(pathFactory.create("/a/b/c/../d/./e/../..").isNormalized(), is(false));
assertThat(pathFactory.create("a/b/c/../d/./e/../..").isNormalized(), is(false));
assertThat(pathFactory.create("a/b/c/./d").isNormalized(), is(false));
assertThat(pathFactory.create("/a/b/c/../d").isNormalized(), is(false));
assertThat(pathFactory.create(".").isNormalized(), is(false));
assertThat(pathFactory.create("/.").isNormalized(), is(false));
}
@Test( expected = InvalidPathException.class )
public void shouldFailToReturnNormalizedPathIfPathContainsReferencesToParentsAboveRoot() {
path = pathFactory.create("/a/../../../..");
assertThat(path.isNormalized(), is(false));
path.getNormalizedPath();
}
@Test
public void shouldReturnRootPathAsTheNormalizedPathForAnAbsolutePathWithZeroSegmentsAfterParentAndSelfReferencesRemoved() {
// "/a/../b/../c/.." => "/"
path = pathFactory.create("/a/../b/../c/../");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath(), is(ROOT));
}
@Test
public void shouldReturnSelfPathAsTheNormalizedPathForARelativePathWithZeroSegmentsAfterParentAndSelfReferencesRemoved() {
// "a/../b/../c/.." => "."
path = pathFactory.create("a/../b/../c/../");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath().size(), is(1));
assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "."));
}
@Test
public void shouldNotHaveAnyParentOrSelfReferencesInTheNormalizedPathOfAnAbsolutePath() {
path = pathFactory.create("/a/b/c/../d/./e/../..");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
assertThat(path.getNormalizedPath().isAbsolute(), is(true));
assertThat(path.getNormalizedPath().isNormalized(), is(true));
}
@Test
public void shouldNotHaveAnyParentReferencesInTheNormalizedPathOfARelativePath() {
path = pathFactory.create("a/b/c/../d/./e/../..");
assertThat(path.isNormalized(), is(false));
assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
assertThat(path.getNormalizedPath().isAbsolute(), is(false));
assertThat(path.getNormalizedPath().isNormalized(), is(true));
}
@Test( expected = InvalidPathException.class )
public void shouldNotComputeCanonicalPathOfNodeThatIsNotAbsolute() {
pathFactory.create("a/b/c/../d/./e/../..").getCanonicalPath();
}
@Test
public void shouldReturnNormalizedPathForTheCanonicalPathOfAbsolutePath() {
path = pathFactory.create("/a/b/c/../d/./e/../..");
assertThat(path.isNormalized(), is(false));
assertThat(path.isAbsolute(), is(true));
assertThat(path.getCanonicalPath(), hasSegments(pathFactory, "a", "b"));
assertThat(path.getCanonicalPath().isAbsolute(), is(true));
assertThat(path.getCanonicalPath().isNormalized(), is(true));
}
@Test
public void shouldReturnSameSegmentsInIteratorAndArrayAndList() {
testSegmentsByIteratorAndListAndArray("/a/b/c/../d/./e/../..", "a", "b", "c", "..", "d", ".", "e", "..", "..");
testSegmentsByIteratorAndListAndArray("/a/b/c", "a", "b", "c");
testSegmentsByIteratorAndListAndArray("a/b/c/../d/./e/../..", "a", "b", "c", "..", "d", ".", "e", "..", "..");
testSegmentsByIteratorAndListAndArray("a/b/c", "a", "b", "c");
testSegmentsByIteratorAndListAndArray("");
testSegmentsByIteratorAndListAndArray(ROOT.getString());
}
public void testSegmentsByIteratorAndListAndArray( String pathStr,
String... expectedSegmentStrings ) {
path = pathFactory.create(pathStr);
assertThat(expectedSegmentStrings.length, is(path.size()));
Path.Segment[] segmentArray = path.getSegmentsArray();
List<Path.Segment> segmentList = path.getSegmentsList();
assertThat(segmentArray.length, is(path.size()));
assertThat(segmentList.size(), is(path.size()));
Iterator<Path.Segment> iter = path.iterator();
Iterator<Path.Segment> listIter = segmentList.iterator();
for (int i = 0; i != path.size(); ++i) {
Path.Segment expected = pathFactory.createSegment(expectedSegmentStrings[i]);
assertThat(path.getSegment(i), is(expected));
assertThat(segmentArray[i], is(expected));
assertThat(segmentList.get(i), is(expected));
assertThat(iter.next(), is(expected));
assertThat(listIter.next(), is(expected));
}
assertThat(iter.hasNext(), is(false));
assertThat(listIter.hasNext(), is(false));
}
@Test
public void shouldGetStringWithNamespaceUrisIfNoNamespaceRegistryIsProvided() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.getString(NO_OP_ENCODER),
is("/{http://www.modeshape.org/1.0}a/{}b/{http://www.modeshape.org/1.0}c/../{}d/./{http://www.modeshape.org/1.0}e/../.."));
}
@Test
public void shouldGetStringWithNamespacePrefixesForAllNamesIfNamespaceRegistryIsProvided() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.getString(registry, NO_OP_ENCODER), is("/mode:a/b/mode:c/../d/./mode:e/../.."));
registry.register("dna2", validNamespaceUri);
assertThat(path.getString(registry, NO_OP_ENCODER), is("/dna2:a/b/dna2:c/../d/./dna2:e/../.."));
}
@Test( expected = IllegalArgumentException.class )
public void shouldFailToReturnSubpathIfStartingIndexIsNegative() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
path.subpath(-1);
}
@Test( expected = IndexOutOfBoundsException.class )
public void shouldFailToReturnSubpathWithoutEndingIndexIfStartingIndexIsEqualToOrLargerThanSize() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
path.subpath(path.size() + 1);
}
@Test( expected = IndexOutOfBoundsException.class )
public void shouldFailToReturnSubpathWithEndingIndexIfStartingIndexIsEqualToOrLargerThanSize() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
path.subpath(path.size() + 1, path.size() + 2);
}
@Test( expected = IndexOutOfBoundsException.class )
public void shouldFailToReturnSubpathIfEndingIndexIsSmallerThanStartingIndex() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
path.subpath(2, 1);
}
@Test( expected = IndexOutOfBoundsException.class )
public void shouldFailToReturnSubpathIfEndingIndexIsEqualToOrLargerThanSize() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
path.subpath(2, path.size() + 1);
}
@Test
public void shouldReturnRootAsSubpathIfStartingIndexAndEndingIndexAreBothZero() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.subpath(0, 0), is(ROOT));
}
@Test
public void shouldReturnSubpathIfValidStartingIndexAndNoEndingIndexAreProvided() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.subpath(0), hasSegments(pathFactory, "mode:a", "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(0), is(path));
assertThat(path.subpath(0), is(sameInstance(path)));
assertThat(path.subpath(1), hasSegments(pathFactory, "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(2), hasSegments(pathFactory, "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(3), hasSegments(pathFactory, "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(4), hasSegments(pathFactory, "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(5), hasSegments(pathFactory, ".", "mode:e", "..", ".."));
assertThat(path.subpath(6), hasSegments(pathFactory, "mode:e", "..", ".."));
assertThat(path.subpath(7), hasSegments(pathFactory, "..", ".."));
assertThat(path.subpath(8), hasSegments(pathFactory, ".."));
path = pathFactory.create("mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.subpath(0), hasSegments(pathFactory, "mode:a", "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(0), is(path));
assertThat(path.subpath(0), is(sameInstance(path)));
assertThat(path.subpath(1), hasSegments(pathFactory, "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(2), hasSegments(pathFactory, "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(3), hasSegments(pathFactory, "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(4), hasSegments(pathFactory, "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(5), hasSegments(pathFactory, ".", "mode:e", "..", ".."));
assertThat(path.subpath(6), hasSegments(pathFactory, "mode:e", "..", ".."));
assertThat(path.subpath(7), hasSegments(pathFactory, "..", ".."));
assertThat(path.subpath(8), hasSegments(pathFactory, ".."));
}
@Test
public void shouldReturnSubpathIfValidStartingIndexAndEndingIndexAreProvided() {
path = pathFactory.create("/mode:a/b/mode:c/../d/./mode:e/../..");
assertThat(path.subpath(0, path.size()),
hasSegments(pathFactory, "mode:a", "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(0, path.size()), is(path));
assertThat(path.subpath(0, path.size()), is(sameInstance(path)));
assertThat(path.subpath(1, path.size()), hasSegments(pathFactory, "b", "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(2, path.size()), hasSegments(pathFactory, "mode:c", "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(3, path.size()), hasSegments(pathFactory, "..", "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(4, path.size()), hasSegments(pathFactory, "d", ".", "mode:e", "..", ".."));
assertThat(path.subpath(5, path.size()), hasSegments(pathFactory, ".", "mode:e", "..", ".."));
assertThat(path.subpath(6, path.size()), hasSegments(pathFactory, "mode:e", "..", ".."));
assertThat(path.subpath(7, path.size()), hasSegments(pathFactory, "..", ".."));
assertThat(path.subpath(8, path.size()), hasSegments(pathFactory, ".."));
assertThat(path.subpath(0, 2), hasSegments(pathFactory, "mode:a", "b"));
assertThat(path.subpath(1, 2), hasSegments(pathFactory, "b"));
assertThat(path.subpath(1, 5), hasSegments(pathFactory, "b", "mode:c", "..", "d"));
assertThat(path.subpath(2, 5), hasSegments(pathFactory, "mode:c", "..", "d"));
assertThat(path.subpath(3, 5), hasSegments(pathFactory, "..", "d"));
}
@Test
public void shouldFindRelativePaths() {
path = pathFactory.create("/a/b/c/d");
assertThat(path.relativeTo(pathFactory.create("/a/e/f")), is(pathFactory.create("../../b/c/d")));
assertThat(path.relativeTo(pathFactory.create("/e/f")), is(pathFactory.create("../../a/b/c/d")));
}
@Test( expected = InvalidPathException.class )
public void shouldNotAllowFindingRelativePathsFromRelativePaths() {
path = pathFactory.create("a/b/c/d");
path.relativeTo(pathFactory.create("/e/f"));
}
@Test( expected = InvalidPathException.class )
public void shouldNotResolveRelativePathToAnotherRelativePath() {
path = pathFactory.create("/a/b/c/d");
path.relativeTo(pathFactory.create("e/f"));
}
@Test( expected = InvalidPathException.class )
public void shouldNotResolveRelativePathUsingAnAbsolutePath() {
path = pathFactory.create("/a/b/c/d");
path.resolve(pathFactory.create("/e/f"));
}
@Test
public void shouldResolveRelativePathToAbsolutePath() {
path = pathFactory.create("/a/b/c/d");
path2 = path.resolve(pathFactory.create("../../e/f"));
assertThat(path2, is(pathFactory.create("/a/b/e/f")));
assertThat(path2.isAbsolute(), is(true));
assertThat(path2.isNormalized(), is(true));
}
@Test
public void shouldOrderPathsCorrectly() {
List<Path> paths = new ArrayList<Path>();
paths.add(pathFactory.create("/a"));
paths.add(pathFactory.create("/a/b"));
paths.add(pathFactory.create("/a/b/alpha"));
paths.add(pathFactory.create("/a/b/beta"));
paths.add(pathFactory.create("/a/b/mode:mixinTypes"));
paths.add(pathFactory.create("/a/b/mode:name"));
paths.add(pathFactory.create("/a/b/mode:primaryType"));
paths.add(pathFactory.create("/a/c[1]"));
paths.add(pathFactory.create("/a/c[1]/alpha"));
paths.add(pathFactory.create("/a/c[1]/beta"));
paths.add(pathFactory.create("/a/c[1]/mode:mixinTypes"));
paths.add(pathFactory.create("/a/c[1]/mode:name"));
paths.add(pathFactory.create("/a/c[1]/mode:primaryType"));
paths.add(pathFactory.create("/a/c[2]"));
paths.add(pathFactory.create("/a/c[2]/alpha"));
paths.add(pathFactory.create("/a/c[2]/beta"));
paths.add(pathFactory.create("/a/c[2]/mode:mixinTypes"));
paths.add(pathFactory.create("/a/c[2]/mode:name"));
paths.add(pathFactory.create("/a/c[2]/mode:primaryType"));
// Randomize the list of paths, so we have something to sort ...
List<Path> randomizedPaths = new ArrayList<Path>(paths);
Collections.shuffle(randomizedPaths);
assertThat(randomizedPaths, is(not(paths)));
// Sort ...
Collections.sort(randomizedPaths);
assertThat(randomizedPaths, is(paths));
}
@Test
public void shouldGetNormalizedPathOfSelfShouldBeSame() {
assertThat(pathFactory.create(".").getNormalizedPath(), is(pathFactory.create(".")));
assertThat(pathFactory.create("./").getNormalizedPath(), is(pathFactory.create(".")));
assertThat(pathFactory.create("./././").getNormalizedPath(), is(pathFactory.create(".")));
}
@Test
public void shouldGetNormalizedPathWithParentReferences() {
assertThat(pathFactory.create("..").getNormalizedPath(), is(pathFactory.create("..")));
assertThat(pathFactory.create("../").getNormalizedPath(), is(pathFactory.create("../")));
assertThat(pathFactory.create("../../../../../..").getNormalizedPath(), is(pathFactory.create("../../../../../..")));
}
@Test
public void shouldGetRelativePathUsingSelf() {
path = pathFactory.create("/a/b/c/d/e/f");
assertThat(path.resolve(pathFactory.create(".")), is(sameInstance(path)));
assertThat(path.resolve(pathFactory.create("././.")), is(sameInstance(path)));
}
@Test
public void shouldResolveRelativePathToParent() {
path = pathFactory.create("/a/b/c/d/e/f");
assertThat(path.resolve(pathFactory.create("..")), is(path.getParent()));
assertThat(path.resolve(pathFactory.create("..")), hasSegments(pathFactory, "a", "b", "c", "d", "e"));
}
@Test
public void shouldResolveRelativePaths() {
path = pathFactory.create("/a/b/c/d/e/f");
assertThat(path.resolve(pathFactory.create("../../../../../..")), is(sameInstance(ROOT)));
assertThat(path.resolve(pathFactory.create("../..")), is(path.getParent().getParent()));
assertThat(path.resolve(pathFactory.create("../..")), hasSegments(pathFactory, "a", "b", "c", "d"));
assertThat(path.resolve(pathFactory.create("../x/../y/../z/..")), is(path.getParent()));
assertThat(path.resolve(pathFactory.create("../x/../y/../z/..")), hasSegments(pathFactory, "a", "b", "c", "d", "e"));
assertThat(path.resolve(pathFactory.create("../x")), hasSegments(pathFactory, "a", "b", "c", "d", "e", "x"));
}
public void shouldResolveNonAbsolutePaths() {
path = pathFactory.create("a/b/c");
assertThat(path, hasSegments(pathFactory, "a", "b", "c"));
}
@Test
public void shouldConvertPathToString() {
TextEncoder encoder = new Jsr283Encoder();
TextEncoder delimEncoder = new TextEncoder() {
@Override
public String encode( String text ) {
if ("/".equals(text)) return "\\/";
if (":".equals(text)) return "\\:";
if ("{".equals(text)) return "\\{";
if ("}".equals(text)) return "\\}";
return text;
}
};
Path path = pathFactory.create("a/b/c");
assertThat(path.getString(registry), is("a/b/c"));
assertThat(path.getString(registry, encoder), is("a/b/c"));
assertThat(path.getString(registry, encoder, delimEncoder), is("a\\/b\\/c"));
path = pathFactory.create("/a/b/c");
assertThat(path.getString(registry), is("/a/b/c"));
assertThat(path.getString(registry, encoder), is("/a/b/c"));
assertThat(path.getString(registry, encoder, delimEncoder), is("\\/a\\/b\\/c"));
path = pathFactory.create("/mode:a/b/c");
assertThat(path.getString(encoder), is("/{" + encoder.encode(ModeShapeLexicon.Namespace.URI) + "}a/{}b/{}c"));
assertThat(path.getString(null, encoder, delimEncoder), is("\\/mode:a\\/\\{\\}b\\/\\{\\}c"));
assertThat(path.getString(registry), is("/mode:a/b/c"));
assertThat(path.getString(registry, encoder), is("/mode:a/b/c"));
assertThat(path.getString(registry, encoder, delimEncoder), is("\\/mode\\:a\\/b\\/c"));
}
}