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());
+        }
     }
 
 

Reply via email to