You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2019/05/02 16:11:04 UTC
[tinkerpop] 01/01: TINKERPOP-2207 Implemented SimpleValueMapStrategy
This is an automated email from the ASF dual-hosted git repository.
dkuppitz pushed a commit to branch TINKERPOP-2207
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 6efb784abbb5744c044a52582c1940478b8ffd01
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Thu May 2 09:10:43 2019 -0700
TINKERPOP-2207 Implemented SimpleValueMapStrategy
---
CHANGELOG.asciidoc | 1 +
docs/src/upgrade/release-3.4.x.asciidoc | 27 +++++
.../tinkerpop/gremlin/jsr223/CoreImports.java | 2 +
.../finalization/SimpleValueMapStrategy.java | 60 ++++++++++
.../structure/io/graphson/GraphSONModule.java | 5 +
.../gremlin/structure/io/gryo/GryoVersion.java | 7 +-
.../finalization/SimpleValueMapStrategyTest.java | 69 +++++++++++
.../gremlin/process/ProcessComputerSuite.java | 6 +-
.../gremlin/process/ProcessStandardSuite.java | 6 +-
.../SimpleValueMapStrategyProcessTest.java | 133 +++++++++++++++++++++
10 files changed, 312 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 2bf08bd..9c9263f 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
This release also includes changes from <<release-3-3-7, 3.3.7>>.
+* Implemented `SimpleValueMapStrategy`.
* Allow a `Traversal` to know what `TraversalSource` it spawned from.
* Fixed problem with connection pool sizing and retry.
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index bb9cf43..914bc34 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -27,6 +27,33 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
Please see the link:https://github.com/apache/tinkerpop/blob/3.4.2/CHANGELOG.asciidoc#release-3-4-2[changelog] for a complete list of all the modifications that are part of this release.
+=== Upgrading for Providers
+
+==== Automatic unfolding of valueMap() values
+
+This release contains a new strategy called `SimpleValueMapStrategy`. The strategy is not added by default, but meant to be added mainly by providers who do not support multi-valued
+properties. The strategy will automatically a `.by(unfold())` modulator to all `valueMap()` steps that don't have a `by()` modulator defined by the user. As a result, `valueMap()` will emit
+maps with single-valued values.
+
+```text
+gremlin> g.V().valueMap()
+==>[name:[marko],age:[29]]
+==>[name:[vadas],age:[27]]
+==>[name:[lop],lang:[java]]
+==>[name:[josh],age:[32]]
+==>[name:[ripple],lang:[java]]
+==>[name:[peter],age:[35]]
+gremlin> g.withStrategies(SimpleValueMapStrategy.instance()).V().valueMap()
+==>[name:marko,age:29]
+==>[name:vadas,age:27]
+==>[name:lop,lang:java]
+==>[name:josh,age:32]
+==>[name:ripple,lang:java]
+==>[name:peter,age:35]
+```
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2207[TINKERPOP-2207],
+
== TinkerPop 3.4.1
*Release Date: March 18, 2019*
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
index cc7881c..23de08a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
@@ -84,6 +84,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.Refe
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.MatchAlgorithmStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ProfileStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.SimpleValueMapStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.AdjacentToIncidentStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -257,6 +258,7 @@ public final class CoreImports {
CLASS_IMPORTS.add(ReferenceElementStrategy.class);
CLASS_IMPORTS.add(StandardVerificationStrategy.class);
CLASS_IMPORTS.add(EdgeLabelVerificationStrategy.class);
+ CLASS_IMPORTS.add(SimpleValueMapStrategy.class);
// graph traversal
CLASS_IMPORTS.add(AnonymousTraversalSource.class);
CLASS_IMPORTS.add(__.class);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategy.java
new file mode 100644
index 0000000..988125e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategy.java
@@ -0,0 +1,60 @@
+/*
+ * 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.finalization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyMapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.structure.PropertyType;
+
+/**
+ * SimpleValueMapStrategy automatically adds a {@code .by(unfold())} to every {@code valueMap()} step that has no
+ * by-modulator specified. This is useful especially for providers who do not support multi-valued properties.
+ *
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class SimpleValueMapStrategy
+ extends AbstractTraversalStrategy<TraversalStrategy.FinalizationStrategy>
+ implements TraversalStrategy.FinalizationStrategy {
+
+ private final static SimpleValueMapStrategy INSTANCE = new SimpleValueMapStrategy();
+
+ private SimpleValueMapStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ if (step instanceof PropertyMapStep) {
+ final PropertyMapStep pms = (PropertyMapStep) step;
+ if (pms.getReturnType() == PropertyType.VALUE && pms.getLocalChildren().isEmpty()) {
+ //noinspection unchecked
+ pms.modulateBy(__.unfold().asAdmin());
+ }
+ }
+ }
+ }
+
+ public static SimpleValueMapStrategy instance() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index 6ad5db7..3b6b8d0 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -43,6 +43,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.Option
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.MatchAlgorithmStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.SimpleValueMapStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.AdjacentToIncidentStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -204,6 +205,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
StandardVerificationStrategy.class,
EarlyLimitStrategy.class,
EdgeLabelVerificationStrategy.class,
+ SimpleValueMapStrategy.class,
//
GraphFilterStrategy.class,
VertexProgramStrategy.class
@@ -328,6 +330,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
StandardVerificationStrategy.class,
EarlyLimitStrategy.class,
EdgeLabelVerificationStrategy.class,
+ SimpleValueMapStrategy.class,
//
GraphFilterStrategy.class,
VertexProgramStrategy.class
@@ -433,6 +436,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
StandardVerificationStrategy.class,
EarlyLimitStrategy.class,
EdgeLabelVerificationStrategy.class,
+ SimpleValueMapStrategy.class,
//
GraphFilterStrategy.class,
VertexProgramStrategy.class
@@ -547,6 +551,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
StandardVerificationStrategy.class,
EarlyLimitStrategy.class,
EdgeLabelVerificationStrategy.class,
+ SimpleValueMapStrategy.class,
//
GraphFilterStrategy.class,
VertexProgramStrategy.class
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
index 73bac27..c13f966 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
@@ -52,6 +52,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.Option
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.MatchAlgorithmStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.SimpleValueMapStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.AdjacentToIncidentStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -354,7 +355,8 @@ public enum GryoVersion {
add(GryoTypeReg.of(EarlyLimitStrategy.class, 188));
add(GryoTypeReg.of(MatchStep.CountMatchAlgorithm.class, 160));
add(GryoTypeReg.of(MatchStep.GreedyMatchAlgorithm.class, 164));
- add(GryoTypeReg.of(EdgeLabelVerificationStrategy.class, 189)); // ***LAST ID***
+ add(GryoTypeReg.of(EdgeLabelVerificationStrategy.class, 189));
+ add(GryoTypeReg.of(SimpleValueMapStrategy.class, 190)); // ***LAST ID***
add(GryoTypeReg.of(TraverserSet.class, 58));
add(GryoTypeReg.of(Tree.class, 61));
@@ -590,7 +592,8 @@ public enum GryoVersion {
add(GryoTypeReg.of(EarlyLimitStrategy.class, 188));
add(GryoTypeReg.of(MatchStep.CountMatchAlgorithm.class, 160));
add(GryoTypeReg.of(MatchStep.GreedyMatchAlgorithm.class, 167));
- add(GryoTypeReg.of(EdgeLabelVerificationStrategy.class, 189)); // ***LAST ID***
+ add(GryoTypeReg.of(EdgeLabelVerificationStrategy.class, 189));
+ add(GryoTypeReg.of(SimpleValueMapStrategy.class, 190)); // ***LAST ID***
// skip 171, 172 to sync with tp33
add(GryoTypeReg.of(IndexedTraverserSet.VertexIndexedTraverserSet.class, 173));
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyTest.java
new file mode 100644
index 0000000..1caf6ae
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.finalization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+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.decoration.ConnectiveStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+@RunWith(Parameterized.class)
+public class SimpleValueMapStrategyTest {
+
+ @Parameterized.Parameter()
+ public Traversal original;
+
+ @Parameterized.Parameter(value = 1)
+ public Traversal changed;
+
+ private void applyStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(SimpleValueMapStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+ }
+
+ @Test
+ public void doTest() {
+ applyStrategy(original);
+ assertEquals(changed, original);
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+ return Arrays.asList(new Traversal[][]{
+ {__.valueMap(), __.valueMap().by(__.unfold())},
+ {__.valueMap("name","age"), __.valueMap("name","age").by(__.unfold())},
+ {__.valueMap().by(__.limit(Scope.local, 1)), __.valueMap().by(__.limit(Scope.local, 1))},
+ {__.valueMap("name","age").by(__.limit(Scope.local, 1)), __.valueMap("name","age").by(__.limit(Scope.local, 1))}
+ });
+ }
+}
\ No newline at end of file
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
index 0951b86..e82e8e2 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
@@ -93,6 +93,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphTe
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TreeTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.SimpleValueMapStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.IncidentToAdjacentStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategyProcessTest;
@@ -214,7 +215,10 @@ public class ProcessComputerSuite extends AbstractGremlinSuite {
// optimizations
IncidentToAdjacentStrategyProcessTest.class,
- EarlyLimitStrategyProcessTest.class
+ EarlyLimitStrategyProcessTest.class,
+
+ // finalization
+ SimpleValueMapStrategyProcessTest.class
};
/**
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
index 6bd6d5b..31d6be7 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
@@ -87,6 +87,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventS
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.SimpleValueMapStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.IncidentToAdjacentStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategyProcessTest;
@@ -195,7 +196,10 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
// optimizations
IncidentToAdjacentStrategyProcessTest.class,
- EarlyLimitStrategyProcessTest.class
+ EarlyLimitStrategyProcessTest.class,
+
+ // finalization
+ SimpleValueMapStrategyProcessTest.class
};
/**
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyProcessTest.java
new file mode 100644
index 0000000..b5c0040
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/SimpleValueMapStrategyProcessTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.finalization;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.WithOptions;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+@RunWith(GremlinProcessRunner.class)
+public class SimpleValueMapStrategyProcessTest extends AbstractGremlinProcessTest {
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void shouldApplyUnfold() throws Exception {
+
+ //
+ // without tokens
+ //
+ GraphTraversal<Vertex, Map<Object, Object>> t = g.withStrategies(SimpleValueMapStrategy.instance())
+ .V().has("person", "name", "marko").valueMap();
+
+ assertTrue(t.hasNext());
+
+ Map<Object, Object> result = t.next();
+
+ assertFalse(t.hasNext());
+ assertEquals(2, result.size());
+ assertTrue(result.containsKey("name"));
+ assertTrue(result.containsKey("age"));
+ assertEquals("marko", result.get("name"));
+ assertEquals(29, result.get("age"));
+
+ //
+ // with tokens
+ //
+ t = g.withStrategies(SimpleValueMapStrategy.instance())
+ .V().has("person", "name", "marko").valueMap().with(WithOptions.tokens);
+
+ assertTrue(t.hasNext());
+
+ result = t.next();
+
+ assertFalse(t.hasNext());
+ assertEquals(4, result.size());
+ assertTrue(result.containsKey(T.id));
+ assertTrue(result.containsKey(T.label));
+ assertTrue(result.containsKey("name"));
+ assertTrue(result.containsKey("age"));
+ assertEquals("person", result.get(T.label));
+ assertEquals("marko", result.get("name"));
+ assertEquals(29, result.get("age"));
+ }
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void shouldNotApplyUnfold() throws Exception {
+
+ final List<String> list = Collections.singletonList("X");
+
+ //
+ // without tokens
+ //
+ GraphTraversal<Vertex, Map<Object, Object>> t = g.withStrategies(SimpleValueMapStrategy.instance())
+ .V().has("person", "name", "marko").valueMap().by(__.constant(list));
+
+ assertTrue(t.hasNext());
+
+ Map<Object, Object> result = t.next();
+
+ assertFalse(t.hasNext());
+ assertEquals(2, result.size());
+ assertTrue(result.containsKey("name"));
+ assertTrue(result.containsKey("age"));
+ assertEquals(list, result.get("name"));
+ assertEquals(list, result.get("age"));
+
+ //
+ // with tokens
+ //
+ t = g.withStrategies(SimpleValueMapStrategy.instance())
+ .V().has("person", "name", "marko").valueMap().with(WithOptions.tokens).by(__.constant(list));
+
+ assertTrue(t.hasNext());
+
+ result = t.next();
+
+ assertFalse(t.hasNext());
+ assertEquals(4, result.size());
+ assertTrue(result.containsKey(T.id));
+ assertTrue(result.containsKey(T.label));
+ assertTrue(result.containsKey("name"));
+ assertTrue(result.containsKey("age"));
+ assertEquals(list, result.get(T.id));
+ assertEquals(list, result.get(T.label));
+ assertEquals(list, result.get("name"));
+ assertEquals(list, result.get("age"));
+ }
+}
\ No newline at end of file