This is an automated email from the ASF dual-hosted git repository. Cole-Greer pushed a commit to branch multi-label-toy-graph in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 5abaae710c1f9342dc7428aafc3dc76f362d6b38 Author: Cole Greer <[email protected]> AuthorDate: Mon Jul 6 13:08:05 2026 -0700 Wire up the zoo graph and convert read-only multi-label scenarios Adds ZOO to the GraphData enum and wires it into every test harness that already supports the other named toy graphs: TinkerWorld (embedded, transaction, and shuffle graph variants), RemoteWorld/TinkerFactoryDataLoader for server-backed tests, both gremlin-server-integration.yaml configs, and the Python, JavaScript, Go, and .NET GLV Gherkin runners. The zoo graph uses tinkergraph-multilabel.properties since it requires ZERO_OR_MORE vertex label cardinality. Updated the two graph-manager tests whose assertions hardcoded the total configured graph count, which shifted by one with the new entry. Converts scenarios in ElementMap.feature, ValueMap.feature, and Labels.feature from a bespoke empty-graph-plus-initializer fixture to the zoo graph wherever the traversal under test is read-only and the zoo's pre-populated multi-label vertices/edges (tux, lagoon, canopy, atlas, etc.) can express the same shape deterministically. Scenarios that mutate the graph, need a vertex with zero or exactly-one label, or depend on a provider's implicit default label-rendering mode (which is a per-World configuration switch independent of graph data) remain on the empty graph. Assisted-by: Claude Code:claude-sonnet-5 --- .../gremlin-server/gremlin-server-integration.yaml | 4 + .../Gherkin/ScenarioData.cs | 2 +- gremlin-go/driver/cucumber/cucumberWorld.go | 2 +- .../gremlin-javascript/test/cucumber/gremlin.js | 16 +- .../gremlin-javascript/test/cucumber/world.js | 2 +- .../src/main/python/tests/feature/terrain.py | 4 +- .../server/util/TinkerFactoryDataLoader.java | 5 +- .../gremlin/driver/remote/RemoteWorld.java | 3 + .../server/util/CheckedGraphManagerTest.java | 2 +- .../server/util/DefaultGraphManagerTest.java | 13 +- .../gremlin/server/gremlin-server-integration.yaml | 4 + .../apache/tinkerpop/gremlin/LoadGraphWith.java | 20 +- .../gremlin/language/translator/translations.json | 256 +++++++-------------- .../gremlin/test/features/map/ElementMap.feature | 36 ++- .../gremlin/test/features/map/Labels.feature | 32 +-- .../gremlin/test/features/map/ValueMap.feature | 24 +- .../tinkerpop/gremlin/tinkergraph/TinkerWorld.java | 17 ++ 17 files changed, 186 insertions(+), 256 deletions(-) diff --git a/docker/gremlin-server/gremlin-server-integration.yaml b/docker/gremlin-server/gremlin-server-integration.yaml index a730970f85..4f2f226b42 100644 --- a/docker/gremlin-server/gremlin-server-integration.yaml +++ b/docker/gremlin-server/gremlin-server-integration.yaml @@ -44,6 +44,9 @@ graphs: { sink: { configuration: conf/tinkergraph-service.properties, traversalSources: [{name: gsink}]}, + zoo: { + configuration: conf/tinkergraph-multilabel.properties, + traversalSources: [{name: gzoo}]}, tx: { configuration: conf/tinkertransactiongraph-service.properties, traversalSources: [{name: gtx}]}} @@ -53,6 +56,7 @@ lifecycleHooks: - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: crew, dataset: crew}} - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: grateful, dataset: grateful}} - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: sink, dataset: sink}} + - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: zoo, dataset: zoo}} scriptEngines: { gremlin-lang : {}, gremlin-groovy: { diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs index b337594415..5cf427fe92 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs @@ -39,7 +39,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin { internal class ScenarioData : IDisposable { - private static readonly string[] GraphNames = {"modern", "classic", "crew", "grateful", "sink"}; + private static readonly string[] GraphNames = {"modern", "classic", "crew", "grateful", "sink", "zoo"}; private static readonly IDictionary<string, Vertex> EmptyVertices = new ReadOnlyDictionary<string, Vertex>(new Dictionary<string, Vertex>()); diff --git a/gremlin-go/driver/cucumber/cucumberWorld.go b/gremlin-go/driver/cucumber/cucumberWorld.go index 9e9b8e0b79..d26e4d9c19 100644 --- a/gremlin-go/driver/cucumber/cucumberWorld.go +++ b/gremlin-go/driver/cucumber/cucumberWorld.go @@ -87,7 +87,7 @@ func NewCucumberWorld() *CucumberWorld { } } -var graphNames = []string{"modern", "classic", "crew", "grateful", "sink", "empty", "multilabel"} +var graphNames = []string{"modern", "classic", "crew", "grateful", "sink", "zoo", "empty", "multilabel"} func (t *CucumberWorld) getDataGraphFromMap(name string) *DataGraph { if val, ok := t.graphDataMap[name]; ok { diff --git a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js index 448d09a2fa..0d3dc0fba2 100644 --- a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js +++ b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js @@ -1209,15 +1209,15 @@ const gremlins = { g_V_elementMapXname_age_nullX: [function({g}) { return g.with_("singlelabel").V().elementMap("name", "age", null) }], g_withXmultilabelX_VXmarkoX_elementMap: [function({g}) { return g.with_("multilabel").V().has("name", "marko").elementMap() }], g_V_elementMap_single_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.V().elementMap() }], - g_withXmultilabelX_V_elementMap_multilabel: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.with_("multilabel").V().elementMap() }], + g_withXmultilabelX_V_elementMap_multilabel: [function({g}) { return g.with_("multilabel").V().has("name", "tux").elementMap("name", "species") }], g_V_elementMap_multi_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.V().elementMap() }], - g_withXsinglelabelX_V_elementMap_multi_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.with_("singlelabel").V().elementMap() }], + g_withXsinglelabelX_V_elementMap_multi_label_default: [function({g}) { return g.with_("singlelabel").V().has("name", "lagoon").elementMap("name", "biome") }], g_V_elementMap_single_label_vertex_multi_label_default: [function({g}) { return g.addV("person").property("name", "marko") }, function({g}) { return g.V().elementMap() }], g_withXsinglelabelX_V_elementMap_zero_label_vertex: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.with_("singlelabel").V().elementMap() }], g_withXmultilabelX_V_elementMap_zero_label_vertex: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.with_("multilabel").V().elementMap() }], g_V_elementMap_zero_label_vertex_multi_label_default: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.V().elementMap() }], g_V_elementMap_zero_label_vertex_single_label_default: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.V().elementMap() }], - g_withXmultilabelX_E_elementMap: [function({g}) { return g.addV("person").property("name", "marko").as("a").addV("person").property("name", "josh").as("b").addE("knows").from_("a").to("b").property("weight", 0.5) }, function({g}) { return g.with_("multilabel").E().elementMap() }], + g_withXmultilabelX_E_elementMap: [function({g}) { return g.with_("multilabel").E().has("since", 2018).hasLabel("livesIn").elementMap() }], g_E_elementMap_multi_label_default: [function({g}) { return g.addV("person").property("name", "marko").as("a").addV("person").property("name", "josh").as("b").addE("knows").from_("a").to("b").property("weight", 0.5) }, function({g}) { return g.E().elementMap() }], g_E_elementMap_single_label_default: [function({g}) { return g.addV("person").property("name", "marko").as("a").addV("person").property("name", "josh").as("b").addE("knows").from_("a").to("b").property("weight", 0.5) }, function({g}) { return g.E().elementMap() }], g_withXsinglelabelX_E_elementMap: [function({g}) { return g.addV("person").property("name", "marko").as("a").addV("person").property("name", "josh").as("b").addE("knows").from_("a").to("b").property("weight", 0.5) }, function({g}) { return g.with_("singlelabel").E().elementMap() }], @@ -1272,15 +1272,15 @@ const gremlins = { g_V_valuesXnameX_lTrim: [function({g}) { 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("ripple").addV("person").property("name", "peter").proper [...] g_V_valuesXnameX_order_fold_lTrimXlocalX: [function({g}) { 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("ripple").addV("person").property("name [...] g_V_hasLabelXpersonX_labels: [function({g}) { return g.V().hasLabel("person").labels() }], - g_V_labels_multilabel: [function({g}) { return g.addV("a", "b") }, function({g}) { return g.V().labels() }], + g_V_labels_multilabel: [function({g}) { return g.V().has("name", "tux").labels() }], g_addVXa_bX_labels_count: [function({g}) { return g.addV("a", "b") }, function({g}) { return g.V().labels().count() }], g_addV_labels: [function({g}) { return g.addV() }, function({g}) { return g.V().labels() }], g_E_labels: [function({g}) { return g.E().hasLabel("knows").labels() }], g_V_hasLabelXpersonX_labels_single_label_graph: [function({g}) { return g.V().hasLabel("person").labels() }], g_V_labels_single_label_graph: [function({g}) { return g.V().labels() }], g_E_labels_single_label_graph: [function({g}) { return g.E().hasLabel("knows").labels() }], - g_V_label_deprecated_multilabel: [function({g}) { return g.addV("a", "b").property("name", "test") }, function({g}) { return g.V().label().count() }], - g_V_label_deprecated_multilabel_value_is_one_of_labels: [function({g}) { return g.addV("a", "b").property("name", "test") }, function({g}) { return g.V().filter(__.label().is(P.within("a", "b"))) }], + g_V_label_deprecated_multilabel: [function({g}) { return g.V().has("name", "tux").label().count() }], + g_V_label_deprecated_multilabel_value_is_one_of_labels: [function({g}) { return g.V().has("name", "tux").filter(__.label().is(P.within("animal", "bird", "aquatic", "endangered"))) }], g_injectXfeature_test_nullX_length: [function({g}) { return g.inject("feature", "test", null).length() }], g_injectXfeature_test_nullX_lengthXlocalX: [function({g}) { return g.inject("feature", "test", null).length(Scope.local) }], g_injectXListXa_bXX_length: [function({g}) { return g.inject(["a", "b"]).length() }], @@ -1860,9 +1860,9 @@ const gremlins = { g_V_valueMapXname_ageX_byXisXxXXbyXunfoldX: [function({g}) { return g.V().valueMap("name", "age").by(__.is("x")).by(__.unfold()) }], g_withXmultilabelX_VXmarkoX_valueMap_withXtokensX: [function({g}) { return g.with_("multilabel").V().has("name", "marko").valueMap().with_(WithOptions.tokens) }], g_V_valueMap_withXtokensX_single_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.V().valueMap().with_(WithOptions.tokens) }], - g_withXmultilabelX_V_valueMap_withXtokensX_multilabel: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.with_("multilabel").V().valueMap().with_(WithOptions.tokens) }], + g_withXmultilabelX_V_valueMap_withXtokensX_multilabel: [function({g}) { return g.with_("multilabel").V().has("name", "tux").valueMap("name", "species").with_(WithOptions.tokens) }], g_V_valueMap_withXtokensX_multi_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.V().valueMap().with_(WithOptions.tokens) }], - g_withXsinglelabelX_V_valueMap_withXtokensX_multi_label_default: [function({g}) { return g.addV("person").addLabel("employee").property("name", "marko") }, function({g}) { return g.with_("singlelabel").V().valueMap().with_(WithOptions.tokens) }], + g_withXsinglelabelX_V_valueMap_withXtokensX_multi_label_default: [function({g}) { return g.with_("singlelabel").V().has("name", "lagoon").valueMap("name", "biome").with_(WithOptions.tokens) }], g_withXsinglelabelX_V_valueMapXtrueX_zero_label_vertex: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.with_("singlelabel").V().valueMap(true) }], g_withXmultilabelX_V_valueMapXtrueX_zero_label_vertex: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.with_("multilabel").V().valueMap(true) }], g_V_valueMapXtrueX_zero_label_vertex_multi_label_default: [function({g}) { return g.addV().property("name", "nobody") }, function({g}) { return g.V().valueMap(true) }], diff --git a/gremlin-js/gremlin-javascript/test/cucumber/world.js b/gremlin-js/gremlin-javascript/test/cucumber/world.js index 04d1125579..be25215efe 100644 --- a/gremlin-js/gremlin-javascript/test/cucumber/world.js +++ b/gremlin-js/gremlin-javascript/test/cucumber/world.js @@ -84,7 +84,7 @@ setWorldConstructor(TinkerPopWorld); BeforeAll(function () { // load all traversals - const promises = ['modern', 'classic', 'crew', 'grateful', 'sink', 'empty', 'multilabel'].map(graphName => { + const promises = ['modern', 'classic', 'crew', 'grateful', 'sink', 'zoo', 'empty', 'multilabel'].map(graphName => { let connection = null; if (graphName === 'empty') { connection = getConnection('ggraph'); diff --git a/gremlin-python/src/main/python/tests/feature/terrain.py b/gremlin-python/src/main/python/tests/feature/terrain.py index 55489c7807..a5035879ea 100644 --- a/gremlin-python/src/main/python/tests/feature/terrain.py +++ b/gremlin-python/src/main/python/tests/feature/terrain.py @@ -42,7 +42,7 @@ def prepare_static_traversal_source(features, marker): # as the various traversal sources for testing do not change their data, there is no need to re-create remotes # and client side lookup data over and over. it can be created once for all tests and be reused. cache = {} - for graph_name in (("modern", "gmodern"), ("classic", "gclassic"), ("crew", "gcrew"), ("grateful", "ggrateful"), ("sink", "gsink")): + for graph_name in (("modern", "gmodern"), ("classic", "gclassic"), ("crew", "gcrew"), ("grateful", "ggrateful"), ("sink", "gsink"), ("zoo", "gzoo")): cache[graph_name[0]] = {} remote = __create_remote(graph_name[1]) cache[graph_name[0]]["remote_conn"] = __create_remote(graph_name[1]) @@ -62,7 +62,7 @@ def prepare_static_traversal_source(features, marker): scenario.context.lookup_e = {} scenario.context.lookup_vp = {} - for graph_name in ("modern", "classic", "crew", "grateful", "sink"): + for graph_name in ("modern", "classic", "crew", "grateful", "sink", "zoo"): scenario.context.remote_conn[graph_name] = cache[graph_name]["remote_conn"] scenario.context.lookup_v[graph_name] = cache[graph_name]["lookup_v"] scenario.context.lookup_e[graph_name] = cache[graph_name]["lookup_e"] diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TinkerFactoryDataLoader.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TinkerFactoryDataLoader.java index a211d81426..3e01a887f4 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TinkerFactoryDataLoader.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TinkerFactoryDataLoader.java @@ -31,7 +31,7 @@ import java.util.Map; * <p>Configuration parameters (via {@code config} in YAML): * <ul> * <li>{@code graph} — name of the graph (as defined in {@code graphs:} config) to load data into</li> - * <li>{@code dataset} — which dataset to load: modern, classic, crew, grateful, sink, airroutes</li> + * <li>{@code dataset} — which dataset to load: modern, classic, crew, grateful, sink, airroutes, zoo</li> * </ul> * * <p>Example YAML usage: @@ -88,6 +88,9 @@ public class TinkerFactoryDataLoader implements LifeCycleHook { case "airroutes": TinkerFactory.generateAirRoutes(tinkerGraph); break; + case "zoo": + TinkerFactory.generateTheZoo(tinkerGraph); + break; default: c.getLogger().warn("TinkerFactoryDataLoader unknown dataset [{}]", dataset); return; 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 8a19b4f3b7..972a753a5d 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 @@ -92,6 +92,9 @@ public abstract class RemoteWorld implements World { case GRATEFUL: remoteTraversalSource = "ggrateful"; break; + case ZOO: + remoteTraversalSource = "gzoo"; + break; default: throw new UnsupportedOperationException("GraphData not supported: " + graphData.name()); } diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/CheckedGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/CheckedGraphManagerTest.java index 490ead1423..f440a3bd5a 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/CheckedGraphManagerTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/CheckedGraphManagerTest.java @@ -66,7 +66,7 @@ public class CheckedGraphManagerTest { public void justAGraphFails() { settings.graphs.put("invalid", "conf/invalidPath"); final GraphManager manager = new CheckedGraphManager(settings); - assertThat(manager.getGraphNames(), hasSize(8)); + assertThat(manager.getGraphNames(), hasSize(9)); } /** diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java index 87af675779..b401b12e79 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/DefaultGraphManagerTest.java @@ -48,7 +48,7 @@ public class DefaultGraphManagerTest { final Set<String> graphNames = graphManager.getGraphNames(); assertNotNull(graphNames); - assertEquals(8, graphNames.size()); + assertEquals(9, graphNames.size()); assertThat(graphNames.contains("graph"), is(true)); assertThat(graphNames.contains("classic"), is(true)); @@ -56,6 +56,7 @@ public class DefaultGraphManagerTest { assertThat(graphNames.contains("crew"), is(true)); assertThat(graphNames.contains("sink"), is(true)); assertThat(graphNames.contains("grateful"), is(true)); + assertThat(graphNames.contains("zoo"), is(true)); assertThat(graphNames.contains("tx"), is(true)); assertThat(graphManager.getGraph("graph"), instanceOf(TinkerGraph.class)); assertThat(graphManager.getGraph("tx"), instanceOf(TinkerTransactionGraph.class)); @@ -68,13 +69,14 @@ public class DefaultGraphManagerTest { final Bindings bindings = graphManager.getAsBindings(); assertNotNull(bindings); - assertEquals(8, bindings.size()); + assertEquals(9, bindings.size()); assertThat(bindings.containsKey("graph"), is(true)); assertThat(bindings.containsKey("classic"), is(true)); assertThat(bindings.containsKey("modern"), is(true)); assertThat(bindings.containsKey("crew"), is(true)); assertThat(bindings.containsKey("sink"), is(true)); assertThat(bindings.containsKey("grateful"), is(true)); + assertThat(bindings.containsKey("zoo"), is(true)); assertThat(bindings.containsKey("tx"), is(true)); assertThat(bindings.get("graph"), instanceOf(TinkerGraph.class)); assertThat(bindings.get("tx"), instanceOf(TinkerTransactionGraph.class)); @@ -99,7 +101,7 @@ public class DefaultGraphManagerTest { final Set<String> graphNames = graphManager.getGraphNames(); assertNotNull(graphNames); - assertEquals(9, graphNames.size()); + assertEquals(10, graphNames.size()); assertThat(graphNames.contains("newGraph"), is(true)); assertThat(graphNames.contains("graph"), is(true)); assertThat(graphNames.contains("classic"), is(true)); @@ -107,6 +109,7 @@ public class DefaultGraphManagerTest { assertThat(graphNames.contains("crew"), is(true)); assertThat(graphNames.contains("sink"), is(true)); assertThat(graphNames.contains("grateful"), is(true)); + assertThat(graphNames.contains("zoo"), is(true)); assertThat(graphNames.contains("tx"), is(true)); assertThat(graphManager.getGraph("newGraph"), instanceOf(TinkerGraph.class)); assertThat(graphManager.getGraph("tx"), instanceOf(TinkerTransactionGraph.class)); @@ -120,14 +123,14 @@ public class DefaultGraphManagerTest { graphManager.putGraph("newGraph", graph); final Set<String> graphNames = graphManager.getGraphNames(); assertNotNull(graphNames); - assertEquals(9, graphNames.size()); + assertEquals(10, graphNames.size()); assertThat(graphNames.contains("newGraph"), is(true)); assertThat(graphManager.getGraph("newGraph"), instanceOf(TinkerGraph.class)); graphManager.removeGraph("newGraph"); final Set<String> graphNames2 = graphManager.getGraphNames(); - assertEquals(8, graphNames2.size()); + assertEquals(9, graphNames2.size()); assertThat(graphNames2.contains("newGraph"), is(false)); } diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml index 5e9a753eed..6e21e6a037 100644 --- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml +++ b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml @@ -53,6 +53,9 @@ graphs: { sink: { configuration: conf/tinkergraph-empty.properties, traversalSources: [{name: gsink}]}, + zoo: { + configuration: conf/tinkergraph-multilabel.properties, + traversalSources: [{name: gzoo}]}, tx: { configuration: conf/tinkertransactiongraph-empty.properties, traversalSources: [{name: gtx}]}} @@ -62,6 +65,7 @@ lifecycleHooks: - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: crew, dataset: crew}} - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: grateful, dataset: grateful}} - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: sink, dataset: sink}} + - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: zoo, dataset: zoo}} scriptEngines: { gremlin-lang : {}, groovy-test: {}, diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/LoadGraphWith.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/LoadGraphWith.java index b11de7411b..5418dff87a 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/LoadGraphWith.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/LoadGraphWith.java @@ -94,7 +94,13 @@ public @interface LoadGraphWith { * Loads the air-routes graph, a real-world dataset of ~3,500 airports and ~50,000 routes suitable for * benchmarking and integration testing of traversals that benefit from larger, denser graphs. */ - AIR_ROUTES; + AIR_ROUTES, + + /** + * Loads "The Zoo" TinkerPop4 toy graph which showcases multi-label vertices and a variety of property + * types. Requires a graph configured with {@code LabelCardinality.ZERO_OR_MORE} (or {@code ONE_OR_MORE}). + */ + ZOO; private static final List<FeatureRequirement> featuresRequiredByClassic = new ArrayList<FeatureRequirement>() {{ add(FeatureRequirement.Factory.create(FEATURE_STRING_VALUES, VertexPropertyFeatures.class)); @@ -132,6 +138,14 @@ public @interface LoadGraphWith { add(FeatureRequirement.Factory.create(FEATURE_INTEGER_VALUES, EdgePropertyFeatures.class)); }}; + private static final List<FeatureRequirement> featuresRequiredByZoo = new ArrayList<FeatureRequirement>() {{ + add(FeatureRequirement.Factory.create(FEATURE_STRING_VALUES, VertexPropertyFeatures.class)); + add(FeatureRequirement.Factory.create(FEATURE_INTEGER_VALUES, VertexPropertyFeatures.class)); + add(FeatureRequirement.Factory.create(FEATURE_DOUBLE_VALUES, VertexPropertyFeatures.class)); + add(FeatureRequirement.Factory.create(FEATURE_BOOLEAN_VALUES, VertexPropertyFeatures.class)); + add(FeatureRequirement.Factory.create(FEATURE_MULTI_PROPERTIES, Graph.Features.VertexFeatures.class)); + }}; + public String location() { switch (this) { case CLASSIC: @@ -146,6 +160,8 @@ public @interface LoadGraphWith { return RESOURCE_PATH_PREFIX + "tinkerpop-sink-v3.kryo"; case AIR_ROUTES: return RESOURCE_PATH_PREFIX + "air-routes-v3.kryo"; + case ZOO: + return RESOURCE_PATH_PREFIX + "tinkerpop-zoo-v3.kryo"; } throw new RuntimeException("No file for this GraphData type"); @@ -165,6 +181,8 @@ public @interface LoadGraphWith { return featuresRequiredBySink; case AIR_ROUTES: return featuresRequiredByAirRoutes; + case ZOO: + return featuresRequiredByZoo; } throw new RuntimeException("No features for this GraphData type"); diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json index b02dd7f067..3731a49316 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json @@ -23710,28 +23710,16 @@ "scenario": "g_withXmultilabelX_V_elementMap_multilabel", "traversals": [ { - "original": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "language": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "canonical": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "anonymized": "g.addV(string0).addLabel(string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "go": "g.AddV(\"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "groovy": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "java": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "javascript": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "python": "g.add_v('person').add_label('employee').property('name', 'marko')" - }, - { - "original": "g.with(\"multilabel\").V().elementMap()", - "language": "g.with(\"multilabel\").V().elementMap()", - "canonical": "g.with(\"multilabel\").V().elementMap()", - "anonymized": "g.with(string0).V().elementMap()", - "dotnet": "g.With(\"multilabel\").V().ElementMap<object>()", - "go": "g.With(\"multilabel\").V().ElementMap()", - "groovy": "g.with(\"multilabel\").V().elementMap()", - "java": "g.with(\"multilabel\").V().elementMap()", - "javascript": "g.with_(\"multilabel\").V().elementMap()", - "python": "g.with_('multilabel').V().element_map()" + "original": "g.with(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "language": "g.with(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "canonical": "g.with(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "anonymized": "g.with(string0).V().has(string1, string2).elementMap(string1, string3)", + "dotnet": "g.With(\"multilabel\").V().Has(\"name\", \"tux\").ElementMap<object>(\"name\", \"species\")", + "go": "g.With(\"multilabel\").V().Has(\"name\", \"tux\").ElementMap(\"name\", \"species\")", + "groovy": "g.with(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "java": "g.with(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "javascript": "g.with_(\"multilabel\").V().has(\"name\", \"tux\").elementMap(\"name\", \"species\")", + "python": "g.with_('multilabel').V().has('name', 'tux').element_map('name', 'species')" } ] }, @@ -23768,28 +23756,16 @@ "scenario": "g_withXsinglelabelX_V_elementMap_multi_label_default", "traversals": [ { - "original": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "language": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "canonical": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "anonymized": "g.addV(string0).addLabel(string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "go": "g.AddV(\"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "groovy": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "java": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "javascript": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "python": "g.add_v('person').add_label('employee').property('name', 'marko')" - }, - { - "original": "g.with(\"singlelabel\").V().elementMap()", - "language": "g.with(\"singlelabel\").V().elementMap()", - "canonical": "g.with(\"singlelabel\").V().elementMap()", - "anonymized": "g.with(string0).V().elementMap()", - "dotnet": "g.With(\"singlelabel\").V().ElementMap<object>()", - "go": "g.With(\"singlelabel\").V().ElementMap()", - "groovy": "g.with(\"singlelabel\").V().elementMap()", - "java": "g.with(\"singlelabel\").V().elementMap()", - "javascript": "g.with_(\"singlelabel\").V().elementMap()", - "python": "g.with_('singlelabel').V().element_map()" + "original": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "language": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "canonical": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "anonymized": "g.with(string0).V().has(string1, string2).elementMap(string1, string3)", + "dotnet": "g.With(\"singlelabel\").V().Has(\"name\", \"lagoon\").ElementMap<object>(\"name\", \"biome\")", + "go": "g.With(\"singlelabel\").V().Has(\"name\", \"lagoon\").ElementMap(\"name\", \"biome\")", + "groovy": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "java": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "javascript": "g.with_(\"singlelabel\").V().has(\"name\", \"lagoon\").elementMap(\"name\", \"biome\")", + "python": "g.with_('singlelabel').V().has('name', 'lagoon').element_map('name', 'biome')" } ] }, @@ -23942,28 +23918,16 @@ "scenario": "g_withXmultilabelX_E_elementMap", "traversals": [ { - "original": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"weight\", 0.5)", - "language": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"weight\", 0.5)", - "canonical": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"weight\", 0.5)", - "anonymized": "g.addV(string0).property(string1, string2).as(string3).addV(string0).property(string1, string4).as(string5).addE(string6).from(string3).to(string5).property(string7, number0)", - "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").As(\"a\").AddV((string) \"person\").Property(\"name\", \"josh\").As(\"b\").AddE((string) \"knows\").From(\"a\").To(\"b\").Property(\"weight\", 0.5)", - "go": "g.AddV(\"person\").Property(\"name\", \"marko\").As(\"a\").AddV(\"person\").Property(\"name\", \"josh\").As(\"b\").AddE(\"knows\").From(\"a\").To(\"b\").Property(\"weight\", 0.5)", - "groovy": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"weight\", 0.5)", - "java": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"weight\", 0.5)", - "javascript": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"josh\").as(\"b\").addE(\"knows\").from_(\"a\").to(\"b\").property(\"weight\", 0.5)", - "python": "g.add_v('person').property('name', 'marko').as_('a').add_v('person').property('name', 'josh').as_('b').add_e('knows').from_('a').to('b').property('weight', 0.5)" - }, - { - "original": "g.with(\"multilabel\").E().elementMap()", - "language": "g.with(\"multilabel\").E().elementMap()", - "canonical": "g.with(\"multilabel\").E().elementMap()", - "anonymized": "g.with(string0).E().elementMap()", - "dotnet": "g.With(\"multilabel\").E().ElementMap<object>()", - "go": "g.With(\"multilabel\").E().ElementMap()", - "groovy": "g.with(\"multilabel\").E().elementMap()", - "java": "g.with(\"multilabel\").E().elementMap()", - "javascript": "g.with_(\"multilabel\").E().elementMap()", - "python": "g.with_('multilabel').E().element_map()" + "original": "g.with(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "language": "g.with(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "canonical": "g.with(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "anonymized": "g.with(string0).E().has(string1, number0).hasLabel(string2).elementMap()", + "dotnet": "g.With(\"multilabel\").E().Has(\"since\", 2018).HasLabel(\"livesIn\").ElementMap<object>()", + "go": "g.With(\"multilabel\").E().Has(\"since\", 2018).HasLabel(\"livesIn\").ElementMap()", + "groovy": "g.with(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "java": "g.with(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "javascript": "g.with_(\"multilabel\").E().has(\"since\", 2018).hasLabel(\"livesIn\").elementMap()", + "python": "g.with_('multilabel').E().has('since', 2018).has_label('livesIn').element_map()" } ] }, @@ -24949,28 +24913,16 @@ "scenario": "g_V_labels_multilabel", "traversals": [ { - "original": "g.addV(\"a\", \"b\")", - "language": "g.addV(\"a\", \"b\")", - "canonical": "g.addV(\"a\", \"b\")", - "anonymized": "g.addV(string0, string1)", - "dotnet": "g.AddV((string) \"a\", (string) \"b\")", - "go": "g.AddV(\"a\", \"b\")", - "groovy": "g.addV(\"a\", \"b\")", - "java": "g.addV(\"a\", \"b\")", - "javascript": "g.addV(\"a\", \"b\")", - "python": "g.add_v('a', 'b')" - }, - { - "original": "g.V().labels()", - "language": "g.V().labels()", - "canonical": "g.V().labels()", - "anonymized": "g.V().labels()", - "dotnet": "g.V().Labels()", - "go": "g.V().Labels()", - "groovy": "g.V().labels()", - "java": "g.V().labels()", - "javascript": "g.V().labels()", - "python": "g.V().labels()" + "original": "g.V().has(\"name\", \"tux\").labels()", + "language": "g.V().has(\"name\", \"tux\").labels()", + "canonical": "g.V().has(\"name\", \"tux\").labels()", + "anonymized": "g.V().has(string0, string1).labels()", + "dotnet": "g.V().Has(\"name\", \"tux\").Labels()", + "go": "g.V().Has(\"name\", \"tux\").Labels()", + "groovy": "g.V().has(\"name\", \"tux\").labels()", + "java": "g.V().has(\"name\", \"tux\").labels()", + "javascript": "g.V().has(\"name\", \"tux\").labels()", + "python": "g.V().has('name', 'tux').labels()" } ] }, @@ -25104,28 +25056,16 @@ "scenario": "g_V_label_deprecated_multilabel", "traversals": [ { - "original": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "language": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "canonical": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "anonymized": "g.addV(string0, string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"a\", (string) \"b\").Property(\"name\", \"test\")", - "go": "g.AddV(\"a\", \"b\").Property(\"name\", \"test\")", - "groovy": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "java": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "javascript": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "python": "g.add_v('a', 'b').property('name', 'test')" - }, - { - "original": "g.V().label().count()", - "language": "g.V().label().count()", - "canonical": "g.V().label().count()", - "anonymized": "g.V().label().count()", - "dotnet": "g.V().Label().Count()", - "go": "g.V().Label().Count()", - "groovy": "g.V().label().count()", - "java": "g.V().label().count()", - "javascript": "g.V().label().count()", - "python": "g.V().label().count()" + "original": "g.V().has(\"name\", \"tux\").label().count()", + "language": "g.V().has(\"name\", \"tux\").label().count()", + "canonical": "g.V().has(\"name\", \"tux\").label().count()", + "anonymized": "g.V().has(string0, string1).label().count()", + "dotnet": "g.V().Has(\"name\", \"tux\").Label().Count()", + "go": "g.V().Has(\"name\", \"tux\").Label().Count()", + "groovy": "g.V().has(\"name\", \"tux\").label().count()", + "java": "g.V().has(\"name\", \"tux\").label().count()", + "javascript": "g.V().has(\"name\", \"tux\").label().count()", + "python": "g.V().has('name', 'tux').label().count()" } ] }, @@ -25133,28 +25073,16 @@ "scenario": "g_V_label_deprecated_multilabel_value_is_one_of_labels", "traversals": [ { - "original": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "language": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "canonical": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "anonymized": "g.addV(string0, string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"a\", (string) \"b\").Property(\"name\", \"test\")", - "go": "g.AddV(\"a\", \"b\").Property(\"name\", \"test\")", - "groovy": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "java": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "javascript": "g.addV(\"a\", \"b\").property(\"name\", \"test\")", - "python": "g.add_v('a', 'b').property('name', 'test')" - }, - { - "original": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "language": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "canonical": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "anonymized": "g.V().filter(__.label().is(P.within(string0, string1)))", - "dotnet": "g.V().Filter(__.Label().Is(P.Within(\"a\", \"b\")))", - "go": "g.V().Filter(gremlingo.T__.Label().Is(gremlingo.P.Within(\"a\", \"b\")))", - "groovy": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "java": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "javascript": "g.V().filter(__.label().is(P.within(\"a\", \"b\")))", - "python": "g.V().filter_(__.label().is_(P.within('a', 'b')))" + "original": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "language": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "canonical": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "anonymized": "g.V().has(string0, string1).filter(__.label().is(P.within(string2, string3, string4, string5)))", + "dotnet": "g.V().Has(\"name\", \"tux\").Filter(__.Label().Is(P.Within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "go": "g.V().Has(\"name\", \"tux\").Filter(gremlingo.T__.Label().Is(gremlingo.P.Within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "groovy": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "java": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "javascript": "g.V().has(\"name\", \"tux\").filter(__.label().is(P.within(\"animal\", \"bird\", \"aquatic\", \"endangered\")))", + "python": "g.V().has('name', 'tux').filter_(__.label().is_(P.within('animal', 'bird', 'aquatic', 'endangered')))" } ] }, @@ -39253,28 +39181,16 @@ "scenario": "g_withXmultilabelX_V_valueMap_withXtokensX_multilabel", "traversals": [ { - "original": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "language": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "canonical": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "anonymized": "g.addV(string0).addLabel(string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "go": "g.AddV(\"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "groovy": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "java": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "javascript": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "python": "g.add_v('person').add_label('employee').property('name', 'marko')" - }, - { - "original": "g.with(\"multilabel\").V().valueMap().with(WithOptions.tokens)", - "language": "g.with(\"multilabel\").V().valueMap().with(WithOptions.tokens)", - "canonical": "g.with(\"multilabel\").V().valueMap().with(WithOptions.tokens)", - "anonymized": "g.with(string0).V().valueMap().with(WithOptions.tokens)", - "dotnet": "g.With(\"multilabel\").V().ValueMap<object, object>().With(WithOptions.Tokens)", - "go": "g.With(\"multilabel\").V().ValueMap().With(gremlingo.WithOptions.Tokens)", - "groovy": "g.with(\"multilabel\").V().valueMap().with(WithOptions.tokens)", - "java": "g.with(\"multilabel\").V().valueMap().with(WithOptions.tokens)", - "javascript": "g.with_(\"multilabel\").V().valueMap().with_(WithOptions.tokens)", - "python": "g.with_('multilabel').V().value_map().with_(WithOptions.tokens)" + "original": "g.with(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with(WithOptions.tokens)", + "language": "g.with(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with(WithOptions.tokens)", + "canonical": "g.with(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with(WithOptions.tokens)", + "anonymized": "g.with(string0).V().has(string1, string2).valueMap(string1, string3).with(WithOptions.tokens)", + "dotnet": "g.With(\"multilabel\").V().Has(\"name\", \"tux\").ValueMap<object, object>(\"name\", \"species\").With(WithOptions.Tokens)", + "go": "g.With(\"multilabel\").V().Has(\"name\", \"tux\").ValueMap(\"name\", \"species\").With(gremlingo.WithOptions.Tokens)", + "groovy": "g.with(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with(WithOptions.tokens)", + "java": "g.with(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with(WithOptions.tokens)", + "javascript": "g.with_(\"multilabel\").V().has(\"name\", \"tux\").valueMap(\"name\", \"species\").with_(WithOptions.tokens)", + "python": "g.with_('multilabel').V().has('name', 'tux').value_map('name', 'species').with_(WithOptions.tokens)" } ] }, @@ -39311,28 +39227,16 @@ "scenario": "g_withXsinglelabelX_V_valueMap_withXtokensX_multi_label_default", "traversals": [ { - "original": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "language": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "canonical": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "anonymized": "g.addV(string0).addLabel(string1).property(string2, string3)", - "dotnet": "g.AddV((string) \"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "go": "g.AddV(\"person\").AddLabel(\"employee\").Property(\"name\", \"marko\")", - "groovy": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "java": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "javascript": "g.addV(\"person\").addLabel(\"employee\").property(\"name\", \"marko\")", - "python": "g.add_v('person').add_label('employee').property('name', 'marko')" - }, - { - "original": "g.with(\"singlelabel\").V().valueMap().with(WithOptions.tokens)", - "language": "g.with(\"singlelabel\").V().valueMap().with(WithOptions.tokens)", - "canonical": "g.with(\"singlelabel\").V().valueMap().with(WithOptions.tokens)", - "anonymized": "g.with(string0).V().valueMap().with(WithOptions.tokens)", - "dotnet": "g.With(\"singlelabel\").V().ValueMap<object, object>().With(WithOptions.Tokens)", - "go": "g.With(\"singlelabel\").V().ValueMap().With(gremlingo.WithOptions.Tokens)", - "groovy": "g.with(\"singlelabel\").V().valueMap().with(WithOptions.tokens)", - "java": "g.with(\"singlelabel\").V().valueMap().with(WithOptions.tokens)", - "javascript": "g.with_(\"singlelabel\").V().valueMap().with_(WithOptions.tokens)", - "python": "g.with_('singlelabel').V().value_map().with_(WithOptions.tokens)" + "original": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with(WithOptions.tokens)", + "language": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with(WithOptions.tokens)", + "canonical": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with(WithOptions.tokens)", + "anonymized": "g.with(string0).V().has(string1, string2).valueMap(string1, string3).with(WithOptions.tokens)", + "dotnet": "g.With(\"singlelabel\").V().Has(\"name\", \"lagoon\").ValueMap<object, object>(\"name\", \"biome\").With(WithOptions.Tokens)", + "go": "g.With(\"singlelabel\").V().Has(\"name\", \"lagoon\").ValueMap(\"name\", \"biome\").With(gremlingo.WithOptions.Tokens)", + "groovy": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with(WithOptions.tokens)", + "java": "g.with(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with(WithOptions.tokens)", + "javascript": "g.with_(\"singlelabel\").V().has(\"name\", \"lagoon\").valueMap(\"name\", \"biome\").with_(WithOptions.tokens)", + "python": "g.with_('singlelabel').V().has('name', 'lagoon').value_map('name', 'biome').with_(WithOptions.tokens)" } ] }, diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ElementMap.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ElementMap.feature index 4cc80f1529..409fba71b1 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ElementMap.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ElementMap.feature @@ -110,19 +110,15 @@ Feature: Step - elementMap() @MultiLabel Scenario: g_withXmultilabelX_V_elementMap_multilabel - Given the empty graph - And the graph initializer of - """ - g.addV("person").addLabel("employee").property("name", "marko") - """ + Given the zoo graph And the traversal of """ - g.with("multilabel").V().elementMap() + g.with("multilabel").V().has("name", "tux").elementMap("name", "species") """ When iterated to list Then the result should be unordered | result | - | m[{"t[id]": "v[marko].id", "t[label]": "s[person,employee]", "name": "marko"}] | + | m[{"t[id]": "v[tux].id", "t[label]": "s[animal,bird,aquatic,endangered]", "name": "tux", "species": "african penguin"}] | @MultiLabel @MultiLabelDefault Scenario: g_V_elementMap_multi_label_default @@ -142,19 +138,17 @@ Feature: Step - elementMap() @MultiLabel @MultiLabelDefault Scenario: g_withXsinglelabelX_V_elementMap_multi_label_default - Given the empty graph - And the graph initializer of - """ - g.addV("person").addLabel("employee").property("name", "marko") - """ + Given the zoo graph And the traversal of """ - g.with("singlelabel").V().elementMap() + g.with("singlelabel").V().has("name", "lagoon").elementMap("name", "biome") """ When iterated to list - Then the result should be unordered + Then the result should have a count of 1 + And the result should be of | result | - | m[{"t[id]": "v[marko].id", "t[label]": "person", "name": "marko"}] | + | m[{"t[id]": "v[lagoon].id", "t[label]": "habitat", "name": "lagoon", "biome": "marine"}] | + | m[{"t[id]": "v[lagoon].id", "t[label]": "aquatic", "name": "lagoon", "biome": "marine"}] | @MultiLabel @MultiLabelDefault Scenario: g_V_elementMap_single_label_vertex_multi_label_default @@ -236,21 +230,17 @@ Feature: Step - elementMap() | result | | m[{"t[id]": "v[nobody].id", "name": "nobody"}] | - @MultiLabel + @GraphComputerVerificationReferenceOnly @MultiLabel Scenario: g_withXmultilabelX_E_elementMap - Given the empty graph - And the graph initializer of - """ - g.addV("person").property("name", "marko").as("a").addV("person").property("name", "josh").as("b").addE("knows").from("a").to("b").property("weight", 0.5) - """ + Given the zoo graph And the traversal of """ - g.with("multilabel").E().elementMap() + g.with("multilabel").E().has("since", 2018).hasLabel("livesIn").elementMap() """ When iterated to list Then the result should be unordered | result | - | m[{"t[id]": "e[marko-knows->josh].id", "t[label]": "s[knows]", "weight": "d[0.5].d", "D[OUT]": "m[{\\"t[id]\\": \\"v[marko].id\\", \\"t[label]\\": \\"s[person]\\"}]", "D[IN]": "m[{\\"t[id]\\": \\"v[josh].id\\", \\"t[label]\\": \\"s[person]\\"}]"}] | + | m[{"t[id]": "e[atlas-livesIn->lagoon].id", "t[label]": "s[livesIn]", "since": 2018, "D[OUT]": "m[{\\"t[id]\\": \\"v[atlas].id\\", \\"t[label]\\": \\"s[animal,reptile,aquatic,endangered]\\"}]", "D[IN]": "m[{\\"t[id]\\": \\"v[lagoon].id\\", \\"t[label]\\": \\"s[habitat,aquatic]\\"}]"}] | @GraphComputerVerificationReferenceOnly @MultiLabel @MultiLabelDefault Scenario: g_E_elementMap_multi_label_default diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Labels.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Labels.feature index aeb21a3404..7598afa791 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Labels.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Labels.feature @@ -35,20 +35,18 @@ Feature: Step - labels() @MultiLabel Scenario: g_V_labels_multilabel - Given the empty graph - And the graph initializer of - """ - g.addV("a", "b") - """ + Given the zoo graph And the traversal of """ - g.V().labels() + g.V().has("name", "tux").labels() """ When iterated to list Then the result should be unordered | result | - | a | - | b | + | animal | + | bird | + | aquatic | + | endangered | @MultiLabel Scenario: g_addVXa_bX_labels_count @@ -137,14 +135,10 @@ Feature: Step - labels() @MultiLabel Scenario: g_V_label_deprecated_multilabel - Given the empty graph - And the graph initializer of - """ - g.addV("a", "b").property("name", "test") - """ + Given the zoo graph And the traversal of """ - g.V().label().count() + g.V().has("name", "tux").label().count() """ When iterated to list Then the result should be unordered @@ -153,14 +147,10 @@ Feature: Step - labels() @MultiLabel Scenario: g_V_label_deprecated_multilabel_value_is_one_of_labels - Given the empty graph - And the graph initializer of - """ - g.addV("a", "b").property("name", "test") - """ + Given the zoo graph And the traversal of """ - g.V().filter(__.label().is(P.within("a", "b"))) + g.V().has("name", "tux").filter(__.label().is(P.within("animal", "bird", "aquatic", "endangered"))) """ When iterated to list - Then the result should have a count of 1 \ No newline at end of file + Then the result should have a count of 1 diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ValueMap.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ValueMap.feature index 351254804e..698dc1d808 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ValueMap.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/ValueMap.feature @@ -252,19 +252,15 @@ Feature: Step - valueMap() @MultiLabel Scenario: g_withXmultilabelX_V_valueMap_withXtokensX_multilabel - Given the empty graph - And the graph initializer of - """ - g.addV("person").addLabel("employee").property("name", "marko") - """ + Given the zoo graph And the traversal of """ - g.with("multilabel").V().valueMap().with(WithOptions.tokens) + g.with("multilabel").V().has("name", "tux").valueMap("name", "species").with(WithOptions.tokens) """ When iterated to list Then the result should be unordered | result | - | m[{"t[id]": "v[marko].id", "t[label]": "s[person,employee]", "name": ["marko"]}] | + | m[{"t[id]": "v[tux].id", "t[label]": "s[animal,bird,aquatic,endangered]", "name": ["tux"], "species": ["african penguin"]}] | @MultiLabel @MultiLabelDefault Scenario: g_V_valueMap_withXtokensX_multi_label_default @@ -284,19 +280,17 @@ Feature: Step - valueMap() @MultiLabel @MultiLabelDefault Scenario: g_withXsinglelabelX_V_valueMap_withXtokensX_multi_label_default - Given the empty graph - And the graph initializer of - """ - g.addV("person").addLabel("employee").property("name", "marko") - """ + Given the zoo graph And the traversal of """ - g.with("singlelabel").V().valueMap().with(WithOptions.tokens) + g.with("singlelabel").V().has("name", "lagoon").valueMap("name", "biome").with(WithOptions.tokens) """ When iterated to list - Then the result should be unordered + Then the result should have a count of 1 + And the result should be of | result | - | m[{"t[id]": "v[marko].id", "t[label]": "person", "name": ["marko"]}] | + | m[{"t[id]": "v[lagoon].id", "t[label]": "habitat", "name": ["lagoon"], "biome": ["marine"]}] | + | m[{"t[id]": "v[lagoon].id", "t[label]": "aquatic", "name": ["lagoon"], "biome": ["marine"]}] | @MultiLabel Scenario: g_withXsinglelabelX_V_valueMapXtrueX_zero_label_vertex 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 66d941bdcd..9a6cedf882 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 @@ -87,6 +87,7 @@ public abstract class TinkerWorld implements World { private static final AbstractTinkerGraph crew = registerTestServices(TinkerFactory.createTheCrew()); private static final AbstractTinkerGraph sink = registerTestServices(TinkerFactory.createKitchenSink()); private static final AbstractTinkerGraph grateful = registerTestServices(TinkerFactory.createGratefulDead()); + private static final AbstractTinkerGraph zoo = registerTestServices(TinkerFactory.createTheZoo()); @Override public GraphTraversalSource getGraphTraversalSource(final LoadGraphWith.GraphData graphData) { @@ -102,6 +103,8 @@ public abstract class TinkerWorld implements World { return sink.traversal(); else if (graphData == LoadGraphWith.GraphData.GRATEFUL) return grateful.traversal(); + else if (graphData == LoadGraphWith.GraphData.ZOO) + return zoo.traversal(); else throw new UnsupportedOperationException("GraphData not supported: " + graphData.name()); } @@ -149,6 +152,7 @@ public abstract class TinkerWorld implements World { private static final AbstractTinkerGraph crew; private static final AbstractTinkerGraph sink; private static final AbstractTinkerGraph grateful; + private static final AbstractTinkerGraph zoo; static { modern = TinkerTransactionGraph.open(getNumberIdManagerConfiguration()); @@ -175,6 +179,11 @@ public abstract class TinkerWorld implements World { TinkerFactory.generateGratefulDead(grateful); grateful.tx().commit(); registerTestServices(grateful); + + zoo = TinkerTransactionGraph.open(getNumberIdManagerConfiguration()); + TinkerFactory.generateTheZoo(zoo); + zoo.tx().commit(); + registerTestServices(zoo); } @Override @@ -191,6 +200,8 @@ public abstract class TinkerWorld implements World { return sink.traversal(); else if (graphData == LoadGraphWith.GraphData.GRATEFUL) return grateful.traversal(); + else if (graphData == LoadGraphWith.GraphData.ZOO) + return zoo.traversal(); else throw new UnsupportedOperationException("GraphData not supported: " + graphData.name()); } @@ -229,6 +240,7 @@ public abstract class TinkerWorld implements World { private static final TinkerGraph crew; private static final TinkerGraph sink; private static final TinkerGraph grateful; + private static final TinkerGraph zoo; static { modern = TinkerShuffleGraph.open(); @@ -246,6 +258,9 @@ public abstract class TinkerWorld implements World { grateful = TinkerShuffleGraph.open(); TinkerFactory.generateGratefulDead(grateful); registerTestServices(grateful); + zoo = TinkerShuffleGraph.open(getNumberIdManagerConfiguration()); + TinkerFactory.generateTheZoo(zoo); + registerTestServices(zoo); } @Override @@ -262,6 +277,8 @@ public abstract class TinkerWorld implements World { return sink.traversal(); else if (graphData == LoadGraphWith.GraphData.GRATEFUL) return grateful.traversal(); + else if (graphData == LoadGraphWith.GraphData.ZOO) + return zoo.traversal(); else throw new UnsupportedOperationException("GraphData not supported: " + graphData.name()); }
