Repository: tinkerpop Updated Branches: refs/heads/TINKERPOP-1834 [created] 3adfe7ec6
Added terminal method to the Traversal bytecode so providers know what the user used to trigger the evaluation. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/3adfe7ec Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/3adfe7ec Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/3adfe7ec Branch: refs/heads/TINKERPOP-1834 Commit: 3adfe7ec66d8cf24f3e8090ffe8dd557600b5b6c Parents: d6f031f Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Wed Nov 15 09:11:26 2017 -0700 Committer: Marko A. Rodriguez <okramma...@gmail.com> Committed: Wed Nov 15 09:11:26 2017 -0700 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + docs/src/upgrade/release-3.3.x.asciidoc | 13 +++ .../gremlin/jsr223/JavaTranslator.java | 2 + .../gremlin/process/traversal/Translator.java | 16 ++++ .../gremlin/process/traversal/Traversal.java | 38 ++++++++- .../process/traversal/TraversalTest.java | 14 ++-- .../gremlin/groovy/jsr223/GroovyTranslator.java | 3 +- .../gremlin/python/jsr223/PythonTranslator.java | 2 + .../gremlin/process/ProcessComputerSuite.java | 3 + .../gremlin/process/ProcessStandardSuite.java | 4 + .../traversal/step/sideEffect/TerminalTest.java | 83 ++++++++++++++++++++ .../decoration/TranslationStrategy.java | 7 +- 12 files changed, 174 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index ce65af6..b0e3124 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima This release also includes changes from <<release-3-2-7, 3.2.7>>. +* Added terminal steps to `Bytecode` so that bytecode consumers know the terminal method called on the traversal. * Fixed bug in serialization of `Path` for GraphSON 3.0 in `gremlin-python`. * Added support for GraphSON 3.0 in Gremlin.Net. * Added `math()`-step which supports scientific calculator capabilities for numbers within a traversal. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/docs/src/upgrade/release-3.3.x.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/upgrade/release-3.3.x.asciidoc b/docs/src/upgrade/release-3.3.x.asciidoc index 80aff8b..20d1ac2 100644 --- a/docs/src/upgrade/release-3.3.x.asciidoc +++ b/docs/src/upgrade/release-3.3.x.asciidoc @@ -169,6 +169,19 @@ changes there may prove important for the provider's implementation. ==== Graph Database Providers +===== Terminal Method Added to Traversal Bytecode + +There are a set of "terminal methods" associated with a `Traversal`. +These include: `toList()`, `toSet()`, `promise()`, `iterate()`, etc. +For some providers, it is important to know which terminal method the user called when executing a traversal. This can allow +them to make certain assumptions about what data to return. Every finalizing terminal method is +appended to the traversal's `Bytecode`. + +``` +gremlin> g.V().out().iterate().getBytecode() +==>[[], [V(), out(), iterate()]] +``` + ===== IO Version Check In the `Graph.io()` method, providers are to bootstrap the `Io` instance returned with their own custom serializers http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java index 11eebbb..4def6b0 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java @@ -78,6 +78,8 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal } boolean spawned = false; for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) { + if (TERMINAL_STEPS.contains(instruction.getOperator())) + continue; if (!spawned) { traversal = (Traversal.Admin) invokeMethod(dynamicSource, Traversal.class, instruction.getOperator(), instruction.getArguments()); spawned = true; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java index 7e97fb3..0ee0f6b 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java @@ -19,6 +19,10 @@ package org.apache.tinkerpop.gremlin.process.traversal; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + /** * A Translator will translate {@link Bytecode} into another representation. That representation may be a * Java instance via {@link StepTranslator} or a String script in some language via {@link ScriptTranslator}. @@ -29,6 +33,18 @@ package org.apache.tinkerpop.gremlin.process.traversal; public interface Translator<S, T> { /** + * A utility parameter providing all terminal steps that should be avoided when compiling bytecode. + */ + public static Set<String> TERMINAL_STEPS = new HashSet<>(Arrays.asList( + Traversal.Symbols.fill, + Traversal.Symbols.iterate, + Traversal.Symbols.promise, + Traversal.Symbols.toBulkSet, + Traversal.Symbols.toList, + Traversal.Symbols.toSet, + Traversal.Symbols.toStream)); + + /** * Get the {@link TraversalSource} representation rooting this translator. * For string-based translators ({@link ScriptTranslator}), this is typically a "g". * For java-based translators ({@link StepTranslator}), this is typically the {@link TraversalSource} instance which the {@link Traversal} will be built from. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java index c085dc7..fb6bff0 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java @@ -68,7 +68,14 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A // static fields only } + public static final String fill = "fill"; + public static final String iterate = "iterate"; public static final String profile = "profile"; + public static final String promise = "promise"; + public static final String toBulkSet = "toBulkSet"; + public static final String toList = "toList"; + public static final String toSet = "toSet"; + public static final String toStream = "toStream"; } /** @@ -112,6 +119,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A * @return the results in a list */ public default List<E> toList() { + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.toList); + this.asAdmin().applyStrategies(); + } return this.fill(new ArrayList<>()); } @@ -121,6 +132,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A * @return the results in a set */ public default Set<E> toSet() { + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.toSet); + this.asAdmin().applyStrategies(); + } return this.fill(new HashSet<>()); } @@ -131,6 +146,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A * @return the results in a bulk set */ public default BulkSet<E> toBulkSet() { + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.toBulkSet); + this.asAdmin().applyStrategies(); + } return this.fill(new BulkSet<>()); } @@ -140,6 +159,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A * @return the traversal as a stream. */ public default Stream<E> toStream() { + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.toStream); + this.asAdmin().applyStrategies(); + } return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, Spliterator.IMMUTABLE | Spliterator.SIZED), false); } @@ -151,7 +174,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A */ public default <T> CompletableFuture<T> promise(final Function<Traversal<S,E>, T> traversalFunction) { // apply strategies to see if RemoteStrategy has any effect (i.e. add RemoteStep) - if (!this.asAdmin().isLocked()) this.asAdmin().applyStrategies(); + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.promise); + this.asAdmin().applyStrategies(); + } // use the end step so the results are bulked final Step<?, E> endStep = this.asAdmin().getEndStep(); @@ -170,7 +196,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A */ public default <C extends Collection<E>> C fill(final C collection) { try { - if (!this.asAdmin().isLocked()) this.asAdmin().applyStrategies(); + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.fill); + this.asAdmin().applyStrategies(); + } // use the end step so the results are bulked final Step<?, E> endStep = this.asAdmin().getEndStep(); while (true) { @@ -191,7 +220,10 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A */ public default <A, B> Traversal<A, B> iterate() { try { - if (!this.asAdmin().isLocked()) this.asAdmin().applyStrategies(); + if (!this.asAdmin().isLocked()) { + this.asAdmin().getBytecode().addStep(Symbols.iterate); + this.asAdmin().applyStrategies(); + } // use the end step so the results are bulked final Step<?, E> endStep = this.asAdmin().getEndStep(); while (true) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalTest.java index 020ed72..830cd58 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalTest.java @@ -66,11 +66,11 @@ public class TraversalTest { final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7); final List<Integer> batchOne = t.next(2); assertEquals(2, batchOne.size()); - assertThat(batchOne, hasItems(1 ,2)); + assertThat(batchOne, hasItems(1, 2)); final List<Integer> batchTwo = t.next(2); assertEquals(2, batchTwo.size()); - assertThat(batchTwo, hasItems(3 ,4)); + assertThat(batchTwo, hasItems(3, 4)); final List<Integer> batchThree = t.next(2); assertEquals(2, batchThree.size()); @@ -90,7 +90,7 @@ public class TraversalTest { final List<Integer> listToFill = new ArrayList<>(); final List<Integer> batch = t.fill(listToFill); assertEquals(7, batch.size()); - assertThat(batch, hasItems(1 ,2, 3, 4, 5, 6, 7)); + assertThat(batch, hasItems(1, 2, 3, 4, 5, 6, 7)); assertThat(t.hasNext(), is(false)); assertSame(listToFill, batch); } @@ -100,7 +100,7 @@ public class TraversalTest { final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7); final List<Integer> batch = t.toStream().collect(Collectors.toList()); assertEquals(7, batch.size()); - assertThat(batch, hasItems(1 ,2, 3, 4, 5, 6, 7)); + assertThat(batch, hasItems(1, 2, 3, 4, 5, 6, 7)); assertThat(t.hasNext(), is(false)); } @@ -145,7 +145,7 @@ public class TraversalTest { } } - private static class MockStep<E> implements Step<E,E> { + private static class MockStep<E> implements Step<E, E> { private final Iterator<E> itty; @@ -239,7 +239,7 @@ public class TraversalTest { } } - private static class MockTraversal<T> implements Traversal.Admin<T,T> { + private static class MockTraversal<T> implements Traversal.Admin<T, T> { private Iterator<T> itty; @@ -267,7 +267,7 @@ public class TraversalTest { @Override public Bytecode getBytecode() { - return null; + return new Bytecode(); } @Override http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java index 78ec0b2..b8478f8 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java @@ -25,7 +25,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions; import org.apache.tinkerpop.gremlin.process.traversal.Translator; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; @@ -87,6 +86,8 @@ public final class GroovyTranslator implements Translator.ScriptTranslator { final StringBuilder traversalScript = new StringBuilder(start); for (final Bytecode.Instruction instruction : bytecode.getInstructions()) { final String methodName = instruction.getOperator(); + if (TERMINAL_STEPS.contains(methodName)) + continue; if (0 == instruction.getArguments().length) traversalScript.append(".").append(methodName).append("()"); else { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java index 568ca03..ac220c7 100644 --- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java +++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java @@ -107,6 +107,8 @@ public class PythonTranslator implements Translator.ScriptTranslator { for (final Bytecode.Instruction instruction : bytecode.getInstructions()) { final String methodName = instruction.getOperator(); final Object[] arguments = instruction.getArguments(); + if (TERMINAL_STEPS.contains(methodName)) + continue; if (0 == arguments.length) traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()"); else if (methodName.equals("range") && 2 == arguments.length && ((Number) arguments[0]).intValue() != 0) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java index 0e0fc81..a3e7226 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java @@ -84,6 +84,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffect import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StoreTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphTest; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TerminalTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TreeTest; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategyProcessTest; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategyProcessTest; @@ -179,6 +180,7 @@ public class ProcessComputerSuite extends AbstractGremlinSuite { SideEffectTest.Traversals.class, StoreTest.Traversals.class, SubgraphTest.Traversals.class, + TerminalTest.Traversals.class, TreeTest.Traversals.class, // compliance @@ -264,6 +266,7 @@ public class ProcessComputerSuite extends AbstractGremlinSuite { SideEffectTest.class, StoreTest.class, SubgraphTest.class, + TerminalTest.class, TreeTest.class }; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java index 18e25d7..ec42c52 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java @@ -78,6 +78,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffect import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StoreTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphTest; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TerminalTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TreeTest; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest; @@ -168,8 +169,10 @@ public class ProcessStandardSuite extends AbstractGremlinSuite { SideEffectTest.Traversals.class, StoreTest.Traversals.class, SubgraphTest.Traversals.class, + TerminalTest.Traversals.class, TreeTest.Traversals.class, + // compliance ComplexTest.Traversals.class, CoreTraversalTest.class, @@ -250,6 +253,7 @@ public class ProcessStandardSuite extends AbstractGremlinSuite { SideEffectTest.class, StoreTest.class, SubgraphTest.class, + TerminalTest.class, TreeTest.class, }; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TerminalTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TerminalTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TerminalTest.java new file mode 100644 index 0000000..fe0127a --- /dev/null +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TerminalTest.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.tinkerpop.gremlin.process.traversal.step.sideEffect; + +import org.apache.tinkerpop.gremlin.LoadGraphWith; +import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest; +import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN; +import static org.junit.Assert.assertEquals; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +@RunWith(GremlinProcessRunner.class) +public abstract class TerminalTest extends AbstractGremlinProcessTest { + + public abstract Traversal<Vertex, Vertex> get_g_V_out_iterate(); + + public abstract Traversal<Vertex, Vertex> get_g_V_out(); + + @Test + @LoadGraphWith(MODERN) + public void g_V_out_iterate() { + final Traversal<Vertex, Vertex> traversal = get_g_V_out_iterate(); + printTraversalForm(traversal); + assertEquals("iterate", traversal.asAdmin().getBytecode().getStepInstructions().get(traversal.asAdmin().getBytecode().getStepInstructions().size() - 1).getOperator()); + } + + @Test + @LoadGraphWith(MODERN) + public void g_V_out_toList() { + final Traversal<Vertex, Vertex> traversal = get_g_V_out(); + assertEquals(6, traversal.toList().size()); + printTraversalForm(traversal); + assertEquals("toList", traversal.asAdmin().getBytecode().getStepInstructions().get(traversal.asAdmin().getBytecode().getStepInstructions().size() - 1).getOperator()); + } + + @Test + @LoadGraphWith(MODERN) + public void g_V_out_toSet() { + final Traversal<Vertex, Vertex> traversal = get_g_V_out(); + assertEquals(6, traversal.toSet().size()); + printTraversalForm(traversal); + assertEquals("toSet", traversal.asAdmin().getBytecode().getStepInstructions().get(traversal.asAdmin().getBytecode().getStepInstructions().size() - 1).getOperator()); + } + + + public static class Traversals extends TerminalTest { + + @Override + public Traversal<Vertex, Vertex> get_g_V_out_iterate() { + return g.V().out().iterate(); + } + + @Override + public Traversal<Vertex, Vertex> get_g_V_out() { + return g.V().out(); + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3adfe7ec/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java index 0736c02..bb6c3cb 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java @@ -113,9 +113,14 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers TraversalHelper.removeAllSteps(traversal); TraversalHelper.removeToTraversal((Step) translatedTraversal.getStartStep(), EmptyStep.instance(), traversal); //////////////// - if (IS_TESTING && !BytecodeHelper.getLambdaLanguage(bytecode).isPresent()) + if (IS_TESTING && !BytecodeHelper.getLambdaLanguage(bytecode).isPresent()) { // this tests to ensure that the bytecode being translated is the same as the bytecode of the generated traversal + final String tailOperator = traversal.getBytecode().getStepInstructions().get(traversal.getBytecode().getStepInstructions().size() - 1).getOperator(); + if (Translator.TERMINAL_STEPS.contains(tailOperator)) { + translatedTraversal.getBytecode().addStep(tailOperator); + } assertEquals(removeTranslationStrategy(traversal.getBytecode()), translatedTraversal.getBytecode()); + } }