TINKERPOP-1784 Added edge assertion support
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f1275923 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f1275923 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f1275923 Branch: refs/heads/TINKERPOP-1784 Commit: f1275923f711e58911b9756dac0c379cd510d5f1 Parents: cabe968 Author: Stephen Mallette <sp...@genoprime.com> Authored: Wed Sep 27 16:18:14 2017 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Nov 2 13:37:22 2017 -0400 ---------------------------------------------------------------------- .../src/main/jython/radish/feature_steps.py | 28 +++-- .../src/main/jython/radish/terrain.py | 29 ++++- gremlin-test/features/map/Vertex.feature | 111 +++++++++++++++++++ 3 files changed, 160 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f1275923/gremlin-python/src/main/jython/radish/feature_steps.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/radish/feature_steps.py b/gremlin-python/src/main/jython/radish/feature_steps.py index 989e781..2154536 100644 --- a/gremlin-python/src/main/jython/radish/feature_steps.py +++ b/gremlin-python/src/main/jython/radish/feature_steps.py @@ -28,6 +28,7 @@ from hamcrest import * regex_as = re.compile(r"\.as\(") regex_in = re.compile(r"\.in\(") + @given("the {graph_name:w} graph") def choose_graph(step, graph_name): # only have modern atm but graphName would be used to select the right one @@ -75,17 +76,23 @@ def assert_result(step, characterized_as): def __convert(val, ctx): - if isinstance(val, dict): + if isinstance(val, dict): # convert dictionary keys/values n = {} for key, value in val.items(): n[__convert(key, ctx)] = __convert(value, ctx) return n - elif isinstance(val, (str, unicode)) and re.match("^d\[.*\]$", val): + elif isinstance(val, (str, unicode)) and re.match("^l\[.*\]$", val): # parse list + return list(map((lambda x: __convert(x, ctx)), val[2:-1].split(","))) + elif isinstance(val, (str, unicode)) and re.match("^d\[.*\]$", val): # parse numeric return long(val[2:-1]) - elif isinstance(val, (str, unicode)) and re.match("^v\[.*\]\.id$", val): - return ctx.lookup["modern"][val[2:-4]].id - elif isinstance(val, (str, unicode)) and re.match("^v\[.*\]$", val): - return ctx.lookup["modern"][val[2:-1]] + elif isinstance(val, (str, unicode)) and re.match("^v\[.*\]\.id$", val): # parse vertex id + return ctx.lookup_v["modern"][val[2:-4]].id + elif isinstance(val, (str, unicode)) and re.match("^v\[.*\]$", val): # parse vertex + return ctx.lookup_v["modern"][val[2:-1]] + elif isinstance(val, (str, unicode)) and re.match("^e\[.*\]\.id$", val): # parse edge id + return ctx.lookup_e["modern"][val[2:-4]].id + elif isinstance(val, (str, unicode)) and re.match("^e\[.*\]$", val): # parse edge + return ctx.lookup_e["modern"][val[2:-1]] elif isinstance(val, unicode): return val.encode('utf-8') else: @@ -108,6 +115,8 @@ def __ordered_assertion(step): assert_that(str(step.context.result[ix]), equal_to(str(line[1]))) elif line[0] == "vertex": assert_that(step.context.result[ix].label, equal_to(line[1])) + elif line[0] == "edge": + assert_that(step.context.result[ix].label, equal_to(line[1])) elif line[0] == "map": assert_that(__convert(step.context.result[ix], step.context), json.loads(line[1])) else: @@ -135,9 +144,14 @@ def __unordered_assertion(step): results_to_test.remove(val) elif line[0] == "vertex": val = str(line[1]) - v = step.context.lookup["modern"][val] + v = step.context.lookup_v["modern"][val] assert_that(v, is_in(results_to_test)) results_to_test.remove(v) + elif line[0] == "edge": + val = str(line[1]) + e = step.context.lookup_e["modern"][val] + assert_that(e, is_in(results_to_test)) + results_to_test.remove(e) elif line[0] == "map": val = __convert(json.loads(line[1]), step.context) assert_that(val, is_in(results_to_test)) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f1275923/gremlin-python/src/main/jython/radish/terrain.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/radish/terrain.py b/gremlin-python/src/main/jython/radish/terrain.py index 59ec8d0..303f64d 100644 --- a/gremlin-python/src/main/jython/radish/terrain.py +++ b/gremlin-python/src/main/jython/radish/terrain.py @@ -17,11 +17,18 @@ specific language governing permissions and limitations under the License. ''' +import re from gremlin_python.structure.graph import Graph from gremlin_python.process.graph_traversal import __ from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection from radish import before, after +outV = __.outV +label = __.label +inV = __.inV +project = __.project +tail = __.tail + @before.each_scenario def prepare_traversal_source(scenario): @@ -30,7 +37,27 @@ def prepare_traversal_source(scenario): g = Graph().traversal().withRemote(remote) # hold a map of name/vertex for use in asserting results - scenario.context.lookup = {"modern": g.V().group().by('name').by(__.tail()).next()} + scenario.context.lookup_v = {"modern": g.V().group().by('name').by(tail()).next()} + + # hold a map of the "name"/edge for use in asserting results - "name" in this context is in the form of + # outgoingV-label->incomingV + projection_of_edges = g.E().group().\ + by(project("o", "l", "i"). + by(outV().values("name")). + by(label()). + by(inV().values("name"))).\ + by(tail()).next() + edges = {} + + # in GraphSON 3.0 the "key" will be a dictionary and this can work more nicely - right now it's stuck as + # a string and has to be parsed + for key, value in projection_of_edges.items(): + o = re.search("o=(.+?)[,\}]", key).group(1) + l = re.search("l=(.+?)[,\}]", key).group(1) + i = re.search("i=(.+?)[,\}]", key).group(1) + edges[o + "-" + l + "->" + i] = value + + scenario.context.lookup_e = {"modern": edges} @after.each_scenario http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f1275923/gremlin-test/features/map/Vertex.feature ---------------------------------------------------------------------- diff --git a/gremlin-test/features/map/Vertex.feature b/gremlin-test/features/map/Vertex.feature new file mode 100644 index 0000000..fbd4168 --- /dev/null +++ b/gremlin-test/features/map/Vertex.feature @@ -0,0 +1,111 @@ +# 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. + +Feature: Step - V(), E(), out(), in(), both(), inE(), outE(), bothE() + + Scenario: g_VXlistX1_2_3XX_name + Given the modern graph + And using the parameter vx is "l[v[marko],v[vadas],v[lop]]" + And the traversal of + """ + g.V(vx).values("name") + """ + When iterated to list + Then the result should be unordered + | string | marko | + | string | vadas | + | string | lop | + + Scenario: g_VXlistXv1_v2_v3XX_name + Given the modern graph + And using the parameter vx is "l[v[marko].id,v[vadas].id,v[lop].id]" + And the traversal of + """ + g.V(vx).values("name") + """ + When iterated to list + Then the result should be unordered + | string | marko | + | string | vadas | + | string | lop | + + Scenario: g_V + Given the modern graph + And the traversal of + """ + g.V() + """ + When iterated to list + Then the result should be unordered + | vertex | marko | + | vertex | vadas | + | vertex | lop | + | vertex | josh | + | vertex | ripple | + | vertex | peter | + + Scenario: g_VX1X_out + Given the modern graph + And using the parameter v1 is "v[marko]" + And the traversal of + """ + g.V(v1).out() + """ + When iterated to list + Then the result should be unordered + | vertex | vadas | + | vertex | lop | + | vertex | josh | + + Scenario: g_VX2X_in + Given the modern graph + And using the parameter v1 is "v[vadas]" + And the traversal of + """ + g.V(v1).in() + """ + When iterated to list + Then the result should be unordered + | vertex | marko | + + Scenario: g_VX4X_both + Given the modern graph + And using the parameter v1 is "v[josh]" + And the traversal of + """ + g.V(v1).both() + """ + When iterated to list + Then the result should be unordered + | vertex | marko | + | vertex | lop | + | vertex | ripple | + + Scenario: g_E + Given the modern graph + And the traversal of + """ + g.E() + """ + When iterated to list + Then the result should be unordered + | edge | marko-created->lop | + | edge | marko-knows->josh | + | edge | marko-knows->vadas | + | edge | peter-created->lop | + | edge | josh-created->lop | + | edge | josh-created->ripple | \ No newline at end of file