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 2015/06/19 21:21:36 UTC

incubator-tinkerpop git commit: Added Pop.all. No more getSingle() and getList() -- just get(pop, label). you can also do get() which is the old semantics of singleton, list, or exception. Got PathTest out of ProcessStandardSuite as its not graph specific

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master e320b16d9 -> d63c21667


Added Pop.all. No more getSingle() and getList() -- just get(pop,label). you can also do get() which is the old semantics of singleton, list, or exception. Got PathTest out of ProcessStandardSuite as its not graph specific.


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

Branch: refs/heads/master
Commit: d63c21667eba6c11f66da264e496f83b19bea668
Parents: e320b16
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Jun 19 13:21:25 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Jun 19 13:21:32 2015 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   5 +-
 .../gremlin/process/traversal/Path.java         |  47 ++--
 .../gremlin/process/traversal/Pop.java          |   6 +-
 .../gremlin/process/traversal/Traverser.java    |   4 +
 .../gremlin/process/traversal/step/Scoping.java |  24 ++-
 .../process/traversal/step/map/MatchStep.java   |   6 +-
 .../process/traversal/step/map/SelectStep.java  |   2 +-
 .../traversal/step/util/ImmutablePath.java      |  36 ++--
 .../traversal/step/util/ImmutablePathImpl.java  |  12 +-
 .../traversal/step/util/MutablePath.java        |  34 ++-
 .../gremlin/process/traversal/PathTest.java     | 202 ++++++++++++++++++
 .../traversal/step/map/MatchStepTest.java       |  51 +++++
 .../gremlin/process/ProcessStandardSuite.java   |   7 +-
 .../gremlin/process/traversal/PathTest.java     | 212 -------------------
 14 files changed, 356 insertions(+), 292 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 5996b91..159d8ce 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -34,8 +34,9 @@ TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
 * `has(key,traversal)` is now an alias for `filter(__.values(key).traversal)` using `TraversalFilterStep`.
 * Simplified `SubgraphStrategy` by using `TraversalFilterStep` instead of the more complex `WhereStep`.
 * Added `TraversalMapStep`, `TraversalFlatMapStep`, `TraversalFilterStep`, and `TraversalSideEffectStep` which all leverage an internal traversal.
