TINKERPOP-1996 Added support/testing for io() in GLVs Had to revert to using iterate() and stop read/write() from terminating the traversal. Kinda stinks, but we rely on iterate() quite heavily and for remoting allowing read()/write() to terminate means that the traversal will execute during traversal construction in the translator (which is early and potentially bad).
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/048ea21c Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/048ea21c Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/048ea21c Branch: refs/heads/TINKERPOP-1967 Commit: 048ea21c0adf9297233d06222e75c64dbe1fa1ca Parents: f8e3b8a Author: Stephen Mallette <sp...@genoprime.com> Authored: Thu Jul 19 13:30:02 2018 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Jul 19 13:41:01 2018 -0400 ---------------------------------------------------------------------- .../traversal/dsl/graph/GraphTraversal.java | 11 +-- gremlin-dotnet/glv/IO.template | 46 +++++++++++ gremlin-dotnet/glv/generate.groovy | 8 ++ .../src/Gremlin.Net/Process/Traversal/IO.cs | 54 +++++++++++++ .../Gherkin/TraversalEvaluation/IOParameter.cs | 82 +++++++++++++++++++ .../TraversalEvaluation/TraversalParser.cs | 7 ++ gremlin-javascript/glv/TraversalSource.template | 9 +++ gremlin-javascript/glv/generate.groovy | 4 + .../gremlin-javascript/lib/process/traversal.js | 25 ++++++ .../test/cucumber/feature-steps.js | 2 + gremlin-python/glv/TraversalSource.template | 11 +++ gremlin-python/glv/generate.groovy | 4 + .../jython/gremlin_python/process/traversal.py | 19 +++++ .../src/main/jython/radish/feature_steps.py | 5 +- gremlin-test/features/sideEffect/Read.feature | 84 ++++++++++++++++++++ gremlin-test/features/sideEffect/Write.feature | 60 ++++++++++++++ .../gremlin/AbstractGraphProvider.java | 2 +- .../process/traversal/step/map/ReadTest.java | 57 ++++++++++--- 18 files changed, 471 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java index 20f8996..a675ad1 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java @@ -124,6 +124,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCount import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IoStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.LambdaSideEffectStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.ProfileSideEffectStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SackValueStep; @@ -2734,13 +2735,13 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { //// - ///////////////////// IO TERMINATOR STEPS ///////////////////// + ///////////////////// IO STEPS ///////////////////// /** * This step is technically a step modulator for the the {@link GraphTraversalSource#io(String)} step which * instructs the step to perform a read with its given configuration. * - * @return the traversal that has been iterated with the read IO action executed + * @return the traversal with the {@link IoStep} modulated to read * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#io-step" target="_blank">Reference Documentation - IO Step</a> * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#read-step" target="_blank">Reference Documentation - Read Step</a> * @since 3.4.0 @@ -2748,14 +2749,14 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { public default GraphTraversal<S,E> read() { this.asAdmin().getBytecode().addStep(Symbols.read); ((ReadWriting) this.asAdmin().getEndStep()).setMode(ReadWriting.Mode.READING); - return this.iterate(); + return this; } /** * This step is technically a step modulator for the the {@link GraphTraversalSource#io(String)} step which * instructs the step to perform a write with its given configuration. * - * @return the traversal that has been iterated with the write IO action executed + * @return the traversal with the {@link IoStep} modulated to write * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#io-step" target="_blank">Reference Documentation - IO Step</a> * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#write-step" target="_blank">Reference Documentation - Write Step</a> * @since 3.4.0 @@ -2763,7 +2764,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { public default GraphTraversal<S,E> write() { this.asAdmin().getBytecode().addStep(Symbols.write); ((ReadWriting) this.asAdmin().getEndStep()).setMode(ReadWriting.Mode.WRITING); - return this.iterate(); + return this; } /** http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-dotnet/glv/IO.template ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/glv/IO.template b/gremlin-dotnet/glv/IO.template new file mode 100644 index 0000000..7b25c88 --- /dev/null +++ b/gremlin-dotnet/glv/IO.template @@ -0,0 +1,46 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +// THIS IS A GENERATED FILE - DO NOT MODIFY THIS FILE DIRECTLY - see pom.xml +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Gremlin.Net.Process.Traversal +{ +#pragma warning disable 1591 + + /// <summary> + /// <see cref="IO" /> keeps configuration options for the io() step. + /// </summary> + public class IO + { + <% io.each {k,v -> %> + public const String <%= k %> = "<%= v %>"; + <% } %> + } + +#pragma warning restore 1591 +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-dotnet/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy index bd2d9d7..58a5026 100644 --- a/gremlin-dotnet/glv/generate.groovy +++ b/gremlin-dotnet/glv/generate.groovy @@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource 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.P +import org.apache.tinkerpop.gremlin.process.traversal.IO import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ import org.apache.tinkerpop.gremlin.structure.Direction import java.lang.reflect.Modifier @@ -303,6 +304,9 @@ def binding = ["pmethods": P.class.getMethods(). def graphTraversalT2 = getGraphTraversalT2ForT2(t2) return ["methodName": javaMethod.name, "t2":t2, "tParam":tParam, "parameters":parameters, "paramNames":paramNames, "callGenericTypeArg":callGenericTypeArg, "graphTraversalT2":graphTraversalT2] }, + "io": IO.class.getFields(). + sort{ a, b -> a.name <=> b.name }. + collectEntries{ f -> [(f.name) : f.get(null)]}, "toCSharpMethodName": toCSharpMethodName] def engine = new groovy.text.GStringTemplateEngine() @@ -322,6 +326,10 @@ def pTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/P.template def pFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/P.cs") pFile.newWriter().withWriter{ it << pTemplate } +def ioTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/IO.template")).make(binding) +def ioFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/IO.cs") +ioFile.newWriter().withWriter{ it << ioTemplate } + def createEnum = { enumClass -> def b = ["enumClass": enumClass, http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IO.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IO.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IO.cs new file mode 100644 index 0000000..288f7e3 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IO.cs @@ -0,0 +1,54 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +// THIS IS A GENERATED FILE - DO NOT MODIFY THIS FILE DIRECTLY - see pom.xml +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Gremlin.Net.Process.Traversal +{ +#pragma warning disable 1591 + + /// <summary> + /// <see cref="IO" /> keeps configuration options for the io() step. + /// </summary> + public class IO + { + + public const String graphml = "graphml"; + + public const String graphson = "graphson"; + + public const String gryo = "gryo"; + + public const String reader = "~tinkerpop.io.reader"; + + public const String writer = "~tinkerpop.io.writer"; + + } + +#pragma warning restore 1591 +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/IOParameter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/IOParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/IOParameter.cs new file mode 100644 index 0000000..513e589 --- /dev/null +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/IOParameter.cs @@ -0,0 +1,82 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Reflection; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation +{ + /// <summary> + /// Represents a parameter for the io() step - (e.g. IO.graphml) + /// </summary> + internal class IOParameter : ITokenParameter, IEquatable<IOParameter> + { + private readonly string _text; + private readonly string _value; + + public IOParameter(string text) + { + _text = text; + var separatorIndex = text.IndexOf('.'); + _value = text.Substring(separatorIndex + 1); + } + + public bool Equals(IOParameter other) + { + return _text == other._text; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((IOParameter) obj); + } + + public override int GetHashCode() + { + return _text.GetHashCode(); + } + + public object GetValue() + { + var field = typeof(IO).GetField(_value, BindingFlags.Static | BindingFlags.Public); + return field.GetValue(null); + } + + public void SetContextParameterValues(IDictionary<string, object> parameterValues) + { + + } + + public Type GetParameterType() + { + return typeof(String); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs index e3f6a3f..f8e4095 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs @@ -44,6 +44,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation private static readonly Regex RegexEnum = new Regex(@"\w+\.\w+", RegexOptions.Compiled); + private static readonly Regex RegexIO = new Regex(@"IO.\w+", RegexOptions.Compiled); + private static readonly Regex RegexParam = new Regex(@"\w+", RegexOptions.Compiled); private static readonly HashSet<Type> NumericTypes = new HashSet<Type> @@ -424,6 +426,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation i += parameterText.Length - 1; return LiteralParameter.Create(Convert.ToBoolean(parameterText)); } + if (RegexIO.IsMatch(parameterText)) + { + i += parameterText.Length - 1; + return new IOParameter(parameterText); + } if (RegexEnum.IsMatch(parameterText)) { i += parameterText.Length - 1; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-javascript/glv/TraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template index 6965110..321956c 100644 --- a/gremlin-javascript/glv/TraversalSource.template +++ b/gremlin-javascript/glv/TraversalSource.template @@ -111,6 +111,14 @@ class Traversal { }; } +class IO { +<% io.each {k,v -> %> + static get <%= k %>() { + return "<%= v %>" + } +<% } %> +} + class P { /** * Represents an operation. @@ -190,6 +198,7 @@ class EnumValue { module.exports = { EnumValue, P, + IO, Traversal, TraversalSideEffects, Traverser<% http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-javascript/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-javascript/glv/generate.groovy b/gremlin-javascript/glv/generate.groovy index 8778e89..a339689 100644 --- a/gremlin-javascript/glv/generate.groovy +++ b/gremlin-javascript/glv/generate.groovy @@ -24,6 +24,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource 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.P +import org.apache.tinkerpop.gremlin.process.traversal.IO import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ import java.lang.reflect.Modifier @@ -88,6 +89,9 @@ def binding = ["enums": CoreImports.getClassImports() collect { it.name }. unique(). sort { a, b -> a <=> b }, + "io": IO.class.getFields(). + sort{ a, b -> a.name <=> b.name }. + collectEntries{ f -> [(f.name) : f.get(null)]}, "toJs": toJs, "version": determineVersion(), "decapitalize": decapitalize] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js index d39ccf0..3f69fb1 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js @@ -111,6 +111,30 @@ class Traversal { }; } +class IO { + + static get graphml() { + return "graphml" + } + + static get graphson() { + return "graphson" + } + + static get gryo() { + return "gryo" + } + + static get reader() { + return "~tinkerpop.io.reader" + } + + static get writer() { + return "~tinkerpop.io.writer" + } + +} + class P { /** * Represents an operation. @@ -250,6 +274,7 @@ class EnumValue { module.exports = { EnumValue, P, + IO, Traversal, TraversalSideEffects, Traverser, http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js ---------------------------------------------------------------------- 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 16aae78..320d3f4 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 @@ -187,6 +187,7 @@ function getSandbox(g, parameters) { }, Order: traversalModule.order, P: traversalModule.P, + IO: traversalModule.IO, Pick: traversalModule.pick, Pop: traversalModule.pop, Scope: traversalModule.scope, @@ -207,6 +208,7 @@ function translate(traversalText) { // Change according to naming convention traversalText = traversalText.replace(/\.in\(/g, '.in_('); traversalText = traversalText.replace(/\.from\(/g, '.from_('); + traversalText = traversalText.replace(/\.with\(/g, '.with_('); return traversalText; } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-python/glv/TraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/TraversalSource.template b/gremlin-python/glv/TraversalSource.template index b6f5b9f..3ca2786 100644 --- a/gremlin-python/glv/TraversalSource.template +++ b/gremlin-python/glv/TraversalSource.template @@ -135,6 +135,17 @@ statics.add_static('<%= method %>',<%= method %>) <% } %> ''' +IO +''' + + +class IO(object): +<% io.each {k,v -> %> + <%= k %> = "<%= v %>" +<% } %> + + +''' TRAVERSER ''' http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-python/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/generate.groovy b/gremlin-python/glv/generate.groovy index 57cc9c9..f810e10 100644 --- a/gremlin-python/glv/generate.groovy +++ b/gremlin-python/glv/generate.groovy @@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource 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.P +import org.apache.tinkerpop.gremlin.process.traversal.IO import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ import java.lang.reflect.Modifier // this is a bit of a copy of what's in SymbolHelper - no way around it because this code generation task occurs @@ -78,6 +79,9 @@ def binding = ["enums": CoreImports.getClassImports() collect { toPython(it.name) }. unique(). sort { a, b -> a <=> b }, + "io": IO.class.getFields(). + sort{ a, b -> a.name <=> b.name }. + collectEntries{ f -> [(f.name) : f.get(null)]}, "toPython": toPython, "toJava": toJava] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-python/src/main/jython/gremlin_python/process/traversal.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py index 068c865..d9fb4d9 100644 --- a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py +++ b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py @@ -305,6 +305,25 @@ statics.add_static('without',without) ''' +IO +''' + + +class IO(object): + + graphml = "graphml" + + graphson = "graphson" + + gryo = "gryo" + + reader = "~tinkerpop.io.reader" + + writer = "~tinkerpop.io.writer" + + + +''' TRAVERSER ''' http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-python/src/main/jython/radish/feature_steps.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/radish/feature_steps.py b/gremlin-python/src/main/jython/radish/feature_steps.py index 5067d1b..99022a0 100644 --- a/gremlin-python/src/main/jython/radish/feature_steps.py +++ b/gremlin-python/src/main/jython/radish/feature_steps.py @@ -21,7 +21,7 @@ import json import re from gremlin_python.structure.graph import Graph, Path from gremlin_python.process.graph_traversal import __ -from gremlin_python.process.traversal import Barrier, Cardinality, P, Pop, Scope, Column, Order, Direction, T, Pick, Operator +from gremlin_python.process.traversal import Barrier, Cardinality, P, Pop, Scope, Column, Order, Direction, T, Pick, Operator, IO from radish import given, when, then from hamcrest import * @@ -34,6 +34,7 @@ regex_in = re.compile(r"([(.,\s])in\(") regex_is = re.compile(r"([(.,\s])is\(") regex_not = re.compile(r"([(.,\s])not\(") regex_or = re.compile(r"([(.,\s])or\(") +regex_with = re.compile(r"([(.,\s])with\(") regex_true = re.compile(r"(true)") regex_false = re.compile(r"(false)") @@ -241,6 +242,7 @@ def _translate(traversal): replaced = regex_not.sub(r"\1not_(", replaced) replaced = regex_or.sub(r"\1or_(", replaced) replaced = regex_in.sub(r"\1in_(", replaced) + replaced = regex_with.sub(r"\1with_(", replaced) replaced = regex_true.sub(r"True", replaced) return regex_false.sub(r"False", replaced) @@ -254,6 +256,7 @@ def _make_traversal(g, traversal_string, params): "Direction": Direction, "Order": Order, "P": P, + "IO": IO, "Pick": Pick, "Pop": Pop, "Scope": Scope, http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-test/features/sideEffect/Read.feature ---------------------------------------------------------------------- diff --git a/gremlin-test/features/sideEffect/Read.feature b/gremlin-test/features/sideEffect/Read.feature new file mode 100644 index 0000000..ae96102 --- /dev/null +++ b/gremlin-test/features/sideEffect/Read.feature @@ -0,0 +1,84 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Feature: Step - read() + + Scenario: g_io_readXkryoX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.kryo").read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" + + Scenario: g_io_read_withXreader_gryoX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.kryo").with(IO.reader, IO.gryo).read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" + + Scenario: g_io_readXgraphsonX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.json").read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" + + Scenario: g_io_read_withXreader_graphsonX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.json").with(IO.reader, IO.graphson).read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" + + Scenario: g_io_readXgraphmlX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.xml").read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" + + Scenario: g_io_read_withXreader_graphmlX + Given the empty graph + And the traversal of + """ + g.io("data/tinkerpop-modern.xml").with(IO.reader, IO.graphml).read() + """ + When iterated to list + Then the result should be empty + And the graph should return 6 for count of "g.V()" + And the graph should return 6 for count of "g.E()" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-test/features/sideEffect/Write.feature ---------------------------------------------------------------------- diff --git a/gremlin-test/features/sideEffect/Write.feature b/gremlin-test/features/sideEffect/Write.feature new file mode 100644 index 0000000..9a774e8 --- /dev/null +++ b/gremlin-test/features/sideEffect/Write.feature @@ -0,0 +1,60 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Feature: Step - write() + + Scenario: g_io_writeXkryoX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ + + Scenario: g_io_write_withXwriter_gryoX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ + + Scenario: g_io_writeXgraphsonX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ + + Scenario: g_io_write_withXwriter_graphsonX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ + + Scenario: g_io_writeXgraphmlX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ + + Scenario: g_io_write_withXwriter_graphmlX + Given an unsupported test + Then nothing should happen because + """ + We don't have a nice way to assert the remotely written file with this framework - just testing compilation. + """ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGraphProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGraphProvider.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGraphProvider.java index b6fc43c..9774411 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGraphProvider.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGraphProvider.java @@ -145,6 +145,6 @@ public abstract class AbstractGraphProvider implements GraphProvider { protected void readIntoGraph(final Graph graph, final String path) throws IOException { final String dataFile = TestHelper.generateTempFileFromResource(graph.getClass(), GryoResourceAccess.class, path.substring(path.lastIndexOf(File.separator) + 1), "", false).getAbsolutePath(); - graph.traversal().io(dataFile).read(); + graph.traversal().io(dataFile).read().iterate(); } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/048ea21c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadTest.java index ab59194..24bacbb 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadTest.java @@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.FeatureRequirementSet; import org.apache.tinkerpop.gremlin.TestHelper; import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest; import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner; +import org.apache.tinkerpop.gremlin.process.remote.RemoteGraph; import org.apache.tinkerpop.gremlin.process.traversal.IO; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.structure.Graph; @@ -34,8 +35,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; +import java.util.function.Supplier; import static org.apache.tinkerpop.gremlin.structure.Graph.Features.GraphFeatures.FEATURE_IO_READ; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; /** @@ -62,9 +65,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GryoResourceAccess.class, "tinkerpop-modern-v3d0.kryo", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_readXkryoX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } @Test @@ -73,9 +81,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GryoResourceAccess.class, "tinkerpop-modern-v3d0.kryo", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_read_withXreader_gryoX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } @Test @@ -84,9 +97,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GraphSONResourceAccess.class, "tinkerpop-modern-v3d0.json", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_readXjsonX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } @Test @@ -95,9 +113,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GraphSONResourceAccess.class, "tinkerpop-modern-v3d0.json", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_read_withXreader_graphsonX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } @Test @@ -106,9 +129,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GraphMLResourceAccess.class, "tinkerpop-modern.xml", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_readXxmlX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } @Test @@ -117,9 +145,14 @@ public abstract class ReadTest extends AbstractGremlinProcessTest { final String fileToRead = TestHelper.generateTempFileFromResource(ReadTest.class, GraphMLResourceAccess.class, "tinkerpop-modern.xml", "").getAbsolutePath().replace('\\', '/'); final Traversal<Object,Object> traversal = get_g_io_read_withXreader_graphmlX(fileToRead); printTraversalForm(traversal); - assertFalse(traversal.hasNext()); + traversal.iterate(); - IoTest.assertModernGraph(graph, false, true); + if (graph instanceof RemoteGraph) { + assertEquals(6L, g.V().count().next().longValue()); + assertEquals(6L, g.E().count().next().longValue()); + } else { + IoTest.assertModernGraph(graph, false, true); + } } public static class Traversals extends ReadTest {