This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/3.7-dev by this push:
new 3a48401d83 getScopingInfo utility added (#3118)
3a48401d83 is described below
commit 3a48401d83656a31c459f541550b62be67084970
Author: Vaibhav Malhotra <[email protected]>
AuthorDate: Thu Jun 12 18:52:14 2025 -0700
getScopingInfo utility added (#3118)
Added PopContaining interface, and its implementation in Scoping.java
and TraversalParent.java, and classes that use these interfaces.
Co-authored-by: Vaibhav Malhotra <[email protected]>
---
CHANGELOG.asciidoc | 1 +
.../process/traversal/step/PopContaining.java | 103 +++++++++++++++++++++
.../gremlin/process/traversal/step/Scoping.java | 20 +++-
.../process/traversal/step/TraversalParent.java | 16 +++-
.../traversal/step/filter/DedupGlobalStep.java | 8 ++
.../traversal/step/filter/WherePredicateStep.java | 8 ++
.../traversal/step/filter/WhereTraversalStep.java | 8 ++
.../traversal/step/map/AddEdgeStartStep.java | 8 ++
.../process/traversal/step/map/AddEdgeStep.java | 8 ++
.../traversal/step/map/AddVertexStartStep.java | 8 ++
.../process/traversal/step/map/AddVertexStep.java | 8 ++
.../process/traversal/step/map/FormatStep.java | 9 ++
.../process/traversal/step/map/MatchStep.java | 8 ++
.../process/traversal/step/map/MathStep.java | 8 ++
.../process/traversal/step/map/SelectOneStep.java | 12 +++
.../process/traversal/step/map/SelectStep.java | 13 ++-
.../traversal/step/map/TraversalSelectStep.java | 12 +++
.../traversal/step/sideEffect/AddPropertyStep.java | 9 ++
.../process/traversal/util/TraversalHelper.java | 20 +++-
.../apache/tinkerpop/gremlin/TestDataBuilder.java | 48 ++++++++++
.../traversal/step/filter/DedupGlobalStepTest.java | 19 ++++
.../traversal/step/filter/WhereStepTest.java | 33 ++++++-
.../traversal/step/map/AddEdgeStepTest.java | 30 ++++++
.../traversal/step/map/AddVertexStepTest.java | 27 ++++++
.../process/traversal/step/map/FormatStepTest.java | 17 ++++
.../process/traversal/step/map/MatchStepTest.java | 19 ++++
.../process/traversal/step/map/MathStepTest.java | 21 +++++
.../traversal/step/map/SelectOneStepTest.java | 48 ++++++++++
.../process/traversal/step/map/SelectStepTest.java | 50 ++++++++++
.../step/map/TraversalSelectStepTest.java | 56 +++++++++++
.../step/sideEffect/AddPropertyStepTest.java | 10 ++
.../traversal/util/TraversalHelperTest.java | 93 +++++++++++++++++++
32 files changed, 753 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 97f29200ff..b3d893c178 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -46,6 +46,7 @@
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Fixed bug in `IndexStep` which prevented Java serialization due to
non-serializable lambda usage by creating serializable function classes.
* Fixed bug in `Operator` which was caused only a single method parameter to
be Collection type checked instead of all parameters.
* Support hot reloading of SSL certificates.
+* Added the `PopContaining` interface designed to get label and `Pop`
combinations held in a `PopInstruction` object.
[[release-3-7-3]]
=== TinkerPop 3.7.3 (October 23, 2024)
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
new file mode 100644
index 0000000000..89fdf28e58
--- /dev/null
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+
+/**
+ * The {@code PopContaining} interface is implemented by traversal steps that
maintain Pop instructions
+ * for label access. It provides a mechanism to track and manage how labeled
elements should
+ * be accessed using {@link Pop} semantics (first, last, all, or mixed).
+ *
+ * In Gremlin traversals, various elements can be labeled and later accessed
via these labels.
+ * The {@link Pop} enum determines how to access these labeled elements when
there are multiple
+ * values associated with the same label.
+ *
+ * <pre>
+ * {@code
+ * // Simple example with default Pop.last behavior
+ * gremlin> g.V().as("a").out().as("a").select("a")
+ * ==>[v[2]] // returns the last element labeled "a"
+ *
+ * // Using Pop.first to get the first labeled element
+ * gremlin> g.V().as("a").out().as("a").select(first, "a")
+ * ==>[v[1]] // returns the first element labeled "a"
+ *
+ * // Using Pop.all to get all labeled elements
+ * gremlin> g.V().as("a").out().as("a").select(all, "a")
+ * ==>[v[1], v[2]] // returns all elements labeled "a"
+ * }
+ * </pre>
+ *
+ * Steps implementing this interface maintain a collection of {@link
PopInstruction} objects, each containing
+ * a label and a {@link Pop} value that specifies how to access elements with
that label.
+ *
+ */
+public interface PopContaining {
+ public Set<PopInstruction> getPopInstructions();
+ /**
+ * A class for storing the Scope Context. It has two elements:
+ * - label: String
+ * - pop: Pop value
+ */
+ class PopInstruction {
+ private final Pop pop;
+ private final String label;
+
+ public PopInstruction(String label, Pop pop) {
+ this.pop = pop;
+ this.label = label;
+ }
+
+ public PopInstruction(final Pop pop, final String label) {
+ this.pop = pop;
+ this.label = label;
+ }
+
+ public PopInstruction() {
+ this.pop = null;
+ this.label = "";
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public Pop getPop() {
+ return pop;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final PopInstruction that = (PopInstruction) o;
+ return getPop() == that.getPop() && Objects.equals(getLabel(),
that.getLabel());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getPop(), getLabel());
+ }
+ }
+}
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 e2c0e17747..a765e77875 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
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -105,7 +106,7 @@ import java.util.Set;
* @author Marko A. Rodriguez (http://markorodriguez.com)
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
-public interface Scoping {
+public interface Scoping extends PopContaining {
public enum Variable {START, END}
@@ -166,6 +167,23 @@ public interface Scoping {
*/
public Set<String> getScopeKeys();
+ /**
+ * Used to get PopInstruction of a Step that implements Scoping.
PopInstruction includes the labels it needs, and the
+ * pop type for each label.
+ *
+ * @return A Set of {@link PopInstruction} values which contain the label
and Pop value
+ */
+ @Override
+ public default HashSet<PopInstruction> getPopInstructions() {
+ final Set<String> labels = this.getScopeKeys();
+ final HashSet<PopInstruction> scopingInfoSet = new HashSet<>();
+ for (final String label : labels) {
+ final PopInstruction scopingInfo = new PopInstruction(Pop.last,
label);
+ scopingInfoSet.add(scopingInfo);
+ }
+ return scopingInfoSet;
+ }
+
public static class KeyNotFoundException extends Exception {
private final Object key;
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
index 695d2972fc..3a43f7b74c 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
@@ -21,16 +21,18 @@ package org.apache.tinkerpop.gremlin.process.traversal.step;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public interface TraversalParent extends AutoCloseable {
+public interface TraversalParent extends PopContaining, AutoCloseable {
public default <S, E> List<Traversal.Admin<S, E>> getGlobalChildren() {
return Collections.emptyList();
@@ -95,4 +97,16 @@ public interface TraversalParent extends AutoCloseable {
traversal.close();
}
}
+
+ @Override
+ public default HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> scopingInfos = new HashSet<>();
+ for (final Traversal.Admin local: this.getLocalChildren()) {
+ scopingInfos.addAll(TraversalHelper.getPopInstructions(local));
+ }
+ for (final Traversal.Admin global: this.getGlobalChildren()) {
+ scopingInfos.addAll(TraversalHelper.getPopInstructions(global));
+ }
+ return scopingInfos;
+ }
}
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
index 9f5b0e5f5c..ed81ecf6bd 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
@@ -186,6 +186,14 @@ public final class DedupGlobalStep<S> extends
FilterStep<S> implements Traversal
return null == this.dedupLabels ? Collections.emptySet() :
this.dedupLabels;
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public void processAllStarts() {
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
index cffe3ebc8c..69b054446a 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
@@ -132,6 +132,14 @@ public final class WherePredicateStep<S> extends
FilterStep<S> implements Scopin
return Collections.unmodifiableSet(this.scopeKeys);
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public WherePredicateStep<S> clone() {
final WherePredicateStep<S> clone = (WherePredicateStep<S>)
super.clone();
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
index dde900348a..1fa30b98b9 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
@@ -147,6 +147,14 @@ public final class WhereTraversalStep<S> extends
FilterStep<S> implements Traver
return this.keepLabels;
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
//////////////////////////////
public static class WhereStartStep<S> extends ScalarMapStep<S, Object>
implements Scoping {
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
index 95907e9c7a..e661c67755 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
@@ -42,6 +42,7 @@ import org.apache.tinkerpop.gremlin.structure.util.Attachable;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -83,6 +84,13 @@ public class AddEdgeStartStep extends AbstractStep<Edge,
Edge>
return this.parameters.getReferencedLabels();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public void configure(final Object... keyValues) {
this.parameters.set(this, keyValues);
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
index f5f7280764..c0c5c8a1fe 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
@@ -38,6 +38,7 @@ import org.apache.tinkerpop.gremlin.structure.util.Attachable;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -79,6 +80,13 @@ public class AddEdgeStep<S> extends ScalarMapStep<S, Edge>
return this.parameters.getReferencedLabels();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public void configure(final Object... keyValues) {
this.parameters.set(this, keyValues);
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
index fd52f445e8..95d0ab8e30 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
@@ -37,6 +37,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -78,6 +79,13 @@ public class AddVertexStartStep extends AbstractStep<Vertex,
Vertex>
return this.parameters.getReferencedLabels();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
return this.parameters.getTraversals();
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
index 0dfb55c2a1..d7de87edfb 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -73,6 +74,13 @@ public class AddVertexStep<S> extends ScalarMapStep<S,
Vertex>
return this.parameters.getReferencedLabels();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
return this.parameters.getTraversals();
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
index c4b50958d9..39d7d00586 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
@@ -34,6 +34,7 @@ import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Property;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
@@ -168,6 +169,14 @@ public final class FormatStep<S> extends MapStep<S,
String> implements ByModulat
return variables;
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public void setKeepLabels(final Set<String> labels) {
this.keepLabels = labels;
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 6de3970236..055f302996 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
@@ -218,6 +218,14 @@ public final class MatchStep<S, E> extends
ComputerAwareStep<S, Map<String, E>>
return this.scopeKeys;
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public String toString() {
return StringFactory.stepString(this, this.dedupLabels,
this.connective, this.matchTraversals);
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
index e36a1311c8..2533070542 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
@@ -165,6 +165,14 @@ public final class MathStep<S> extends MapStep<S, Double>
implements ByModulatin
return this.expression.getVariables();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public void setKeepLabels(final Set<String> labels) {
this.keepLabels = labels;
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
index b2de4b002c..dd6661eb77 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
@@ -134,6 +134,18 @@ public final class SelectOneStep<S, E> extends MapStep<S,
E> implements Traversa
return Collections.singleton(this.selectKey);
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ final Set<String> labels = this.getScopeKeys();
+ for (String label : labels) {
+ final PopInstruction scopingInfo = new
PopInstruction(this.getPop(), label);
+ popInstructions.add(scopingInfo);
+ }
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
public Pop getPop() {
return this.pop;
}
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 24c9771ed2..d47c903739 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
@@ -34,7 +34,6 @@ import
org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -149,6 +148,18 @@ public final class SelectStep<S, E> extends MapStep<S,
Map<String, E>> implement
return this.selectKeysSet;
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ final Set<String> labels = this.getScopeKeys();
+ for (final String label : labels) {
+ final PopInstruction scopingInfo = new
PopInstruction(this.getPop(), label);
+ popInstructions.add(scopingInfo);
+ }
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
/**
* Get the keys for this SelectStep. Unlike {@link
SelectStep#getScopeKeys()}, this returns a list possibly with
* a duplicate key. This guarantees to return the keys in the same order
as passed in.
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
index ff9f0996f5..0eea87f36c 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
@@ -85,6 +85,18 @@ public final class TraversalSelectStep<S, E> extends
MapStep<S, E> implements Tr
return Collections.emptySet();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ final Set<String> labels = this.getScopeKeys();
+ for (String label : labels) {
+ final PopInstruction scopingInfo = new
PopInstruction(this.getPop(), label);
+ popInstructions.add(scopingInfo);
+ }
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public String toString() {
return StringFactory.stepString(this, this.pop, this.keyTraversal,
this.selectTraversal);
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
index 7d155a40bd..c9b2acd86b 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
@@ -38,6 +38,7 @@ import
org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.structure.util.keyed.KeyedProperty;
import org.apache.tinkerpop.gremlin.structure.util.keyed.KeyedVertexProperty;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -70,6 +71,14 @@ public class AddPropertyStep<S extends Element> extends
SideEffectStep<S>
return this.parameters.getReferencedLabels();
}
+ @Override
+ public HashSet<PopInstruction> getPopInstructions() {
+ final HashSet<PopInstruction> popInstructions = new HashSet<>();
+ popInstructions.addAll(Scoping.super.getPopInstructions());
+ popInstructions.addAll(TraversalParent.super.getPopInstructions());
+ return popInstructions;
+ }
+
@Override
public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
return this.parameters.getTraversals();
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index 19117d6e9a..44df37cfd0 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -28,6 +28,7 @@ import
org.apache.tinkerpop.gremlin.process.traversal.lambda.ValueTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
@@ -54,7 +55,6 @@ import
org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -788,4 +788,22 @@ public final class TraversalHelper {
} else
return (T) traversal.addStep(new HasStep<>(traversal,
hasContainer));
}
+
+ /**
+ * Used to get PopInstruction of a traversal. Pop Instruction includes the
labels it needs, and the pop type for each label.
+ *
+ * @param traversal the traversal to get Scope Context for
+ * @param <T> the traversal type
+ * @return A Set of {@link
org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining.PopInstruction}
values which contain the label and Pop value
+ */
+ public static <T extends Traversal.Admin<?, ?>>
Set<PopContaining.PopInstruction> getPopInstructions(final T traversal) {
+ final Set<PopContaining.PopInstruction> scopingInfos = new HashSet<>();
+ for (final Step step: traversal.getSteps()) {
+ if (step instanceof PopContaining) {
+ scopingInfos.addAll(((PopContaining)
step).getPopInstructions());
+ }
+ }
+ return scopingInfos;
+ }
+
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java
new file mode 100644
index 0000000000..1f429659fa
--- /dev/null
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+
+/**
+ * This class is responsible for building test data for `PopInstruction` Unit
tests.
+ * It provides methods to create a set of `PopInstruction` test data objects.
+ *
+ */
+public class TestDataBuilder {
+
+ // Helper function to create a Set of `PopInstruction` values
+ public static HashSet<PopContaining.PopInstruction>
createPopInstructionSet(final Object[]... pairs) {
+ final HashSet<PopContaining.PopInstruction> popInstructions = new
HashSet<>();
+
+ // Each pair should contain a name (String) and a Pop value
+ for (final Object[] pair : pairs) {
+ if (pair.length == 2 && pair[0] instanceof String && pair[1]
instanceof Pop) {
+ popInstructions.add(new
PopContaining.PopInstruction((String)pair[0], (Pop)pair[1]));
+ } else {
+ throw new IllegalArgumentException("Invalid pair: " + pair);
+ }
+ }
+
+ return popInstructions;
+ }
+}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
index 67331c2a88..911fd72f4d 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
@@ -18,13 +18,20 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
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.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import static org.junit.Assert.assertEquals;
+
/**
* @author Daniel Kuppitz (http://gremlin.guru)
*/
@@ -37,4 +44,16 @@ public class DedupGlobalStepTest extends StepTest {
__.dedup().by("name")
);
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ final DedupGlobalStep dedupGlobalStep = new
DedupGlobalStep(__.identity().asAdmin(), "label1", "label2", "label1");
+
+ final HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"label1", Pop.last},
+ new Object[]{"label2", Pop.last}
+ );
+
+ assertEquals(dedupGlobalStep.getPopInstructions(), popInstructionSet);
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
index fa9adeb1f7..24700083f5 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
@@ -18,15 +18,20 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
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.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
import org.junit.Test;
-
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
import static org.junit.Assert.assertEquals;
@@ -65,4 +70,30 @@ public class WhereStepTest extends StepTest {
assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>)
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
}
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+
+ // Testing WherePredicate Step
+ final WherePredicateStep wherePredicateStep = new
WherePredicateStep(__.identity().asAdmin(), Optional.of("key1"),
P.neq("label1"));
+
+ HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"key1", Pop.last},
+ new Object[]{"label1", Pop.last}
+ );
+
+ assertEquals(wherePredicateStep.getPopInstructions(),
popInstructionSet);
+
+ // Testing WhereTraversal Test
+ final WhereTraversalStep whereTraversalStep = new
WhereTraversalStep<>(new DefaultTraversal(), __.as("x").select(Pop.first, "a",
"b").asAdmin());
+
+ popInstructionSet = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.last},
+ new Object[]{"a", Pop.first},
+ new Object[]{"b", Pop.first}
+ );
+
+ assertEquals(whereTraversalStep.getPopInstructions(),
popInstructionSet);
+
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
index f4282aec69..d5742ba1f0 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
@@ -18,13 +18,23 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
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 org.junit.Test;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import static org.junit.Assert.assertEquals;
+
+
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+
+
/**
* @author Daniel Kuppitz (http://gremlin.guru)
*/
@@ -39,4 +49,24 @@ public class AddEdgeStepTest extends StepTest {
__.addE("knows").property("c", "d")
);
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ // Edge Step Test
+ final AddEdgeStep<Object> addEdgeStep = new
AddEdgeStep<>(__.identity().asAdmin(),
+ (Traversal.Admin) __.select(Pop.first, "b").select("a"));
+
+ final HashSet<PopContaining.PopInstruction> expectedOutput =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"b", Pop.first},
+ new Object[]{"a", Pop.last}
+ );
+
+ assertEquals(addEdgeStep.getPopInstructions(), expectedOutput);
+
+ // Edge Step Start test
+ final AddEdgeStartStep addEdgeStartStep = new
AddEdgeStartStep(__.identity().asAdmin(),
+ __.select(Pop.first, "b").select("a"));
+
+ assertEquals(addEdgeStartStep.getPopInstructions(), expectedOutput);
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
index d5ae0ec900..bda33a2507 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
@@ -18,7 +18,13 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import java.util.HashSet;
+
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
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.PopContaining;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.util.function.TraverserSetSupplier;
@@ -49,4 +55,25 @@ public class AddVertexStepTest {
final AddVertexStep step = new AddVertexStep(t, (String) null);
assertEquals(Vertex.DEFAULT_LABEL,
starStep.getParameters().getRaw().get(T.label).get(0));
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ // Vertex Step Test
+ final AddVertexStep addVertexStep = new
AddVertexStep(__.identity().asAdmin(),
+ (Traversal.Admin) __.select(Pop.first,
"b").select("a").select(Pop.last, "c"));
+
+ final HashSet<PopContaining.PopInstruction> expectedOutput =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"b", Pop.first},
+ new Object[]{"a", Pop.last},
+ new Object[]{"c", Pop.last}
+ );
+
+ assertEquals(addVertexStep.getPopInstructions(), expectedOutput);
+
+ // Vertex Start Step Test
+ final AddVertexStartStep addVertexStartStep = new
AddVertexStartStep(__.identity().asAdmin(),
+ __.select(Pop.first, "b").select("a").select(Pop.last, "c"));
+
+ assertEquals(addVertexStartStep.getPopInstructions(), expectedOutput);
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
index cf66458f45..977afa37f2 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
@@ -18,8 +18,11 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
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.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
@@ -29,6 +32,7 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import static org.apache.tinkerpop.gremlin.util.CollectionUtil.asMap;
@@ -180,4 +184,17 @@ public class FormatStepTest extends StepTest {
__.__("Marko").as("name").
constant(vertex).format("Hello %{name}").next());
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ final FormatStep formatStep = new FormatStep(__.identity().asAdmin(),
"%{Hello} %{world}");
+
+ final HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"Hello", Pop.last},
+ new Object[]{"world", Pop.last}
+ );
+
+ assertEquals(formatStep.getPopInstructions(), popInstructionSet);
+
+ }
}
\ No newline at end of file
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
index 9b204cf285..f2dd400494 100644
---
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
@@ -18,10 +18,13 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import
org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
@@ -418,4 +421,20 @@ public class MatchStepTest extends StepTest {
assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?,
?>) traversal.getStartStep()).getGlobalChildren()));
}
+ @Test
+ public void shouldObtainPopInstructions() {
+ final Traversal.Admin<?, ?> traversal =
__.match(as("a").out().as("b"), as("c").path().as("d")).asAdmin();
+ final MatchStep<?, ?> matchStep = (MatchStep<?, ?>)
traversal.getStartStep();
+
+ final HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last},
+ new Object[]{"b", Pop.last},
+ new Object[]{"c", Pop.last},
+ new Object[]{"d", Pop.last}
+ );
+
+
+ assertEquals(matchStep.getPopInstructions(), popInstructionSet);
+ }
+
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
index 0a9141c335..6dd0a147cc 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
@@ -19,14 +19,19 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
@@ -71,4 +76,20 @@ public class MathStepTest extends StepTest {
assertEquals(Arrays.asList("number1", "expected_value"), new
ArrayList<>(MathStep.getVariables("number1-expected_value")));
}
+ @Test
+ public void shouldObtainPopInstructions() {
+ final GraphTraversal<Object, Object> traversal = __.identity();
+
+ final MathStep mathStep = new MathStep<>((Traversal.Admin) traversal,
"a + b - c");
+
+ // Expected Output
+ final HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last},
+ new Object[]{"b", Pop.last},
+ new Object[]{"c", Pop.last}
+ );
+
+ assertEquals(popInstructionSet, mathStep.getPopInstructions());
+ }
+
}
\ No newline at end of file
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
index 480c0b1f09..1ce46d47d2 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
@@ -18,14 +18,18 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.junit.Test;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -61,4 +65,48 @@ public class SelectOneStepTest extends StepTest {
assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>)
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
}
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ final GraphTraversal<Object, Object> traversal = __.identity();
+
+ // Expected Output
+ HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.all}
+ );
+
+ // Pop.all
+ final SelectOneStep selectOneStepAll = new
SelectOneStep((Traversal.Admin) traversal, Pop.all, "x");
+
+ assertEquals(selectOneStepAll.getPopInstructions(), popInstructionSet);
+
+
+ // Pop.last
+ final SelectOneStep selectOneStepLast = new
SelectOneStep<>((Traversal.Admin) traversal, Pop.last, "x");
+ popInstructionSet = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.last}
+ );
+
+ assertEquals(selectOneStepLast.getPopInstructions(),
popInstructionSet);
+
+
+ // Pop.first
+ final SelectOneStep selectOneStepFirst = new
SelectOneStep<>((Traversal.Admin) traversal, Pop.first, "x");
+ popInstructionSet = popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.first}
+ );
+
+ assertEquals(selectOneStepFirst.getPopInstructions(),
popInstructionSet);
+
+
+ // Pop.mixed
+ final SelectOneStep selectOneStepMixed = new
SelectOneStep<>((Traversal.Admin) traversal, Pop.mixed, "x");
+ popInstructionSet = popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.mixed}
+ );
+
+
+ assertEquals(selectOneStepMixed.getPopInstructions(),
popInstructionSet);
+
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
index 5393403d81..4d39cdd239 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
@@ -18,14 +18,18 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.junit.Test;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -63,4 +67,50 @@ public class SelectStepTest extends StepTest {
assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>)
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
}
}
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ final GraphTraversal<Object, Object> traversal = __.identity();
+
+ // 2 keys, and Pop.all
+ final SelectStep selectStepAll = new SelectStep<>((Traversal.Admin)
traversal, Pop.all, "x", "y");
+ HashSet<PopContaining.PopInstruction> popInstructionSet =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.all},
+ new Object[]{"y", Pop.all}
+ );
+
+ assertEquals(selectStepAll.getPopInstructions(), popInstructionSet);
+
+
+ // 3 keys, and Pop.last
+ final SelectStep selectStepLast = new SelectStep<>((Traversal.Admin)
traversal, Pop.last, "x", "y", "z");
+ popInstructionSet = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.last},
+ new Object[]{"y", Pop.last},
+ new Object[]{"z", Pop.last}
+ );
+
+ assertEquals(selectStepLast.getPopInstructions(), popInstructionSet);
+
+
+ // 2 keys, and Pop.first
+ final SelectStep selectStepFirst = new SelectStep<>((Traversal.Admin)
traversal, Pop.first, "x", "y");
+ popInstructionSet = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.first},
+ new Object[]{"y", Pop.first}
+ );
+
+ assertEquals(selectStepFirst.getPopInstructions(), popInstructionSet);
+
+
+ // 2 keys, and Pop.mixed
+ final SelectStep selectStepMixed = new SelectStep<>((Traversal.Admin)
traversal, Pop.mixed, "x", "y");
+ popInstructionSet = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"x", Pop.mixed},
+ new Object[]{"y", Pop.mixed}
+ );
+
+ assertEquals(selectStepMixed.getPopInstructions(), popInstructionSet);
+
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
new file mode 100644
index 0000000000..1e0198ba57
--- /dev/null
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 anmvn limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashSet;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+import org.junit.Test;
+
+public class TraversalSelectStepTest {
+
+ @Test
+ public void shouldObtainPopInstructions() {
+ TraversalSelectStep step = new
TraversalSelectStep(__.select("a").asAdmin(), Pop.first, __.select(Pop.first,
"b").select("c"));
+
+ HashSet<PopContaining.PopInstruction> expectedOutput =
TestDataBuilder.createPopInstructionSet(
+ new Object[]{"b", Pop.first},
+ new Object[]{"c", Pop.last}
+ );
+
+ assertEquals(step.getPopInstructions(), expectedOutput);
+
+ step = new TraversalSelectStep(__.identity().asAdmin(), Pop.first,
__.select(Pop.first, "a", "b", "c"));
+
+ // 3 keys, and Pop.first
+ expectedOutput = TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.first},
+ new Object[]{"c", Pop.first},
+ new Object[]{"b", Pop.first}
+ );
+
+ assertEquals(step.getPopInstructions(), expectedOutput);
+
+
+}
+}
\ No newline at end of file
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
index 26d145aa05..d14e0b8ad3 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
@@ -21,10 +21,13 @@ package
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
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 org.junit.Test;
import java.util.Arrays;
import java.util.List;
+import static org.junit.Assert.assertEquals;
+
/**
* @author Daniel Kuppitz (http://gremlin.guru)
*/
@@ -38,4 +41,11 @@ public class AddPropertyStepTest extends StepTest {
// __.property("y", 0)
);
}
+
+ @Test
+ public void testGetPopInstructions() {
+ final AddPropertyStep step = new
AddPropertyStep(__.identity().select("s").asAdmin(), null, "x", 0);
+
+ assertEquals(0, step.getPopInstructions().size());
+ }
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
index c7884451ac..aa86a0d913 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
@@ -18,10 +18,14 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.util;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
import
org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.TraversalVertexProgramStep;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
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.PopContaining;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
@@ -47,14 +51,22 @@ import
org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.junit.Test;
import org.mockito.Mockito;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
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.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.path;
+import static
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.repeat;
+import static
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
+import static
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
+import static
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -485,4 +497,85 @@ public class TraversalHelperTest {
assertEquals("e", ((PropertiesStep)
steps.get(4)).getPropertyKeys()[0]);
assertEquals("f", ((PropertiesStep)
steps.get(5)).getPropertyKeys()[0]);
}
+
+ @Test
+ public void shouldGetPopInstructions() {
+ final List<Traversal.Admin<?,?>> traversals = new ArrayList<>();
+ final List<Set<PopContaining.PopInstruction>> expectedResults = new
ArrayList<>();
+
+ ///
+ traversals.add(__.V().has("person", "name",
"marko").as("start").repeat(out().as("reached").select("start")).times(2).select("reached").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"start", Pop.last},
+ new Object[]{"reached", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().select("vertex").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"vertex", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().out().as("a").repeat(union(out().select("a"),
path().select(Pop.mixed, "b"))).select(Pop.first,"c").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last},
+ new Object[]{"b", Pop.mixed},
+ new Object[]{"c", Pop.first}
+ ));
+ ///
+
traversals.add(__.V().as("b").repeat(select("b").out().as("a")).times(2).select(Pop.first,
"a").select(Pop.last, "a").project("bb").by(__.select(Pop.all,
"a")).asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"b", Pop.last},
+ new Object[]{"a", Pop.first},
+ new Object[]{"a", Pop.all},
+ new Object[]{"a", Pop.last}
+ ));
+ ///
+
traversals.add(__.V("1").as("b").repeat(select("b").out().as("a")).times(2).path().as("c").by("name").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"b", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().union(out().as("a"),
repeat(out().as("a")).emit()).select(Pop.last, "a").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().has("person", "name",
"marko").as("start").repeat(out()).times(2).where(P.neq("start")).values("name").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"start", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().union(out(),
repeat(out().as("a")).emit()).select(Pop.last, "a").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last}
+ ));
+ ///
+ traversals.add(__.V().as("a").union(path(),
repeat(out().select(Pop.last, "a"))).asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"a", Pop.last}
+ ));
+ ///
+
traversals.add(__.V().hasLabel("person").repeat(out("created")).emit().as("software").select("software").values("name",
"lang").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"software", Pop.last}
+ ));
+ ///
+
traversals.add(__.V().hasLabel("person").repeat(out("created").as("created_thing")).emit().as("final").select(Pop.mixed,
"created_thing", "final"). by("name").by("lang").asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"created_thing", Pop.mixed},
+ new Object[]{"final", Pop.mixed}
+ ));
+ ///
+ traversals.add(__.V().has("person", "name",
"marko").as("start").repeat(out().as("path_element")).until(has("lang")).as("software").select("start",
"path_element", "software").by("name").by("name").by(valueMap("name",
"lang")).asAdmin());
+ expectedResults.add(TestDataBuilder.createPopInstructionSet(
+ new Object[]{"start", Pop.last},
+ new Object[]{"path_element", Pop.last},
+ new Object[]{"software", Pop.last}
+ ));
+
+ // Run all the tests
+ for (int i = 0; i < traversals.size(); i++) {
+
assertEquals(TraversalHelper.getPopInstructions(traversals.get(i)),
expectedResults.get(i));
+ }
+ }
}