/*
* Copyright 2003-2016 JetBrains s.r.o.
*
* 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 jetbrains.mps.openapi.editor.cells.traversal;
import jetbrains.mps.openapi.editor.cells.CellTraversalUtil;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.mps.openapi.editor.cells.EditorCell_Collection;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.util.TreeIterator;
import org.jetbrains.mps.util.Condition;
import org.jetbrains.mps.util.TreeFilterIterator;
import org.junit.Before;
import org.junit.Test;
import java.util.Iterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class CellTreeTraversalTest extends CellTreeTest {
private EditorCell_Collection startA, childB, childF, childI, topX;
private EditorCell leafD, leafE, lastJ, lastY;
private static String traverseWholeTreeFrom(EditorCell cell) {
return traverseSubtreeFrom(null, cell);
}
private static String traverseSubtreeFrom(@Nullable EditorCell root, EditorCell cell) {
return ids(CellTraversalUtil.iterateTree(root, cell, true).iterator());
}
private static String traverseSubtreeWithFilter(EditorCell start, EditorCell filterSubtree) {
return ids(new TreeFilterIterator<>(traverserForSubtree(start), new IsSameAs(filterSubtree)));
}
private static String traverseSubtree(EditorCell start) {
return ids(traverserForSubtree(start));
}
private static String traverseSubtreeSkipping(EditorCell start, EditorCell skipSubtree) {
StringBuilder rv = new StringBuilder();
for (TreeIterator<EditorCell> it = traverserForSubtree(start); it.hasNext(); ) {
EditorCell n = it.next();
if (n == skipSubtree) {
it.skipChildren();
continue;
}
rv.append(n.getCellId());
}
return rv.toString();
}
private static String ids(Iterator<EditorCell> iterator) {
StringBuilder result = new StringBuilder();
while (iterator.hasNext()) {
result.append(iterator.next().getCellId());
}
return result.toString();
}
private static TreeIterator<EditorCell> traverserForSubtree(EditorCell start) {
return CellTraversalUtil.iterateTree(start, start, true).iterator();
}
@Before
public void setUp() {
startA =
newNode("A",
childB = newNode("B",
newNode("C"),
leafD = newNode("D"),
leafE = newNode("E")),
childF = newNode("F",
newNode("G"),
newNode("H")),
childI = newNode("I",
lastJ = newNode("J")));
topX = newNode("X", startA, lastY = newNode("Y"));
}
@Test
public void traverseSubtree_complete() {
assertEquals("ABCDEFGHIJ", traverseSubtree(startA));
}
@Test
public void traverseSubtree_singleElement() {
assertEquals("W", traverseSubtree(newNode("W")));
}
@Test
public void traverseSubtree_skipNonLeaf() {
assertEquals("ABCDEIJ", traverseSubtreeSkipping(startA, childF));
}
@Test
public void traverseSubtree_skipLeafWithoutSibling() {
assertEquals("ABCDFGHIJ", traverseSubtreeSkipping(startA, leafE));
}
@Test
public void traverseSubtree_skipLeafWithSibling() {
assertEquals("ABCEFGHIJ", traverseSubtreeSkipping(startA, leafD));
}
@Test
public void traverseSubtree_skipLastElement() {
assertEquals("ABCDEFGHI", traverseSubtreeSkipping(startA, lastJ));
}
@Test
public void traverseSubtree_skipRoot() {
assertTrue(traverseSubtreeSkipping(startA, startA).isEmpty());
}
@Test
public void traverseSubtree_skipRootOfSingletonTree() {
final EditorCell root = newNode("W");
assertTrue(traverseSubtreeSkipping(root, root).isEmpty());
}
@Test
public void treeFilterIterator_skipNonLeaf() {
assertEquals("ABCDEIJ", traverseSubtreeWithFilter(startA, childF));
}
@Test
public void treeFilterIterator_skipI() {
assertEquals("ABCDEFGH", traverseSubtreeWithFilter(startA, childI));
}
@Test
public void treeFilterIterator_skipStartNode() {
assertEquals("", traverseSubtreeWithFilter(startA, startA));
}
@Test
public void treeFilterIterator_skipLastElement() {
// skip last element (last leaf)
assertEquals("ABCDEFGHI", traverseSubtreeWithFilter(startA, lastJ));
}
@Test
public void treeFilterIterator_skipOutsideNode() {
// skip node which is not from the sub-tree
assertEquals("ABCDEFGHIJ", traverseSubtreeWithFilter(startA, topX));
}
@Test
public void traverseWholeTree_fromLast() {
assertEquals("Y", traverseWholeTreeFrom(lastY));
}
@Test
public void traverseWholeTree_fromBeforeLast() {
assertEquals("JY", traverseWholeTreeFrom(lastJ));
}
@Test
public void traverseWholeTree_fromTop() {
assertEquals("XABCDEFGHIJY", traverseWholeTreeFrom(topX));
}
@Test
public void traverseWholeTree_fromStart() {
assertEquals("ABCDEFGHIJY", traverseWholeTreeFrom(startA));
}
@Test
public void traverseWholeTree_fromMiddle() {
assertEquals("FGHIJY", traverseWholeTreeFrom(childF));
}
@Test
public void traverseWholeTree_fromLeaf() {
assertEquals("DEFGHIJY", traverseWholeTreeFrom(leafD));
}
@Test
public void traverseSubtree_fromStart() {
assertEquals("BCDE", traverseSubtreeFrom(childB, childB));
}
@Test
public void traverseSubtree_fromMiddle() {
assertEquals("DE", traverseSubtreeFrom(childB, leafD));
}
@Test
public void traverseSubtree_fromEnd() {
assertEquals("E", traverseSubtreeFrom(childB, leafE));
}
private static class IsSameAs implements Condition<EditorCell> {
@Nullable
private final EditorCell myCell;
IsSameAs(@Nullable EditorCell cell) {
myCell = cell;
}
@Override
public boolean met(EditorCell object) {
return object == myCell;
}
}
}