Merge branch 'TINKERPOP-1874' into TINKERPOP-1874-master
Conflicts:
docs/src/dev/io/graphson.asciidoc
gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyHasTest.groovy
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7eaaa25d
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7eaaa25d
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7eaaa25d
Branch: refs/heads/master
Commit: 7eaaa25d28955695a71d48814f818649927c0264
Parents: 3126c44 1c33340
Author: Stephen Mallette <[email protected]>
Authored: Fri Jan 19 09:18:16 2018 -0500
Committer: Stephen Mallette <[email protected]>
Committed: Fri Jan 19 09:18:16 2018 -0500
----------------------------------------------------------------------
docs/src/dev/io/graphson.asciidoc | 53 ++++++++++++++++-
.../GraphSONMapperPartialEmbeddedTypeTest.java | 28 +++++++++
gremlin-dotnet/glv/P.template | 7 ++-
.../src/Gremlin.Net/Process/Traversal/P.cs | 6 +-
gremlin-test/features/filter/Has.feature | 44 ++++++++++++++
.../process/traversal/step/filter/HasTest.java | 60 ++++++++++++++++++++
6 files changed, 191 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7eaaa25d/docs/src/dev/io/graphson.asciidoc
----------------------------------------------------------------------
diff --cc docs/src/dev/io/graphson.asciidoc
index 0ae37fd,37af4ed..097a18b
--- a/docs/src/dev/io/graphson.asciidoc
+++ b/docs/src/dev/io/graphson.asciidoc
@@@ -99,132 -81,21 +99,134 @@@ file.withWriter { writer -
result(Arrays.asList(graph.vertices().next())).create()
writer.write(toJson(msg, "Standard Result", "The following
`ResponseMessage` is a typical example of the typical successful response
Gremlin Server will return when returning results from a script."))
+}
+
+mapper = GraphSONMapper.build().
+ addRegistry(TinkerIoRegistryV2d0.instance()).
+ typeInfo(TypeInfo.PARTIAL_TYPES).
+
addCustomModule(GraphSONXModuleV2d0.build().create(false)).
+ addCustomModule(new
org.apache.tinkerpop.gremlin.driver.ser.AbstractGraphSONMessageSerializerV2d0.GremlinServerModule()).
+ version(GraphSONVersion.V2_0).create().createMapper()
+
+file = new File("io-output/out-graphson-2d0-partial.txt")
+file.withWriter { writer ->
+
+ writer.write("=== Core\n\n")
+ writer.write(toJson(File, "Class", "", "v2d0-partial"))
+ writer.write(toJson(new Date(1481750076295L), "Date", "", "v2d0-partial"))
+ writer.write(toJson(100.00d, "Double", "", "v2d0-partial"))
+ writer.write(toJson(100.00f, "Float", "", "v2d0-partial"))
+ writer.write(toJson(100, "Integer", "", "v2d0-partial"))
+ writer.write(toJson(100L, "Long", "", "v2d0-partial"))
+ writer.write(toJson(new java.sql.Timestamp(1481750076295L), "Timestamp",
"", "v2d0-partial"))
+
writer.write(toJson(UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786"),
"UUID", "", "v2d0-partial"))
+
+ writer.write("\n")
+ writer.write("=== Graph Structure\n\n")
+ writer.write(toJson(graph.edges().next(), "Edge", "", "v2d0-partial"))
+ writer.write(toJson(g.V().out().out().path().next(), "Path", "",
"v2d0-partial"))
+ writer.write(toJson(graph.edges().next().properties().next(), "Property",
"", "v2d0-partial"))
+ writer.write(toJson(new
org.apache.tinkerpop.gremlin.structure.util.star.DirectionalStarGraph(org.apache.tinkerpop.gremlin.structure.util.star.StarGraph.of(graph.vertices().next()),
Direction.BOTH), "StarGraph", "", "v2d0-partial"))
+ writer.write(toJson(graph, "TinkerGraph", "`TinkerGraph` has a custom
serializer that is registered as part of the `TinkerIoRegistry`.",
"v2d0-partial"))
+ writer.write(toJson(g.V().out().out().tree().next(), "Tree", "",
"v2d0-partial"))
+ writer.write(toJson(graph.vertices().next(), "Vertex", "", "v2d0-partial"))
+ writer.write(toJson(graph.vertices().next().properties().next(),
"VertexProperty", "", "v2d0-partial"))
+
+ writer.write("\n")
+ writer.write("=== Graph Process\n\n")
+ writer.write(toJson(SackFunctions.Barrier.normSack, "Barrier", "",
"v2d0-partial"))
+ writer.write(toJson(new Bytecode.Binding("x", 1), "Binding", "A \"Binding\"
refers to a `Bytecode.Binding`.", "v2d0-partial"))
+ writer.write(toJson(g.V().hasLabel('person').out().in().tree(), "Bytecode",
"The following `Bytecode` example represents the traversal of
`g.V().hasLabel('person').out().in().tree()`. Obviously the serialized
`Bytecode` would be quite different for the endless variations of commands that
could be used together in the Gremlin language.", "v2d0-partial"))
+ writer.write(toJson(VertexProperty.Cardinality.list, "Cardinality", "",
"v2d0-partial"))
+ writer.write(toJson(Column.keys, "Column", "", "v2d0-partial"))
+ writer.write(toJson(Direction.OUT, "Direction", "", "v2d0-partial"))
+ writer.write(toJson(Operator.sum, "Operator", "", "v2d0-partial"))
+ writer.write(toJson(Order.incr, "Order", "", "v2d0-partial"))
+
writer.write(toJson(org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick.any,
"Pick", "", "v2d0-partial"))
+ writer.write(toJson(Pop.all, "Pop", "", "v2d0-partial"))
+
writer.write(toJson(org.apache.tinkerpop.gremlin.util.function.Lambda.function("{
it.get() }"), "Lambda", "", "v2d0-partial"))
+ tm = g.V().hasLabel('person').out().out().tree().profile().next()
+ metrics = new
org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(0));
+ metrics.addNested(new
org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(1)));
+ writer.write(toJson(metrics, "Metrics", "", "v2d0-partial"))
+ writer.write(toJson(P.gt(0), "P", "", "v2d0-partial"))
++ writer.write(toJson(P.within(1), "P within", "v2d0-partial"))
++ writer.write(toJson(P.without(1,2), "P without", "v2d0-partial"))
+ writer.write(toJson(P.gt(0).and(P.lt(10)), "P and", "", "v2d0-partial"))
+ writer.write(toJson(P.gt(0).or(P.within(-1, -10, -100)), "P or", "",
"v2d0-partial"))
+ writer.write(toJson(Scope.local, "Scope", "", "v2d0-partial"))
+ writer.write(toJson(T.label, "T", "", "v2d0-partial"))
+
writer.write(toJson(g.V().hasLabel('person').out().out().tree().profile().next(),
"TraversalMetrics", "", "v2d0-partial"))
+ writer.write(toJson(g.V().hasLabel('person').nextTraverser(), "Traverser",
"", "v2d0-partial"))
+
+ writer.write("\n")
+ writer.write("=== RequestMessage\n\n")
+ msg = RequestMessage.build("authentication").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("saslMechanism", "PLAIN", "sasl",
"AHN0ZXBocGhlbgBwYXNzd29yZA==").create()
+ writer.write(toJson(msg, "Authentication Response", "The following
`RequestMessage` is an example of the response that should be made to a
SASL-based authentication challenge.", "v2d0-partial"))
+ msg = RequestMessage.build("eval").processor("session").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("gremlin", "g.V(x)", "bindings", [x: 1], "language",
"gremlin-groovy", "session",
UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).create()
+ writer.write(toJson(msg, "Session Eval", "The following `RequestMessage` is
an example of a simple session request for a script evaluation with
parameters.", "v2d0-partial"))
+ msg = RequestMessage.build("eval").processor("session").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("gremlin", "social.V(x)", "bindings", [x: 1], "language",
"gremlin-groovy", "aliases", [g: "social"], "session",
UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).create()
+ writer.write(toJson(msg, "Session Eval Aliased", "The following
`RequestMessage` is an example of a session request for a script evaluation
with an alias that binds the `TraversalSource` of \"g\" to \"social\".",
"v2d0-partial"))
+ msg = RequestMessage.build("close").processor("session").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("session",
UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).create()
+ writer.write(toJson(msg, "Session Close", "The following `RequestMessage`
is an example of a request to close a session.", "v2d0-partial"))
+ msg = RequestMessage.build("eval").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("gremlin", "g.V(x)", "bindings", [x: 1], "language",
"gremlin-groovy").create()
+ writer.write(toJson(msg, "Sessionless Eval", "The following
`RequestMessage` is an example of a simple sessionless request for a script
evaluation with parameters.", "v2d0-partial"))
+ msg = RequestMessage.build("eval").
+
overrideRequestId(UUID.fromString("cb682578-9d92-4499-9ebc-5c6aa73c5397")).
+ add("gremlin", "social.V(x)", "bindings", [x: 1], "language",
"gremlin-groovy", "aliases", [g: "social"]).create()
+ writer.write(toJson(msg, "Sessionless Eval Aliased", "The following
`RequestMessage` is an example of a sessionless request for a script evaluation
with an alias that binds the `TraversalSource` of \"g\" to \"social\".",
"v2d0-partial"))
+
+ writer.write("\n")
+ writer.write("=== ResponseMessage\n\n")
+ msg =
ResponseMessage.build(UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).
+
code(org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode.AUTHENTICATE).create()
+ writer.write(toJson(msg, "Authentication Challenge", "When authentication
is enabled, an initial request to the server will result in an authentication
challenge. The typical response message will appear as follows, but handling it
could be different dependending on the SASL implementation (e.g. multiple
challenges maybe requested in some cases, but no in the default provided by
Gremlin Server).", "v2d0-partial"))
+ msg =
ResponseMessage.build(UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).
+
code(org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode.SUCCESS).
+
result(Arrays.asList(graph.vertices().next())).create()
+ writer.write(toJson(msg, "Standard Result", "The following
`ResponseMessage` is a typical example of the typical successful response
Gremlin Server will return when returning results from a script.",
"v2d0-partial"))
+
writer.write("\n")
- writer.write("=== Time\n\n")
- writer.write(toJson(Duration.ofDays(5), "Duration", "The following example
is a `Duration` of five days."))
- writer.write(toJson(Instant.now(), "Instant"))
- writer.write(toJson(LocalDate.of(2016, 1, 1), "LocalDate"))
- writer.write(toJson(LocalDateTime.of(2016, 1, 1, 12, 30), "LocalDateTime"))
- writer.write(toJson(LocalTime.of(12, 30, 45), "LocalTime"))
- writer.write(toJson(MonthDay.of(1, 1), "MonthDay"))
- writer.write(toJson(OffsetDateTime.now(), "OffsetDateTime"))
- writer.write(toJson(OffsetTime.now(), "OffsetTime"))
- writer.write(toJson(Period.of(1, 6, 15), "Period", "The following example
is a `Period` of one year, six months and fifteen days."))
- writer.write(toJson(Year.of(2016), "Year", "The following example is of the
`Year` \"2016\"."))
- writer.write(toJson(YearMonth.of(2016, 6), "YearMonth", "The following
example is a `YearMonth` of \"June 2016\""))
- writer.write(toJson(ZonedDateTime.now(), "ZonedDateTime"))
- writer.write(toJson(ZoneOffset.ofHoursMinutesSeconds(3, 6, 9),
"ZoneOffset", "The following example is a `ZoneOffset` of three hours, six
minutes, and nine seconds."))
+ writer.write("=== Extended\n\n")
+ writer.write("""Note that the "extended" types require the addition of the
separate `GraphSONXModuleV2d0` module as follows:\n
+[source,java]
+----
+mapper = GraphSONMapper.build().
+ typeInfo(TypeInfo.PARTIAL_TYPES).
+
addCustomModule(GraphSONXModuleV2d0.build().create(false)).
+ version(GraphSONVersion.V2_0).create().createMapper()
+----\n
+""")
+ writer.write(toJson(new java.math.BigDecimal(new
java.math.BigInteger("123456789987654321123456789987654321")), "BigDecimal",
"", "v2d0-partial"))
+ writer.write(toJson(new
java.math.BigInteger("123456789987654321123456789987654321"), "BigInteger", "",
"v2d0-partial"))
+ writer.write(toJson(new Byte("1"), "Byte", "", "v2d0-partial"))
+ writer.write(toJson(java.nio.ByteBuffer.wrap("some bytes for
you".getBytes()), "ByteBuffer", "", "v2d0-partial"))
+ writer.write(toJson("x".charAt(0), "Char", "", "v2d0-partial"))
+ writer.write(toJson(Duration.ofDays(5), "Duration", "The following example
is a `Duration` of five days.", "v2d0-partial"))
+ writer.write(toJson(java.net.InetAddress.getByName("localhost"),
"InetAddress", "", "v2d0-partial"))
+ writer.write(toJson(Instant.parse("2016-12-14T16:39:19.349Z"), "Instant",
"", "v2d0-partial"))
+ writer.write(toJson(LocalDate.of(2016, 1, 1), "LocalDate", "",
"v2d0-partial"))
+ writer.write(toJson(LocalDateTime.of(2016, 1, 1, 12, 30), "LocalDateTime",
"", "v2d0-partial"))
+ writer.write(toJson(LocalTime.of(12, 30, 45), "LocalTime", "",
"v2d0-partial"))
+ writer.write(toJson(MonthDay.of(1, 1), "MonthDay", "", "v2d0-partial"))
+ writer.write(toJson(OffsetDateTime.parse("2007-12-03T10:15:30+01:00"),
"OffsetDateTime", "", "v2d0-partial"))
+ writer.write(toJson(OffsetTime.parse("10:15:30+01:00"), "OffsetTime", "",
"v2d0-partial"))
+ writer.write(toJson(Period.of(1, 6, 15), "Period", "The following example
is a `Period` of one year, six months and fifteen days.", "v2d0-partial"))
+ writer.write(toJson(new Short("100"), "Short", "", "v2d0-partial"))
+ writer.write(toJson(Year.of(2016), "Year", "The following example is of the
`Year` \"2016\".", "v2d0-partial"))
+ writer.write(toJson(YearMonth.of(2016, 6), "YearMonth", "The following
example is a `YearMonth` of \"June 2016\"", "v2d0-partial"))
+ writer.write(toJson(ZonedDateTime.of(2016, 12, 23, 12, 12, 24, 36,
ZoneId.of("GMT+2")), "ZonedDateTime", "", "v2d0-partial"))
+ writer.write(toJson(ZoneOffset.ofHoursMinutesSeconds(3, 6, 9),
"ZoneOffset", "The following example is a `ZoneOffset` of three hours, six
minutes, and nine seconds.", "v2d0-partial"))
}
@@@ -274,14 -146,16 +276,16 @@@ file.withWriter { writer -
tm = g.V().hasLabel('person').out().out().tree().profile().next()
metrics = new
org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(0));
metrics.addNested(new
org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(1)));
- writer.write(toJson(metrics, "Metrics"))
- writer.write(toJson(P.gt(0), "P"))
- writer.write(toJson(P.within(1), "P within"))
- writer.write(toJson(P.without(1,2), "P without"))
- writer.write(toJson(P.gt(0).and(P.lt(10)), "P and"))
- writer.write(toJson(P.gt(0).or(P.within(-1, -10, -100)), "P or"))
- writer.write(toJson(Scope.local, "Scope"))
- writer.write(toJson(T.label, "T"))
-
writer.write(toJson(g.V().hasLabel('person').out().out().tree().profile().next(),
"TraversalMetrics"))
- writer.write(toJson(g.V().hasLabel('person').nextTraverser(), "Traverser"))
+ writer.write(toJson(metrics, "Metrics", "", "v2d0-no-types"))
+ writer.write(toJson(P.gt(0), "P", "", "v2d0-no-types"))
++ writer.write(toJson(P.within(1), "P within", "v2d0-no-types"))
++ writer.write(toJson(P.without(1,2), "P without", "v2d0-no-types"))
+ writer.write(toJson(P.gt(0).and(P.lt(10)), "P and", "", "v2d0-no-types"))
+ writer.write(toJson(P.gt(0).or(P.within(-1, -10, -100)), "P or", "",
"v2d0-no-types"))
+ writer.write(toJson(Scope.local, "Scope", "", "v2d0-no-types"))
+ writer.write(toJson(T.label, "T", "", "v2d0-no-types"))
+
writer.write(toJson(g.V().hasLabel('person').out().out().tree().profile().next(),
"TraversalMetrics", "", "v2d0-no-types"))
+ writer.write(toJson(g.V().hasLabel('person').nextTraverser(), "Traverser",
"", "v2d0-no-types"))
writer.write("\n")
writer.write("=== RequestMessage\n\n")
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7eaaa25d/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --cc
gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
index de4cc58,0000000..7935050
mode 100644,000000..100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
@@@ -1,297 -1,0 +1,325 @@@
+/*
+ * 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.structure.io.graphson;
+
+import
org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
++import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0+.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class GraphSONMapperPartialEmbeddedTypeTest extends
AbstractGraphSONTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {"v2", GraphSONMapper.build().version(GraphSONVersion.V2_0)
+
.addCustomModule(GraphSONXModuleV2d0.build().create(false))
+
.typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()},
+ {"v3", GraphSONMapper.build().version(GraphSONVersion.V3_0)
+
.addCustomModule(GraphSONXModuleV3d0.build().create(false))
+
.typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()}
+ });
+ }
+
+ @Parameterized.Parameter(1)
+ public ObjectMapper mapper;
+
+
+ @Parameterized.Parameter(0)
+ public String version;
+
+ @Test
+ public void
shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly()
throws Exception {
+ // Trying to fail the TypeDeserializer type detection
+ final UUID uuid = UUID.randomUUID();
+ final List<Object> myList = new ArrayList<>();
+
+ final List<Object> myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ final Map<String,Object> map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ final Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+ assertEquals(myList, serializeDeserializeAuto(mapper, myList));
+
+ // no "@value" property
+ String s = "{\""+GraphSONTokens.VALUETYPE+"\":\"" +
GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID\", \"test\":2}";
+ Map<String,Object> map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUETYPE,
GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID");
+ map.put("test", 2);
+ Object res = mapper.readValue(s, Object.class);
+ assertEquals(map, res);
+
+ // "@value" and "@type" property reversed
+ s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"" +
GraphSONTokens.VALUETYPE + "\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE +
":Int64\"}";
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, 2L);
+ assertEquals(res.getClass(), Long.class);
+
+ // no "@type" property.
+ s = "{\""+GraphSONTokens.VALUEPROP + "\":2, \"id\":2}";
+ map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUEPROP, 2);
+ map.put("id", 2);
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, map);
+ }
+
+ @Test
+ public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
+ String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" +
GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE
+":Int64\", \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than
properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type
pattern in the JSON payload but the map containing the types and values
contains other fields. This is not allowed by the deserializer."));
+ }
+ s = "{\"" + GraphSONTokens.VALUETYPE +
"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":Int64\",\"" +
GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than
properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type
pattern in the JSON payload but the map containing the types and values
contains other fields. This is not allowed by the deserializer."));
+ }
+ }
+
+ @Test
+ public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
+ final ZoneOffset o = ZonedDateTime.now().getOffset();
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ try {
+ mapper.writeValue(stream, o);
+ final InputStream inputStream = new
ByteArrayInputStream(stream.toByteArray());
+ // What has been serialized is a ZoneOffset with the type, but
the user explicitly requires another type.
+ mapper.readValue(inputStream, Instant.class);
+ fail("Should have failed decoding the value");
+ } catch (Exception e) {
+ assertThat(e.getMessage(), containsString("Could not deserialize
the JSON value as required. Nested exception: java.lang.InstantiationException:
Cannot deserialize the value with the detected type contained in the JSON ('" +
GraphSONTokens.GREMLINX_TYPE_NAMESPACE + ":ZoneOffset') to the type specified
in parameter to the object mapper (class java.time.Instant). Those types are
incompatible."));
+ }
+ }
+
+ @Test
+ public void shouldHandleRawPOJOs() throws Exception {
+ final FunObject funObject = new FunObject();
+ funObject.setVal("test");
+ assertEquals(funObject.toString(), serializeDeserialize(mapper,
funObject, FunObject.class).toString());
+ assertEquals(funObject.getClass(), serializeDeserialize(mapper,
funObject, FunObject.class).getClass());
+ }
+
+ @Test
+ public void shouldHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws
Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.PARTIAL_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100L, read.get("test"));
+ }
+
+ @Test
+ public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws
Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100, read.get("test"));
+ }
+
+ @Test
+ public void shouldHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws
Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V1_0)
+ .typeInfo(TypeInfo.PARTIAL_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100L, read.get("test"));
+ }
+
+ @Test
+ public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws
Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V1_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100, read.get("test"));
+ }
+
+ @Test
+ public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ final UUID uuid = UUID.randomUUID();
+ final List<Object> myList = new ArrayList<>();
+
+ final List<Object> myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ final Map<String,Object> map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ final Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+
+ final String json = mapper.writeValueAsString(myList);
+ final Object read = mapper.readValue(json, Object.class);
+
+ // Not equals because of type loss
+ assertNotEquals(myList, read);
+ }
+
+ @Test
+ public void shouldHandleDefaultRemoteTraverser() throws Exception {
+ final DefaultRemoteTraverser<String> o = new
DefaultRemoteTraverser<>("test", 100);
+ assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));
+ }
+
++ @Test
++ public void shouldHandleVariantsOfP() throws Exception {
++ final List<P> variantsOfP = Arrays.asList(
++ P.between(1,2),
++ P.eq(1),
++ P.gt(1),
++ P.gte(1),
++ P.inside(1,2),
++ P.lt(1),
++ P.lte(1),
++ P.neq(1),
++ P.not(P.eq(1)),
++ P.outside(1,2),
++ P.within(1),
++ P.within(1,2,3,4),
++ P.within(Arrays.asList(1,2,3,4)),
++ P.without(1),
++ P.without(1,2,3,4),
++ P.without(Arrays.asList(1,2,3,4)),
++ P.eq(1).and(P.eq(2)),
++ P.eq(1).or(P.eq(2)));
++
++ for (P p : variantsOfP) {
++ assertEquals(p, serializeDeserialize(mapper, p, P.class));
++ }
++ }
++
+ // Class needs to be defined as statics as it's a nested class.
+ public static class FunObject {
+ private String val;
+
+ public FunObject() {
+ }
+
+ public String getVal() {
+ return this.val;
+ }
+
+ public void setVal(String s) {
+ this.val = s;
+ }
+
+ public String toString() {
+ return this.val;
+ }
+ }
+
+
+}