You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/09/20 16:05:11 UTC

tinkerpop git commit: AbstractLambdaTraversals now support a bypassTraversal which allows strategies to easily change the semantics of the lambda traversal. Found a bug in TraversalVertexProgram around order() and the use of ConnectiveSteps. Added more t

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1456 4f723eed8 -> d2ae1aaa8


AbstractLambdaTraversals now support a bypassTraversal which allows strategies to easily change the semantics of the lambda traversal. Found a bug in TraversalVertexProgram around order() and the use of ConnectiveSteps. Added more tests to SubgraphStrategyProcessTest to test vertex properties and ordering. Added checkOrderedResult() to AbstractGremlinProcessTest which makes it easy to check ordered streams. Updated OrderTest to use this model -- much simpler.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/d2ae1aaa
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/d2ae1aaa
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/d2ae1aaa

Branch: refs/heads/TINKERPOP-1456
Commit: d2ae1aaa8bce78d260e53dc4ecc047c78f905b16
Parents: 4f723ee
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Sep 20 10:04:56 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Sep 20 10:04:56 2016 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  4 +
 .../computer/traversal/MasterExecutor.java      |  7 +-
 .../lambda/AbstractLambdaTraversal.java         | 68 ++++++++++----
 .../traversal/lambda/ElementValueTraversal.java | 12 ++-
 .../strategy/decoration/SubgraphStrategy.java   | 16 ++++
 .../process/AbstractGremlinProcessTest.java     | 13 +++
 .../process/traversal/step/map/OrderTest.java   | 94 ++++----------------
 .../decoration/SubgraphStrategyProcessTest.java | 10 +++
 8 files changed, 122 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 7c4178d..94391b9 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,10 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.3 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Fixed a bug in `TraversalVertexProgram` (OLAP) around ordering and connectives (i.e. `and()` and `or()`).
+* Added `AbstractGremlinProcessTest.checkOrderedResults()` to make testing ordered results easier.
+* `AbstractLambdaTraversal` now supports a `bypassTraversal` and thus, it is possible for strategies to redefine such lambda traversals.
+* `SubgraphStrategy` now supports vertex property filtering.
 * Fixed a bug in Gremlin-Python `P` where predicates reversed the order of the predicates.
 * Fixed a naming bug in Gremlin-Python where `P._and` and `P._or` should be `P.and_` and `P.or_`. (*breaking*)
 * `where()` predicate-based steps now support `by()`-modulation.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/MasterExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/MasterExecutor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/MasterExecutor.java
index b83b6d6..f81ca14 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/MasterExecutor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/MasterExecutor.java
@@ -20,15 +20,16 @@
 package org.apache.tinkerpop.gremlin.process.computer.traversal;
 
 import org.apache.tinkerpop.gremlin.process.computer.Memory;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
 import org.apache.tinkerpop.gremlin.process.traversal.step.LocalBarrier;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
@@ -38,6 +39,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyValueStep
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SackStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
 import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMatrix;
