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/27 18:46:03 UTC

[06/23] 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. Adde

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/9338e499
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/9338e499
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/9338e499

Branch: refs/heads/master
Commit: 9338e499d61e42b3e281a36e5034a0ba4bcd1490
Parents: c01b52a
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 27 12:45:49 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/9338e499/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 5874ca7..0eef92f 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.
 * Added tests to `DedupTest` for the `dedup(Scope, String...)` overload.
 * Fixed a bug in serialization of `Lambda` instances in GraphSON, which prevented their use in remote traversals.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9338e499/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/9338e499/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/9338e499/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/9338e499/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/9338e499/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 1e37478..9dbf261 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
@@ -104,6 +104,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/9338e499/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/9338e499/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"));
     }