diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterable.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterable.java new file mode 100644 index 000000000..24b9fe7d8 --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterable.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel; + +import org.eclipse.xtext.nodemodel.impl.AbstractNode; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class BasicNodeIterable extends org.eclipse.xtext.nodemodel.impl.BasicNodeIterable { + + protected BasicNodeIterable(AbstractNode startWith) { + super(startWith); + } + +} diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterableTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterableTest.java new file mode 100644 index 000000000..6f10cbebe --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterableTest.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.xtext.nodemodel.impl.AbstractNode; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class BasicNodeIterableTest { + + @Test + public void forEachTest() { + AbstractNode alpha = BasicNodeIteratorTest.nodeWithTwoSiblings(); + BasicNodeIterable iterable = new BasicNodeIterable(alpha); + + List tokens = new ArrayList(); + for (INode node : iterable) { + tokens.add(node.getText()); + } + + Assert.assertEquals("alpha", tokens.get(0)); + Assert.assertEquals("beta", tokens.get(1)); + Assert.assertEquals("gamma", tokens.get(2)); + } + + @Test + public void forEachReverseTest() { + AbstractNode alpha = BasicNodeIteratorTest.nodeWithTwoSiblings(); + BasicNodeIterable iterable = new BasicNodeIterable(alpha); + + List tokens = new ArrayList(); + for (INode node : iterable.reverse()) { + tokens.add(node.getText()); + } + + Assert.assertEquals("gamma", tokens.get(0)); + Assert.assertEquals("beta", tokens.get(1)); + Assert.assertEquals("alpha", tokens.get(2)); + } + + @Test(expected=NullPointerException.class) + public void testStartWithNullThrowsNPE() { + new BasicNodeIterable(null); + } +} diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterator.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterator.java new file mode 100644 index 000000000..c8bb3ebaa --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIterator.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel; + +import org.eclipse.xtext.nodemodel.impl.AbstractNode; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class BasicNodeIterator extends org.eclipse.xtext.nodemodel.impl.BasicNodeIterator { + + public BasicNodeIterator(AbstractNode startWith) { + super(startWith); + } +} diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIteratorTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIteratorTest.java new file mode 100644 index 000000000..b92a77647 --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/BasicNodeIteratorTest.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel; + +import java.util.NoSuchElementException; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.xtext.nodemodel.impl.AbstractNode; +import org.eclipse.xtext.nodemodel.impl.NodeModelBuilder; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class BasicNodeIteratorTest { + + private static AbstractNode getSingleNode() { + return new RootNode(); + } + + public static AbstractNode nodeWithTwoSiblings() { + NodeModelBuilder builder = new NodeModelBuilder(); + String text = "alpha beta gamma"; + + RootNode root = new RootNode(); + root.basicSetCompleteContent(text); + + EObject alpha = new EObjectImpl() {}; + builder.newLeafNode(text.indexOf("alpha"), "alpha".length(), alpha, false, null, root); + + EObject beta = new EObjectImpl() {}; + builder.newLeafNode(text.indexOf("beta"), "beta".length(), beta, false, null, root); + + EObject gamma = new EObjectImpl() {}; + builder.newLeafNode(text.indexOf("gamma"), "gamma".length(), gamma, false, null, root); + + return root.basicGetFirstChild(); + + } + + @Test(expected=NullPointerException.class) + public void testStartWithNullThrowsNPE() { + new BasicNodeIterator(null); + } + + @Test + public void testSingleNodeHasNext() { + AbstractNode single = getSingleNode(); + BasicNodeIterator it = new BasicNodeIterator(single); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertFalse(it.hasNext()); + } + + @Test(expected=NoSuchElementException.class) + public void testNextTooFarThrowsException() { + AbstractNode single = getSingleNode(); + BasicNodeIterator it = new BasicNodeIterator(single); + + it.next(); + + it.next(); + } + + @Test + public void testIterateThreeNodes() { + AbstractNode alpha = nodeWithTwoSiblings(); + BasicNodeIterator it = new BasicNodeIterator(alpha); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertFalse(it.hasNext()); + } + + @Test + public void testSingleNodeHasPrevious() { + AbstractNode single = getSingleNode(); + BasicNodeIterator it = new BasicNodeIterator(single); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertFalse(it.hasPrevious()); + } + + @Test + public void testIteratePreviousStartsWithLastNode() { + AbstractNode alpha = nodeWithTwoSiblings(); + BasicNodeIterator it = new BasicNodeIterator(alpha); + + INode result = it.previous(); + + Assert.assertEquals("gamma", result.getText()); + } + + @Test(expected=NoSuchElementException.class) + public void testPreviousTooFarThrowsException() { + AbstractNode single = getSingleNode(); + BasicNodeIterator it = new BasicNodeIterator(single); + + it.previous(); + + it.previous(); + } + + @Test + public void testIterateThreeNodesInReverse() { + AbstractNode alpha = nodeWithTwoSiblings(); + BasicNodeIterator it = new BasicNodeIterator(alpha); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertFalse(it.hasPrevious()); + } +} diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIterableTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIterableTest.java new file mode 100644 index 000000000..8457a074f --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIterableTest.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel.util; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.xtext.nodemodel.INode; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class NodeIterableTest { + + @Test + public void forEachTest() { + INode alpha = NodeIteratorTest.nodeWithTwoSiblings(); + NodeIterable iterable = new NodeIterable(alpha); + + List tokens = new ArrayList(); + for (INode node : iterable) { + tokens.add(node.getText()); + } + + Assert.assertEquals("alpha", tokens.get(0)); + Assert.assertEquals("beta", tokens.get(1)); + Assert.assertEquals("gamma", tokens.get(2)); + } + + @Test + public void forEachReverseTest() { + INode alpha = NodeIteratorTest.nodeWithTwoSiblings(); + NodeIterable iterable = new NodeIterable(alpha); + + List tokens = new ArrayList(); + for (INode node : iterable.reverse()) { + tokens.add(node.getText()); + } + + Assert.assertEquals("gamma", tokens.get(0)); + Assert.assertEquals("beta", tokens.get(1)); + Assert.assertEquals("alpha", tokens.get(2)); + } + + @Test(expected=NullPointerException.class) + public void testStartWithNullThrowsNPE() { + new NodeIterable(null); + } +} diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIteratorTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIteratorTest.java new file mode 100644 index 000000000..f2cc86539 --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/util/NodeIteratorTest.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2020 Robert Lewis and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.nodemodel.util; + +import java.util.NoSuchElementException; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.ILeafNode; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.nodemodel.impl.NodeModelBuilder; +import org.eclipse.xtext.nodemodel.impl.RootNode; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Robert Lewis - Initial contribution and API + */ +public class NodeIteratorTest { + + private static INode getSingleNode() { + return new RootNode(); + } + + public static INode nodeWithTwoSiblings() { + NodeModelBuilder builder = new NodeModelBuilder(); + String text = "alpha beta gamma"; + + ICompositeNode root = builder.newRootNode(text); + + EObject alpha = new EObjectImpl() {}; + ILeafNode alphaNode = builder.newLeafNode(text.indexOf("alpha"), "alpha".length(), alpha, false, null, root); + + EObject beta = new EObjectImpl() {}; + builder.newLeafNode(text.indexOf("beta"), "beta".length(), beta, false, null, root); + + EObject gamma = new EObjectImpl() {}; + builder.newLeafNode(text.indexOf("gamma"), "gamma".length(), gamma, false, null, root); + + return alphaNode; + } + + @Test(expected=NullPointerException.class) + public void testStartWithNullThrowsNPE() { + new NodeIterator(null); + } + + @Test + public void testSingleNodeHasNext() { + INode single = getSingleNode(); + NodeIterator it = new NodeIterator(single); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertFalse(it.hasNext()); + } + + @Test(expected=NoSuchElementException.class) + public void testNextTooFarThrowsException() { + INode single = getSingleNode(); + NodeIterator it = new NodeIterator(single); + + it.next(); + + it.next(); + } + + @Test + public void testIterateThreeNodes() { + INode alpha = nodeWithTwoSiblings(); + NodeIterator it = new NodeIterator(alpha); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertTrue(it.hasNext()); + it.next(); + + Assert.assertFalse(it.hasNext()); + } + + @Test + public void testSingleNodeHasPrevious() { + INode single = getSingleNode(); + NodeIterator it = new NodeIterator(single); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertFalse(it.hasPrevious()); + } + + @Test + public void testIteratePreviousStartsWithLastNode() { + INode alpha = nodeWithTwoSiblings(); + NodeIterator it = new NodeIterator(alpha); + + INode result = it.previous(); + + Assert.assertEquals("gamma", result.getText()); + } + + @Test(expected=NoSuchElementException.class) + public void testPreviousTooFarThrowsException() { + INode single = getSingleNode(); + NodeIterator it = new NodeIterator(single); + + it.previous(); + + it.previous(); + } + + @Test + public void testIterateThreeNodesInReverse() { + INode alpha = nodeWithTwoSiblings(); + NodeIterator it = new NodeIterator(alpha); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertTrue(it.hasPrevious()); + it.previous(); + + Assert.assertFalse(it.hasPrevious()); + } +} diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterable.java b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterable.java index ec87306e1..e0e0cf9c3 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterable.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterable.java @@ -1,5 +1,7 @@ package org.eclipse.xtext.nodemodel.impl; +import java.util.Objects; + import org.eclipse.xtext.nodemodel.BidiIterable; import org.eclipse.xtext.nodemodel.BidiIterator; import org.eclipse.xtext.nodemodel.util.ReversedBidiIterator; @@ -12,6 +14,7 @@ public class BasicNodeIterable implements BidiIterable { private final AbstractNode startWith; protected BasicNodeIterable(AbstractNode startWith) { + Objects.requireNonNull(startWith); this.startWith = startWith; } diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterator.java b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterator.java index 4577c8e72..fe12a1114 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterator.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/impl/BasicNodeIterator.java @@ -8,6 +8,7 @@ package org.eclipse.xtext.nodemodel.impl; import java.util.NoSuchElementException; +import java.util.Objects; import org.eclipse.xtext.nodemodel.BidiIterator; @@ -23,6 +24,7 @@ public class BasicNodeIterator extends UnmodifiableIterator implem private AbstractNode lastReturned; protected BasicNodeIterator(AbstractNode startWith) { + Objects.requireNonNull(startWith); this.startWith = startWith; } diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterable.java b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterable.java index cc673c970..c48d8b559 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterable.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterable.java @@ -1,5 +1,7 @@ package org.eclipse.xtext.nodemodel.util; +import java.util.Objects; + import org.eclipse.xtext.nodemodel.BidiIterable; import org.eclipse.xtext.nodemodel.BidiIterator; import org.eclipse.xtext.nodemodel.INode; @@ -12,6 +14,7 @@ public class NodeIterable implements BidiIterable { private final INode startWith; public NodeIterable(INode startWith) { + Objects.requireNonNull(startWith); this.startWith = startWith; } diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterator.java b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterator.java index 494956fc0..51ee3532f 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterator.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/util/NodeIterator.java @@ -8,6 +8,7 @@ package org.eclipse.xtext.nodemodel.util; import java.util.NoSuchElementException; +import java.util.Objects; import org.eclipse.xtext.nodemodel.BidiIterator; import org.eclipse.xtext.nodemodel.INode; @@ -23,6 +24,7 @@ public class NodeIterator extends UnmodifiableIterator implements BidiIte private INode lastReturned; public NodeIterator(INode startWith) { + Objects.requireNonNull(startWith); this.startWith = startWith; }