TINKERPOP-1784 Added support for path() testing
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/fa95b273 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/fa95b273 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/fa95b273 Branch: refs/heads/TINKERPOP-1784 Commit: fa95b273642c1f82ae4282258cb4c34a5faf0b9b Parents: 6569e78 Author: Stephen Mallette <sp...@genoprime.com> Authored: Thu Oct 12 11:26:41 2017 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Nov 2 13:37:23 2017 -0400 ---------------------------------------------------------------------- gremlin-python/pom.xml | 2 +- .../src/main/jython/radish/feature_steps.py | 29 ++++-- gremlin-test/features/map/Path.feature | 98 ++++++++++++++++++++ .../gremlin/process/FeatureCoverageTest.java | 10 +- 4 files changed, 130 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa95b273/gremlin-python/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml index d1a4a76..67cc35b 100644 --- a/gremlin-python/pom.xml +++ b/gremlin-python/pom.xml @@ -449,7 +449,7 @@ limitations under the License. <exec executable="env/bin/radish" dir="${project.build.directory}/python2" failonerror="true"> <env key="PYTHONPATH" value=""/> - <arg line="-e -t -b ${project.build.directory}/python2/radish ${project.basedir}/../gremlin-test/features/"/> <!-- -no-line-jump --> + <arg line="-e -t -b ${project.build.directory}/python2/radish ${project.basedir}/../gremlin-test/features/ --no-line-jump"/> <!-- -no-line-jump --> </exec> </target> </configuration> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa95b273/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 1876f5b..859d809 100644 --- a/gremlin-python/src/main/jython/radish/feature_steps.py +++ b/gremlin-python/src/main/jython/radish/feature_steps.py @@ -27,8 +27,11 @@ from hamcrest import * regex_and = re.compile(r"([(.,\s])and\(") regex_as = re.compile(r"([(.,\s])as\(") +regex_from = re.compile(r"([(.,\s])from\(") regex_in = re.compile(r"([(.,\s])in\(") regex_is = re.compile(r"([(.,\s])is\(") +regex_not = re.compile(r"([(.,\s])not\(") +regex_or = re.compile(r"([(.,\s])or\(") @given("the {graph_name:w} graph") @@ -67,13 +70,13 @@ def translate_traversal(step): if hasattr(step.context, "traversal_params"): b.update(step.context.traversal_params) - print _translate(step.text + " - " + str(b)) + # print _translate(step.text + " - " + str(b)) step.context.traversal = eval(_translate(step.text), b) @when("iterated to list") def iterate_the_traversal(step): - step.context.result = step.context.traversal.toList() + step.context.result = map(lambda x: _convert_results(x), step.context.traversal.toList()) @then("the result should be {characterized_as:w}") @@ -99,7 +102,7 @@ def _convert(val, ctx): for key, value in val.items(): n[_convert(key, ctx)] = _convert(value, ctx) return n - elif isinstance(val, unicode): # stupid unicode/string nonsense in py 2/x + elif isinstance(val, unicode): # convert annoying python 2.x unicode nonsense return _convert(val.encode('utf-8'), ctx) elif isinstance(val, str) and re.match("^l\[.*\]$", val): # parse list return list(map((lambda x: _convert(x, ctx)), val[2:-1].split(","))) @@ -121,14 +124,21 @@ def _convert(val, ctx): return _convert(json.loads(val[2:-1]), ctx) elif isinstance(val, str) and re.match("^p\[.*\]$", val): # parse path path_objects = list(map((lambda x: _convert(x, ctx)), val[2:-1].split(","))) - labels = [set([]) for i in range(len(path_objects))] - return Path(labels, path_objects) + return Path([set([])], path_objects) elif isinstance(val, str) and re.match("^c\[.*\]$", val): # parse lambda/closure return lambda: (val[2:-1], "gremlin-groovy") else: return val +def _convert_results(val): + if isinstance(val, Path): + # kill out labels as they aren't in the assertion logic + return Path([set([])], map(lambda p: p.encode("utf-8") if isinstance(p, unicode) else p, val.objects)) + else: + return val + + def _table_assertion(data, result, ctx, ordered): # results from traversal should have the same number of entries as the feature data table assert_that(len(result), equal_to(len(data))) @@ -139,10 +149,14 @@ def _table_assertion(data, result, ctx, ordered): # from the list - in the end there should be no items left over and each will have been asserted for ix, line in enumerate(data): val = _convert(line[0], ctx) + + # clear the labels since we don't define them in .feature files + if isinstance(val, Path): + val.labels = [set([])] + if ordered: assert_that(results_to_test[ix], equal_to(val)) else: - print str(type(val)) + "---------" + str(type(results_to_test[0])) assert_that(val, is_in(results_to_test)) results_to_test.remove(val) @@ -152,6 +166,9 @@ def _table_assertion(data, result, ctx, ordered): def _translate(traversal): replaced = traversal.replace("\n", "") replaced = regex_and.sub(r"\1and_(", replaced) + replaced = regex_from.sub(r"\1from_(", replaced) replaced = regex_as.sub(r"\1as_(", replaced) replaced = regex_is.sub(r"\1is_(", replaced) + replaced = regex_not.sub(r"\1not_(", replaced) + replaced = regex_or.sub(r"\1or_(", replaced) return regex_in.sub(r"\1in_(", replaced) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa95b273/gremlin-test/features/map/Path.feature ---------------------------------------------------------------------- diff --git a/gremlin-test/features/map/Path.feature b/gremlin-test/features/map/Path.feature new file mode 100644 index 0000000..350e6c6 --- /dev/null +++ b/gremlin-test/features/map/Path.feature @@ -0,0 +1,98 @@ +# 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 - count() + + Scenario: g_VX1X_name_path + Given the modern graph + And using the parameter v1Id is "v[marko].id" + And the traversal of + """ + g.V(v1Id).values("name").path() + """ + When iterated to list + Then the result should be unordered + | p[v[marko],marko] | + + Scenario: g_VX1X_out_path_byXageX_byXnameX + Given the modern graph + And using the parameter v1Id is "v[marko].id" + And the traversal of + """ + g.V(v1Id).out().path().by("age").by("name") + """ + When iterated to list + Then the result should be unordered + | p[d[29],lop] | + | p[d[29],vadas] | + | p[d[29],josh] | + + Scenario: g_V_repeatXoutX_timesX2X_path_by_byXnameX_byXlangX + Given the modern graph + And the traversal of + """ + g.V().repeat(__.out()).times(2).path().by().by("name").by("lang") + """ + When iterated to list + Then the result should be unordered + | p[v[marko],josh,java] | + | p[v[marko],josh,java] | + + Scenario: g_V_out_out_path_byXnameX_byXageX + Given the modern graph + And the traversal of + """ + g.V().out().out().path().by("name").by("age") + """ + When iterated to list + Then the result should be unordered + | p[marko,d[32],ripple] | + | p[marko,d[32],lop] | + + Scenario: g_V_asXaX_hasXname_markoX_asXbX_hasXage_29X_asXcX_path + Given the modern graph + And the traversal of + """ + g.V().as("a").has("name", "marko").as("b").has("age", 29).as("c").path() + """ + When iterated to list + Then the result should be unordered + | p[v[marko]] | + + Scenario: g_VX1X_outEXcreatedX_inV_inE_outV_path + Given the modern graph + And using the parameter v1Id is "v[marko].id" + And the traversal of + """ + g.V(v1Id).outE("created").inV().inE().outV().path() + """ + When iterated to list + Then the result should be unordered + | p[v[marko],e[marko-created->lop],v[lop],e[marko-created->lop],v[marko]] | + | p[v[marko],e[marko-created->lop],v[lop],e[josh-created->lop],v[josh]] | + | p[v[marko],e[marko-created->lop],v[lop],e[peter-created->lop],v[peter]] | + + Scenario: g_V_asXaX_out_asXbX_out_asXcX_path_fromXbX_toXcX_byXnameX + Given the modern graph + And the traversal of + """ + g.V().as("a").out().as("b").out().as("c").path().from("b").to("c").by("name") + """ + When iterated to list + Then the result should be unordered + | p[josh,ripple] | + | p[josh,lop] | http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa95b273/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java index 1ac9ed8..c3b46be 100644 --- a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java +++ b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java @@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.branch.ChooseTest; import org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalTest; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinTest; import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountTest; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest; import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexTest; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountTest; import org.junit.Test; @@ -59,13 +60,18 @@ public class FeatureCoverageTest { // TEMPORARY while test framework is under development - all tests should ultimately be included final List<Class<?>> temp = Arrays.asList( + // branch BranchTest.class, ChooseTest.class, OptionalTest.class, + // filter CoinTest.class, + // map CountTest.class, - GroupCountTest.class, - VertexTest.class); + PathTest.class, + VertexTest.class, + // sideEffect + GroupCountTest.class); final Field field = ProcessStandardSuite.class.getDeclaredField("testsToEnforce"); field.setAccessible(true);