You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2025/04/22 11:32:28 UTC
(tinkerpop) 04/11: TINKERPOP-3136 Added subgraph() tests to gherkin
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch TINKERPOP-3136
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 6d0b744a6645a1daa9af05365c42ab8c45a27be9
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Tue Apr 15 19:28:25 2025 -0400
TINKERPOP-3136 Added subgraph() tests to gherkin
Minor restructuring to V/E tests with more specific tags for mid-traversal V/E.
---
docs/src/dev/developer/for-committers.asciidoc | 2 +
.../Gherkin/GherkinTestRunner.cs | 2 +
.../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 28 +--
.../Gherkin/IgnoreException.cs | 7 +-
gremlin-go/driver/cucumber/cucumberSteps_test.go | 2 +-
gremlin-go/driver/cucumber/gremlin.go | 28 +--
.../test/cucumber/feature-steps.js | 12 ++
.../gremlin-javascript/test/cucumber/gremlin.js | 28 +--
.../src/main/python/radish/feature_steps.py | 2 +
gremlin-python/src/main/python/radish/gremlin.py | 28 +--
.../GraphBinaryRemoteComputerFeatureTest.java | 3 +-
.../remote/GraphSONRemoteComputerFeatureTest.java | 2 +-
.../gremlin/driver/remote/RemoteWorld.java | 22 ++-
.../tinkerpop/gremlin/features/StepDefinition.java | 59 ++++++
.../process/ProcessEmbeddedComputerSuite.java | 2 -
.../process/ProcessEmbeddedStandardSuite.java | 5 -
.../gremlin/test/features/map/Edge.feature | 120 +++++++++++-
.../gremlin/test/features/map/Graph.feature | 109 -----------
.../gremlin/test/features/map/Vertex.feature | 207 ++++++++++-----------
.../test/features/sideEffect/Subgraph.feature | 55 ++++++
.../hadoop/HadoopGraphFeatureIntegrateTest.java | 2 +-
.../spark/SparkGraphFeatureIntegrateTest.java | 1 +
.../TinkerGraphComputerFeatureTest.java | 2 +-
.../TinkerTransactionGraphComputerFeatureTest.java | 2 +-
.../tinkerpop/gremlin/tinkergraph/TinkerWorld.java | 10 +-
25 files changed, 446 insertions(+), 294 deletions(-)
diff --git a/docs/src/dev/developer/for-committers.asciidoc b/docs/src/dev/developer/for-committers.asciidoc
index f0e0cda24c..59f46161e8 100644
--- a/docs/src/dev/developer/for-committers.asciidoc
+++ b/docs/src/dev/developer/for-committers.asciidoc
@@ -567,6 +567,8 @@ tag when one is necessary will cause provider tests to fail:
* `@GraphComputerOnly` - The scenario is only supported with `GraphComputer`.
* `@GraphComputerVerificationInjectionNotSupported` - The scenario will not work on with `GraphComputer` because the
`inject()` step is not supported.
+* `@GraphComputerVerificationMidENotSupported` - The scenario will not work on with `GraphComputer` because the
+mid-`E()` step is not supported.
* `@GraphComputerVerificationMidVNotSupported` - The scenario will not work on with `GraphComputer` because the
mid-`V()` step is not supported.
* `@GraphComputerVerificationOneBulk` - The scenario will not work because `withBulk(false)` is configured and that
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
index e12a89b64f..20272e626b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
@@ -48,6 +48,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
new Dictionary<string, IgnoreReason>
{
// Add here the name of scenarios to ignore and the reason, e.g.:
+ {"g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX", IgnoreReason.SubgraphStepNotSupported},
+ {"g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX", IgnoreReason.SubgraphStepNotSupported},
{"g_withStrategiesXProductiveByStrategyX_V_group_byXageX", IgnoreReason.NullKeysInMapNotSupported},
{"g_withStrategiesXProductiveByStrategyX_V_groupCount_byXageX", IgnoreReason.NullKeysInMapNotSupported},
{"g_withoutStrategiesXCountStrategyX_V_count", IgnoreReason.NoReason}, // needs investigation
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index aec6a2f218..0f7523940d 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -769,6 +769,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_injectXa_null_bX_disjunctXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).Disjunct(p["xx2"])}},
{"g_injectXa_null_bX_disjunctXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).Disjunct(p["xx2"])}},
{"g_injectX3_threeX_disjunctXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).Disjunct(p["xx2"])}},
+ {"g_E", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E()}},
+ {"g_EX11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"])}},
+ {"g_EX11AsStringX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"])}},
+ {"g_EXe11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["e11"])}},
+ {"g_EXe7_e11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["e7"], p["e11"])}},
+ {"g_EXlistXe7_e11XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["xx1"])}},
+ {"g_EXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(null)}},
+ {"g_EXlistXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["xx1"])}},
+ {"g_EX11_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"], null)}},
{"g_V_EX11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().E(p["eid11"])}},
{"g_EX11X_E", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"]).E()}},
{"g_V_EXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().E(null)}},
@@ -804,10 +813,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_V_elementMap_formatXstrX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ElementMap<object>().Format("%{name} is %{age} years old")}},
{"g_V_hasLabelXpersonX_asXaX_valuesXnameX_asXp1X_selectXaX_inXknowsX_formatXstrX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").As("a").Values<object>("name").As("p1").Select<object>("a").In("knows").Format("%{p1} knows %{name}")}},
{"g_V_asXsX_label_asXsubjectX_selectXsX_outE_asXpX_label_asXpredicateX_selectXpX_inV_label_asXobjectX_formatXstrX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("s").Label().As("subject").Select<object>("s").OutE().As("p").Label().As("predicate").Select<object>("p").InV().Label().As("object").Format("%{subject} %{predicate} %{object}")}},
- {"g_VX1X_V_valuesXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).V().Values<object>("name")}},
- {"g_V_outXknowsX_V_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out("knows").V().Values<object>("name")}},
- {"g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("artist", "name", "Garcia").In("sungBy").As("song").V().Has("artist", "name", "Willie_Dixon").In("writtenBy").Where(P.Eq("song")).Values<object>("name")}},
- {"g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29).As("marko").AddV("person").Property("name", "vadas").Property("age", 27).As("vadas").AddV("software").Property("name", "lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh").Property("age", 32).As("josh").AddV("software").Property("name", "ri [...]
{"g_V_hasLabelXsoftwareX_index_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Index<object>().Unfold<object>()}},
{"g_V_hasLabelXsoftwareX_order_byXnameX_index_withXmapX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Order().By("name").Index<object>().With(WithOptions.Indexer, WithOptions.Map)}},
{"g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Values<object>("name").Fold().Order(Scope.Local).Index<object>().Unfold<object>().Order().By(__.Tail<object>(Scope.Local, 1))}},
@@ -1367,15 +1372,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_VX1X_out", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Out()}},
{"g_VX2X_in", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid2"]).In()}},
{"g_VX4X_both", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid4"]).Both()}},
- {"g_E", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E()}},
- {"g_EX11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"])}},
- {"g_EX11AsStringX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"])}},
- {"g_EXe11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["e11"])}},
- {"g_EXe7_e11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["e7"], p["e11"])}},
- {"g_EXlistXe7_e11XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["xx1"])}},
- {"g_EXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(null)}},
- {"g_EXlistXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["xx1"])}},
- {"g_EX11_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"], null)}},
{"g_VX1X_outE", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).OutE()}},
{"g_VX2X_outE", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid2"]).InE()}},
{"g_VX4X_bothEXcreatedX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid4"]).BothE("created")}},
@@ -1405,6 +1401,10 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_V_hasLabelXloopsX_bothXselfX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("loops").Both("self")}},
{"g_injectX1X_VXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(1).V(null)}},
{"g_injectX1X_VX1_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(1).V(p["vid1"], null)}},
+ {"g_VX1X_V_valuesXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).V().Values<object>("name")}},
+ {"g_V_outXknowsX_V_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out("knows").V().Values<object>("name")}},
+ {"g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("artist", "name", "Garcia").In("sungBy").As("song").V().Has("artist", "name", "Willie_Dixon").In("writtenBy").Where(P.Eq("song")).Values<object>("name")}},
+ {"g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29).As("marko").AddV("person").Property("name", "vadas").Property("age", 27).As("vadas").AddV("software").Property("name", "lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh").Property("age", 32).As("josh").AddV("software").Property("name", "ri [...]
{"InjectXnullX_eqXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Is(P.Eq(null))}},
{"InjectXnullX_neqXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Is(P.Neq(null))}},
{"InjectXnullX_ltXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Is(P.Lt(null))}},
@@ -1671,6 +1671,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithSideEffect("a", p["xx1"]).V().Both().Values<object>("name").Store("a").Cap<object>("a")}},
{"g_withSideEffectXa_set_inlineX_V_both_name_storeXaX_capXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithSideEffect("a", new HashSet<object> { "alice" }).V().Both().Values<object>("name").Store("a").Cap<object>("a")}},
{"g_V_storeXaX_byXoutEXcreatedX_countX_out_out_storeXaX_byXinEXcreatedX_weight_sumX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Store("a").By(__.OutE("created").Count()).Out().Out().Store("a").By(__.InE("created").Values<object>("weight").Sum<object>()).Cap<object>("a")}},
+ {"g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).OutE("knows").Subgraph("sg").Values<object>("name").Cap<object>("sg")}},
+ {"g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Repeat(__.BothE("created").Subgraph("sg").OutV()).Times(5).Values<object>("name").Dedup().Cap<object>("sg")}},
};
public static ITraversal UseTraversal(string scenarioName, GraphTraversalSource g, IDictionary<string, object> parameters)
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
index d409cc4dec..480cf87d93 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
@@ -65,6 +65,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
/// <summary>
/// Tests with lambdas can't be translated. This should be removed once lambdas are completely dropped.
/// </summary>
- LambdasNotTranslated
+ LambdasNotTranslated,
+
+ /// <summary>
+ /// subgraph() is not supported yet
+ /// </summary>
+ SubgraphStepNotSupported
}
}
\ No newline at end of file
diff --git a/gremlin-go/driver/cucumber/cucumberSteps_test.go b/gremlin-go/driver/cucumber/cucumberSteps_test.go
index 294bcfef54..c543e038ab 100644
--- a/gremlin-go/driver/cucumber/cucumberSteps_test.go
+++ b/gremlin-go/driver/cucumber/cucumberSteps_test.go
@@ -956,7 +956,7 @@ func TestCucumberFeatures(t *testing.T) {
TestSuiteInitializer: InitializeTestSuite,
ScenarioInitializer: InitializeScenario,
Options: &godog.Options{
- Tags: "~@GraphComputerOnly && ~@AllowNullPropertyValues",
+ Tags: "~@GraphComputerOnly && ~@AllowNullPropertyValues && ~@StepSubgraph",
Format: "pretty",
Paths: []string{getEnvOrDefaultString("CUCUMBER_FEATURE_FOLDER", "../../../gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features")},
TestingT: t, // Testing instance that will run subtests.
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index 89eb923edb..658a2ca905 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -738,6 +738,15 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_injectXa_null_bX_disjunctXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}},
"g_injectXa_null_bX_disjunctXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}},
"g_injectX3_threeX_disjunctXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}},
+ "g_E": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E()}},
+ "g_EX11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"])}},
+ "g_EX11AsStringX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"])}},
+ "g_EXe11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["e11"])}},
+ "g_EXe7_e11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["e7"], p["e11"])}},
+ "g_EXlistXe7_e11XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["xx1"])}},
+ "g_EXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(nil)}},
+ "g_EXlistXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["xx1"])}},
+ "g_EX11_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"], nil)}},
"g_V_EX11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().E(p["eid11"])}},
"g_EX11X_E": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"]).E()}},
"g_V_EXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().E(nil)}},
@@ -773,10 +782,6 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_V_elementMap_formatXstrX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ElementMap().Format("%{name} is %{age} years old")}},
"g_V_hasLabelXpersonX_asXaX_valuesXnameX_asXp1X_selectXaX_inXknowsX_formatXstrX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").As("a").Values("name").As("p1").Select("a").In("knows").Format("%{p1} knows %{name}")}},
"g_V_asXsX_label_asXsubjectX_selectXsX_outE_asXpX_label_asXpredicateX_selectXpX_inV_label_asXobjectX_formatXstrX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("s").Label().As("subject").Select("s").OutE().As("p").Label().As("predicate").Select("p").InV().Label().As("object").Format("%{subject} %{predicate} %{object}")}},
- "g_VX1X_V_valuesXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).V().Values("name")}},
- "g_V_outXknowsX_V_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out("knows").V().Values("name")}},
- "g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("artist", "name", "Garcia").In("sungBy").As("song").V().Has("artist", "name", "Willie_Dixon").In("writtenBy").Where(gremlingo.P.Eq("song")).Values("name")}},
- "g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29).As("marko").AddV("person").Property("name", "vadas").Property("age", 27).As("vadas").AddV("software").Property("name", "lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh").Property("age", 32).As("josh").AddV("software").Property("name", " [...]
"g_V_hasLabelXsoftwareX_index_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Index().Unfold()}},
"g_V_hasLabelXsoftwareX_order_byXnameX_index_withXmapX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Order().By("name").Index().With(gremlingo.WithOptions.Indexer, gremlingo.WithOptions.Map)}},
"g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Values("name").Fold().Order(gremlingo.Scope.Local).Index().Unfold().Order().By(gremlingo.T__.Tail(gremlingo.Scope.Local, 1))}},
@@ -1336,15 +1341,6 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_VX1X_out": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Out()}},
"g_VX2X_in": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid2"]).In()}},
"g_VX4X_both": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid4"]).Both()}},
- "g_E": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E()}},
- "g_EX11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"])}},
- "g_EX11AsStringX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"])}},
- "g_EXe11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["e11"])}},
- "g_EXe7_e11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["e7"], p["e11"])}},
- "g_EXlistXe7_e11XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["xx1"])}},
- "g_EXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(nil)}},
- "g_EXlistXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["xx1"])}},
- "g_EX11_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"], nil)}},
"g_VX1X_outE": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).OutE()}},
"g_VX2X_outE": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid2"]).InE()}},
"g_VX4X_bothEXcreatedX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid4"]).BothE("created")}},
@@ -1374,6 +1370,10 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_V_hasLabelXloopsX_bothXselfX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("loops").Both("self")}},
"g_injectX1X_VXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1).V(nil)}},
"g_injectX1X_VX1_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1).V(p["vid1"], nil)}},
+ "g_VX1X_V_valuesXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).V().Values("name")}},
+ "g_V_outXknowsX_V_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out("knows").V().Values("name")}},
+ "g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("artist", "name", "Garcia").In("sungBy").As("song").V().Has("artist", "name", "Willie_Dixon").In("writtenBy").Where(gremlingo.P.Eq("song")).Values("name")}},
+ "g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29).As("marko").AddV("person").Property("name", "vadas").Property("age", 27).As("vadas").AddV("software").Property("name", "lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh").Property("age", 32).As("josh").AddV("software").Property("name", " [...]
"InjectXnullX_eqXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Is(gremlingo.P.Eq(nil))}},
"InjectXnullX_neqXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Is(gremlingo.P.Neq(nil))}},
"InjectXnullX_ltXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Is(gremlingo.P.Lt(nil))}},
@@ -1640,6 +1640,8 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithSideEffect("a", p["xx1"]).V().Both().Values("name").Store("a").Cap("a")}},
"g_withSideEffectXa_set_inlineX_V_both_name_storeXaX_capXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithSideEffect("a", gremlingo.NewSimpleSet("alice")).V().Both().Values("name").Store("a").Cap("a")}},
"g_V_storeXaX_byXoutEXcreatedX_countX_out_out_storeXaX_byXinEXcreatedX_weight_sumX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Store("a").By(gremlingo.T__.OutE("created").Count()).Out().Out().Store("a").By(gremlingo.T__.InE("created").Values("weight").Sum()).Cap("a")}},
+ "g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).OutE("knows").Subgraph("sg").Values("name").Cap("sg")}},
+ "g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Repeat(gremlingo.T__.BothE("created").Subgraph("sg").OutV()).Times(5).Values("name").Dedup().Cap("sg")}},
}
func GetTraversal(scenarioName string, g *gremlingo.GraphTraversalSource, parameters map[string]interface{}) (*gremlingo.GraphTraversal, error) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 42e3899e55..75758c8294 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -73,10 +73,14 @@ const ignoreReason = {
classNotSupported: "Javascript does not support the class type in GraphBinary",
nullKeysInMapNotSupportedWell: "Javascript does not nicely support 'null' as a key in Map instances",
floatingPointIssues: "Javascript floating point numbers not working in this case",
+ subgraphStepNotSupported: "Javascript does not yet support subgraph()",
needsFurtherInvestigation: '',
};
const ignoredScenarios = {
+ // javascript doesn't have subgraph() step yet
+ 'g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX': new IgnoreError(ignoreReason.subgraphStepNotSupported),
+ 'g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX': new IgnoreError(ignoreReason.subgraphStepNotSupported),
// An associative array containing the scenario name as key, for example:
'g_withStrategiesXProductiveByStrategyX_V_groupCount_byXageX': new IgnoreError(ignoreReason.nullKeysInMapNotSupportedWell),
'g_withoutStrategiesXCountStrategyX_V_count': new IgnoreError(ignoreReason.classNotSupported),
@@ -279,6 +283,14 @@ Then(/^the result should be (\w+)$/, function assertResult(characterizedAs, resu
}
});
+Then('the result should be a subgraph with edges', _ => {
+ // subgraph is not supported yet in javascript
+});
+
+Then('the result should be a subgraph with vertices', _ => {
+ // subgraph is not supported yet in javascript
+});
+
Then(/^the graph should return (\d+) for count of "(.+)"$/, function (stringCount, traversalText) {
expect(this.result).to.not.be.a.instanceof(Error);
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index 866632b370..993257eee6 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -759,6 +759,15 @@ const gremlins = {
g_injectXa_null_bX_disjunctXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }],
g_injectXa_null_bX_disjunctXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }],
g_injectX3_threeX_disjunctXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }],
+ g_E: [function({g}) { return g.E() }],
+ g_EX11X: [function({g, eid11}) { return g.E(eid11) }],
+ g_EX11AsStringX: [function({g, eid11}) { return g.E(eid11) }],
+ g_EXe11X: [function({g, e11}) { return g.E(e11) }],
+ g_EXe7_e11X: [function({g, e7, e11}) { return g.E(e7, e11) }],
+ g_EXlistXe7_e11XX: [function({g, xx1}) { return g.E(xx1) }],
+ g_EXnullX: [function({g}) { return g.E(null) }],
+ g_EXlistXnullXX: [function({g, xx1}) { return g.E(xx1) }],
+ g_EX11_nullX: [function({g, eid11}) { return g.E(eid11, null) }],
g_V_EX11X: [function({g, eid11}) { return g.V().E(eid11) }],
g_EX11X_E: [function({g, eid11}) { return g.E(eid11).E() }],
g_V_EXnullX: [function({g}) { return g.V().E(null) }],
@@ -794,10 +803,6 @@ const gremlins = {
g_V_elementMap_formatXstrX: [function({g}) { return g.V().elementMap().format("%{name} is %{age} years old") }],
g_V_hasLabelXpersonX_asXaX_valuesXnameX_asXp1X_selectXaX_inXknowsX_formatXstrX: [function({g}) { return g.V().hasLabel("person").as("a").values("name").as("p1").select("a").in_("knows").format("%{p1} knows %{name}") }],
g_V_asXsX_label_asXsubjectX_selectXsX_outE_asXpX_label_asXpredicateX_selectXpX_inV_label_asXobjectX_formatXstrX: [function({g}) { return g.V().as("s").label().as("subject").select("s").outE().as("p").label().as("predicate").select("p").inV().label().as("object").format("%{subject} %{predicate} %{object}") }],
- g_VX1X_V_valuesXnameX: [function({g, vid1}) { return g.V(vid1).V().values("name") }],
- g_V_outXknowsX_V_name: [function({g}) { return g.V().out("knows").V().values("name") }],
- g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name: [function({g}) { return g.V().has("artist", "name", "Garcia").in_("sungBy").as("song").V().has("artist", "name", "Willie_Dixon").in_("writtenBy").where(P.eq("song")).values("name") }],
- g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX: [function({g, xx1, vid1, vid2, vid3, vid4, vid5, vid6}) { return g.addV("person").property("name", "marko").property("age", 29).as("marko").addV("person").property("name", "vadas").property("age", 27).as("vadas").addV("software").property("name", "lop").property("lang", "java").as("lop").addV("person").property("name", "josh").property("age", 32).as("josh").addV("software").property("name", "ripple").property("lang", "java").as(" [...]
g_V_hasLabelXsoftwareX_index_unfold: [function({g}) { return g.V().hasLabel("software").index().unfold() }],
g_V_hasLabelXsoftwareX_order_byXnameX_index_withXmapX: [function({g}) { return g.V().hasLabel("software").order().by("name").index().with_(WithOptions.indexer, WithOptions.map) }],
g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX: [function({g}) { return g.V().hasLabel("software").values("name").fold().order(Scope.local).index().unfold().order().by(__.tail(Scope.local, 1)) }],
@@ -1357,15 +1362,6 @@ const gremlins = {
g_VX1X_out: [function({g, vid1}) { return g.V(vid1).out() }],
g_VX2X_in: [function({g, vid2}) { return g.V(vid2).in_() }],
g_VX4X_both: [function({g, vid4}) { return g.V(vid4).both() }],
- g_E: [function({g}) { return g.E() }],
- g_EX11X: [function({g, eid11}) { return g.E(eid11) }],
- g_EX11AsStringX: [function({g, eid11}) { return g.E(eid11) }],
- g_EXe11X: [function({g, e11}) { return g.E(e11) }],
- g_EXe7_e11X: [function({g, e7, e11}) { return g.E(e7, e11) }],
- g_EXlistXe7_e11XX: [function({g, xx1}) { return g.E(xx1) }],
- g_EXnullX: [function({g}) { return g.E(null) }],
- g_EXlistXnullXX: [function({g, xx1}) { return g.E(xx1) }],
- g_EX11_nullX: [function({g, eid11}) { return g.E(eid11, null) }],
g_VX1X_outE: [function({g, vid1}) { return g.V(vid1).outE() }],
g_VX2X_outE: [function({g, vid2}) { return g.V(vid2).inE() }],
g_VX4X_bothEXcreatedX: [function({g, vid4}) { return g.V(vid4).bothE("created") }],
@@ -1395,6 +1391,10 @@ const gremlins = {
g_V_hasLabelXloopsX_bothXselfX: [function({g}) { return g.V().hasLabel("loops").both("self") }],
g_injectX1X_VXnullX: [function({g}) { return g.inject(1).V(null) }],
g_injectX1X_VX1_nullX: [function({g, vid1}) { return g.inject(1).V(vid1, null) }],
+ g_VX1X_V_valuesXnameX: [function({g, vid1}) { return g.V(vid1).V().values("name") }],
+ g_V_outXknowsX_V_name: [function({g}) { return g.V().out("knows").V().values("name") }],
+ g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name: [function({g}) { return g.V().has("artist", "name", "Garcia").in_("sungBy").as("song").V().has("artist", "name", "Willie_Dixon").in_("writtenBy").where(P.eq("song")).values("name") }],
+ g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX: [function({g, xx1, vid1, vid2, vid3, vid4, vid5, vid6}) { return g.addV("person").property("name", "marko").property("age", 29).as("marko").addV("person").property("name", "vadas").property("age", 27).as("vadas").addV("software").property("name", "lop").property("lang", "java").as("lop").addV("person").property("name", "josh").property("age", 32).as("josh").addV("software").property("name", "ripple").property("lang", "java").as(" [...]
InjectXnullX_eqXnullX: [function({g}) { return g.inject(null).is(P.eq(null)) }],
InjectXnullX_neqXnullX: [function({g}) { return g.inject(null).is(P.neq(null)) }],
InjectXnullX_ltXnullX: [function({g}) { return g.inject(null).is(P.lt(null)) }],
@@ -1661,6 +1661,8 @@ const gremlins = {
g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX: [function({g, xx1}) { return g.withSideEffect("a", xx1).V().both().values("name").store("a").cap("a") }],
g_withSideEffectXa_set_inlineX_V_both_name_storeXaX_capXaX: [function({g}) { return g.withSideEffect("a", new Set(["alice"])).V().both().values("name").store("a").cap("a") }],
g_V_storeXaX_byXoutEXcreatedX_countX_out_out_storeXaX_byXinEXcreatedX_weight_sumX: [function({g}) { return g.V().store("a").by(__.outE("created").count()).out().out().store("a").by(__.inE("created").values("weight").sum()).cap("a") }],
+ g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX: [function({g, vid1}) { return g.V(vid1).outE("knows").subgraph("sg").values("name").cap("sg") }],
+ g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX: [function({g}) { return g.V().repeat(__.bothE("created").subgraph("sg").outV()).times(5).values("name").dedup().cap("sg") }],
}
exports.gremlin = gremlins
diff --git a/gremlin-python/src/main/python/radish/feature_steps.py b/gremlin-python/src/main/python/radish/feature_steps.py
index 6b1e0110c6..75659da2e7 100644
--- a/gremlin-python/src/main/python/radish/feature_steps.py
+++ b/gremlin-python/src/main/python/radish/feature_steps.py
@@ -36,6 +36,8 @@ project = __.project
tail = __.tail
ignores = [
+ "g.V(vid1).outE(\"knows\").subgraph(\"sg\").values(\"name\").cap(\"sg\")",
+ "g.V().repeat(__.bothE(\"created\").subgraph(\"sg\").outV()).times(5).values(\"name\").dedup().cap(\"sg\")",
"g.V().choose(has(T.label, \"person\"),values(\"age\").groupCount(\"a\"), values(\"name\").groupCount(\"b\")).cap(\"a\", \"b\").unfold()", # uses embedded Map in assertion
"g.withSideEffect(\"x\",{}).V().both().both().sideEffect(__.store(\"x\").by(\"name\")).cap(\"x\").unfold()", # Objects must be both of Map or Collection: a=LinkedHashMap b=BulkSet???
"g.withoutStrategies(CountStrategy).V().count()" # serialization issues with Class in GraphSON
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 1ecb050051..b9ba790cec 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -741,6 +741,15 @@ world.gremlins = {
'g_injectXa_null_bX_disjunctXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))],
'g_injectXa_null_bX_disjunctXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))],
'g_injectX3_threeX_disjunctXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))],
+ 'g_E': [(lambda g:g.E())],
+ 'g_EX11X': [(lambda g, eid11=None:g.E(eid11))],
+ 'g_EX11AsStringX': [(lambda g, eid11=None:g.E(eid11))],
+ 'g_EXe11X': [(lambda g, e11=None:g.E(e11))],
+ 'g_EXe7_e11X': [(lambda g, e7=None,e11=None:g.E(e7, e11))],
+ 'g_EXlistXe7_e11XX': [(lambda g, xx1=None:g.E(xx1))],
+ 'g_EXnullX': [(lambda g:g.E(None))],
+ 'g_EXlistXnullXX': [(lambda g, xx1=None:g.E(xx1))],
+ 'g_EX11_nullX': [(lambda g, eid11=None:g.E(eid11, None))],
'g_V_EX11X': [(lambda g, eid11=None:g.V().E(eid11))],
'g_EX11X_E': [(lambda g, eid11=None:g.E(eid11).E())],
'g_V_EXnullX': [(lambda g:g.V().E(None))],
@@ -776,10 +785,6 @@ world.gremlins = {
'g_V_elementMap_formatXstrX': [(lambda g:g.V().element_map().format_('%{name} is %{age} years old'))],
'g_V_hasLabelXpersonX_asXaX_valuesXnameX_asXp1X_selectXaX_inXknowsX_formatXstrX': [(lambda g:g.V().has_label('person').as_('a').values('name').as_('p1').select('a').in_('knows').format_('%{p1} knows %{name}'))],
'g_V_asXsX_label_asXsubjectX_selectXsX_outE_asXpX_label_asXpredicateX_selectXpX_inV_label_asXobjectX_formatXstrX': [(lambda g:g.V().as_('s').label().as_('subject').select('s').out_e().as_('p').label().as_('predicate').select('p').in_v().label().as_('object').format_('%{subject} %{predicate} %{object}'))],
- 'g_VX1X_V_valuesXnameX': [(lambda g, vid1=None:g.V(vid1).V().values('name'))],
- 'g_V_outXknowsX_V_name': [(lambda g:g.V().out('knows').V().values('name'))],
- 'g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name': [(lambda g:g.V().has('artist', 'name', 'Garcia').in_('sungBy').as_('song').V().has('artist', 'name', 'Willie_Dixon').in_('writtenBy').where(P.eq('song')).values('name'))],
- 'g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX': [(lambda g, xx1=None,vid1=None,vid2=None,vid3=None,vid4=None,vid5=None,vid6=None:g.add_v('person').property('name', 'marko').property('age', 29).as_('marko').add_v('person').property('name', 'vadas').property('age', 27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 'java').as_('lop').add_v('person').property('name', 'josh').property('age', 32).as_('josh').add_v('software').property('name', 'ripple').pr [...]
'g_V_hasLabelXsoftwareX_index_unfold': [(lambda g:g.V().has_label('software').index().unfold())],
'g_V_hasLabelXsoftwareX_order_byXnameX_index_withXmapX': [(lambda g:g.V().has_label('software').order().by('name').index().with_(WithOptions.indexer, WithOptions.map))],
'g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX': [(lambda g:g.V().has_label('software').values('name').fold().order(Scope.local).index().unfold().order().by(__.tail(Scope.local, 1)))],
@@ -1339,15 +1344,6 @@ world.gremlins = {
'g_VX1X_out': [(lambda g, vid1=None:g.V(vid1).out())],
'g_VX2X_in': [(lambda g, vid2=None:g.V(vid2).in_())],
'g_VX4X_both': [(lambda g, vid4=None:g.V(vid4).both())],
- 'g_E': [(lambda g:g.E())],
- 'g_EX11X': [(lambda g, eid11=None:g.E(eid11))],
- 'g_EX11AsStringX': [(lambda g, eid11=None:g.E(eid11))],
- 'g_EXe11X': [(lambda g, e11=None:g.E(e11))],
- 'g_EXe7_e11X': [(lambda g, e7=None,e11=None:g.E(e7, e11))],
- 'g_EXlistXe7_e11XX': [(lambda g, xx1=None:g.E(xx1))],
- 'g_EXnullX': [(lambda g:g.E(None))],
- 'g_EXlistXnullXX': [(lambda g, xx1=None:g.E(xx1))],
- 'g_EX11_nullX': [(lambda g, eid11=None:g.E(eid11, None))],
'g_VX1X_outE': [(lambda g, vid1=None:g.V(vid1).out_e())],
'g_VX2X_outE': [(lambda g, vid2=None:g.V(vid2).in_e())],
'g_VX4X_bothEXcreatedX': [(lambda g, vid4=None:g.V(vid4).both_e('created'))],
@@ -1377,6 +1373,10 @@ world.gremlins = {
'g_V_hasLabelXloopsX_bothXselfX': [(lambda g:g.V().has_label('loops').both('self'))],
'g_injectX1X_VXnullX': [(lambda g:g.inject(1).V(None))],
'g_injectX1X_VX1_nullX': [(lambda g, vid1=None:g.inject(1).V(vid1, None))],
+ 'g_VX1X_V_valuesXnameX': [(lambda g, vid1=None:g.V(vid1).V().values('name'))],
+ 'g_V_outXknowsX_V_name': [(lambda g:g.V().out('knows').V().values('name'))],
+ 'g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name': [(lambda g:g.V().has('artist', 'name', 'Garcia').in_('sungBy').as_('song').V().has('artist', 'name', 'Willie_Dixon').in_('writtenBy').where(P.eq('song')).values('name'))],
+ 'g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX': [(lambda g, xx1=None,vid1=None,vid2=None,vid3=None,vid4=None,vid5=None,vid6=None:g.add_v('person').property('name', 'marko').property('age', 29).as_('marko').add_v('person').property('name', 'vadas').property('age', 27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 'java').as_('lop').add_v('person').property('name', 'josh').property('age', 32).as_('josh').add_v('software').property('name', 'ripple').pr [...]
'InjectXnullX_eqXnullX': [(lambda g:g.inject(None).is_(P.eq(None)))],
'InjectXnullX_neqXnullX': [(lambda g:g.inject(None).is_(P.neq(None)))],
'InjectXnullX_ltXnullX': [(lambda g:g.inject(None).is_(P.lt(None)))],
@@ -1643,4 +1643,6 @@ world.gremlins = {
'g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX': [(lambda g, xx1=None:g.with_side_effect('a', xx1).V().both().values('name').store('a').cap('a'))],
'g_withSideEffectXa_set_inlineX_V_both_name_storeXaX_capXaX': [(lambda g:g.with_side_effect('a', {'alice'}).V().both().values('name').store('a').cap('a'))],
'g_V_storeXaX_byXoutEXcreatedX_countX_out_out_storeXaX_byXinEXcreatedX_weight_sumX': [(lambda g:g.V().store('a').by(__.out_e('created').count()).out().out().store('a').by(__.in_e('created').values('weight').sum_()).cap('a'))],
+ 'g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX': [(lambda g, vid1=None:g.V(vid1).out_e('knows').subgraph('sg').values('name').cap('sg'))],
+ 'g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX': [(lambda g:g.V().repeat(__.both_e('created').subgraph('sg').out_v()).times(5).values('name').dedup().cap('sg'))],
}
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryRemoteComputerFeatureTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryRemoteComputerFeatureTest.java
index 3b610a8041..0d04270b1f 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryRemoteComputerFeatureTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryRemoteComputerFeatureTest.java
@@ -30,8 +30,7 @@ import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
- tags = "not @RemoteOnly and not @GraphComputerVerificationElementSupported and " +
- "not @GraphComputerVerificationReferenceOnly and not @InsertionOrderingRequired",
+ tags = "not @RemoteOnly",
glue = { "org.apache.tinkerpop.gremlin.features" },
objectFactory = GraphBinaryRemoteComputerFeatureTest.RemoteGuiceFactory.class,
features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphSONRemoteComputerFeatureTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphSONRemoteComputerFeatureTest.java
index ed170e470f..2f9b17742b 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphSONRemoteComputerFeatureTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphSONRemoteComputerFeatureTest.java
@@ -30,7 +30,7 @@ import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
- tags = "not @RemoteOnly and not @GraphComputerVerificationElementSupported",
+ tags = "not @RemoteOnly",
glue = { "org.apache.tinkerpop.gremlin.features" },
objectFactory = GraphSONRemoteComputerFeatureTest.RemoteGuiceFactory.class,
features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
index e6a18ea753..966d50cf4a 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
@@ -114,10 +114,15 @@ public abstract class RemoteWorld implements World {
private static final List<String> TAGS_TO_IGNORE = Arrays.asList(
"@StepDrop",
"@StepInject",
- "@StepV",
- "@StepE",
+ "@StepMidV",
+ "@StepMidE",
+ "@StepSubgraph",
+ "@InsertionOrderingRequired",
+ "@StepIndex",
+ "@GraphComputerVerificationElementSupported",
"@GraphComputerVerificationOneBulk",
"@GraphComputerVerificationStrategyNotSupported",
+ "@GraphComputerVerificationMidENotSupported",
"@GraphComputerVerificationMidVNotSupported",
"@GraphComputerVerificationInjectionNotSupported",
"@GraphComputerVerificationStarGraphExceeded",
@@ -135,6 +140,8 @@ public abstract class RemoteWorld implements World {
final List<String> ignores = TAGS_TO_IGNORE.stream().filter(t -> scenario.getSourceTagNames().contains(t)).collect(Collectors.toList());
if (!ignores.isEmpty())
throw new AssumptionViolatedException(String.format("This scenario is not supported with GraphComputer: %s", ignores));
+
+ super.beforeEachScenario(scenario);
}
@Override
@@ -173,6 +180,17 @@ public abstract class RemoteWorld implements World {
public static class GraphSONRemoteWorld extends RemoteWorld {
public GraphSONRemoteWorld() { super(createTestCluster(Serializers.GRAPHSON_V3)); }
+
+ @Override
+ public void beforeEachScenario(final Scenario scenario) {
+ // not sure if it is expected or not that subgraph() does not work with GraphSON fully.
+ // getting serialization problems
+ final List<String> ignores = Arrays.asList("@StepSubgraph").stream().filter(t -> scenario.getSourceTagNames().contains(t)).collect(Collectors.toList());
+ if (!ignores.isEmpty())
+ throw new AssumptionViolatedException(String.format("This scenario is not supported with GraphComputer: %s", ignores));
+
+ super.beforeEachScenario(scenario);
+ }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index cefdc619dc..14e115e885 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -39,9 +39,11 @@ import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
@@ -58,7 +60,9 @@ import org.junit.AssumptionViolatedException;
import static org.apache.commons.text.StringEscapeUtils.escapeJava;
import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.Every.everyItem;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.StringContains.containsStringIgnoringCase;
@@ -80,6 +84,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -374,6 +379,60 @@ public final class StepDefinition {
fail(String.format("Missing an assert for this type", result.getClass()));
}
+ @Then("the result should be a subgraph with edges")
+ public void theResultShouldBeASubgraphWithEdges(final DataTable dataTable) {
+ assertThatNoErrorWasThrown();
+
+ // result should be a graph
+ assertThat(result, instanceOf(Graph.class));
+
+ // pop a graph traversal source from what was returned so we can use it for assertions
+ final GraphTraversalSource sg = ((Graph) result).traversal();
+
+ // grab the expected edges in the subgraph
+ final List<Edge> expectedEdges = dataTable.asList().stream().map(this::convertToObject).
+ map(e -> (Edge) e).collect(Collectors.toList());
+
+ // assert the structure of the subgraph. there should be no references here as this is serialized as
+ // a full TinkerGraph. also, ids should be the same as they are in the source graph so we can use all
+ // of this to do a complete assertion. there is only support for the modern graph right now but it
+ // wouldn't be hard to add others.
+ for (Edge edge : expectedEdges) {
+ assertThat(sg.E(edge.id()).
+ has(edge.label(), "weight", eq(edge.value("weight"))).
+ filter(__.outV().hasId(edge.outVertex().id())).
+ filter(__.inV().hasId(edge.inVertex().id())).hasNext(),
+ equalTo(true));
+ }
+ }
+
+ @Then("the result should be a subgraph with vertices")
+ public void theResultShouldBeASubgraphWithVertices(final DataTable dataTable) {
+ assertThatNoErrorWasThrown();
+
+ // result should be a graph
+ assertThat(result, instanceOf(Graph.class));
+
+ // pop a graph traversal source from what was returned so we can use it for assertions
+ final GraphTraversalSource sg = ((Graph) result).traversal();
+
+ // grab the expected vertex in the subgraph
+ final List<Vertex> expectedEdges = dataTable.asList().stream().map(this::convertToObject).
+ map(v -> (Vertex) v).collect(Collectors.toList());
+
+ // assert the structure of the subgraph. there should be no references here as this is serialized as
+ // a full TinkerGraph. also, ids should be the same as they are in the source graph so we can use all
+ // of this to do a complete assertion. there is only support for the modern graph right now but it
+ // wouldn't be hard to add others.
+ for (Vertex vertex : expectedEdges) {
+ final String variableKey = vertex.label().equals("person") ? "age" : "lang";
+
+ assertThat(sg.V(vertex.id()).has(vertex.label(), "name", eq(vertex.value("name"))).
+ has(variableKey, eq(vertex.value(variableKey))).hasNext(),
+ equalTo(true));
+ }
+ }
+
@Then("the graph should return {int} for count of {string}")
public void theGraphShouldReturnForCountOf(final Integer count, final String gremlin) {
assertThatNoErrorWasThrown();
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedComputerSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedComputerSuite.java
index f85568902f..68b3bebbc0 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedComputerSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedComputerSuite.java
@@ -62,7 +62,6 @@ public class ProcessEmbeddedComputerSuite extends AbstractGremlinSuite {
ProgramTest.Traversals.class,
WriteTest.Traversals.class,
ExplainTest.Traversals.class,
- SubgraphTest.Traversals.class,
TreeTest.Traversals.class,
LambdaStepTest.Traversals.class,
@@ -89,7 +88,6 @@ public class ProcessEmbeddedComputerSuite extends AbstractGremlinSuite {
MatchTest.class,
ProfileTest.class,
ProgramTest.class,
- SubgraphTest.class,
TreeTest.class
};
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedStandardSuite.java
index 2f746a49e3..086fa1fcc6 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessEmbeddedStandardSuite.java
@@ -22,19 +22,16 @@ import org.apache.tinkerpop.gremlin.AbstractGremlinSuite;
import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ComplexTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.LambdaStepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.TernaryBooleanLogicsTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProfileTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.ExplainTest;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.TreeTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.IncidentToAdjacentStrategyProcessTest;
@@ -62,7 +59,6 @@ public class ProcessEmbeddedStandardSuite extends AbstractGremlinSuite {
ProfileTest.Traversals.class,
WriteTest.Traversals.class,
ExplainTest.Traversals.class,
- SubgraphTest.Traversals.class,
TreeTest.Traversals.class,
// compliance
@@ -89,7 +85,6 @@ public class ProcessEmbeddedStandardSuite extends AbstractGremlinSuite {
*/
private static final Class<?>[] testsToEnforce = new Class<?>[]{
ProfileTest.class,
- SubgraphTest.class,
TreeTest.class,
};
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Edge.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Edge.feature
index f3d92320d2..70a5510558 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Edge.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Edge.feature
@@ -18,6 +18,117 @@
@StepClassMap @StepE
Feature: Step - E()
+ Scenario: g_E
+ Given the modern graph
+ And the traversal of
+ """
+ g.E()
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[marko-created->lop] |
+ | e[marko-knows->josh] |
+ | e[marko-knows->vadas] |
+ | e[peter-created->lop] |
+ | e[josh-created->lop] |
+ | e[josh-created->ripple] |
+
+ Scenario: g_EX11X
+ Given the modern graph
+ And using the parameter eid11 defined as "e[josh-created->lop].id"
+ And the traversal of
+ """
+ g.E(eid11)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[josh-created->lop] |
+
+ Scenario: g_EX11AsStringX
+ Given the modern graph
+ And using the parameter eid11 defined as "e[josh-created->lop].sid"
+ And the traversal of
+ """
+ g.E(eid11)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[josh-created->lop] |
+
+ Scenario: g_EXe11X
+ Given the modern graph
+ And using the parameter e11 defined as "e[josh-created->lop]"
+ And the traversal of
+ """
+ g.E(e11)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[josh-created->lop] |
+
+ Scenario: g_EXe7_e11X
+ Given the modern graph
+ And using the parameter e7 defined as "e[marko-knows->vadas]"
+ And using the parameter e11 defined as "e[josh-created->lop]"
+ And the traversal of
+ """
+ g.E(e7,e11)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[marko-knows->vadas] |
+ | e[josh-created->lop] |
+
+ Scenario: g_EXlistXe7_e11XX
+ Given the modern graph
+ And using the parameter xx1 defined as "l[e[marko-knows->vadas],e[josh-created->lop]]"
+ And the traversal of
+ """
+ g.E(xx1)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[marko-knows->vadas] |
+ | e[josh-created->lop] |
+
+ Scenario: g_EXnullX
+ Given the modern graph
+ And the traversal of
+ """
+ g.E(null)
+ """
+ When iterated to list
+ Then the result should be empty
+
+ Scenario: g_EXlistXnullXX
+ Given the modern graph
+ And using the parameter xx1 defined as "l[null]"
+ And the traversal of
+ """
+ g.E(xx1)
+ """
+ When iterated to list
+ Then the result should be empty
+
+ Scenario: g_EX11_nullX
+ Given the modern graph
+ And using the parameter eid11 defined as "e[josh-created->lop].id"
+ And the traversal of
+ """
+ g.E(eid11,null)
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | e[josh-created->lop] |
+
+ @GraphComputerVerificationMidENotSupported
Scenario: g_V_EX11X
Given the modern graph
And using the parameter eid11 defined as "e[josh-created->lop].id"
@@ -35,6 +146,7 @@ Feature: Step - E()
| e[josh-created->lop] |
| e[josh-created->lop] |
+ @GraphComputerVerificationMidENotSupported
Scenario: g_EX11X_E
Given the modern graph
And using the parameter eid11 defined as "e[josh-created->lop].id"
@@ -51,7 +163,8 @@ Feature: Step - E()
| e[peter-created->lop] |
| e[josh-created->lop] |
| e[josh-created->ripple] |
-
+
+ @GraphComputerVerificationMidENotSupported
Scenario: g_V_EXnullX
Given the modern graph
And the traversal of
@@ -61,6 +174,7 @@ Feature: Step - E()
When iterated to list
Then the result should be empty
+ @GraphComputerVerificationMidENotSupported
Scenario: g_V_EXlistXnullXX
Given the modern graph
And using the parameter xx1 defined as "l[null]"
@@ -71,6 +185,7 @@ Feature: Step - E()
When iterated to list
Then the result should be empty
+ @GraphComputerVerificationMidENotSupported
Scenario: g_injectX1X_EX11_nullX
Given the modern graph
And using the parameter eid11 defined as "e[josh-created->lop].id"
@@ -83,7 +198,8 @@ Feature: Step - E()
| result |
| e[josh-created->lop] |
- Scenario: g_injectX1X_coalesceXEX_hasLabelXtestsX_addEXtestsX_from_V_hasXnameX_XjoshXX_toXV_hasXnameX_XvadasXXX
+ @GraphComputerVerificationMidENotSupported
+ Scenario: g_injectX1X_coalesceXEX_hasLabelXtestsX_addEXtestsX_from_V_hasXnameX_XjoshXX_toXV_hasXnameX_XvadasXXX
Given the empty graph
And the graph initializer of
"""
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Graph.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Graph.feature
deleted file mode 100644
index d86ae75bd4..0000000000
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Graph.feature
+++ /dev/null
@@ -1,109 +0,0 @@
-# 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.
-
-@StepClassMap @StepV
-Feature: Step - V()
-
- Scenario: g_VX1X_V_valuesXnameX
- Given the modern graph
- And using the parameter vid1 defined as "v[marko].id"
- And the traversal of
- """
- g.V(vid1).V().values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | marko |
- | vadas |
- | lop |
- | josh |
- | ripple |
- | peter |
-
- Scenario: g_V_outXknowsX_V_name
- Given the modern graph
- And the traversal of
- """
- g.V().out("knows").V().values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | marko |
- | marko |
- | vadas |
- | vadas |
- | lop |
- | lop |
- | josh |
- | josh |
- | ripple |
- | ripple |
- | peter |
- | peter |
-
- Scenario: g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name
- Given the grateful graph
- And the traversal of
- """
- g.V().has("artist", "name", "Garcia").in("sungBy").as("song").
- V().has("artist", "name", "Willie_Dixon").in("writtenBy").where(P.eq("song")).values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | MY BABE |
- | HOOCHIE COOCHIE MAN |
-
- Scenario: g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX
- Given the empty graph
- And the graph initializer of
- """
- g.addV("person").property("name", "marko").property("age", 29).as("marko").
- addV("person").property("name", "vadas").property("age", 27).as("vadas").
- addV("software").property("name", "lop").property("lang", "java").as("lop").
- addV("person").property("name","josh").property("age", 32).as("josh").
- addV("software").property("name", "ripple").property("lang", "java").as("ripple").
- addV("person").property("name", "peter").property("age", 35).as('peter').
- addE("knows").from("marko").to("vadas").property("weight", 0.5d).
- addE("knows").from("marko").to("josh").property("weight", 1.0d).
- addE("created").from("marko").to("lop").property("weight", 0.4d).
- addE("created").from("josh").to("ripple").property("weight", 1.0d).
- addE("created").from("josh").to("lop").property("weight", 0.4d).
- addE("created").from("peter").to("lop").property("weight", 0.2d)
- """
- And using the parameter xx1 defined as "l[v[lop],v[ripple]]"
- And using the parameter vid1 defined as "v[marko].id"
- And using the parameter vid2 defined as "v[vadas].id"
- And using the parameter vid3 defined as "v[lop].id"
- And using the parameter vid4 defined as "v[josh].id"
- And using the parameter vid5 defined as "v[ripple].id"
- And using the parameter vid6 defined as "v[peter].id"
- And the traversal of
- """
- g.V().hasLabel("person").as("p").V(xx1).addE("uses").from("p")
- """
- When iterated to list
- Then the result should have a count of 8
- And the graph should return 8 for count of "g.E().hasLabel(\"uses\")"
- And the graph should return 2 for count of "g.V(vid1).outE(\"uses\")"
- And the graph should return 2 for count of "g.V(vid2).outE(\"uses\")"
- And the graph should return 4 for count of "g.V(vid3).inE(\"uses\")"
- And the graph should return 2 for count of "g.V(vid4).outE(\"uses\")"
- And the graph should return 4 for count of "g.V(vid5).inE(\"uses\")"
- And the graph should return 2 for count of "g.V(vid6).outE(\"uses\")"
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Vertex.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Vertex.feature
index f0b3c95a93..0d835cb5f5 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Vertex.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Vertex.feature
@@ -16,7 +16,7 @@
# under the License.
@StepClassMap @StepVertex
-Feature: Step - V(), E(), out(), in(), both(), inE(), outE(), bothE()
+Feature: Step - V(), out(), in(), both(), inE(), outE(), bothE()
Scenario: g_VXnullX
Given the modern graph
@@ -147,116 +147,6 @@ Feature: Step - V(), E(), out(), in(), both(), inE(), outE(), bothE()
| v[lop] |
| v[ripple] |
- Scenario: g_E
- Given the modern graph
- And the traversal of
- """
- g.E()
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[marko-created->lop] |
- | e[marko-knows->josh] |
- | e[marko-knows->vadas] |
- | e[peter-created->lop] |
- | e[josh-created->lop] |
- | e[josh-created->ripple] |
-
- Scenario: g_EX11X
- Given the modern graph
- And using the parameter eid11 defined as "e[josh-created->lop].id"
- And the traversal of
- """
- g.E(eid11)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[josh-created->lop] |
-
- Scenario: g_EX11AsStringX
- Given the modern graph
- And using the parameter eid11 defined as "e[josh-created->lop].sid"
- And the traversal of
- """
- g.E(eid11)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[josh-created->lop] |
-
- Scenario: g_EXe11X
- Given the modern graph
- And using the parameter e11 defined as "e[josh-created->lop]"
- And the traversal of
- """
- g.E(e11)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[josh-created->lop] |
-
- Scenario: g_EXe7_e11X
- Given the modern graph
- And using the parameter e7 defined as "e[marko-knows->vadas]"
- And using the parameter e11 defined as "e[josh-created->lop]"
- And the traversal of
- """
- g.E(e7,e11)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[marko-knows->vadas] |
- | e[josh-created->lop] |
-
- Scenario: g_EXlistXe7_e11XX
- Given the modern graph
- And using the parameter xx1 defined as "l[e[marko-knows->vadas],e[josh-created->lop]]"
- And the traversal of
- """
- g.E(xx1)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[marko-knows->vadas] |
- | e[josh-created->lop] |
-
- Scenario: g_EXnullX
- Given the modern graph
- And the traversal of
- """
- g.E(null)
- """
- When iterated to list
- Then the result should be empty
-
- Scenario: g_EXlistXnullXX
- Given the modern graph
- And using the parameter xx1 defined as "l[null]"
- And the traversal of
- """
- g.E(xx1)
- """
- When iterated to list
- Then the result should be empty
-
- Scenario: g_EX11_nullX
- Given the modern graph
- And using the parameter eid11 defined as "e[josh-created->lop].id"
- And the traversal of
- """
- g.E(eid11,null)
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | e[josh-created->lop] |
-
Scenario: g_VX1X_outE
Given the modern graph
And using the parameter vid1 defined as "v[marko].id"
@@ -663,4 +553,97 @@ Feature: Step - V(), E(), out(), in(), both(), inE(), outE(), bothE()
When iterated to list
Then the result should be unordered
| result |
- | v[marko] |
\ No newline at end of file
+ | v[marko] |
+
+ @GraphComputerVerificationMidENotSupported
+ Scenario: g_VX1X_V_valuesXnameX
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
+ And the traversal of
+ """
+ g.V(vid1).V().values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | marko |
+ | vadas |
+ | lop |
+ | josh |
+ | ripple |
+ | peter |
+
+ @GraphComputerVerificationMidENotSupported
+ Scenario: g_V_outXknowsX_V_name
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().out("knows").V().values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | marko |
+ | marko |
+ | vadas |
+ | vadas |
+ | lop |
+ | lop |
+ | josh |
+ | josh |
+ | ripple |
+ | ripple |
+ | peter |
+ | peter |
+
+ @GraphComputerVerificationMidENotSupported
+ Scenario: g_V_hasXname_GarciaX_inXsungByX_asXsongX_V_hasXname_Willie_DixonX_inXwrittenByX_whereXeqXsongXX_name
+ Given the grateful graph
+ And the traversal of
+ """
+ g.V().has("artist", "name", "Garcia").in("sungBy").as("song").
+ V().has("artist", "name", "Willie_Dixon").in("writtenBy").where(P.eq("song")).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | MY BABE |
+ | HOOCHIE COOCHIE MAN |
+
+ Scenario: g_V_hasLabelXpersonX_asXpX_VXsoftwareX_addInEXuses_pX
+ Given the empty graph
+ And the graph initializer of
+ """
+ g.addV("person").property("name", "marko").property("age", 29).as("marko").
+ addV("person").property("name", "vadas").property("age", 27).as("vadas").
+ addV("software").property("name", "lop").property("lang", "java").as("lop").
+ addV("person").property("name","josh").property("age", 32).as("josh").
+ addV("software").property("name", "ripple").property("lang", "java").as("ripple").
+ addV("person").property("name", "peter").property("age", 35).as('peter').
+ addE("knows").from("marko").to("vadas").property("weight", 0.5d).
+ addE("knows").from("marko").to("josh").property("weight", 1.0d).
+ addE("created").from("marko").to("lop").property("weight", 0.4d).
+ addE("created").from("josh").to("ripple").property("weight", 1.0d).
+ addE("created").from("josh").to("lop").property("weight", 0.4d).
+ addE("created").from("peter").to("lop").property("weight", 0.2d)
+ """
+ And using the parameter xx1 defined as "l[v[lop],v[ripple]]"
+ And using the parameter vid1 defined as "v[marko].id"
+ And using the parameter vid2 defined as "v[vadas].id"
+ And using the parameter vid3 defined as "v[lop].id"
+ And using the parameter vid4 defined as "v[josh].id"
+ And using the parameter vid5 defined as "v[ripple].id"
+ And using the parameter vid6 defined as "v[peter].id"
+ And the traversal of
+ """
+ g.V().hasLabel("person").as("p").V(xx1).addE("uses").from("p")
+ """
+ When iterated to list
+ Then the result should have a count of 8
+ And the graph should return 8 for count of "g.E().hasLabel(\"uses\")"
+ And the graph should return 2 for count of "g.V(vid1).outE(\"uses\")"
+ And the graph should return 2 for count of "g.V(vid2).outE(\"uses\")"
+ And the graph should return 4 for count of "g.V(vid3).inE(\"uses\")"
+ And the graph should return 2 for count of "g.V(vid4).outE(\"uses\")"
+ And the graph should return 4 for count of "g.V(vid5).inE(\"uses\")"
+ And the graph should return 2 for count of "g.V(vid6).outE(\"uses\")"
\ No newline at end of file
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Subgraph.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Subgraph.feature
new file mode 100644
index 0000000000..93fb651fec
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Subgraph.feature
@@ -0,0 +1,55 @@
+# 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.
+
+@StepClassSideEffect @StepSubgraph
+Feature: Step - subgraph()
+
+ Scenario: g_VX1X_outEXknowsX_subgraphXsgX_name_capXsgX
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
+ And the traversal of
+ """
+ g.V(vid1).outE("knows").subgraph("sg").values("name").cap("sg")
+ """
+ When iterated next
+ Then the result should be a subgraph with edges
+ | e[marko-knows->josh] |
+ | e[marko-knows->vadas] |
+ And the result should be a subgraph with vertices
+ | v[marko] |
+ | v[vadas] |
+ | v[josh] |
+
+ Scenario: g_V_repeatXbothEXcreatedX_subgraphXsgX_outVX_timesX5X_name_dedup_capXsgX
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
+ And the traversal of
+ """
+ g.V().repeat(__.bothE("created").subgraph("sg").outV()).times(5).values("name").dedup().cap("sg")
+ """
+ When iterated next
+ Then the result should be a subgraph with edges
+ | e[marko-created->lop] |
+ | e[josh-created->lop] |
+ | e[josh-created->ripple] |
+ | e[peter-created->lop] |
+ And the result should be a subgraph with vertices
+ | v[marko] |
+ | v[lop] |
+ | v[josh] |
+ | v[peter] |
+ | v[ripple] |
\ No newline at end of file
diff --git a/hadoop-gremlin/src/test/java/org/apache/tinkerpop/gremlin/hadoop/HadoopGraphFeatureIntegrateTest.java b/hadoop-gremlin/src/test/java/org/apache/tinkerpop/gremlin/hadoop/HadoopGraphFeatureIntegrateTest.java
index d98aa132c0..b9fad5f7c8 100644
--- a/hadoop-gremlin/src/test/java/org/apache/tinkerpop/gremlin/hadoop/HadoopGraphFeatureIntegrateTest.java
+++ b/hadoop-gremlin/src/test/java/org/apache/tinkerpop/gremlin/hadoop/HadoopGraphFeatureIntegrateTest.java
@@ -53,7 +53,7 @@ import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData;
@RunWith(Cucumber.class)
@CucumberOptions(
- tags = "not @RemoteOnly and not @GraphComputerOnly and not @TinkerServiceRegistry and not @GraphComputerVerificationElementSupported",
+ tags = "not @RemoteOnly and not @GraphComputerOnly and not @TinkerServiceRegistry and not @InsertionOrderingRequired",
glue = { "org.apache.tinkerpop.gremlin.features" },
objectFactory = GuiceFactory.class,
features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
diff --git a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/SparkGraphFeatureIntegrateTest.java b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/SparkGraphFeatureIntegrateTest.java
index 03bd30c185..404bad3830 100644
--- a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/SparkGraphFeatureIntegrateTest.java
+++ b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/SparkGraphFeatureIntegrateTest.java
@@ -58,6 +58,7 @@ import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData;
@RunWith(Cucumber.class)
@CucumberOptions(
tags = "not @RemoteOnly and not @StepDrop and not @StepV and not @StepE and not @StepIndex and not @StepInject and " +
+ "not @StepSubgraph and not @GraphComputerVerificationMidENotSupported and " +
"not @GraphComputerVerificationOneBulk and not @GraphComputerVerificationStrategyNotSupported and " +
"not @GraphComputerVerificationMidVNotSupported and not @GraphComputerVerificationElementSupported and " +
"not @GraphComputerVerificationInjectionNotSupported and " +
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphComputerFeatureTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphComputerFeatureTest.java
index c519e1c416..51b39756e4 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphComputerFeatureTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphComputerFeatureTest.java
@@ -31,7 +31,7 @@ import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
- tags = "not @RemoteOnly and not @GraphComputerVerificationElementSupported",
+ tags = "not @RemoteOnly",
glue = { "org.apache.tinkerpop.gremlin.features" },
objectFactory = TinkerGraphComputerFeatureTest.TinkerGraphGuiceFactory.class,
features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerTransactionGraphComputerFeatureTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerTransactionGraphComputerFeatureTest.java
index e0efdb9249..748c6dd609 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerTransactionGraphComputerFeatureTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerTransactionGraphComputerFeatureTest.java
@@ -31,7 +31,7 @@ import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
- tags = "not @RemoteOnly and not @GraphComputerVerificationElementSupported",
+ tags = "not @RemoteOnly",
glue = { "org.apache.tinkerpop.gremlin.features" },
objectFactory = TinkerTransactionGraphComputerFeatureTest.TinkerGraphGuiceFactory.class,
features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerWorld.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerWorld.java
index 632f90e457..ca94f2d7ea 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerWorld.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerWorld.java
@@ -280,13 +280,19 @@ public abstract class TinkerWorld implements World {
public static class ComputerWorld implements World {
private static final Random RANDOM = TestHelper.RANDOM;
+ /**
+ * Defining these here allows them to be globally ignored for all {@code withComputer()} test setups.
+ */
private static final List<String> TAGS_TO_IGNORE = Arrays.asList(
"@StepDrop",
"@StepInject",
- "@StepV",
- "@StepE",
+ "@StepSubgraph",
+ "@InsertionOrderingRequired",
+ "@StepIndex",
+ "@GraphComputerVerificationElementSupported",
"@GraphComputerVerificationOneBulk",
"@GraphComputerVerificationStrategyNotSupported",
+ "@GraphComputerVerificationMidENotSupported",
"@GraphComputerVerificationMidVNotSupported",
"@GraphComputerVerificationInjectionNotSupported",
"@GraphComputerVerificationStarGraphExceeded",