You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2025/06/06 19:07:29 UTC

(tinkerpop) branch GValueManager3.8-wip updated: wip-tests

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

spmallette pushed a commit to branch GValueManager3.8-wip
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/GValueManager3.8-wip by this push:
     new cb5133e247 wip-tests
cb5133e247 is described below

commit cb5133e24744e69c5870b77838407545bf236c0b
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Jun 6 15:07:06 2025 -0400

    wip-tests
---
 .../gremlin/process/traversal/GValueManager.java   |  40 +++--
 .../traversal/strategy/GValueManagerVerifier.java  |  12 +-
 .../AdjacentToIncidentStrategyTest.java            |  12 +-
 .../ByModulatorOptimizationStrategyTest.java       |  14 +-
 .../strategy/optimization/CountStrategyTest.java   | 196 ++++++++++-----------
 .../optimization/EarlyLimitStrategyTest.java       |   2 +-
 .../optimization/FilterRankingStrategyTest.java    |  12 +-
 .../optimization/IdentityRemovalStrategyTest.java  |  15 +-
 8 files changed, 141 insertions(+), 162 deletions(-)

diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
index 4757f926e3..a9483c95af 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
@@ -170,7 +170,7 @@ public final class GValueManager implements Serializable, Cloneable {
             final Set<GValue> gvalues = new HashSet<>();
             for (StepContract contract : stepRegistry.values()) {
                 extractGValues(contract).stream().
-                        filter(gv -> gv.getName() != null).forEach(gvalues::add);
+                        filter(GValue::isVariable).forEach(gvalues::add);
             }
             return Collections.unmodifiableSet(gvalues);
         }
@@ -212,10 +212,18 @@ public final class GValueManager implements Serializable, Cloneable {
     }
 
     /**
-     * Determines whether the GValueManager contains any registered GValues, steps, or predicates.
+     * Determines whether the manager has step registrations.
      */