@@ -144,6 +146,7 @@ final class MasterExecutor {
         return step instanceof PropertiesStep || step instanceof PropertyMapStep ||
                 step instanceof IdStep || step instanceof LabelStep || step instanceof SackStep ||
                 step instanceof PropertyKeyStep || step instanceof PropertyValueStep ||
-                step instanceof TailGlobalStep || step instanceof RangeGlobalStep || step instanceof HasStep;
+                step instanceof TailGlobalStep || step instanceof RangeGlobalStep || step instanceof HasStep ||
+                step instanceof ConnectiveStep;
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
index 77b6675..b2335b9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
@@ -45,73 +45,90 @@ public abstract class AbstractLambdaTraversal<S, E> implements Traversal.Admin<S
 
     private static final Set<TraverserRequirement> REQUIREMENTS = Collections.singleton(TraverserRequirement.OBJECT);
 
+    protected Traversal.Admin<S, E> bypassTraversal = null;
+
+    public void setBypassTraversal(final Traversal.Admin<S, E> bypassTraversal) {
+        this.bypassTraversal = bypassTraversal;
+    }
+
+    @Override
     public List<Step> getSteps() {
-        return Collections.emptyList();
+        return null == this.bypassTraversal ? Collections.emptyList() : this.bypassTraversal.getSteps();
     }
 
+    @Override
     public Bytecode getBytecode() {
-        return new Bytecode();
+        return null == this.bypassTraversal ? new Bytecode() : this.bypassTraversal.getBytecode();
     }
 
+
     @Override
     public void reset() {
-
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.reset();
     }
 
     @Override
     public <S2, E2> Traversal.Admin<S2, E2> addStep(final int index, final Step<?, ?> step) throws IllegalStateException {
-        return (Traversal.Admin<S2, E2>) this;
+        return null == this.bypassTraversal ? (Traversal.Admin<S2, E2>) this : this.bypassTraversal.addStep(index, step);
     }
 
     @Override
     public <S2, E2> Traversal.Admin<S2, E2> removeStep(final int index) throws IllegalStateException {
-        return (Traversal.Admin<S2, E2>) this;
+        return null == this.bypassTraversal ? (Traversal.Admin<S2, E2>) this : this.bypassTraversal.removeStep(index);
     }
 
     @Override
     public void applyStrategies() throws IllegalStateException {
-
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.applyStrategies();
     }
 
     @Override
     public TraverserGenerator getTraverserGenerator() {
-        return B_O_TraverserGenerator.instance();
+        return null == this.bypassTraversal ? B_O_TraverserGenerator.instance() : this.bypassTraversal.getTraverserGenerator();
     }
 
     @Override
     public void setSideEffects(final TraversalSideEffects sideEffects) {
-
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.setSideEffects(sideEffects);
     }
 
     @Override
     public TraversalSideEffects getSideEffects() {
-        return EmptyTraversalSideEffects.instance();
+        return null == this.bypassTraversal ? EmptyTraversalSideEffects.instance() : this.bypassTraversal.getSideEffects();
     }
 
     @Override
     public void setStrategies(final TraversalStrategies strategies) {
-
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.setStrategies(strategies);
     }
 
     @Override
     public TraversalStrategies getStrategies() {
-        return EmptyTraversalStrategies.instance();
+        return null == this.bypassTraversal ? EmptyTraversalStrategies.instance() : this.bypassTraversal.getStrategies();
     }
 
     @Override
     public void setParent(final TraversalParent step) {
-
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.setParent(step);
     }
 
     @Override
     public TraversalParent getParent() {
-        return EmptyStep.instance();
+        return null == this.bypassTraversal ? EmptyStep.instance() : this.bypassTraversal.getParent();
     }
 
     @Override
     public Traversal.Admin<S, E> clone() {
         try {
-            return (AbstractLambdaTraversal<S, E>) super.clone();
+            final AbstractLambdaTraversal<S, E> clone = (AbstractLambdaTraversal<S, E>) super.clone();
+            if (null != this.bypassTraversal)
+                clone.bypassTraversal = this.bypassTraversal.clone();
+            return clone;
         } catch (final CloneNotSupportedException e) {
             throw new IllegalStateException(e.getMessage(), e);
         }
@@ -119,41 +136,54 @@ public abstract class AbstractLambdaTraversal<S, E> implements Traversal.Admin<S
 
     @Override
     public E next() {
+        if (null != this.bypassTraversal)
+            return this.bypassTraversal.next();
+        throw new UnsupportedOperationException("The " + this.getClass().getSimpleName() + " can only be used as a predicate traversal");
+    }
+
+    @Override
+    public Traverser.Admin<E> nextTraverser() {
+        if (null != this.bypassTraversal)
+            return this.bypassTraversal.nextTraverser();
         throw new UnsupportedOperationException("The " + this.getClass().getSimpleName() + " can only be used as a predicate traversal");
     }
 
     @Override
     public boolean hasNext() {
-        return true;
+        return null == this.bypassTraversal || this.bypassTraversal.hasNext();
     }
 
     @Override
     public void addStart(final Traverser.Admin<S> start) {
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.addStart(start);
     }
 
     @Override
     public boolean isLocked() {
-        return true;
+        return null == this.bypassTraversal || this.bypassTraversal.isLocked();
     }
 
     @Override
     public Optional<Graph> getGraph() {
-        return Optional.empty();
+        return null == this.bypassTraversal ? Optional.empty() : this.bypassTraversal.getGraph();
     }
 
     @Override
     public void setGraph(final Graph graph) {
+        if (null != this.bypassTraversal)
+            this.bypassTraversal.setGraph(graph);
 
     }
 
     @Override
     public Set<TraverserRequirement> getTraverserRequirements() {
-        return REQUIREMENTS;
+        return null == this.bypassTraversal ? REQUIREMENTS : this.bypassTraversal.getTraverserRequirements();
     }
 
     @Override
     public int hashCode() {
-        return this.getClass().hashCode();
+        return null == this.bypassTraversal ? this.getClass().hashCode() : this.bypassTraversal.hashCode();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
index a38e8e2..2e9b26c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.lambda;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.Element;
 
 /**
@@ -39,8 +40,13 @@ public final class ElementValueTraversal<V> extends AbstractLambdaTraversal<Elem
     }
 
     @Override
+    public boolean hasNext() {
+        return true;
+    }
+
+    @Override
     public void addStart(final Traverser.Admin<Element> start) {
-        this.value = start.get().value(this.propertyKey);
+        this.value = null == this.bypassTraversal ? start.get().value(this.propertyKey) : TraversalUtil.apply(start, this.bypassTraversal);
     }
 
     public String getPropertyKey() {
@@ -49,11 +55,11 @@ public final class ElementValueTraversal<V> extends AbstractLambdaTraversal<Elem
 
     @Override
     public String toString() {
-        return "value(" + this.propertyKey + ')';
+        return "value(" + (null == this.bypassTraversal ? this.propertyKey : this.bypassTraversal) + ')';
     }
 
     @Override
     public int hashCode() {
-        return this.getClass().hashCode() ^ this.propertyKey.hashCode();
+        return super.hashCode() ^ this.propertyKey.hashCode();
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
index f1a42cd..475a3d7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
@@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.LambdaFilterStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.OrStep;
@@ -50,6 +51,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * This {@link TraversalStrategy} provides a way to limit the view of a {@link Traversal}.  By providing
@@ -168,6 +170,20 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
             final OrStep<Object> wrappedCriterion = new OrStep<>(traversal,
                     new DefaultTraversal<>().addStep(new LambdaFilterStep<>(traversal, t -> !(t.get() instanceof VertexProperty))),
                     new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone())));
+            // turn all ElementValueTraversals into filters
+            for (final Step<?, ?> step : traversal.getSteps()) {
+                // gremlin> g.V().local(properties('name','stateOfMind').group().by(key()).by(value().fold()))
+                if (step instanceof TraversalParent) {
+                    Stream.concat(((TraversalParent) step).getGlobalChildren().stream(), ((TraversalParent) step).getLocalChildren().stream())
+                            .filter(t -> t instanceof ElementValueTraversal)
+                            .forEach(t -> {
+                                final Traversal.Admin<?, ?> temp = new DefaultTraversal<>();
+                                temp.addStep(new PropertiesStep<>(temp, PropertyType.VALUE, ((ElementValueTraversal) t).getPropertyKey()));
+                                temp.setParent((TraversalParent)step);
+                                ((ElementValueTraversal) t).setBypassTraversal(temp);
+                            });
+                }
+            }
             for (final PropertiesStep<?> step : TraversalHelper.getStepsOfAssignableClass(PropertiesStep.class, traversal)) {
                 if (PropertyType.PROPERTY.equals(step.getReturnType())) {
                     // if the property step returns a property, then simply append the criterion

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 201822c..7f685d2 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@ -102,6 +102,19 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
         assertEquals(StringFactory.traversalSideEffectsString(sideEffects), sideEffects.toString());
     }
 
+    public static <T> void checkOrderedResults(final List<T> expectedResults, final Traversal<?, T> traversal) {
+        final List<T> results = traversal.toList();
+        assertFalse(traversal.hasNext());
+        if (expectedResults.size() != results.size()) {
+            logger.error("Expected results: " + expectedResults);
+            logger.error("Actual results:   " + results);
+            assertEquals("Checking result size", expectedResults.size(), results.size());
+        }
+        for (int i = 0; i < expectedResults.size(); i++) {
+            assertEquals(expectedResults.get(i), results.get(i));
+        }
+    }
+
     public static <T> void checkResults(final List<T> expectedResults, final Traversal<?, T> traversal) {
         final List<T> results = traversal.toList();
         assertFalse(traversal.hasNext());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
index 453a663..7935252 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
@@ -101,7 +101,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_name_order() {
         final Traversal<Vertex, String> traversal = get_g_V_name_order();
         printTraversalForm(traversal);
-        assertCommon(traversal);
+        checkOrderedResults(Arrays.asList("josh", "lop", "marko", "peter", "ripple", "vadas"), traversal);
     }
 
     @Test
@@ -109,14 +109,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_name_order_byXa1_b1X_byXb2_a2X() {
         final Traversal<Vertex, String> traversal = get_g_V_name_order_byXa1_b1X_byXb2_a2X();
         printTraversalForm(traversal);
-        final List<String> names = traversal.toList();
-        assertEquals(names.size(), 6);
-        assertEquals("marko", names.get(0));
-        assertEquals("vadas", names.get(1));
-        assertEquals("peter", names.get(2));
-        assertEquals("ripple", names.get(3));
-        assertEquals("josh", names.get(4));
-        assertEquals("lop", names.get(5));
+        checkOrderedResults(Arrays.asList("marko", "vadas", "peter", "ripple", "josh", "lop"), traversal);
     }
 
     @Test
@@ -124,7 +117,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_order_byXname_incrX_name() {
         final Traversal<Vertex, String> traversal = get_g_V_order_byXname_incrX_name();
         printTraversalForm(traversal);
-        assertCommon(traversal);
+        checkOrderedResults(Arrays.asList("josh", "lop", "marko", "peter", "ripple", "vadas"), traversal);
     }
 
     @Test
@@ -132,18 +125,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_order_byXnameX_name() {
         final Traversal<Vertex, String> traversal = get_g_V_order_byXnameX_name();
         printTraversalForm(traversal);
-        assertCommon(traversal);
-    }
-
-    private static void assertCommon(Traversal<Vertex, String> traversal) {
-        final List<String> names = traversal.toList();
-        assertEquals(names.size(), 6);
-        assertEquals("josh", names.get(0));
-        assertEquals("lop", names.get(1));
-        assertEquals("marko", names.get(2));
-        assertEquals("peter", names.get(3));
-        assertEquals("ripple", names.get(4));
-        assertEquals("vadas", names.get(5));
+        checkOrderedResults(Arrays.asList("josh", "lop", "marko", "peter", "ripple", "vadas"), traversal);
     }
 
     @Test
@@ -151,15 +133,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_outE_order_byXweight_decrX_weight() {
         final Traversal<Vertex, Double> traversal = get_g_V_outE_order_byXweight_decrX_weight();
         printTraversalForm(traversal);
-        final List<Double> weights = traversal.toList();
-        assertEquals(6, weights.size());
-        assertEquals(Double.valueOf(1.0d), weights.get(0));
-        assertEquals(Double.valueOf(1.0d), weights.get(1));
-        assertEquals(Double.valueOf(0.5d), weights.get(2));
-        assertEquals(Double.valueOf(0.4d), weights.get(3));
-        assertEquals(Double.valueOf(0.4d), weights.get(4));
-        assertEquals(Double.valueOf(0.2d), weights.get(5));
-
+        checkOrderedResults(Arrays.asList(1.0d, 1.0d, 0.5d, 0.4d, 0.4d, 0.2d), traversal);
     }
 
     @Test
@@ -167,14 +141,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_order_byXname_a1_b1X_byXname_b2_a2X_name() {
         final Traversal<Vertex, String> traversal = get_g_V_order_byXname_a1_b1X_byXname_b2_a2X_name();
         printTraversalForm(traversal);
-        final List<String> names = traversal.toList();
-        assertEquals(names.size(), 6);
-        assertEquals("marko", names.get(0));
-        assertEquals("vadas", names.get(1));
-        assertEquals("peter", names.get(2));
-        assertEquals("ripple", names.get(3));
-        assertEquals("josh", names.get(4));
-        assertEquals("lop", names.get(5));
+        checkOrderedResults(Arrays.asList("marko", "vadas", "peter", "ripple", "josh", "lop"), traversal);
     }
 
     @Test
@@ -337,11 +304,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_hasLabelXpersonX_order_byXvalueXageX__decrX_name() {
         final Traversal<Vertex, String> traversal = get_g_V_hasLabelXpersonX_order_byXvalueXageX__decrX_name();
         printTraversalForm(traversal);
-        assertEquals("peter", traversal.next());
-        assertEquals("josh", traversal.next());
-        assertEquals("marko", traversal.next());
-        assertEquals("vadas", traversal.next());
-        assertFalse(traversal.hasNext());
+        checkOrderedResults(Arrays.asList("peter", "josh", "marko", "vadas"), traversal);
     }
 
     @Test
@@ -349,19 +312,10 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_properties_order_byXkey_decrX_key() {
         final Traversal<Vertex, String> traversal = get_g_V_properties_order_byXkey_decrX_key();
         printTraversalForm(traversal);
-        assertEquals("name", traversal.next());
-        assertEquals("name", traversal.next());
-        assertEquals("name", traversal.next());
-        assertEquals("name", traversal.next());
-        assertEquals("name", traversal.next());
-        assertEquals("name", traversal.next());
-        assertEquals("lang", traversal.next());
-        assertEquals("lang", traversal.next());
-        assertEquals("age", traversal.next());
-        assertEquals("age", traversal.next());
-        assertEquals("age", traversal.next());
-        assertEquals("age", traversal.next());
-        assertFalse(traversal.hasNext());
+        checkOrderedResults(Arrays.asList(
+                "name", "name", "name", "name", "name", "name",
+                "lang", "lang",
+                "age", "age", "age", "age"), traversal);
     }
 
     @Test
@@ -391,14 +345,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_both_hasLabelXpersonX_order_byXage_decrX_limitX5X_name() {
         final Traversal<Vertex, String> traversal = get_g_V_both_hasLabelXpersonX_order_byXage_decrX_limitX5X_name();
         printTraversalForm(traversal);
-        final List<String> results = traversal.toList();
-        assertEquals(5, results.size());
-        assertFalse(traversal.hasNext());
-        assertEquals("peter", results.get(0));
-        assertEquals("josh", results.get(1));
-        assertEquals("josh", results.get(2));
-        assertEquals("josh", results.get(3));
-        assertEquals("marko", results.get(4));
+        checkOrderedResults(Arrays.asList("peter", "josh", "josh", "josh", "marko"), traversal);
     }
 
     @Test
@@ -421,19 +368,10 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
     public void g_V_hasLabelXsongX_order_byXperfomances_decrX_byXnameX_rangeX110_120X_name() {
         final Traversal<Vertex, String> traversal = get_g_V_hasLabelXsongX_order_byXperfomances_decrX_byXnameX_rangeX110_120X_name();
         printTraversalForm(traversal);
-        final List<String> results = traversal.toList();
-        assertEquals(10, results.size());
-        assertEquals("WANG DANG DOODLE", results.get(0));
-        assertEquals("THE ELEVEN", results.get(1));
-        assertEquals("WAY TO GO HOME", results.get(2));
-        assertEquals("FOOLISH HEART", results.get(3));
-        assertEquals("GIMME SOME LOVING", results.get(4));
-        assertEquals("DUPREES DIAMOND BLUES", results.get(5));
-        assertEquals("CORRINA", results.get(6));
-        assertEquals("PICASSO MOON", results.get(7));
-        assertEquals("KNOCKING ON HEAVENS DOOR", results.get(8));
-        assertEquals("MEMPHIS BLUES", results.get(9));
-        assertFalse(traversal.hasNext());
+        checkOrderedResults(Arrays.asList(
+                "WANG DANG DOODLE", "THE ELEVEN", "WAY TO GO HOME", "FOOLISH HEART",
+                "GIMME SOME LOVING", "DUPREES DIAMOND BLUES", "CORRINA", "PICASSO MOON",
+                "KNOCKING ON HEAVENS DOOR", "MEMPHIS BLUES"), traversal);
     }
 
     public static class Traversals extends OrderTest {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d2ae1aaa/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
index 1d49d92..e303281 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
@@ -21,12 +21,14 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 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.Order;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -39,6 +41,7 @@ import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.bothE;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasNot;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -384,6 +387,13 @@ public class SubgraphStrategyProcessTest extends AbstractGremlinProcessTest {
         sg = create(SubgraphStrategy.build().vertices(has("name", P.not(P.within("stephen", "daniel")))).vertexProperties(has("startTime", P.gt(2005))).create());
         checkResults(Arrays.asList("baltimore", "oakland", "seattle"), sg.V().properties("location").value());
         checkResults(Arrays.asList("baltimore", "oakland", "seattle"), sg.V().values("location"));
+        //
+        sg = create(SubgraphStrategy.build().vertices(has("name", P.eq("matthias"))).vertexProperties(has("startTime", P.gte(2014))).create());
+        System.out.println(sg.V().groupCount().by("location").explain());
+        checkResults(makeMapList(1, "seattle", 1L), sg.V().groupCount().by("location"));
+        //
+        sg = create(SubgraphStrategy.build().vertices(has("location")).vertexProperties(hasNot("endTime")).create());
+        checkOrderedResults(Arrays.asList("aachen", "purcellville", "santa fe", "seattle"), sg.V().order().by("location", Order.incr).values("location"));
     }