Repository: tinkerpop Updated Branches: refs/heads/TINKERPOP-1552-master 5c3cc5acd -> 8fd4c8cdc
Gremlin .NET: GraphSON3 Deserialization Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6b3fdcb8 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6b3fdcb8 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6b3fdcb8 Branch: refs/heads/TINKERPOP-1552-master Commit: 6b3fdcb8dc076f2d4c8e00f0058ff4aa0c665ce5 Parents: 5c3cc5a Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> Authored: Fri Jul 14 16:53:19 2017 +0200 Committer: Jorge Bay Gondra <jorgebaygon...@gmail.com> Committed: Fri Jul 14 16:53:19 2017 +0200 ---------------------------------------------------------------------- .../src/Gremlin.Net/Driver/ConnectionFactory.cs | 5 +- .../src/Gremlin.Net/Driver/GremlinClient.cs | 2 +- .../Structure/IO/GraphSON/GraphSON2Reader.cs | 50 ++++++ .../Structure/IO/GraphSON/GraphSON3Reader.cs | 66 +++++++ .../Structure/IO/GraphSON/GraphSON3Writer.cs | 57 ++++++ .../Structure/IO/GraphSON/GraphSONReader.cs | 19 +- .../Structure/IO/GraphSON/GraphSONWriter.cs | 17 +- .../Structure/IO/GraphSON/ListSerializer.cs | 54 ++++++ .../Structure/IO/GraphSON/MapSerializer.cs | 52 ++++++ .../Structure/IO/GraphSON/SetSerializer.cs | 48 +++++ .../IO/GraphSON/GraphSONReaderTests.cs | 173 +++++++++++++------ 11 files changed, 473 insertions(+), 70 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs index 0041a67..e3fd068 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs @@ -21,6 +21,7 @@ #endregion +using System; using Gremlin.Net.Structure.IO.GraphSON; namespace Gremlin.Net.Driver @@ -35,8 +36,8 @@ namespace Gremlin.Net.Driver GraphSONWriter graphSONWriter) { _gremlinServer = gremlinServer; - _graphSONReader = graphSONReader; - _graphSONWriter = graphSONWriter; + _graphSONReader = graphSONReader ?? throw new ArgumentNullException(nameof(graphSONReader)); + _graphSONWriter = graphSONWriter ?? throw new ArgumentNullException(nameof(graphSONWriter)); } public Connection CreateConnection() http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs index 46dd8a6..a81c17e 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs @@ -45,7 +45,7 @@ namespace Gremlin.Net.Driver public GremlinClient(GremlinServer gremlinServer, GraphSONReader graphSONReader = null, GraphSONWriter graphSONWriter = null) { - var reader = graphSONReader ?? new GraphSONReader(); + var reader = graphSONReader ?? new GraphSON3Reader(); var writer = graphSONWriter ?? new GraphSONWriter(); var connectionFactory = new ConnectionFactory(gremlinServer, reader, writer); _connectionPool = new ConnectionPool(connectionFactory); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON2Reader.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON2Reader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON2Reader.cs new file mode 100644 index 0000000..90c9e4d --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON2Reader.cs @@ -0,0 +1,50 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Handles deserialization of GraphSON3 data. + /// </summary> + public class GraphSON2Reader : GraphSONReader + { + /// <summary> + /// Creates a new instance of <see cref="GraphSON2Reader"/>. + /// </summary> + public GraphSON2Reader() + { + + } + + /// <summary> + /// Creates a new instance of <see cref="GraphSON2Reader"/>. + /// </summary> + public GraphSON2Reader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType) : + base(deserializerByGraphSONType) + { + + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Reader.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Reader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Reader.cs new file mode 100644 index 0000000..4bc7878 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Reader.cs @@ -0,0 +1,66 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Handles deserialization of GraphSON3 data. + /// </summary> + public class GraphSON3Reader : GraphSONReader + { + private static readonly IDictionary<string, IGraphSONDeserializer> GraphSON3SpecificDeserializers = + new Dictionary<string, IGraphSONDeserializer> + { + { "g:List", new ListSerializer() }, + { "g:Set", new SetSerializer() }, + { "g:Map", new MapSerializer() } + }; + + /// <summary> + /// Creates a new instance of <see cref="GraphSON3Reader"/>. + /// </summary> + public GraphSON3Reader() + { + foreach (var kv in GraphSON3SpecificDeserializers) + { + Deserializers[kv.Key] = kv.Value; + } + } + + /// <summary> + /// Creates a new instance of <see cref="GraphSON3Reader"/>. + /// </summary> + /// <param name="deserializerByGraphSONType"> + /// Overrides <see cref="IGraphSONDeserializer" /> instances by their type identifier. + /// </param> + public GraphSON3Reader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType) : this() + { + foreach (var deserializerAndGraphSONType in deserializerByGraphSONType) + { + Deserializers[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Writer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Writer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Writer.cs new file mode 100644 index 0000000..96c303c --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSON3Writer.cs @@ -0,0 +1,57 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Handles deserialization of GraphSON3 data. + /// </summary> + public class GraphSON3Writer : GraphSONWriter + { + /// <summary> + /// Creates a new instance of <see cref="GraphSON3Writer"/>. + /// </summary> + public GraphSON3Writer() + { + // TODO: Include GraphSON3 specific serializers + } + + /// <summary> + /// Creates a new instance of <see cref="GraphSON3Writer"/>. + /// </summary> + /// <param name="customSerializerByType"> + /// <see cref="IGraphSONSerializer" /> serializers identified by their + /// <see cref="Type" />. + /// </param> + public GraphSON3Writer(IReadOnlyDictionary<Type, IGraphSONSerializer> customSerializerByType) : this() + { + foreach (var serializerAndType in customSerializerByType) + { + Serializers[serializerAndType.Key] = serializerAndType.Value; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs index aa1fc48..ee54a9b 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs @@ -31,9 +31,12 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// <summary> /// Allows to deserialize GraphSON to objects. /// </summary> - public class GraphSONReader + public abstract class GraphSONReader { - private readonly Dictionary<string, IGraphSONDeserializer> _deserializerByGraphSONType = new Dictionary + /// <summary> + /// Contains the <see cref="IGraphSONDeserializer" /> instances by their type identifier. + /// </summary> + protected readonly Dictionary<string, IGraphSONDeserializer> Deserializers = new Dictionary <string, IGraphSONDeserializer> { {"g:Traverser", new TraverserReader()}, @@ -54,7 +57,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// <summary> /// Initializes a new instance of the <see cref="GraphSONReader" /> class. /// </summary> - public GraphSONReader() + protected GraphSONReader() { } @@ -65,10 +68,10 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// <see cref="IGraphSONDeserializer" /> deserializers identified by their /// GraphSON type. /// </param> - public GraphSONReader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType) + protected GraphSONReader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType) { foreach (var deserializerAndGraphSONType in deserializerByGraphSONType) - _deserializerByGraphSONType[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value; + Deserializers[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value; } /// <summary> @@ -76,7 +79,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// </summary> /// <param name="graphSonData">The GraphSON collection to deserialize.</param> /// <returns>The deserialized object.</returns> - public dynamic ToObject(IEnumerable<JToken> graphSonData) + public virtual dynamic ToObject(IEnumerable<JToken> graphSonData) { return graphSonData.Select(graphson => ToObject(graphson)); } @@ -86,7 +89,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// </summary> /// <param name="jToken">The GraphSON to deserialize.</param> /// <returns>The deserialized object.</returns> - public dynamic ToObject(JToken jToken) + public virtual dynamic ToObject(JToken jToken) { if (jToken is JArray) return jToken.Select(t => ToObject(t)); @@ -104,7 +107,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON private dynamic ReadTypedValue(JToken typedValue) { var graphSONType = (string) typedValue[GraphSONTokens.TypeKey]; - return _deserializerByGraphSONType[graphSONType].Objectify(typedValue[GraphSONTokens.ValueKey], this); + return Deserializers[graphSONType].Objectify(typedValue[GraphSONTokens.ValueKey], this); } private dynamic ReadDictionary(JToken jtokenDict) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs index ba632b1..db0ae7d 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs @@ -38,7 +38,10 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// </summary> public class GraphSONWriter { - private readonly Dictionary<Type, IGraphSONSerializer> _serializerByType = new Dictionary + /// <summary> + /// Contains the information of serializers by type. + /// </summary> + protected readonly Dictionary<Type, IGraphSONSerializer> Serializers = new Dictionary <Type, IGraphSONSerializer> { {typeof(ITraversal), new TraversalSerializer()}, @@ -77,7 +80,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON public GraphSONWriter(IReadOnlyDictionary<Type, IGraphSONSerializer> customSerializerByType) { foreach (var serializerAndType in customSerializerByType) - _serializerByType[serializerAndType.Key] = serializerAndType.Value; + Serializers[serializerAndType.Key] = serializerAndType.Value; } /// <summary> @@ -85,7 +88,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON /// </summary> /// <param name="objectData">The object to serialize.</param> /// <returns>The serialized GraphSON.</returns> - public string WriteObject(dynamic objectData) + public virtual string WriteObject(dynamic objectData) { return JsonConvert.SerializeObject(ToDict(objectData)); } @@ -104,15 +107,15 @@ namespace Gremlin.Net.Structure.IO.GraphSON private bool TryGetSerializerFor(out IGraphSONSerializer serializer, Type type) { - if (_serializerByType.ContainsKey(type)) + if (Serializers.ContainsKey(type)) { - serializer = _serializerByType[type]; + serializer = Serializers[type]; return true; } - foreach (var supportedType in _serializerByType.Keys) + foreach (var supportedType in Serializers.Keys) if (supportedType.IsAssignableFrom(type)) { - serializer = _serializerByType[supportedType]; + serializer = Serializers[supportedType]; return true; } serializer = null; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs new file mode 100644 index 0000000..f738ac8 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs @@ -0,0 +1,54 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class ListSerializer : IGraphSONDeserializer, IGraphSONSerializer + { + private static readonly IReadOnlyList<object> EmptyList = new object[0]; + + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var jArray = graphsonObject as JArray; + if (jArray == null) + { + return EmptyList; + } + var result = new object[jArray.Count]; + for (var i = 0; i < result.Length; i++) + { + result[i] = reader.ToObject(jArray[i]); + } + // object[] implements IList<object> + return result; + } + + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs new file mode 100644 index 0000000..5f9c326 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs @@ -0,0 +1,52 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class MapSerializer : IGraphSONDeserializer, IGraphSONSerializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var jArray = graphsonObject as JArray; + if (jArray == null) + { + return new Dictionary<object, object>(0); + } + var result = new Dictionary<object, object>(jArray.Count / 2); + for (var i = 0; i < jArray.Count; i += 2) + { + result[reader.ToObject(jArray[i])] = reader.ToObject(jArray[i + 1]); + } + // IDictionary<object, object> + return result; + } + + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs new file mode 100644 index 0000000..ed2a973 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs @@ -0,0 +1,48 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class SetSerializer : IGraphSONDeserializer, IGraphSONSerializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var jArray = graphsonObject as JArray; + if (jArray == null) + { + return new HashSet<object>(); + } + // ISet<object> + return new HashSet<object>(jArray.Select(reader.ToObject)); + } + + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6b3fdcb8/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs index 747a94e..e2c6dc9 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs @@ -33,9 +33,30 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON { public class GraphSONReaderTests { - private GraphSONReader CreateStandardGraphSONReader() + /// <summary> + /// Parameters for each test supporting multiple versions of GraphSON + /// </summary> + public static IEnumerable<object[]> Versions => new [] { - return new GraphSONReader(); + new object[] { 2 }, + new object[] { 3 } + }; + + /// <summary> + /// Parameters for each collections test supporting multiple versions of GraphSON + /// </summary> + public static IEnumerable<object[]> VersionsSupportingCollections => new [] + { + new object[] { 3 } + }; + + private GraphSONReader CreateStandardGraphSONReader(int version) + { + if (version == 3) + { + return new GraphSON3Reader(); + } + return new GraphSON2Reader(); } [Fact] @@ -45,7 +66,7 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON { {"NS:TestClass", new TestGraphSONDeserializer()} }; - var reader = new GraphSONReader(deserializerByGraphSONType); + var reader = new GraphSON2Reader(deserializerByGraphSONType); var graphSON = "{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}"; var jObject = JObject.Parse(graphSON); @@ -63,7 +84,7 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON { {overrideTypeString, customSerializerMock.Object} }; - var reader = new GraphSONReader(customSerializerByType); + var reader = new GraphSON2Reader(customSerializerByType); reader.ToObject(JObject.Parse($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}")); @@ -71,11 +92,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON customSerializerMock.Verify(m => m.Objectify(It.IsAny<JToken>(), It.IsAny<GraphSONReader>())); } - [Fact] - public void ShouldDeserializeDateToDateTime() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeDateToDateTime(int version) { var graphSon = "{\"@type\":\"g:Date\",\"@value\":1475583442552}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon)); @@ -83,11 +104,12 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(expectedDateTime, readDateTime); } - [Fact] - public void ShouldDeserializeDictionary() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeDictionary(int version) { + Console.WriteLine("Starting"); var serializedDict = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"]}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JObject.Parse(serializedDict); var deserializedDict = reader.ToObject(jObject); @@ -100,12 +122,12 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(expectedDict, deserializedDict); } - [Fact] - public void ShouldDeserializeEdge() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeEdge(int version) { var graphSon = "{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":17},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\",\"properties\":{\"aKey\":\"aValue\",\"bKey\":true}}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); Edge readEdge = reader.ToObject(JObject.Parse(graphSon)); @@ -115,11 +137,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(new Vertex("y"), readEdge.OutV); } - [Fact] - public void ShouldDeserializeInt() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeInt(int version) { var serializedValue = "{\"@type\":\"g:Int32\",\"@value\":5}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JObject.Parse(serializedValue); var deserializedValue = reader.ToObject(jObject); @@ -127,11 +149,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(5, deserializedValue); } - [Fact] - public void ShouldDeserializeLong() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeLong(int version) { var serializedValue = "{\"@type\":\"g:Int64\",\"@value\":5}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JObject.Parse(serializedValue); var deserializedValue = reader.ToObject(jObject); @@ -139,11 +161,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal((long) 5, deserializedValue); } - [Fact] - public void ShouldDeserializeFloat() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeFloat(int version) { var serializedValue = "{\"@type\":\"g:Float\",\"@value\":31.3}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JObject.Parse(serializedValue); var deserializedValue = reader.ToObject(jObject); @@ -151,11 +173,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal((float) 31.3, deserializedValue); } - [Fact] - public void ShouldDeserializeDouble() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeDouble(int version) { var serializedValue = "{\"@type\":\"g:Double\",\"@value\":31.2}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JObject.Parse(serializedValue); var deserializedValue = reader.ToObject(jObject); @@ -163,11 +185,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(31.2, deserializedValue); } - [Fact] - public void ShouldDeserializeList() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeList(int version) { var serializedValue = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var jObject = JArray.Parse(serializedValue); var deserializedValue = reader.ToObject(jObject); @@ -175,12 +197,12 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(new List<object> {5, 6}, deserializedValue); } - [Fact] - public void ShouldDeserializePath() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializePath(int version) { var graphSon = "{\"@type\":\"g:Path\",\"@value\":{\"labels\":[[\"a\"],[\"b\",\"c\"],[]],\"objects\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\",\"label\":\"name\"}}],\"age\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29},\"label\":\"age\"}}]}}},{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":3},\"label\":\"software\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":4},\"value\":\"lop\",\"label\":\"name\"}}],\"lang\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":5},\"value\":\"java\",\"label\":\"lang\"}}]}}},\"lop\"]}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); Path readPath = reader.ToObject(JObject.Parse(graphSon)); @@ -191,12 +213,12 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(3, readPath.Count); } - [Fact] - public void ShouldDeserializePropertyWithEdgeElement() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializePropertyWithEdgeElement(int version) { var graphSon = "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":{\"@type\":\"g:Int64\",\"@value\":17},\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":122},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\"}}}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); Property readProperty = reader.ToObject(JObject.Parse(graphSon)); @@ -210,11 +232,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal("y", edge.OutV.Id); } - [Fact] - public void ShouldDeserializeTimestampToDateTime() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeTimestampToDateTime(int version) { var graphSon = "{\"@type\":\"g:Timestamp\",\"@value\":1475583442558}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon)); @@ -222,23 +244,23 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(expectedDateTime, readDateTime); } - [Fact] - public void ShouldDeserializeGuid() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeGuid(int version) { var graphSon = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); Guid readGuid = reader.ToObject(JObject.Parse(graphSon)); Assert.Equal(Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786"), readGuid); } - [Fact] - public void ShouldDeserializeVertexProperty() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeVertexProperty(int version) { var graphSon = "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"value\":true,\"vertex\":{\"@type\":\"g:Int32\",\"@value\":9}}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon)); @@ -248,12 +270,12 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.NotNull(readVertexProperty.Vertex); } - [Fact] - public void ShouldDeserializeVertexPropertyWithLabel() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeVertexPropertyWithLabel(int version) { var graphSon = "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"name\",\"value\":\"marko\"}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon)); @@ -263,23 +285,23 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Null(readVertexProperty.Vertex); } - [Fact] - public void ShouldDeserializeVertex() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeVertex(int version) { var graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23}}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var readVertex = reader.ToObject(JObject.Parse(graphSon)); Assert.Equal(new Vertex(45.23f), readVertex); } - [Fact] - public void ShouldDeserializeVertexWithEdges() + [Theory, MemberData(nameof(Versions))] + public void ShouldDeserializeVertexWithEdges(int version) { var graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"outE\":{\"created\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":9},\"inV\":{\"@type\":\"g:Int32\",\"@value\":3},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.4}}}],\"knows\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"inV\":{\"@type\":\"g:Int32\",\"@value\":2},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.5}}},{\"id\":{\"@type\":\"g:Int32\",\"@value\":8},\"inV\":{\"@type\":\"g:Int32\",\"@value\":4},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":1.0}}}]},\"properties\":{\"name\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\"}],\"age\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29}}]}}}"; - var reader = CreateStandardGraphSONReader(); + var reader = CreateStandardGraphSONReader(version); var readVertex = reader.ToObject(JObject.Parse(graphSon)); @@ -288,6 +310,53 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON Assert.Equal(typeof(int), readVertex.Id.GetType()); } + [Theory, MemberData(nameof(VersionsSupportingCollections))] + public void ShouldDeserializeEmptyGList(int version) + { + var graphSon = + "{\"@type\":\"g:List\", \"@value\": []}"; + var reader = CreateStandardGraphSONReader(version); + + var deserializedValue = reader.ToObject(JObject.Parse(graphSon)); + Assert.Equal(new object[0], deserializedValue); + } + + [Theory, MemberData(nameof(VersionsSupportingCollections))] + public void ShouldDeserializeGList(int version) + { + const string json = "{\"@type\":\"g:List\", \"@value\": [{\"@type\": \"g:Int32\", \"@value\": 1}," + + "{\"@type\": \"g:Int32\", \"@value\": 2}, {\"@type\": \"g:Int32\", \"@value\": 3}]}"; + var reader = CreateStandardGraphSONReader(version); + + var deserializedValue = reader.ToObject(JObject.Parse(json)); + + Assert.Equal((IList<object>)new object[] { 1, 2, 3}, deserializedValue); + } + + [Theory, MemberData(nameof(VersionsSupportingCollections))] + public void ShouldDeserializeGSet(int version) + { + const string json = "{\"@type\":\"g:Set\", \"@value\": [{\"@type\": \"g:Int32\", \"@value\": 1}," + + "{\"@type\": \"g:Int32\", \"@value\": 2}, {\"@type\": \"g:Int32\", \"@value\": 3}]}"; + var reader = CreateStandardGraphSONReader(version); + + var deserializedValue = reader.ToObject(JObject.Parse(json)); + + Assert.Equal((ISet<object>)new HashSet<object>{ 1, 2, 3}, deserializedValue); + } + + [Theory, MemberData(nameof(VersionsSupportingCollections))] + public void ShouldDeserializeGMap(int version) + { + const string json = "{\"@type\":\"g:Map\", \"@value\": [\"a\",{\"@type\": \"g:Int32\", \"@value\": 1}, " + + "\"b\", {\"@type\": \"g:Int32\", \"@value\": 2}]}"; + var reader = CreateStandardGraphSONReader(version); + + var deserializedValue = reader.ToObject(JObject.Parse(json)); + + Assert.Equal(new Dictionary<object, object>{ { "a", 1 }, { "b", 2 }}, deserializedValue); + } + [Fact] public void ShouldDeserializeTraverser() {