-    public boolean isEmpty() {
-        return gValueRegistry.isEmpty() && stepRegistry.isEmpty();
+    public boolean hasStepRegistrations() {
+        return stepRegistry.isEmpty();
+    }
+
+    /**
+     * Determines whether the manager has step registrations. This call is not consistent until {@link #lock()} is
+     * called.
+     */
+    public boolean hasVariables() {
+        return variableNames().isEmpty();
     }
 
     /**
@@ -272,10 +280,6 @@ public final class GValueManager implements Serializable, Cloneable {
         }
     }
 
-    private Collection<GValue<?>> extractPredicateGValues(final P predicate) {
-        return predicate.getGValueRegistry().getGValues();
-    }
-
     private Collection<GValue<?>> extractGValues(final StepContract contract) {
         if (contract instanceof RangeContract) {
             return extractGValue((RangeContract<GValue<Long>>) contract);
@@ -309,7 +313,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final RangeContract<GValue<Long>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         if (contract.getHighRange().isVariable()) {
             results.add(contract.getHighRange());
         }
@@ -335,7 +339,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final MergeElementContract<GValue<Map<?,?>>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         if (contract.getMergeMap() != null) {
             results.add(contract.getMergeMap());
         }
@@ -353,7 +357,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final ElementIdsContract<GValue<?>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         for (GValue gValue: contract.getIds()) {
             if (gValue.isVariable()) {
                 results.add(gValue);
@@ -367,7 +371,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final AddVertexContract<GValue<String>, ?, GValue<?>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         if (contract.getLabel() != null) {
             results.add(contract.getLabel());
         }
@@ -382,7 +386,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final AddEdgeContract<GValue<String>, GValue<Vertex>, ?, GValue<?>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         if (contract.getLabel() != null) {
             results.add(contract.getLabel());
         }
@@ -405,7 +409,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final AddPropertyContract<?, GValue<?>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         results.add(contract.getValue());
         for (GValue<?> value : contract.getProperties().values()) {
             results.add(value);
@@ -418,7 +422,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final EdgeLabelContract<GValue<String>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         for (GValue gValue: contract.getEdgeLabels()) {
             if (gValue.getName() != null) {
                 results.add(gValue);
@@ -432,7 +436,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final CallContract<GValue<Map<?,?>>> contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         if (contract.getStaticParams().getName() != null) {
             results.add(contract.getStaticParams());
         }
@@ -455,7 +459,7 @@ public final class GValueManager implements Serializable, Cloneable {
      * manager.
      */
     private Collection<GValue<?>> extractGValue(final HasContainerHolder contract) {
-        Collection<GValue<?>> results = new ArrayList();
+        final Collection<GValue<?>> results = new ArrayList();
         for (P<?> predicate : contract.getPredicates()) {
             if (predicate != null) {
                 results.addAll(predicate.getGValueRegistry().getGValues());
@@ -466,7 +470,7 @@ public final class GValueManager implements Serializable, Cloneable {
 
     private void registerGValues(final Collection<GValue<?>> gValues) {
         for (GValue<?> gValue : gValues) {
-            if (gValue.getName() != null) {
+            if (gValue.isVariable()) {
                 gValueRegistry.put(gValue.getName(), gValue);
             }
         }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
index ba5028767a..3989d3cadf 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
@@ -24,7 +24,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.stepContract.EdgeLabelContract;
 import org.apache.tinkerpop.gremlin.process.traversal.step.stepContract.RangeContract;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -34,7 +33,6 @@ import org.apache.tinkerpop.gremlin.util.CollectionUtil;
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -43,7 +41,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
 
 /**
  * Provides utilities to verify the state and behavior of {@code GValueManager} during and after traversal strategy
@@ -204,15 +201,18 @@ public class GValueManagerVerifier {
         }
 
         /**
-         * Returns this instance cast to the implementing class type
+         * Returns this instance cast to the implementing class type.
          */
         protected abstract T self();
 
         /**
-         * Verifies that GValueManager is empty
+         * Verifies that GValueManager is empty, specifically meaning that there are no variables in the manager. There
+         * might yet be unnamed {@link GValue} instances but since we don't bind to those and they are usually incident
+         * to something like {@code V(1, x=2, 3)} where one variable implies that all arguments must be converted to
+         * {@link GValue} you can have scenarios where there is a mix.
          */
         public T managerIsEmpty() {
-            assertThat("GValueManager should be empty", manager.isEmpty(), is(true));
+            assertThat(String.format("GValueManager should be empty but contains [%s]", manager.gValues()), manager.hasVariables(), is(true));
             return self();
         }
 
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
index 85929d4ccf..02ef89b8a5 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
@@ -60,13 +60,6 @@ public class AdjacentToIncidentStrategyTest {
         @Parameterized.Parameter(value = 1)
         public Traversal optimized;
 
-        void applyAdjacentToIncidentStrategy(final Traversal traversal) {
-            final TraversalStrategies strategies = new DefaultTraversalStrategies();
-            strategies.addStrategies(AdjacentToIncidentStrategy.instance());
-            traversal.asAdmin().setStrategies(strategies);
-            traversal.asAdmin().applyStrategies();
-        }
-
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Traversal[][]{
@@ -94,9 +87,10 @@ public class AdjacentToIncidentStrategyTest {
         @Test
         public void doTest() {
             final String repr = translator.translate(original.getBytecode()).getScript();
-            applyAdjacentToIncidentStrategy(original);
+            GValueManagerVerifier.verify(original.asAdmin(), AdjacentToIncidentStrategy.instance())
+                    .afterApplying()
+                    .managerIsEmpty();
             assertEquals(repr, optimized, original);
-            assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
         }
     }
 
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
index 53f87ff294..f97b3e7f6b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
@@ -25,6 +25,7 @@ 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.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.GValueManagerVerifier;
 import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
 import org.apache.tinkerpop.gremlin.structure.T;
@@ -37,6 +38,8 @@ import java.util.List;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.Operator.assign;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -177,17 +180,12 @@ public class ByModulatorOptimizationStrategyTest {
         return originalAndOptimized;
     }
 
-    private void applyByModulatorOptimizationStrategy(final Traversal traversal) {
-        final TraversalStrategies strategies = new DefaultTraversalStrategies();
-        strategies.addStrategies(ByModulatorOptimizationStrategy.instance());
-        traversal.asAdmin().setStrategies(strategies);
-        traversal.asAdmin().applyStrategies();
-    }
-
     @Test
     public void doTest() {
         final String repr = translator.translate(original.getBytecode()).getScript();
-        applyByModulatorOptimizationStrategy(original);
+        GValueManagerVerifier.verify(original.asAdmin(), ByModulatorOptimizationStrategy.instance())
+                .afterApplying()
+                .managerIsEmpty();
         assertEquals(repr, optimized, original);
     }
 }
\ No newline at end of file
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
index 8fc6eae9ef..cc299bd177 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
@@ -73,114 +73,106 @@ public class CountStrategyTest {
 
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
-
-        return Arrays.asList(new Traversal[][]{
-                {__.count().is(0), __.limit(1).count().is(0)},
-                {__.count().is(1), __.limit(2).count().is(1)},
-                {__.count().is(-1), __.limit(0).count().is(-1)}, // -1 for RangeGlobalStep means no upper limit
-                {__.count().is(-2), __.limit(0).count().is(-2)},
-                {__.count().is(-2023), __.limit(0).count().is(-2023)},
-                {__.count().is(P.between(0, 10)), __.limit(10).count().is(P.between(0, 10))},
-                {__.count().is(P.between(5, 10)), __.limit(10).count().is(P.between(5, 10))},
-                {__.count().is(P.gt(10).or(lt(5))), __.limit(11).count().is(P.gt(10).or(lt(5)))},
-                {__.out().count().is(0), __.out().limit(1).count().is(0)},
-                {__.outE().count().is(lt(1)), __.outE().limit(1).count().is(lt(1))},
-                {__.both().count().is(lte(0)), __.both().limit(1).count().is(lte(0))},
-                {__.map(__.out().count().is(0)), __.map(__.out().limit(1).count().is(0))},
-                {__.map(__.outE().count().is(lt(1))), __.map(__.outE().limit(1).count().is(lt(1)))},
-                {__.map(__.both().count().is(lte(0))), __.map(__.both().limit(1).count().is(lte(0)))},
-                {__.filter(__.out().count().is(0)), __.not(__.out())},
-                {__.filter(__.outE().count().is(lt(1))), __.not(__.outE())},
-                {__.filter(__.both().count().is(lte(0))), __.not(__.both())},
-                {__.filter(__.out().out().count().is(0)), __.not(__.out().out())},
-                {__.store("x").count().is(0).as("a"), __.store("x").limit(1).count().is(0).as("a")},
-                {__.out().count().as("a").is(0), __.out().limit(1).count().as("a").is(0)},
-                {__.out().count().is(neq(4)), __.out().limit(5).count().is(neq(4))},
-                {__.out().count().is(lte(3)), __.out().limit(4).count().is(lte(3))},
-                {__.out().count().is(lt(3)), __.out().limit(3).count().is(lt(3))},
-                {__.out().count().is(gt(2)), __.out().limit(3).count().is(gt(2))},
-                {__.out().count().is(gte(2)), __.out().limit(2).count().is(gte(2))},
-                {__.out().count().is(inside(2, 4)), __.out().limit(4).count().is(inside(2, 4))},
-                {__.out().count().is(outside(2, 4)), __.out().limit(5).count().is(outside(2, 4))},
-                {__.out().count().is(within(2, 6, 4)), __.out().limit(7).count().is(within(2, 6, 4))},
-                {__.out().count().is(without(2, 6, 4)), __.out().limit(6).count().is(without(2, 6, 4))},
-                {__.map(__.count().is(0)), __.map(__.limit(1).count().is(0))},
-                {__.flatMap(__.count().is(0)), __.flatMap(__.limit(1).count().is(0))},
-                {__.flatMap(__.count().is(0)).as("a"), __.flatMap(__.count().is(0)).as("a")}, // no change
-                {__.filter(__.count().is(0)).as("a"), __.not(__.identity()).as("a")},
-                {__.filter(__.count().is(0)), __.not(__.identity())},
-                {__.sideEffect(__.count().is(0)), __.sideEffect(__.not(__.identity()))},
-                {__.branch(__.count().is(0)), __.branch(__.limit(1).count().is(0))},
-                {__.count().is(0).store("x"), __.limit(1).count().is(0).store("x")},
-                {__.repeat(__.out()).until(__.outE().count().is(0)), __.repeat(__.out()).until(__.not(__.outE()))},
-                {__.repeat(__.out()).until(__.out().out().values("name").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.values("name")))},
-                {__.repeat(__.out()).until(__.out().out().properties("age").has("x").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.properties("age").has("x")))},
-                {__.repeat(__.out()).emit(__.outE().count().is(0)), __.repeat(__.out()).emit(__.not(__.outE()))},
-                {__.where(__.outE().hasLabel("created").count().is(0)), __.not(__.outE().hasLabel("created"))},
-                {__.where(__.out().outE().hasLabel("created").count().is(0)), __.not(__.out().outE().hasLabel("created"))},
-                {__.where(__.out().outE().hasLabel("created").count().is(0).store("x")), __.where(__.out().outE().hasLabel("created").limit(1).count().is(0).store("x"))},
-                {__.where(__.or(__.out("none").out().count().is(0), __.has("none"))), __.where(__.or(__.not(__.out("none").out()), __.has("none"))) },
-                {__.where(__.or(__.out("none").out().count().is(0), __.has("none").count().is(0))), __.where(__.or(__.not(__.out("none").out()), __.not(__.has("none")))) },
-                {__.where(__.or(__.out("none").out(), __.has("none").count().is(0))), __.where(__.or(__.out("none").out(), __.not(__.has("none")))) },
-                {__.filter(__.out().count().is(gt(-1))), __.filter(__.out().limit(0).count().is(gt(-1)))},
-                {__.filter(__.out().count().is(gte(-1))), __.filter(__.out().limit(0).count().is(gte(-1)))},
-                {__.filter(__.out().count().is(gte(0))), __.filter(__.out().limit(0).count().is(gte(0)))},
-                {__.filter(__.out().count().is(lt(-1))), __.filter(__.out().limit(0).count().is(lt(-1)))},
-                {__.filter(__.out().count().is(lt(0))), __.filter(__.out().limit(0).count().is(lt(0)))},
-                {__.filter(__.out().count().is(lt(2))), __.filter(__.out().limit(2).count().is(lt(2)))},
-                {__.filter(__.out().count().is(lte(-1))), __.filter(__.out().limit(0).count().is(lte(-1)))},
-                {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
-                {__.filter(__.out().count().is(eq(-1))), __.filter(__.out().limit(0).count().is(eq(-1)))},
-                {__.filter(__.out().count().is(neq(-1))), __.filter(__.out().limit(0).count().is(neq(-1)))},
-                {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
-                {__.filter(__.out().count().is(lt(-3).and(gt(0)))), __.filter(__.out().limit(1).count().is(lt(-3).and(gt(0))))},
-                {__.filter(__.out().count().is(lt(1).and(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).and(gt(-5))))},
-                {__.filter(__.out().count().is(gt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).and(lt(1))))},
-                {__.filter(__.out().count().is(gt(-5).and(gt(7)))), __.filter(__.out().limit(8).count().is(gt(-5).and(gt(7))))},
-                {__.filter(__.out().count().is(lt(1).or(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).or(gt(-5))))},
-                {__.filter(__.out().count().is(lt(1).or(gt(3)))), __.filter(__.out().limit(4).count().is(lt(1).or(gt(3))))},
-                {__.filter(__.out().count().is(gt(3).or(lt(-51)))), __.filter(__.out().limit(4).count().is(gt(3).or(lt(-51))))},
-                {__.filter(__.out().count().is(gt(-5).or(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).or(lt(1))))},
-                {__.filter(__.out().count().is(lt(10).and(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).and(gt(1))))},
-                {__.filter(__.out().count().is(gt(1).and(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).and(lt(10))))},
-                {__.filter(__.out().count().is(lt(10).or(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).or(gt(1))))},
-                {__.filter(__.out().count().is(gt(1).or(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).or(lt(10))))},
-                {__.filter(__.out().count().is(lt(5).and(gt(10)))), __.filter(__.out().limit(11).count().is(lt(5).and(gt(10))))},
-                {__.filter(__.out().count().is(gt(10).and(lt(5)))), __.filter(__.out().limit(11).count().is(gt(10).and(lt(5))))},
-                {__.filter(__.out().count().is(lt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(lt(-5).and(lt(1))))},
-                {__.filter(__.out().count().is(lt(-5).and(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).and(lt(-1))))},
-                {__.filter(__.out().count().is(lt(-5).or(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).or(lt(-1))))},
-                {__.where(__.in("knows").count().is(inside(-1,1).and(lt(-1)))), __.where(__.in("knows").limit(1).count().is(inside(-1,1).and(lt(-1))))}, // TINKERPOP-2893
-                {__.where(__.inV().count().is(outside(-1,-2))), __.where(__.inV().limit(0).count().is(outside(-1,-2)))}, // TINKERPOP-2892
-                {__.filter(__.bothE().count().is(gt(0))), __.filter(__.bothE())},
-                {__.filter(__.bothE().count().is(gte(1))), __.filter(__.bothE())},
-                {__.filter(__.bothE().count().is(gt(1))), __.filter(__.bothE().limit(2).count().is(gt(1)))},
-                {__.filter(__.bothE().count().is(gte(2))), __.filter(__.bothE().limit(2).count().is(gte(2)))},
-                {__.and(__.out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out()), __.not(__.in()))},
-                {__.and(__.out().count().is(0), __.in().count().is(1)), __.and(__.not(__.out()), __.in().limit(2).count().is(1))},
-                {__.and(__.out().count().is(1), __.in().count().is(0)), __.and(__.out().limit(2).count().is(1), __.not(__.in()))},
-                {__.and(__.out().out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out().out()), __.not(__.in()))},
-                {__.or(__.out().count().is(0), __.in().count().is(0)), __.or(__.not(__.out()), __.not(__.in()))},
-                {__.path().filter(__.count().is(gte(0.5))).limit(5), __.path().identity().limit(5)}, // unfortunately we can't just remove the filter step
-                {__.path().filter(__.unfold().count().is(gte(0.5))), __.path().filter(__.unfold())},
-                {__.path().filter(__.unfold().count().is(gte(1.5))), __.path().filter(__.unfold().limit(2).count().is(gte(1.5)))},
-        });
-    }
-
-        void applyCountStrategy(final Traversal traversal) {
-            final TraversalStrategies strategies = new DefaultTraversalStrategies();
-            strategies.addStrategies(CountStrategy.instance());
-            traversal.asAdmin().setStrategies(strategies);
-            traversal.asAdmin().applyStrategies();
+            return Arrays.asList(new Traversal[][]{
+                    {__.count().is(0), __.limit(1).count().is(0)},
+                    {__.count().is(1), __.limit(2).count().is(1)},
+                    {__.count().is(-1), __.limit(0).count().is(-1)}, // -1 for RangeGlobalStep means no upper limit
+                    {__.count().is(-2), __.limit(0).count().is(-2)},
+                    {__.count().is(-2023), __.limit(0).count().is(-2023)},
+                    {__.count().is(P.between(0, 10)), __.limit(10).count().is(P.between(0, 10))},
+                    {__.count().is(P.between(5, 10)), __.limit(10).count().is(P.between(5, 10))},
+                    {__.count().is(P.gt(10).or(lt(5))), __.limit(11).count().is(P.gt(10).or(lt(5)))},
+                    {__.out().count().is(0), __.out().limit(1).count().is(0)},
+                    {__.outE().count().is(lt(1)), __.outE().limit(1).count().is(lt(1))},
+                    {__.both().count().is(lte(0)), __.both().limit(1).count().is(lte(0))},
+                    {__.map(__.out().count().is(0)), __.map(__.out().limit(1).count().is(0))},
+                    {__.map(__.outE().count().is(lt(1))), __.map(__.outE().limit(1).count().is(lt(1)))},
+                    {__.map(__.both().count().is(lte(0))), __.map(__.both().limit(1).count().is(lte(0)))},
+                    {__.filter(__.out().count().is(0)), __.not(__.out())},
+                    {__.filter(__.outE().count().is(lt(1))), __.not(__.outE())},
+                    {__.filter(__.both().count().is(lte(0))), __.not(__.both())},
+                    {__.filter(__.out().out().count().is(0)), __.not(__.out().out())},
+                    {__.store("x").count().is(0).as("a"), __.store("x").limit(1).count().is(0).as("a")},
+                    {__.out().count().as("a").is(0), __.out().limit(1).count().as("a").is(0)},
+                    {__.out().count().is(neq(4)), __.out().limit(5).count().is(neq(4))},
+                    {__.out().count().is(lte(3)), __.out().limit(4).count().is(lte(3))},
+                    {__.out().count().is(lt(3)), __.out().limit(3).count().is(lt(3))},
+                    {__.out().count().is(gt(2)), __.out().limit(3).count().is(gt(2))},
+                    {__.out().count().is(gte(2)), __.out().limit(2).count().is(gte(2))},
+                    {__.out().count().is(inside(2, 4)), __.out().limit(4).count().is(inside(2, 4))},
+                    {__.out().count().is(outside(2, 4)), __.out().limit(5).count().is(outside(2, 4))},
+                    {__.out().count().is(within(2, 6, 4)), __.out().limit(7).count().is(within(2, 6, 4))},
+                    {__.out().count().is(without(2, 6, 4)), __.out().limit(6).count().is(without(2, 6, 4))},
+                    {__.map(__.count().is(0)), __.map(__.limit(1).count().is(0))},
+                    {__.flatMap(__.count().is(0)), __.flatMap(__.limit(1).count().is(0))},
+                    {__.flatMap(__.count().is(0)).as("a"), __.flatMap(__.count().is(0)).as("a")}, // no change
+                    {__.filter(__.count().is(0)).as("a"), __.not(__.identity()).as("a")},
+                    {__.filter(__.count().is(0)), __.not(__.identity())},
+                    {__.sideEffect(__.count().is(0)), __.sideEffect(__.not(__.identity()))},
+                    {__.branch(__.count().is(0)), __.branch(__.limit(1).count().is(0))},
+                    {__.count().is(0).store("x"), __.limit(1).count().is(0).store("x")},
+                    {__.repeat(__.out()).until(__.outE().count().is(0)), __.repeat(__.out()).until(__.not(__.outE()))},
+                    {__.repeat(__.out()).until(__.out().out().values("name").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.values("name")))},
+                    {__.repeat(__.out()).until(__.out().out().properties("age").has("x").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.properties("age").has("x")))},
+                    {__.repeat(__.out()).emit(__.outE().count().is(0)), __.repeat(__.out()).emit(__.not(__.outE()))},
+                    {__.where(__.outE().hasLabel("created").count().is(0)), __.not(__.outE().hasLabel("created"))},
+                    {__.where(__.out().outE().hasLabel("created").count().is(0)), __.not(__.out().outE().hasLabel("created"))},
+                    {__.where(__.out().outE().hasLabel("created").count().is(0).store("x")), __.where(__.out().outE().hasLabel("created").limit(1).count().is(0).store("x"))},
+                    {__.where(__.or(__.out("none").out().count().is(0), __.has("none"))), __.where(__.or(__.not(__.out("none").out()), __.has("none"))) },
+                    {__.where(__.or(__.out("none").out().count().is(0), __.has("none").count().is(0))), __.where(__.or(__.not(__.out("none").out()), __.not(__.has("none")))) },
+                    {__.where(__.or(__.out("none").out(), __.has("none").count().is(0))), __.where(__.or(__.out("none").out(), __.not(__.has("none")))) },
+                    {__.filter(__.out().count().is(gt(-1))), __.filter(__.out().limit(0).count().is(gt(-1)))},
+                    {__.filter(__.out().count().is(gte(-1))), __.filter(__.out().limit(0).count().is(gte(-1)))},
+                    {__.filter(__.out().count().is(gte(0))), __.filter(__.out().limit(0).count().is(gte(0)))},
+                    {__.filter(__.out().count().is(lt(-1))), __.filter(__.out().limit(0).count().is(lt(-1)))},
+                    {__.filter(__.out().count().is(lt(0))), __.filter(__.out().limit(0).count().is(lt(0)))},
+                    {__.filter(__.out().count().is(lt(2))), __.filter(__.out().limit(2).count().is(lt(2)))},
+                    {__.filter(__.out().count().is(lte(-1))), __.filter(__.out().limit(0).count().is(lte(-1)))},
+                    {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
+                    {__.filter(__.out().count().is(eq(-1))), __.filter(__.out().limit(0).count().is(eq(-1)))},
+                    {__.filter(__.out().count().is(neq(-1))), __.filter(__.out().limit(0).count().is(neq(-1)))},
+                    {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
+                    {__.filter(__.out().count().is(lt(-3).and(gt(0)))), __.filter(__.out().limit(1).count().is(lt(-3).and(gt(0))))},
+                    {__.filter(__.out().count().is(lt(1).and(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).and(gt(-5))))},
+                    {__.filter(__.out().count().is(gt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).and(lt(1))))},
+                    {__.filter(__.out().count().is(gt(-5).and(gt(7)))), __.filter(__.out().limit(8).count().is(gt(-5).and(gt(7))))},
+                    {__.filter(__.out().count().is(lt(1).or(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).or(gt(-5))))},
+                    {__.filter(__.out().count().is(lt(1).or(gt(3)))), __.filter(__.out().limit(4).count().is(lt(1).or(gt(3))))},
+                    {__.filter(__.out().count().is(gt(3).or(lt(-51)))), __.filter(__.out().limit(4).count().is(gt(3).or(lt(-51))))},
+                    {__.filter(__.out().count().is(gt(-5).or(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).or(lt(1))))},
+                    {__.filter(__.out().count().is(lt(10).and(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).and(gt(1))))},
+                    {__.filter(__.out().count().is(gt(1).and(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).and(lt(10))))},
+                    {__.filter(__.out().count().is(lt(10).or(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).or(gt(1))))},
+                    {__.filter(__.out().count().is(gt(1).or(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).or(lt(10))))},
+                    {__.filter(__.out().count().is(lt(5).and(gt(10)))), __.filter(__.out().limit(11).count().is(lt(5).and(gt(10))))},
+                    {__.filter(__.out().count().is(gt(10).and(lt(5)))), __.filter(__.out().limit(11).count().is(gt(10).and(lt(5))))},
+                    {__.filter(__.out().count().is(lt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(lt(-5).and(lt(1))))},
+                    {__.filter(__.out().count().is(lt(-5).and(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).and(lt(-1))))},
+                    {__.filter(__.out().count().is(lt(-5).or(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).or(lt(-1))))},
+                    {__.where(__.in("knows").count().is(inside(-1,1).and(lt(-1)))), __.where(__.in("knows").limit(1).count().is(inside(-1,1).and(lt(-1))))}, // TINKERPOP-2893
+                    {__.where(__.inV().count().is(outside(-1,-2))), __.where(__.inV().limit(0).count().is(outside(-1,-2)))}, // TINKERPOP-2892
+                    {__.filter(__.bothE().count().is(gt(0))), __.filter(__.bothE())},
+                    {__.filter(__.bothE().count().is(gte(1))), __.filter(__.bothE())},
+                    {__.filter(__.bothE().count().is(gt(1))), __.filter(__.bothE().limit(2).count().is(gt(1)))},
+                    {__.filter(__.bothE().count().is(gte(2))), __.filter(__.bothE().limit(2).count().is(gte(2)))},
+                    {__.and(__.out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out()), __.not(__.in()))},
+                    {__.and(__.out().count().is(0), __.in().count().is(1)), __.and(__.not(__.out()), __.in().limit(2).count().is(1))},
+                    {__.and(__.out().count().is(1), __.in().count().is(0)), __.and(__.out().limit(2).count().is(1), __.not(__.in()))},
+                    {__.and(__.out().out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out().out()), __.not(__.in()))},
+                    {__.or(__.out().count().is(0), __.in().count().is(0)), __.or(__.not(__.out()), __.not(__.in()))},
+                    {__.path().filter(__.count().is(gte(0.5))).limit(5), __.path().identity().limit(5)}, // unfortunately we can't just remove the filter step
+                    {__.path().filter(__.unfold().count().is(gte(0.5))), __.path().filter(__.unfold())},
+                    {__.path().filter(__.unfold().count().is(gte(1.5))), __.path().filter(__.unfold().limit(2).count().is(gte(1.5)))},
+            });
         }
 
         @Test
         public void doTest() {
             final String repr = translator.translate(original.getBytecode()).getScript();
-            applyCountStrategy(original);
+            GValueManagerVerifier.verify(original.asAdmin(), CountStrategy.instance())
+                    .afterApplying()
+                    .managerIsEmpty();
             assertEquals(repr, optimized, original);
-
-            assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
         }
     }
 
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
index 244c1bfd3f..f4415b42eb 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
@@ -124,7 +124,7 @@ public class EarlyLimitStrategyTest {
             this.original.asAdmin().applyStrategies();
             assertEquals(repr, this.optimized, this.original);
 
-            assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
+            assertThat(original.asAdmin().getGValueManager().hasVariables(), is(true));
         }
     }
 
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
index 47cc08d444..6329122414 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
@@ -57,6 +57,8 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.or;
 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.__.properties;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -228,13 +230,9 @@ public class FilterRankingStrategyTest {
         @Test
         public void doTest() {
             final String repr = translator.translate(original.getBytecode()).getScript();
-            final TraversalStrategies strategies = new DefaultTraversalStrategies();
-            strategies.addStrategies(FilterRankingStrategy.instance());
-            for (final TraversalStrategy strategy : this.otherStrategies) {
-                strategies.addStrategies(strategy);
-            }
-            this.original.asAdmin().setStrategies(strategies);
-            this.original.asAdmin().applyStrategies();
+            GValueManagerVerifier.verify(original.asAdmin(), FilterRankingStrategy.instance(), otherStrategies)
+                    .afterApplying()
+                    .managerIsEmpty();
             assertEquals(repr, this.optimized, this.original);
         }
     }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index c0ead528bb..d18d97e8c8 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -20,10 +20,9 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
 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.strategy.GValueManagerVerifier;
 import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator;
-import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -72,15 +71,9 @@ public class IdentityRemovalStrategyTest {
     @Test
     public void doTest() {
         final String repr = translator.translate(original.getBytecode()).getScript();
-        applyIdentityRemovalStrategy(original);
+        GValueManagerVerifier.verify(original.asAdmin(), IdentityRemovalStrategy.instance())
+                .afterApplying()
+                .managerIsEmpty();
         assertEquals(repr, optimized, original);
     }
-
-    private void applyIdentityRemovalStrategy(final Traversal traversal) {
-        final TraversalStrategies strategies = new DefaultTraversalStrategies();
-        strategies.addStrategies(IdentityRemovalStrategy.instance());
-        traversal.asAdmin().setStrategies(strategies);
-        traversal.asAdmin().applyStrategies();
-
-    }
 }