This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 8c95cf378013a6f173708d7e50399a66f750bc2c
Author: Stephen Mallette <[email protected]>
AuthorDate: Thu Sep 11 15:24:24 2025 -0400

    Remove recursion in GValue reduction strategies and added provider specific 
one
---
 .../optimization/GValueReductionStrategy.java      |  13 +-
 .../provider/ProviderGValueReductionStrategy.java  |  15 +-
 .../optimization/GValueReductionStrategyTest.java  | 269 +++++++++++++++++++++
 .../ProviderGValueReductionStrategyTest.java       | 254 +++++++++++++++++++
 4 files changed, 533 insertions(+), 18 deletions(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategy.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategy.java
index 2f2888931a..7bdaa741db 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategy.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategy.java
@@ -50,15 +50,12 @@ public final class GValueReductionStrategy extends 
AbstractTraversalStrategy<Tra
 
     @Override
     public void apply(final Traversal.Admin<?, ?> traversal) {
-        TraversalHelper.applyTraversalRecursively(t -> {
-            // we get accused of concurrentmodification if we try a 
for(Iterable)
-            final List<Step> steps = t.getSteps();
-            for (int i = 0; i < steps.size(); i++) {
-                if (steps.get(i) instanceof GValueHolder) {
-                    ((GValueHolder) steps.get(i)).reduce();
-                }
+        final List<Step> steps = traversal.getSteps();
+        for (int i = 0; i < steps.size(); i++) {
+            if (steps.get(i) instanceof GValueHolder) {
+                ((GValueHolder) steps.get(i)).reduce();
             }
-        }, traversal);
+        }
     }
 
     public static GValueReductionStrategy instance() {
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
index 3d2e178964..a3c3c92a27 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
@@ -45,19 +45,14 @@ public class ProviderGValueReductionStrategy extends 
AbstractTraversalStrategy<T
 
     private static final ProviderGValueReductionStrategy INSTANCE = new 
ProviderGValueReductionStrategy();
 
-    private ProviderGValueReductionStrategy() {}
-
     @Override
     public void apply(final Traversal.Admin<?, ?> traversal) {
-        TraversalHelper.applyTraversalRecursively(t -> {
-            // we get accused of concurrentmodification if we try a 
for(Iterable)
-            final List<Step> steps = t.getSteps();
-            for (int i = 0; i < steps.size(); i++) {
-                if (steps.get(i) instanceof GValueHolder) {
-                    ((GValueHolder) steps.get(i)).reduce();
-                }
+        final List<Step> steps = traversal.getSteps();
+        for (int i = 0; i < steps.size(); i++) {
+            if (steps.get(i) instanceof GValueHolder) {
+                ((GValueHolder) steps.get(i)).reduce();
             }
-        }, traversal);
+        }
     }
 
     public static ProviderGValueReductionStrategy instance() {
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategyTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategyTest.java
new file mode 100644
index 0000000000..85130afadd
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/GValueReductionStrategyTest.java
@@ -0,0 +1,269 @@
+/*
+ * 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.strategy.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValueHolder;
+import 
org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
+import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import 
org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class GValueReductionStrategyTest {
+
+    private static void applyAndAssertOneForOne(final Traversal.Admin<?, ?> 
traversal) {
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+        final int preTopLevelStepCount = traversal.getSteps().size();
+
+        final TraversalStrategies strategies = new 
DefaultTraversalStrategies();
+        strategies.addStrategies(GValueReductionStrategy.instance());
+        traversal.setStrategies(strategies);
+        traversal.applyStrategies();
+
+        final List<GValueHolder> postPlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertThat("All GValueHolder steps should be reduced after applying 
strategy", postPlaceholders.isEmpty(), is(true));
+        final int postTopLevelStepCount = traversal.getSteps().size();
+        assertEquals("Top-level step count should remain the same after 
reduction", preTopLevelStepCount, postTopLevelStepCount);
+    }
+
+    @Test
+    public void shouldReduceGValueHoldersInRootTraversalOneForOne() {
+        // Build a traversal that will contain GValueHolder placeholders 
(IsStepPlaceholder, RangeGlobalStepPlaceholder)
+        final Traversal.Admin<?, ?> traversal = __.identity()
+                .is(P.eq(GValue.of("x", 1)))
+                .range(GValue.of("l", 0L), GValue.of("h", 10L))
+                .asAdmin();
+
+        // Pre-condition: there should be GValueHolder steps present
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+
+        // Capture step count before applying the strategy (top-level 
traversal only)
+        final int preStepCount = traversal.getSteps().size();
+
+        // Apply and assert
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceGValueHoldersInChildTraversalsOneForOne() {
+        // Build a traversal with a child traversal that includes placeholders 
and add a root placeholder as well
+        final Traversal.Admin<?, ?> traversal = 
__.map(__.identity().is(P.eq(GValue.of("y", 2))))
+                .tail(GValue.of("t", 5L))
+                .asAdmin();
+
+        // Pre-condition: there should be GValueHolder steps present 
recursively (child + root)
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+
+        // Capture step counts before applying the strategy
+        final int preTopLevelStepCount = traversal.getSteps().size();
+
+        // Also capture the child traversal step count for the TraversalMapStep
+        final TraversalMapStep<?, ?> mapStepBefore = 
TraversalHelper.getFirstStepOfAssignableClass(TraversalMapStep.class, 
traversal).get();
+        final Traversal.Admin<?, ?> childBefore = 
mapStepBefore.getLocalChildren().get(0);
+        final int preChildStepCount = childBefore.getSteps().size();
+
+        // Apply GValueReductionStrategy
+        final TraversalStrategies strategies = new 
DefaultTraversalStrategies();
+        strategies.addStrategies(GValueReductionStrategy.instance());
+        traversal.setStrategies(strategies);
+        traversal.applyStrategies();
+
+        // Post-condition: there should be no GValueHolder steps remaining 
recursively
+        final List<GValueHolder> postPlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertThat("All GValueHolder steps should be reduced in both root and 
child traversals", postPlaceholders.isEmpty(), is(true));
+
+        // Validate one-for-one replacement: top-level step count unchanged
+        final int postTopLevelStepCount = traversal.getSteps().size();
+        assertEquals("Top-level step count should remain the same after 
reduction", preTopLevelStepCount, postTopLevelStepCount);
+
+        // Validate one-for-one replacement: child traversal step count 
unchanged
+        final TraversalMapStep<?, ?> mapStepAfter = 
TraversalHelper.getFirstStepOfAssignableClass(TraversalMapStep.class, 
traversal).get();
+        final Traversal.Admin<?, ?> childAfter = 
mapStepAfter.getLocalChildren().get(0);
+        final int postChildStepCount = childAfter.getSteps().size();
+        assertEquals("Child traversal step count should remain the same after 
reduction", preChildStepCount, postChildStepCount);
+
+        // Sanity: ensure that TailGlobalStep is concrete after reduction
+        assertThat("Tail step should be concrete after reduction",
+                
TraversalHelper.getFirstStepOfAssignableClass(TailGlobalStep.class, 
traversal).isPresent(), is(true));
+    }
+
+    @Test
+    public void shouldReduceGraphStepPlaceholderV() {
+        final Traversal.Admin<?, ?> traversal = __.V(GValue.of("id", 
1)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceGraphStepPlaceholderE() {
+        final Traversal.Admin<?, ?> traversal = __.E(GValue.of("id", 
2)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceOutWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.out(GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceInWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.in(GValue.of("l", 
"created")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceBothWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.both(GValue.of("l", 
"uses")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceToDirectionWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = 
__.to(org.apache.tinkerpop.gremlin.structure.Direction.OUT, GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceOutEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.outE(GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceInEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.inE(GValue.of("l", 
"created")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceBothEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.bothE(GValue.of("l", 
"uses")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceToEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = 
__.toE(org.apache.tinkerpop.gremlin.structure.Direction.IN, GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceRangeGlobalWithGValues() {
+        final Traversal.Admin<?, ?> traversal = __.range(GValue.of("low", 1L), 
GValue.of("high", 3L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceRangeLocalWithGValues() {
+        final Traversal.Admin<?, ?> traversal = 
__.range(org.apache.tinkerpop.gremlin.process.traversal.Scope.local,
+                GValue.of("low", 0L), GValue.of("high", 2L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceLimitGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.limit(GValue.of("lim", 
5L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceLimitLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.limit(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("lim", 2L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceSkipGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.skip(GValue.of("sk", 
7L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceSkipLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.skip(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("sk", 3L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceTailGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.tail(GValue.of("t", 
4L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceTailLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.tail(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("t", 1L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddVWithGValueLabel() {
+        final Traversal.Admin<?, ?> traversal = __.addV(GValue.of("vl", 
"person")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddEWithGValueLabel() {
+        final Traversal.Admin<?, ?> traversal = __.addE(GValue.of("el", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddPropertyWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.addV("x").property("name", 
GValue.of("n", "marko")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+//    @Test
+//    public void shouldReduceCallWithGValueParams() {
+//        final java.util.Map<String, Object> params = java.util.Map.of("a", 
1);
+//        final Traversal.Admin<?, ?> traversal = __.call("svc", 
GValue.of("p", params)).asAdmin();
+//        applyAndAssertOneForOne(traversal);
+//    }
+
+    @Test
+    public void shouldReduceMergeVWithGValue() {
+        final java.util.Map<Object, Object> merge = java.util.Map.of("name", 
"x");
+        final Traversal.Admin<?, ?> traversal = __.mergeV(GValue.of("m", 
merge)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceMergeEWithGValue() {
+        final java.util.Map<Object, Object> merge = java.util.Map.of("label", 
"knows");
+        final Traversal.Admin<?, ?> traversal = __.mergeE(GValue.of("m", 
merge)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+}
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategyTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategyTest.java
new file mode 100644
index 0000000000..2939abb921
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategyTest.java
@@ -0,0 +1,254 @@
+/*
+ * 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.strategy.provider;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValueHolder;
+import 
org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
+import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import 
org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ProviderGValueReductionStrategyTest {
+
+    private static void applyAndAssertOneForOne(final Traversal.Admin<?, ?> 
traversal) {
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+        final int preTopLevelStepCount = traversal.getSteps().size();
+
+        final TraversalStrategies strategies = new 
DefaultTraversalStrategies();
+        strategies.addStrategies(ProviderGValueReductionStrategy.instance());
+        traversal.setStrategies(strategies);
+        traversal.applyStrategies();
+
+        final List<GValueHolder> postPlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertThat("All GValueHolder steps should be reduced after applying 
strategy", postPlaceholders.isEmpty(), is(true));
+        final int postTopLevelStepCount = traversal.getSteps().size();
+        assertEquals("Top-level step count should remain the same after 
reduction", preTopLevelStepCount, postTopLevelStepCount);
+    }
+
+    @Test
+    public void shouldReduceGValueHoldersInRootTraversalOneForOne() {
+        final Traversal.Admin<?, ?> traversal = __.identity()
+                .is(P.eq(GValue.of("x", 1)))
+                .range(GValue.of("l", 0L), GValue.of("h", 10L))
+                .asAdmin();
+
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceGValueHoldersInChildTraversalsOneForOne() {
+        final Traversal.Admin<?, ?> traversal = 
__.map(__.identity().is(P.eq(GValue.of("y", 2))))
+                .tail(GValue.of("t", 5L))
+                .asAdmin();
+
+        final List<GValueHolder> prePlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertTrue("Expected GValueHolder steps before applying strategy", 
!prePlaceholders.isEmpty());
+
+        final int preTopLevelStepCount = traversal.getSteps().size();
+
+        final TraversalMapStep<?, ?> mapStepBefore = 
TraversalHelper.getFirstStepOfAssignableClass(TraversalMapStep.class, 
traversal).get();
+        final Traversal.Admin<?, ?> childBefore = 
mapStepBefore.getLocalChildren().get(0);
+        final int preChildStepCount = childBefore.getSteps().size();
+
+        final TraversalStrategies strategies = new 
DefaultTraversalStrategies();
+        strategies.addStrategies(ProviderGValueReductionStrategy.instance());
+        traversal.setStrategies(strategies);
+        traversal.applyStrategies();
+
+        final List<GValueHolder> postPlaceholders = 
TraversalHelper.getStepsOfAssignableClassRecursively(GValueHolder.class, 
traversal);
+        assertThat("All GValueHolder steps should be reduced in both root and 
child traversals", postPlaceholders.isEmpty(), is(true));
+
+        final int postTopLevelStepCount = traversal.getSteps().size();
+        assertEquals("Top-level step count should remain the same after 
reduction", preTopLevelStepCount, postTopLevelStepCount);
+
+        final TraversalMapStep<?, ?> mapStepAfter = 
TraversalHelper.getFirstStepOfAssignableClass(TraversalMapStep.class, 
traversal).get();
+        final Traversal.Admin<?, ?> childAfter = 
mapStepAfter.getLocalChildren().get(0);
+        final int postChildStepCount = childAfter.getSteps().size();
+        assertEquals("Child traversal step count should remain the same after 
reduction", preChildStepCount, postChildStepCount);
+
+        assertThat("Tail step should be concrete after reduction",
+                
TraversalHelper.getFirstStepOfAssignableClass(TailGlobalStep.class, 
traversal).isPresent(), is(true));
+    }
+
+    @Test
+    public void shouldReduceGraphStepPlaceholderV() {
+        final Traversal.Admin<?, ?> traversal = __.V(GValue.of("id", 
1)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceGraphStepPlaceholderE() {
+        final Traversal.Admin<?, ?> traversal = __.E(GValue.of("id", 
2)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceOutWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.out(GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceInWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.in(GValue.of("l", 
"created")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceBothWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.both(GValue.of("l", 
"uses")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceToDirectionWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = 
__.to(org.apache.tinkerpop.gremlin.structure.Direction.OUT, GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceOutEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.outE(GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceInEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.inE(GValue.of("l", 
"created")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceBothEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = __.bothE(GValue.of("l", 
"uses")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceToEWithGValueLabels() {
+        final Traversal.Admin<?, ?> traversal = 
__.toE(org.apache.tinkerpop.gremlin.structure.Direction.IN, GValue.of("l", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceRangeGlobalWithGValues() {
+        final Traversal.Admin<?, ?> traversal = __.range(GValue.of("low", 1L), 
GValue.of("high", 3L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceRangeLocalWithGValues() {
+        final Traversal.Admin<?, ?> traversal = 
__.range(org.apache.tinkerpop.gremlin.process.traversal.Scope.local,
+                GValue.of("low", 0L), GValue.of("high", 2L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceLimitGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.limit(GValue.of("lim", 
5L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceLimitLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.limit(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("lim", 2L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceSkipGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.skip(GValue.of("sk", 
7L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceSkipLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.skip(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("sk", 3L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceTailGlobalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.tail(GValue.of("t", 
4L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceTailLocalWithGValue() {
+        final Traversal.Admin<?, ?> traversal = 
__.tail(org.apache.tinkerpop.gremlin.process.traversal.Scope.local, 
GValue.of("t", 1L)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddVWithGValueLabel() {
+        final Traversal.Admin<?, ?> traversal = __.addV(GValue.of("vl", 
"person")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddEWithGValueLabel() {
+        final Traversal.Admin<?, ?> traversal = __.addE(GValue.of("el", 
"knows")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceAddPropertyWithGValue() {
+        final Traversal.Admin<?, ?> traversal = __.addV("x").property("name", 
GValue.of("n", "marko")).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+//    @Test
+//    public void shouldReduceCallWithGValueParams() {
+//        final java.util.Map<String, Object> params = java.util.Map.of("a", 
1);
+//        final Traversal.Admin<?, ?> traversal = __.call("svc", 
GValue.of("p", params)).asAdmin();
+//        applyAndAssertOneForOne(traversal);
+//    }
+
+    @Test
+    public void shouldReduceMergeVWithGValue() {
+        final java.util.Map<Object, Object> merge = java.util.Map.of("name", 
"x");
+        final Traversal.Admin<?, ?> traversal = __.mergeV(GValue.of("m", 
merge)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+
+    @Test
+    public void shouldReduceMergeEWithGValue() {
+        final java.util.Map<Object, Object> merge = java.util.Map.of("label", 
"knows");
+        final Traversal.Admin<?, ?> traversal = __.mergeE(GValue.of("m", 
merge)).asAdmin();
+        applyAndAssertOneForOne(traversal);
+    }
+}

Reply via email to