/*
* Copyright (C) 2011 Laurent Caillette
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.novelang.common.tree;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
/**
* Tests for {@link TreepathTools}.
*
* @author Laurent Caillette
*/
public class TreepathToolsTest {
@Test
public void replaceEnd() {
final MyTree grandChild = MyTree.create( "grandChild" ) ; // parent
final MyTree parent = MyTree.create( // / \
"parent", // child0 child1
MyTree.create( "child0", grandChild ), // |
MyTree.create( "child1" ) // grandChild (becomes newGrandChild)
) ;
final MyTree newGrandChild = MyTree.create( "newGrandChild" ) ;
// original: parent <- child0 <- grandChild
final Treepath< MyTree > original = Treepath.create( parent, 0, 0 ) ;
final Treepath< MyTree > reparented = TreepathTools.replaceTreepathEnd( original, newGrandChild ) ;
assertEquals( 3, reparented.getLength() ) ;
assertEquals( "parent", reparented.getTreeAtDistance( 2 ).getPayload() ) ;
assertEquals( 2, reparented.getTreeAtDistance( 2 ).getChildCount() ) ;
assertEquals( "child0", reparented.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 1, reparented.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "newGrandChild", reparented.getTreeAtDistance( 0 ).getPayload() ) ;
assertEquals( 0, reparented.getTreeAtDistance( 0 ).getChildCount() ) ;
}
@Test
public void addSiblingLast() {
// parent
final MyTree child0 = MyTree.create( "child0" ) ; // |
final MyTree parent = MyTree.create( "parent", child0 ) ; // child0
final MyTree child1 = MyTree.create( "child1" ) ;
final Treepath< MyTree > treepath = TreepathTools.addSiblingLast( // parent
Treepath.< MyTree >create( parent, 0 ), // | \
child1// ^ IntelliJ IDEA 7.0.3 requires this. // child0 child1
) ;
assertEquals( "parent", treepath.getTreeAtStart().getPayload() ) ;
assertEquals( 2, treepath.getTreeAtStart().getChildCount() ) ;
assertEquals( "child0", treepath.getTreeAtStart().getChildAt( 0 ).getPayload() ) ;
assertEquals( 0, treepath.getTreeAtStart().getChildAt( 0 ).getChildCount() ) ;
assertEquals( "child1", treepath.getTreeAtStart().getChildAt( 1 ).getPayload() ) ;
assertEquals( 0, treepath.getTreeAtStart().getChildAt( 1 ).getChildCount() ) ;
}
@Test
public void removeEnd() {
// grandParent
final MyTree child0 = MyTree.create( "child0" ) ; // |
final MyTree child1 = MyTree.create( "child1" ) ; // parent
final MyTree parent = MyTree.create( "parent", child0, child1 ) ; // / \
final MyTree grandParent = MyTree.create( "grandParent", parent ) ; // child0 child1
// treepath: grandParent <- parent <- child0
final Treepath< MyTree > treepath = Treepath.create( grandParent, 0, 0 ) ;
// afterRemoval: grandParent <- parent
final Treepath< MyTree > afterRemoval = TreepathTools.removeEnd( treepath ) ;
assertEquals( 2, afterRemoval.getLength() ) ;
assertEquals( 1, afterRemoval.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "grandParent", afterRemoval.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 1, afterRemoval.getTreeAtDistance( 0 ).getChildCount() ) ;
assertEquals( "parent", afterRemoval.getTreeAtDistance( 0 ).getPayload() ) ;
assertSame( child1, afterRemoval.getTreeAtDistance( 0 ).getChildAt( 0 ) ) ;
}
@Test
public void removeNextSibling() {
final MyTree child0 = MyTree.create( "child0" ) ; // parent
final MyTree child1 = MyTree.create( "child1" ) ; // / | \
final MyTree child2 = MyTree.create( "child2" ) ; // child0 child1 child2
final MyTree parent = MyTree.create( "parent", child0, child1, child2 ) ;
// treepath: parent <- child0
final Treepath< MyTree > treepath = Treepath.create( parent, 0 ) ;
// afterRemoval: parent <- child0
final Treepath< MyTree > afterRemoval = TreepathTools.removeNextSibling( treepath ) ;
assertEquals( 2, afterRemoval.getLength() ) ;
assertEquals( 2, afterRemoval.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "parent", afterRemoval.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 0, afterRemoval.getTreeAtDistance( 0 ).getChildCount() ) ;
assertSame( child0, afterRemoval.getTreeAtDistance( 1 ).getChildAt( 0 ) ) ;
assertSame( child2, afterRemoval.getTreeAtDistance( 1 ).getChildAt( 1 ) ) ;
}
@Test
public void removePreviousSibling3() {
final MyTree child0 = MyTree.create( "child0" ) ; // parent
final MyTree child1 = MyTree.create( "child1" ) ; // / | \
final MyTree child2 = MyTree.create( "child2" ) ; // child0 child1 child2
final MyTree parent = MyTree.create( "parent", child0, child1, child2 ) ;
// treepath: parent <- child1
final Treepath< MyTree > treepath = Treepath.create( parent, 1 ) ;
// afterRemoval: parent <- child1
final Treepath< MyTree > afterRemoval = TreepathTools.removePreviousSibling( treepath ) ;
assertEquals( 2, afterRemoval.getLength() ) ;
assertEquals( 2, afterRemoval.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "parent", afterRemoval.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 0, afterRemoval.getTreeAtDistance( 0 ).getChildCount() ) ;
assertSame( child1, afterRemoval.getTreeAtDistance( 1 ).getChildAt( 0 ) ) ;
assertSame( child2, afterRemoval.getTreeAtDistance( 1 ).getChildAt( 1 ) ) ;
}
@Test
public void removePreviousSibling2() {
final MyTree child0 = MyTree.create( "child0" ) ; // parent
final MyTree child1 = MyTree.create( "child1" ) ; // / \
final MyTree parent = MyTree.create( "parent", child0, child1 ) ; // child0 child1
// treepath: child1 -> parent
final Treepath< MyTree > treepath = Treepath.create( parent, 1 ) ;
// afterRemoval: child1 -> parent
final Treepath< MyTree > afterRemoval = TreepathTools.removePreviousSibling( treepath ) ;
assertEquals( 2, afterRemoval.getLength() ) ;
assertEquals( 1, afterRemoval.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "parent", afterRemoval.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 0, afterRemoval.getTreeAtDistance( 0 ).getChildCount() ) ;
assertSame( child1, afterRemoval.getTreeAtDistance( 1 ).getChildAt( 0 ) ) ;
}
@Test
public void getSiblingAt() {
final MyTree child0 = MyTree.create( "child0" ) ; // parent
final MyTree child1 = MyTree.create( "child1" ) ; // / | \
final MyTree child2 = MyTree.create( "child2" ) ; // child0 child1 child2
final MyTree parent = MyTree.create( "parent", child0, child1, child2 ) ;
// treepath: parent <- child0
final Treepath< MyTree > treepath = Treepath.create( parent, 0 ) ;
final Treepath< MyTree > sibling = TreepathTools.getSiblingAt( treepath, 2 ) ;
assertEquals( "child2", sibling.getTreeAtEnd().getPayload() ) ;
}
@Test
public void becomeLastChildOfPreviousSibling() {
final MyTree child = MyTree.create( "child" ) ; // parent
final MyTree moving = MyTree.create( "moving" ) ; // | \
final MyTree parent = MyTree.create( "parent", child, moving ) ; // child moving
final Treepath< MyTree > original = Treepath.create( parent, 1 ) ;
// parent
// | \
// child moving
final Treepath< MyTree > moved = // |
TreepathTools.becomeLastChildOfPreviousSibling( original ) ; // moving
assertEquals( 3, moved.getLength() ) ;
assertEquals( "parent", moved.getTreeAtDistance( 2 ).getPayload() ) ;
assertEquals( 1, moved.getTreeAtDistance( 2 ).getChildCount() ) ;
assertEquals( "child", moved.getTreeAtDistance( 1 ).getPayload() ) ;
assertEquals( 1, moved.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "moving", moved.getTreeAtEnd().getPayload() ) ;
assertEquals( "moving", moved.getTreeAtDistance( 0 ).getPayload() ) ;
assertEquals( 0, moved.getTreeAtDistance( 0 ).getChildCount() ) ;
}
@Test ( expected = IllegalArgumentException.class )
public void removeSubtreeDetectsUnrelatedTreepaths() {
final Treepath< MyTree > treepath1 = Treepath.create( MyTree.create( "1" ) ) ;
final Treepath< MyTree > treepath2 = Treepath.create( MyTree.create( "2" ) ) ;
TreepathTools.removeSubtree( treepath1, treepath2 ) ;
}
@Test (expected = IllegalArgumentException.class )
public void removeSubtreeDetectsSubtreeContainingContainer() {
// grandParent
// |
final MyTree child = MyTree.create( "child" ) ; // parent
final MyTree parent = MyTree.create( "parent", child ) ; // |
final MyTree grandParent = MyTree.create( "grandParent", parent ) ; // child
// treepath: grandParent <- parent
final Treepath< MyTree > sub = Treepath.create( grandParent, 0, 0 ) ;
// treepath: grandParent <- parent <- child
final Treepath< MyTree > container = Treepath.create( grandParent, 0, 0 ) ;
TreepathTools.removeSubtree( container, sub ) ;
}
@Test
public void removeSubtreeWithSiblings() {
// grandParent
final MyTree child0 = MyTree.create( "child0" ) ; // |
final MyTree child1 = MyTree.create( "child1" ) ; // parent
final MyTree parent = MyTree.create( "parent", child0, child1 ) ; // / \
final MyTree grandParent = MyTree.create( "grandParent", parent ) ; // child0 child1
// treepath: grandParent <- parent <- child1
final Treepath< MyTree > container = Treepath.create( grandParent, 0, 1 ) ;
// treepath: grandParent <- parent <- child0
final Treepath< MyTree > subtree = Treepath.create( grandParent, 0, 0 ) ;
final Treepath< MyTree > afterRemoval = TreepathTools.removeSubtree( container, subtree ) ;
assertEquals( 3, afterRemoval.getLength() ) ;
assertEquals( 1, afterRemoval.getTreeAtDistance( 2 ).getChildCount() ) ;
assertEquals( "grandParent", afterRemoval.getTreeAtDistance( 2 ).getPayload() ) ;
assertEquals( 1, afterRemoval.getTreeAtDistance( 1 ).getChildCount() ) ;
assertEquals( "parent", afterRemoval.getTreeAtDistance( 1 ).getPayload() ) ;
assertSame( child1, afterRemoval.getTreeAtDistance( 0 ) ) ;
}
}