-* Added `Path.getSingle(pop,label)` and `Path.getList(label)` as default helpers in `Path`.
-* Added `Pop.first` and `Pop.last` as enums for getting single items from a collection.* Changed `GremlinServer.start()` to return a `CompletableFuture` that contains the constructed `ServerGremlinExecutor`.
+* Added `Path.get(pop,label)` as default helpers in `Path`.
+* Added `Pop.first`, `Pop.last`, and `Pop.all` as enums for getting single items from a collection or a list of said items.
+* Changed `GremlinServer.start()` to return a `CompletableFuture` that contains the constructed `ServerGremlinExecutor`.
 * Restructured `IoTest` breaking it up into smaller and more logically grouped test cases.
 * Gremlin Server `Settings` now has sensible defaults thus allowing the server to be started with no additional configuration.
 * Fixed garbled characters in Gremlin Console that notably showed up in `:help`

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
index 9318b9c..f8fa67b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
@@ -98,39 +98,32 @@ public interface Path extends Cloneable {
     }
 
     /**
-     * Get the list of objects associated with the particular label of the path.
+     * Pop the object(s) associated with the label of the path.
      *
-     * @param label the label of the path
-     * @param <A>   the type of the object associated with the label
-     * @return the list of objects (List<A>) associated with the label of the path, or empty list if label is not found
-     */
-    public default <A> List<A> getList(final String label) throws IllegalArgumentException {
-        if (this.hasLabel(label)) {
-            final Object object = this.get(label);
-            if (object instanceof List)
-                return (List<A>) object;
-            else
-                return Collections.singletonList((A) object);
-        } else {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * Get the object most/least recently associated with the particular label of the path.
-     *
-     * @param pop   first for least recent, last for most recent
+     * @param pop   first for least recent, last for most recent, and all for all in a list
      * @param label the label of the path
      * @param <A>   the type of the object associated with the label
      * @return the object associated with the label of the path
      * @throws IllegalArgumentException if the path does not contain the label
      */
-    public default <A> A getSingle(final Pop pop, final String label) throws IllegalArgumentException {
-        final Object object = this.get(label);
-        if (object instanceof List) {
-            return Pop.last == pop ? ((List<A>) object).get(((List) object).size() - 1) : ((List<A>) object).get(0);
-        } else
-            return (A) object;
+    public default <A> A get(final Pop pop, final String label) throws IllegalArgumentException {
+        if(Pop.all == pop) {
+            if (this.hasLabel(label)) {
+                final Object object = this.get(label);
+                if (object instanceof List)
+                    return (A) object;
+                else
+                    return (A) Collections.singletonList(object);
+            } else {
+                return (A) Collections.emptyList();
+            }
+        } else {
+            final Object object = this.get(label);
+            if (object instanceof List) {
+                return Pop.last == pop ? ((List<A>) object).get(((List) object).size() - 1) : ((List<A>) object).get(0);
+            } else
+                return (A) object;
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Pop.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Pop.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Pop.java
index 7edf656..ad27e16 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Pop.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Pop.java
@@ -33,5 +33,9 @@ public enum Pop {
     /**
      * The last item in an ordered collection (i.e. <code>collection[collection.size()-1]</code>)
      */
-    last
+    last,
+    /**
+     * Get all the items and return them as a list
+     */
+    all
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
index 51e6d4a..fc5d421 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
@@ -76,6 +76,10 @@ public interface Traverser<T> extends Serializable, Comparable<Traverser<T>>, Cl
         return this.path().get(stepLabel);
     }
 
+    public default <A> A path(final Pop pop, final String stepLabel) {
+        return this.path().get(pop, stepLabel);
+    }
+
     /**
      * Return the number of times the traverser has gone through a looping section of a traversal.
      *

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
index 8703056..60f5fc5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
@@ -39,15 +39,19 @@ public interface Scoping {
         if (traverser.getSideEffects().get(key).isPresent())
             return traverser.getSideEffects().<S>get(key).get();
         if (Scope.local == this.getScope()) {
-            final S s = ((Map<String, S>) traverser.get()).get(key);
-            if (null != s)
-                return s;
-            else
-                throw new IllegalArgumentException("Neither the current map nor sideEffects have a " + key + "-key:" + this);
+            try {
+                final S s = ((Map<String, S>) traverser.get()).get(key);
+                if (null != s)
+                    return s;
+                else
+                    throw new IllegalArgumentException("Neither the current map nor sideEffects have a " + key + "-key:" + this);
+            } catch (final ClassCastException e) {
+                throw new IllegalStateException("The current step was compiled to an invalid local scope and this is a compilation error. Please report the query that yielded this exception: " + this);
+            }
         } else {
             final Path path = traverser.path();
             if (path.hasLabel(key))
-                return null == pop ? path.get(key) : path.getSingle(pop, key);
+                return null == pop ? path.get(key) : path.get(pop, key);
             else
                 throw new IllegalArgumentException("Neither the current path nor sideEffects have a " + key + "-key: " + this);
         }
@@ -58,10 +62,14 @@ public interface Scoping {
             return traverser.getSideEffects().<S>get(key);
 
         if (Scope.local == this.getScope()) {
-            return Optional.ofNullable(((Map<String, S>) traverser.get()).get(key));
+            try {
+                return Optional.ofNullable(((Map<String, S>) traverser.get()).get(key));
+            } catch (ClassCastException e) {
+                throw new IllegalStateException("The current step was compiled to an invalid local scope and this is a compilation error. Please report the query that yielded this exception: " + this);
+            }
         } else {
             final Path path = traverser.path();
-            return path.hasLabel(key) ? Optional.of(null == pop ? path.get(key) : path.getSingle(pop, key)) : Optional.<S>empty();
+            return path.hasLabel(key) ? Optional.of(null == pop ? path.get(key) : path.get(pop, key)) : Optional.<S>empty();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
index c33b796..eda7204 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
@@ -304,7 +304,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
 
     @Override
     public int hashCode() {
-        return super.hashCode() ^ this.matchTraversals.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode());
+        return super.hashCode() ^ this.matchTraversals.hashCode() ^ this.conjunction.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode());
     }
 
     @Override
@@ -330,7 +330,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
             traverser.path().addLabel(this.getId());
             ((MatchStep<?, ?>) this.getTraversal().getParent()).getMatchAlgorithm().recordStart(traverser, this.getTraversal());
             // TODO: sideEffect check?
-            return null == this.selectKey ? traverser : traverser.split(traverser.path().getSingle(Pop.last, this.selectKey), this);
+            return null == this.selectKey ? traverser : traverser.split(traverser.path().get(Pop.last, this.selectKey), this);
         }
 
         @Override
@@ -399,7 +399,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 // TODO: sideEffect check?
                 // path check
                 final Path path = traverser.path();
-                if (!path.hasLabel(this.matchKey) || traverser.get().equals(path.getSingle(Pop.first, this.matchKey))) {
+                if (!path.hasLabel(this.matchKey) || traverser.get().equals(path.get(Pop.first, this.matchKey))) {
                     if (this.traverserStepIdSetByChild)
                         traverser.setStepId(((MatchStep<?, ?>) this.getTraversal().getParent()).getId());
                     traverser.path().addLabel(this.matchKey);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
index d9cc631..79d1581 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
@@ -70,7 +70,7 @@ public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implement
                 ((Map<String, Object>) start).forEach((key, value) -> bindings.put(key, (E) TraversalUtil.apply(value, this.traversalRing.next())));
             else {
                 final Path path = traverser.path();
-                path.labels().stream().flatMap(Set::stream).distinct().forEach(label -> bindings.put(label, (E) TraversalUtil.apply(null == this.pop ? path.<Object>get(label) : path.getSingle(this.pop, label), this.traversalRing.next())));
+                path.labels().stream().flatMap(Set::stream).distinct().forEach(label -> bindings.put(label, (E) TraversalUtil.apply(null == this.pop ? path.<Object>get(label) : path.get(this.pop, label), this.traversalRing.next())));
             }
         } else {
             for (final String label : this.selectLabels) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
index dc42162..93f7623 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.step.util;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -76,16 +77,6 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
     }
 
     @Override
-    public <A> List<A> getList(final String label) {
-        // Recursively build the list to avoid building objects/labels collections.
-        final List<A> list = this.previousPath.getList(label);
-        // Add our object, if our step labels match.
-        if (this.currentLabels.contains(label))
-            list.add((A) currentObject);
-        return list;
-    }
-
-    @Override
     public <A> A getSingleHead(final String label) {
         // Recursively search for the single value to avoid building throwaway collections, and to stop looking when we
         // find it.
@@ -115,6 +106,25 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
     }
 
     @Override
+    public <A> A get(final Pop pop, final String label) {
+        if (Pop.all == pop) {
+            // Recursively build the list to avoid building objects/labels collections.
+            final List<A> list = this.previousPath.get(Pop.all, label);
+            // Add our object, if our step labels match.
+            if (this.currentLabels.contains(label))
+                list.add((A) currentObject);
+            return (A) list;
+        } else {
+            // Delegate to the non-throwing, optimized head/tail calculations.
+            final A single = Pop.first == pop ? this.getSingleTail(label) : this.getSingleHead(label);
+            // Throw if we didn't find the label.
+            if (null == single)
+                throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
+            return single;
+        }
+    }
+
+    @Override
     public boolean hasLabel(final String label) {
         return this.currentLabels.contains(label) || this.previousPath.hasLabel(label);
     }
@@ -172,10 +182,10 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
             return (A) Collections.emptyList().get(index);
         }
 
+
         @Override
-        public <A> List<A> getList(final String label) {
-            // Provide an empty, modifiable list as a seed for ImmutablePath.getList.
-            return new ArrayList<A>();
+        public <A> A get(final Pop pop, final String label) {
+            return pop == Pop.all ? (A) new ArrayList<>() : null;
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePathImpl.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePathImpl.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePathImpl.java
index 3cd3b16..2bb84ba 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePathImpl.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePathImpl.java
@@ -21,6 +21,8 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.util;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
 import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 
+import java.util.List;
+
 /**
  * Internal interface used by ImmutablePath to provide more efficient implementation.
  *
@@ -28,16 +30,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
  */
 interface ImmutablePathImpl extends Path {
 
-    @Override
-    public default <A> A getSingle(final Pop pop, final String label) {
-        // Delegate to the non-throwing, optimized head/tail calculations.
-        final A single = Pop.first == pop ? this.getSingleTail(label) : this.getSingleHead(label);
-        // Throw if we didn't find the label.
-        if (null == single)
-            throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
-        return single;
-    }
-
     /**
      * Get the object least recently associated with the particular label of the path.
      *

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
index 817e2db..67f9d57 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
@@ -81,20 +81,32 @@ public class MutablePath implements Path, Serializable {
     }
 
     @Override
-    public <A> A getSingle(final Pop pop, final String label) {
-        // Override default to avoid building temporary list, and to stop looking when we find the label.
-        if (Pop.last == pop) {
-            for (int i = this.labels.size() - 1; i >= 0; i--) {
-                if (labels.get(i).contains(label))
-                    return (A) objects.get(i);
+    public <A> A get(final Pop pop, final String label) {
+        if(Pop.all == pop) {
+            if (this.hasLabel(label)) {
+                final Object object = this.get(label);
+                if (object instanceof List)
+                    return (A) object;
+                else
+                    return (A) Collections.singletonList(object);
+            } else {
+                return (A) Collections.emptyList();
             }
-        } else {
-            for (int i = 0; i != this.labels.size(); i++) {
-                if (labels.get(i).contains(label))
-                    return (A) objects.get(i);
+        }  else {
+            // Override default to avoid building temporary list, and to stop looking when we find the label.
+            if (Pop.last == pop) {
+                for (int i = this.labels.size() - 1; i >= 0; i--) {
+                    if (labels.get(i).contains(label))
+                        return (A) objects.get(i);
+                }
+            } else {
+                for (int i = 0; i != this.labels.size(); i++) {
+                    if (labels.get(i).contains(label))
+                        return (A) objects.get(i);
+                }
             }
+            throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
         }
-        throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
new file mode 100644
index 0000000..e24e024
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
@@ -0,0 +1,202 @@
+/*
+ *
+ *  * 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;
+
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedPath;
+import org.apache.tinkerpop.gremlin.structure.util.reference.ReferencePath;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PathTest {
+
+    private final static List<Supplier<Path>> PATH_SUPPLIERS =
+            Arrays.asList(MutablePath::make, ImmutablePath::make, DetachedPath::make, ReferencePath::make);
+
+    @Test
+    public void shouldHaveStandardSemanticsImplementedCorrectly() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            assertTrue(path.isSimple());
+            assertEquals(0, path.size());
+            path = path.extend(1, Collections.singleton("a"));
+            path = path.extend(2, Collections.singleton("b"));
+            path = path.extend(3, Collections.singleton("c"));
+            assertEquals(3, path.size());
+            assertEquals(Integer.valueOf(1), path.get("a"));
+            assertEquals(Integer.valueOf(2), path.get("b"));
+            assertEquals(Integer.valueOf(3), path.get("c"));
+            path.addLabel("d");
+            assertEquals(3, path.size());
+            assertEquals(Integer.valueOf(1), path.get("a"));
+            assertEquals(Integer.valueOf(2), path.get("b"));
+            assertEquals(Integer.valueOf(3), path.get("c"));
+            assertEquals(Integer.valueOf(3), path.get("d"));
+            assertTrue(path.hasLabel("a"));
+            assertTrue(path.hasLabel("b"));
+            assertTrue(path.hasLabel("c"));
+            assertTrue(path.hasLabel("d"));
+            assertFalse(path.hasLabel("e"));
+            assertTrue(path.isSimple());
+            path = path.extend(3, Collections.singleton("e"));
+            assertFalse(path.isSimple());
+            assertTrue(path.hasLabel("e"));
+            assertEquals(4, path.size());
+            assertEquals(Integer.valueOf(1), path.get(0));
+            assertEquals(Integer.valueOf(2), path.get(1));
+            assertEquals(Integer.valueOf(3), path.get(2));
+            assertEquals(Integer.valueOf(3), path.get(3));
+        });
+    }
+
+    @Test
+    public void shouldHandleMultiLabelPaths() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            path = path.extend("marko", Collections.singleton("a"));
+            path = path.extend("stephen", Collections.singleton("b"));
+            path = path.extend("matthias", Collections.singleton("a"));
+            assertEquals(3, path.size());
+            assertEquals(3, path.objects().size());
+            assertEquals(3, path.labels().size());
+            assertEquals(2, new HashSet<>(path.labels()).size());
+            assertTrue(path.get("a") instanceof List);
+            assertTrue(path.get("b") instanceof String);
+            assertEquals(2, path.<List<String>>get("a").size());
+            assertTrue(path.<List<String>>get("a").contains("marko"));
+            assertTrue(path.<List<String>>get("a").contains("matthias"));
+        });
+    }
+
+    @Test
+    public void shouldExcludeUnlabeledLabelsFromPath() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            path = path.extend("marko", "a");
+            path = path.extend("stephen", "b");
+            path = path.extend("matthias", "c", "d");
+            assertEquals(3, path.size());
+            assertEquals(3, path.objects().size());
+            assertEquals(3, path.labels().size());
+            assertEquals(1, path.labels().get(0).size());
+            assertEquals(1, path.labels().get(1).size());
+            assertEquals("b", path.labels().get(1).iterator().next());
+            assertEquals(2, path.labels().get(2).size());
+            assertTrue(path.labels().get(2).contains("c"));
+            assertTrue(path.labels().get(2).contains("d"));
+        });
+    }
+
+    @Test
+    public void shouldHaveOrderedPathLabels() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            path = path.extend("marko", "a", "b");
+            path = path.extend("stephen", "c", "a");
+            path = path.extend("matthias", "a", "b");
+            assertEquals(3, path.size());
+            assertEquals(3, path.objects().size());
+            assertEquals(3, path.labels().size());
+            assertEquals(2, path.labels().get(0).size());
+            assertEquals(2, path.labels().get(1).size());
+            assertEquals(2, path.labels().get(2).size());
+            ///
+            Iterator<String> labels = path.labels().get(0).iterator();
+            assertEquals("a", labels.next());
+            assertEquals("b", labels.next());
+            assertFalse(labels.hasNext());
+            labels = path.labels().get(1).iterator();
+            assertEquals("c", labels.next());
+            assertEquals("a", labels.next());
+            assertFalse(labels.hasNext());
+            labels = path.labels().get(2).iterator();
+            assertEquals("a", labels.next());
+            assertEquals("b", labels.next());
+            assertFalse(labels.hasNext());
+            ///
+            List<String> names = path.get("a");
+            assertEquals("marko", names.get(0));
+            assertEquals("stephen", names.get(1));
+            assertEquals("matthias", names.get(2));
+            names = path.get("b");
+            assertEquals("marko", names.get(0));
+            assertEquals("matthias", names.get(1));
+            assertEquals("stephen", path.get("c"));
+        });
+    }
+
+    @Test
+    public void shouldSelectSingleCorrectly() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            path = path.extend("marko", "a", "b");
+            path = path.extend("stephen", "a", "c");
+            path = path.extend("matthias", "c", "d");
+            assertEquals(3, path.size());
+            assertEquals("marko", path.get(Pop.first, "a"));
+            assertEquals("marko", path.get(Pop.first, "b"));
+            assertEquals("stephen", path.get(Pop.first, "c"));
+            assertEquals("matthias", path.get(Pop.first, "d"));
+            ///
+            assertEquals("marko", path.get(Pop.last, "b"));
+            assertEquals("stephen", path.get(Pop.last, "a"));
+            assertEquals("matthias", path.get(Pop.last, "c"));
+            assertEquals("matthias", path.get(Pop.last, "d"));
+        });
+    }
+
+    @Test
+    public void shouldSelectListCorrectly() {
+        PATH_SUPPLIERS.forEach(supplier -> {
+            Path path = supplier.get();
+            path = path.extend("marko", "a", "b");
+            path = path.extend("stephen", "a", "c");
+            path = path.extend("matthias", "c", "d");
+            assertEquals(3, path.size());
+            assertEquals(2, path.<List>get(Pop.all, "a").size());
+            assertEquals("marko", path.<List>get(Pop.all, "a").get(0));
+            assertEquals("stephen", path.<List>get(Pop.all, "a").get(1));
+            assertEquals(1, path.<List>get(Pop.all, "b").size());
+            assertEquals("marko", path.<List>get(Pop.all, "b").get(0));
+            assertEquals(2, path.<List>get(Pop.all, "c").size());
+            assertEquals("stephen", path.<List>get(Pop.all, "c").get(0));
+            assertEquals("matthias", path.<List>get(Pop.all, "c").get(1));
+            assertEquals(1, path.<List>get(Pop.all, "d").size());
+            assertEquals("matthias", path.<List>get(Pop.all, "d").get(0));
+            ///
+            assertEquals(0, path.<List>get(Pop.all, "noExist").size());
+        });
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
new file mode 100644
index 0000000..278b3b8
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
@@ -0,0 +1,51 @@
+/*
+ *
+ *  * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class MatchStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.match("a", as("a").out("knows").as("b")),
+                __.match(as("a").out("knows").as("b")),
+                __.match("a", as("a").out().as("b")),
+                __.match(as("a").out().as("b")),
+                ////
+                __.match("a", where(as("a").out("knows").as("b"))),
+                __.match(where(as("a").out("knows").as("b"))),
+                __.match("a", as("a").where(out().as("b"))),
+                __.match(as("a").where(out().as("b")))
+        );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/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 da2a6c6..6422638 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
@@ -20,7 +20,6 @@ package org.apache.tinkerpop.gremlin.process;
 
 import org.apache.tinkerpop.gremlin.AbstractGremlinSuite;
 import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
-import org.apache.tinkerpop.gremlin.process.traversal.PathTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffectsTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.BranchTest;
@@ -54,6 +53,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SumTest;
@@ -134,7 +134,7 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
             MinTest.Traversals.class,
             SumTest.Traversals.class,
             OrderTest.Traversals.class,
-            org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest.Traversals.class,
+            PathTest.Traversals.class,
             PropertiesTest.Traversals.class,
             SelectTest.Traversals.class,
             VertexTest.Traversals.class,
@@ -156,7 +156,6 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
 
             // util
             TraversalSideEffectsTest.Traversals.class,
-            PathTest.class,
 
             // compliance
             CoreTraversalTest.class,
@@ -216,7 +215,7 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
             MinTest.class,
             SumTest.class,
             OrderTest.class,
-            org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest.class,   // note that there are two PathTest in this suite - only one is enforce
+            PathTest.class,
             PropertiesTest.class,
             SelectTest.class,
             VertexTest.class,

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d63c2166/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
deleted file mode 100644
index 825b6ec..0000000
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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;
-
-import org.apache.tinkerpop.gremlin.LoadGraphWith;
-import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedPath;
-import org.apache.tinkerpop.gremlin.structure.util.reference.ReferencePath;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.function.Supplier;
-
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
-import static org.junit.Assert.*;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class PathTest extends AbstractGremlinProcessTest {
-
-    private final static List<Supplier<Path>> PATH_SUPPLIERS =
-            Arrays.asList(MutablePath::make, ImmutablePath::make, DetachedPath::make, ReferencePath::make);
-
-    @Test
-    public void shouldHaveStandardSemanticsImplementedCorrectly() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            assertTrue(path.isSimple());
-            assertEquals(0, path.size());
-            path = path.extend(1, Collections.singleton("a"));
-            path = path.extend(2, Collections.singleton("b"));
-            path = path.extend(3, Collections.singleton("c"));
-            assertEquals(3, path.size());
-            assertEquals(Integer.valueOf(1), path.get("a"));
-            assertEquals(Integer.valueOf(2), path.get("b"));
-            assertEquals(Integer.valueOf(3), path.get("c"));
-            path.addLabel("d");
-            assertEquals(3, path.size());
-            assertEquals(Integer.valueOf(1), path.get("a"));
-            assertEquals(Integer.valueOf(2), path.get("b"));
-            assertEquals(Integer.valueOf(3), path.get("c"));
-            assertEquals(Integer.valueOf(3), path.get("d"));
-            assertTrue(path.hasLabel("a"));
-            assertTrue(path.hasLabel("b"));
-            assertTrue(path.hasLabel("c"));
-            assertTrue(path.hasLabel("d"));
-            assertFalse(path.hasLabel("e"));
-            assertTrue(path.isSimple());
-            path = path.extend(3, Collections.singleton("e"));
-            assertFalse(path.isSimple());
-            assertTrue(path.hasLabel("e"));
-            assertEquals(4, path.size());
-            assertEquals(Integer.valueOf(1), path.get(0));
-            assertEquals(Integer.valueOf(2), path.get(1));
-            assertEquals(Integer.valueOf(3), path.get(2));
-            assertEquals(Integer.valueOf(3), path.get(3));
-        });
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    public void shouldHandleMultiLabelPaths() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            path = path.extend("marko", Collections.singleton("a"));
-            path = path.extend("stephen", Collections.singleton("b"));
-            path = path.extend("matthias", Collections.singleton("a"));
-            assertEquals(3, path.size());
-            assertEquals(3, path.objects().size());
-            assertEquals(3, path.labels().size());
-            assertEquals(2, new HashSet<>(path.labels()).size());
-            assertTrue(path.get("a") instanceof List);
-            assertTrue(path.get("b") instanceof String);
-            assertEquals(2, path.<List<String>>get("a").size());
-            assertTrue(path.<List<String>>get("a").contains("marko"));
-            assertTrue(path.<List<String>>get("a").contains("matthias"));
-        });
-
-        final Path path = g.V().as("x").repeat(out().as("y")).times(2).path().by("name").next();
-        assertEquals(3, path.size());
-        assertEquals(3, path.labels().size());
-        assertEquals(2, new HashSet<>(path.labels()).size());
-        assertTrue(path.get("x") instanceof String);
-        assertTrue(path.get("y") instanceof List);
-        assertEquals(2, path.<List<String>>get("y").size());
-        assertTrue(path.<List<String>>get("y").contains("josh"));
-        assertTrue(path.<List<String>>get("y").contains("ripple") || path.<List<String>>get("y").contains("lop"));
-    }
-
-    @Test
-    public void shouldExcludeUnlabeledLabelsFromPath() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            path = path.extend("marko", "a");
-            path = path.extend("stephen", "b");
-            path = path.extend("matthias", "c", "d");
-            assertEquals(3, path.size());
-            assertEquals(3, path.objects().size());
-            assertEquals(3, path.labels().size());
-            assertEquals(1, path.labels().get(0).size());
-            assertEquals(1, path.labels().get(1).size());
-            assertEquals("b", path.labels().get(1).iterator().next());
-            assertEquals(2, path.labels().get(2).size());
-            assertTrue(path.labels().get(2).contains("c"));
-            assertTrue(path.labels().get(2).contains("d"));
-        });
-    }
-
-    @Test
-    public void shouldHaveOrderedPathLabels() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            path = path.extend("marko", "a", "b");
-            path = path.extend("stephen", "c", "a");
-            path = path.extend("matthias", "a", "b");
-            assertEquals(3, path.size());
-            assertEquals(3, path.objects().size());
-            assertEquals(3, path.labels().size());
-            assertEquals(2, path.labels().get(0).size());
-            assertEquals(2, path.labels().get(1).size());
-            assertEquals(2, path.labels().get(2).size());
-            ///
-            Iterator<String> labels = path.labels().get(0).iterator();
-            assertEquals("a", labels.next());
-            assertEquals("b", labels.next());
-            assertFalse(labels.hasNext());
-            labels = path.labels().get(1).iterator();
-            assertEquals("c", labels.next());
-            assertEquals("a", labels.next());
-            assertFalse(labels.hasNext());
-            labels = path.labels().get(2).iterator();
-            assertEquals("a", labels.next());
-            assertEquals("b", labels.next());
-            assertFalse(labels.hasNext());
-            ///
-            List<String> names = path.get("a");
-            assertEquals("marko", names.get(0));
-            assertEquals("stephen", names.get(1));
-            assertEquals("matthias", names.get(2));
-            names = path.get("b");
-            assertEquals("marko", names.get(0));
-            assertEquals("matthias", names.get(1));
-            assertEquals("stephen", path.get("c"));
-        });
-    }
-
-    @Test
-    public void shouldSelectSingleCorrectly() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            path = path.extend("marko", "a", "b");
-            path = path.extend("stephen", "a", "c");
-            path = path.extend("matthias", "c", "d");
-            assertEquals(3, path.size());
-            assertEquals("marko", path.getSingle(Pop.first, "a"));
-            assertEquals("marko", path.getSingle(Pop.first, "b"));
-            assertEquals("stephen", path.getSingle(Pop.first, "c"));
-            assertEquals("matthias", path.getSingle(Pop.first, "d"));
-            ///
-            assertEquals("marko", path.getSingle(Pop.last, "b"));
-            assertEquals("stephen", path.getSingle(Pop.last, "a"));
-            assertEquals("matthias", path.getSingle(Pop.last, "c"));
-            assertEquals("matthias", path.getSingle(Pop.last, "d"));
-        });
-    }
-
-    @Test
-    public void shouldSelectListCorrectly() {
-        PATH_SUPPLIERS.forEach(supplier -> {
-            Path path = supplier.get();
-            path = path.extend("marko", "a", "b");
-            path = path.extend("stephen", "a", "c");
-            path = path.extend("matthias", "c", "d");
-            assertEquals(3, path.size());
-            assertEquals(2, path.getList("a").size());
-            assertEquals("marko", path.getList("a").get(0));
-            assertEquals("stephen", path.getList("a").get(1));
-            assertEquals(1, path.getList("b").size());
-            assertEquals("marko", path.getList("b").get(0));
-            assertEquals(2, path.getList("c").size());
-            assertEquals("stephen", path.getList("c").get(0));
-            assertEquals("matthias", path.getList("c").get(1));
-            assertEquals(1, path.getList("d").size());
-            assertEquals("matthias", path.getList("d").get(0));
-            ///
-            assertEquals(0,path.getList("noExist").size());
-        });
-    }
-}