Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1854 b4586c710 -> 976079d6e (forced update)


TINKERPOP-1854 Add Lambdas for Gremlin.Net

All features are passing now (no ignored ones any more).


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/976079d6
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/976079d6
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/976079d6

Branch: refs/heads/TINKERPOP-1854
Commit: 976079d6e7ded8b7f71605adba102ce530a4ecde
Parents: 0bcab7f
Author: Florian Hockmann <[email protected]>
Authored: Sat Jan 27 14:41:28 2018 +0100
Committer: Florian Hockmann <[email protected]>
Committed: Sat Jan 27 14:41:28 2018 +0100

----------------------------------------------------------------------
 docs/src/reference/gremlin-variants.asciidoc    | 26 ++++++--
 gremlin-dotnet/glv/generate.groovy              |  2 +-
 .../Process/Traversal/GraphTraversal.cs         | 10 +--
 .../src/Gremlin.Net/Process/Traversal/Lambda.cs | 67 ++++++++++++++++++++
 .../src/Gremlin.Net/Process/Traversal/__.cs     | 10 +--
 .../Structure/IO/GraphSON/GraphSONWriter.cs     |  3 +-
 .../Structure/IO/GraphSON/LambdaSerializer.cs   | 45 +++++++++++++
 .../Gherkin/CommonSteps.cs                      |  2 +-
 .../Gherkin/GherkinTestRunner.cs                | 35 ++--------
 .../Gherkin/IgnoreException.cs                  | 55 ----------------
 .../TraversalEvaluation/TraversalParser.cs      |  2 +-
 .../IO/GraphSON/GraphSONWriterTests.cs          | 13 ++++
 12 files changed, 168 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc 
b/docs/src/reference/gremlin-variants.asciidoc
index 4a2fe7a..baa0ec2 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -46,7 +46,7 @@ implementation of Gremlin and serves as the foundation by 
which all other Gremli
 === The Lambda Solution
 
 Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous 
functions] across languages is difficult as
-most language do not support lambda introspection and thus, code analysis. In 
Gremlin-Java, Java8 lambdas can be leveraged.
+most languages do not support lambda introspection and thus, code analysis. In 
Gremlin-Java, Java8 lambdas can be leveraged.
 
 [source,java]
 g.V().out("knows").map(t -> t.get().value("name") + " is the friend name") <1>
@@ -281,7 +281,7 @@ re-construction machine-side.
 === The Lambda Solution
 
 Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous 
functions] across languages is difficult as
-most language do not support lambda introspection and thus, code analysis. In 
Gremlin-Python,
+most languages do not support lambda introspection and thus, code analysis. In 
Gremlin-Python,
 a link:https://docs.python.org/2/reference/expressions.html#lambda[Python 
lambda] should be represented as a zero-arg callable
 that returns a string representation of a lambda. The default lambda language 
is `gremlin-python` and can be changed via
 `gremlin_python.statics.default_lambda_language`. When the lambda is 
represented in `Bytecode` its language is encoded
@@ -346,8 +346,10 @@ var g = graph.Traversal().WithRemote(new 
DriverRemoteConnection(new GremlinClien
 
 When a traversal from the `GraphTraversalSource` is iterated, the 
traversal’s `Bytecode` is sent over the wire via the registered
 `IRemoteConnection`. The bytecode is used to construct the equivalent 
traversal at the remote traversal source.
-Since Gremlin.Net currently doesn't support lambda expressions, all traversals 
can be translated to Gremlin-Java on the remote
-location (e.g. Gremlin Server).
+Moreover, typically the bytecode is analyzed to determine which language the 
bytecode should be translated to. If the traversal
+does not contain lambdas, the remote location (e.g. Gremlin Server) will 
typically
+use Gremlin-Java. If it has lambdas written in Groovy, it will use 
Gremlin-Groovy (e.g. `GremlinGroovyScriptEngine`).
+Likewise, if it has lambdas represented in Python, it will use Gremlin-Python 
(e.g. `GremlinJythonScriptEngine`).
 
 IMPORTANT: Gremlin.Net’s `ITraversal` interface supports the standard 
Gremlin methods such as `Next()`, `NextTraverser()`, `ToSet()`,
 `ToList()`, etc. Such "terminal" methods trigger the evaluation of the 
traversal.
@@ -436,6 +438,22 @@ NOTE: Many of the TraversalStrategy classes in Gremlin.Net 
are proxies to the re
 JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method 
does nothing. However, the strategy is
 encoded in the Gremlin.Net bytecode and transmitted to the Gremlin traversal 
machine for re-construction machine-side.
 
+=== The Lambda Solution
+
+Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous 
functions] across languages is difficult as
+most languages do not support lambda introspection and thus, code analysis. 
While Gremlin.Net doesn't support C# lambdas, it
+is still able to represent lambdas in other languages. When the lambda is 
represented in `Bytecode` its language is encoded
+such that the remote connection host can infer which translator and ultimate 
execution engine to use.
+
+[source,csharp]
+----
+g.V().Out().Map<int>(Lambda.Groovy("it.get().value('name').length()")).Sum<int>().ToList();
      <1>
+g.V().Out().Map<int>(Lambda.Python("lambda x: 
len(x.get().value('name'))")).Sum<int>().ToList(); <2>
+----
+
+<1> `Lambda.Groovy()` can be used to create a Groovy lambda. 
+<2> `Lambda.Python()` can be used to create a Python lambda.
+
 [[gremlin-javascript]]
 == Gremlin-JavaScript
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/glv/generate.groovy
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/glv/generate.groovy 
b/gremlin-dotnet/glv/generate.groovy
index 12cfa88..f1b0ee4 100644
--- a/gremlin-dotnet/glv/generate.groovy
+++ b/gremlin-dotnet/glv/generate.groovy
@@ -48,7 +48,7 @@ def toCSharpTypeMap = ["Long": "long",
                        "TraversalMetrics": "E2",
                        "Traversal": "ITraversal",
                        "Traversal[]": "ITraversal[]",
-                       "Predicate": "TraversalPredicate",
+                       "Predicate": "object",
                        "P": "TraversalPredicate",
                        "TraversalStrategy": "ITraversalStrategy",
                        "TraversalStrategy[]": "ITraversalStrategy[]",

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index d8e26ad..1c00f11 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -355,7 +355,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the choose step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
-        public GraphTraversal<S, E2> Choose<E2> (TraversalPredicate 
choosePredicate, ITraversal trueChoice)
+        public GraphTraversal<S, E2> Choose<E2> (object choosePredicate, 
ITraversal trueChoice)
         {
             Bytecode.AddStep("choose", choosePredicate, trueChoice);
             return Wrap<S, E2>(this);
@@ -364,7 +364,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the choose step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
-        public GraphTraversal<S, E2> Choose<E2> (TraversalPredicate 
choosePredicate, ITraversal trueChoice, ITraversal falseChoice)
+        public GraphTraversal<S, E2> Choose<E2> (object choosePredicate, 
ITraversal trueChoice, ITraversal falseChoice)
         {
             Bytecode.AddStep("choose", choosePredicate, trueChoice, 
falseChoice);
             return Wrap<S, E2>(this);
@@ -496,7 +496,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the emit step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
-        public GraphTraversal<S, E> Emit (TraversalPredicate emitPredicate)
+        public GraphTraversal<S, E> Emit (object emitPredicate)
         {
             Bytecode.AddStep("emit", emitPredicate);
             return Wrap<S, E>(this);
@@ -514,7 +514,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the filter step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
-        public GraphTraversal<S, E> Filter (TraversalPredicate predicate)
+        public GraphTraversal<S, E> Filter (object predicate)
         {
             Bytecode.AddStep("filter", predicate);
             return Wrap<S, E>(this);
@@ -1591,7 +1591,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the until step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
-        public GraphTraversal<S, E> Until (TraversalPredicate untilPredicate)
+        public GraphTraversal<S, E> Until (object untilPredicate)
         {
             Bytecode.AddStep("until", untilPredicate);
             return Wrap<S, E>(this);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
new file mode 100644
index 0000000..5709567
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
@@ -0,0 +1,67 @@
+#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
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents a lambda.
+    /// </summary>
+    public class Lambda
+    {
+        private Lambda(string expression, string language)
+        {
+            LambdaExpression = expression;
+            Language = language;
+        }
+
+        /// <summary>
+        ///     Gets the lambda expression.
+        /// </summary>
+        public string LambdaExpression { get; }
+
+        /// <summary>
+        ///     Gets the language of this lambda.
+        /// </summary>
+        public string Language { get; }
+
+        /// <summary>
+        ///     Creates a new Groovy <see cref="Lambda"/>.
+        /// </summary>
+        /// <param name="expression">The lambda expression.</param>
+        /// <returns>The created <see cref="Lambda"/>.</returns>
+        public static Lambda Groovy(string expression)
+        {
+            return new Lambda(expression, "gremlin-groovy");
+        }
+
+        /// <summary>
+        ///     Creates a new Python <see cref="Lambda"/>.
+        /// </summary>
+        /// <param name="expression">The lambda expression.</param>
+        /// <returns>The created <see cref="Lambda"/>.</returns>
+        public static Lambda Python(string expression)
+        {
+            return new Lambda(expression, "gremlin-python");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
index 1788bad..9c186ee 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
@@ -231,7 +231,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the choose step to that traversal.
         /// </summary>
-        public static GraphTraversal<object, E2> Choose<E2>(TraversalPredicate 
choosePredicate, ITraversal trueChoice)
+        public static GraphTraversal<object, E2> Choose<E2>(object 
choosePredicate, ITraversal trueChoice)
         {
             return new GraphTraversal<object, 
E2>().Choose<E2>(choosePredicate, trueChoice);            
         }
@@ -239,7 +239,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the choose step to that traversal.
         /// </summary>
-        public static GraphTraversal<object, E2> Choose<E2>(TraversalPredicate 
choosePredicate, ITraversal trueChoice, ITraversal falseChoice)
+        public static GraphTraversal<object, E2> Choose<E2>(object 
choosePredicate, ITraversal trueChoice, ITraversal falseChoice)
         {
             return new GraphTraversal<object, 
E2>().Choose<E2>(choosePredicate, trueChoice, falseChoice);            
         }
@@ -357,7 +357,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the emit step to that traversal.
         /// </summary>
-        public static GraphTraversal<object, object> Emit(TraversalPredicate 
emitPredicate)
+        public static GraphTraversal<object, object> Emit(object emitPredicate)
         {
             return new GraphTraversal<object, object>().Emit(emitPredicate);   
         
         }
@@ -373,7 +373,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the filter step to that traversal.
         /// </summary>
-        public static GraphTraversal<object, object> Filter(TraversalPredicate 
predicate)
+        public static GraphTraversal<object, object> Filter(object predicate)
         {
             return new GraphTraversal<object, object>().Filter(predicate);     
       
         }
@@ -1239,7 +1239,7 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the until step to that traversal.
         /// </summary>
-        public static GraphTraversal<object, object> Until(TraversalPredicate 
untilPredicate)
+        public static GraphTraversal<object, object> Until(object 
untilPredicate)
         {
             return new GraphTraversal<object, object>().Until(untilPredicate); 
           
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
index a60a558..e4a2999 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -59,7 +59,8 @@ namespace Gremlin.Net.Structure.IO.GraphSON
                 {typeof(Edge), new EdgeSerializer()},
                 {typeof(Property), new PropertySerializer()},
                 {typeof(VertexProperty), new VertexPropertySerializer()},
-                {typeof(AbstractTraversalStrategy), new 
TraversalStrategySerializer()}
+                {typeof(AbstractTraversalStrategy), new 
TraversalStrategySerializer()},
+                {typeof(Lambda), new LambdaSerializer()}
             };
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs 
b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
new file mode 100644
index 0000000..8e712b1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
@@ -0,0 +1,45 @@
+#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.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class LambdaSerializer : IGraphSONSerializer
+    {
+        private const int DefaultArgument = -1;
+
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, 
GraphSONWriter writer)
+        {
+            Lambda lambda = objectData;
+            var valueDict = new Dictionary<string, dynamic>
+            {
+                {"script", lambda.LambdaExpression},
+                {"language", lambda.Language},
+                {"arguments", DefaultArgument}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Lambda), valueDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index 0abc247..dd96474 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -233,7 +233,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
 
         private static object ToLambda(string stringLambda, string graphName)
         {
-            throw new IgnoreException(IgnoreReason.LambdaNotSupported);
+            return Lambda.Groovy(stringLambda);
         }
 
         private static object ToNumber(string stringNumber, string graphName)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
index 9cb3cf0..2db1c9b 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
@@ -37,9 +37,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
 {
     public class GherkinTestRunner
     {
-        private static readonly IDictionary<string, IgnoreReason> 
IgnoredScenarios =
-            new Dictionary<string, IgnoreReason>();
-        
         private static class Keywords
         {
             public const string Given = "GIVEN";
@@ -84,11 +81,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                 {
                     var failedSteps = new Dictionary<Step, Exception>();
                     resultFeature.Scenarios[scenario] = failedSteps;
-                    if (IgnoredScenarios.TryGetValue(scenario.Name, out var 
reason))
-                    {
-                        failedSteps.Add(scenario.Steps.First(), new 
IgnoreException(reason));
-                        break;
-                    }
                     StepBlock? currentStep = null;
                     StepDefinition stepDefinition = null;
                     foreach (var step in scenario.Steps)
@@ -136,7 +128,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             var failures = new List<Tuple<string, Exception>>();
             var totalScenarios = 0;
             var totalFailed = 0;
-            var totalIgnored = 0;
             foreach (var resultFeature in results)
             {
                 foreach (var resultScenario in resultFeature.Scenarios)
@@ -152,16 +143,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                         }
                         else
                         {
-                            if (failure is IgnoreException)
-                            {
-                                totalIgnored++;
-                                WriteOutput($"    {++identifier}) 
{step.Keyword} {step.Text} (ignored)");
-                            }
-                            else
-                            {
-                                totalFailed++;
-                                WriteOutput($"    {++identifier}) 
{step.Keyword} {step.Text} (failed)");
-                            }
+                            totalFailed++;
+                            WriteOutput($"    {++identifier}) {step.Keyword} 
{step.Text} (failed)");
                             failures.Add(Tuple.Create(resultScenario.Key.Name, 
failure));
                         }
                     }
@@ -169,24 +152,18 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             }
             if (totalFailed > 0)
             {
-                WriteOutput("Failures" + (totalIgnored > 0 ? " and skipped 
scenarios" : "") + ":");
-            }
-            else if (totalIgnored > 0)
-            {
-                WriteOutput("Skipped scenarios:");
+                WriteOutput("Failures:");
             }
             for (var index = 0; index < failures.Count; index++)
             {
                 var failure = failures[index];
-                var message = failure.Item2 is IgnoreException
-                    ? ": " + failure.Item2.Message
-                    : ": Failed\n" + failure.Item2;
+                var message = ": Failed\n" + failure.Item2;
                 WriteOutput($"{index+1}) {failure.Item1}{message}");
             }
             WriteOutput("-----------------");
             WriteOutput($"Total scenarios: {totalScenarios}." +
-                              $" Passed: 
{totalScenarios-totalFailed-totalIgnored}." +
-                              $" Failed: {totalFailed}. Skipped: 
{totalIgnored}.");
+                              $" Passed: {totalScenarios-totalFailed}." +
+                              $" Failed: {totalFailed}.");
             if (totalFailed == 0)
             {
                 return;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
deleted file mode 100644
index ae236c7..0000000
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-#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;
-
-namespace Gremlin.Net.IntegrationTest.Gherkin
-{
-    /// <summary>
-    /// Represents a test exception that should be ignored, given a reason 
(ie: feature not supported in the .NET GLV)
-    /// </summary>
-    public class IgnoreException : Exception
-    {
-        public IgnoreException(IgnoreReason reason) : base(GetMessage(reason))
-        {
-            
-        }
-
-        private static string GetMessage(IgnoreReason reason)
-        {
-            string reasonSuffix = null;
-            switch (reason)
-            {
-                case IgnoreReason.LambdaNotSupported:
-                    reasonSuffix = " because lambdas are not supported in 
Gremlin.NET";
-                    break;
-            }
-            return $"Scenario ignored" + reasonSuffix;
-        }
-    }
-    
-    public enum IgnoreReason
-    {
-        LambdaNotSupported
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/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 118fcea..aeef107 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
@@ -398,7 +398,7 @@ namespace 
Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             {
                 return ParseNumber(text, ref i);
             }
-            if (text.Substring(i, 3).StartsWith("__."))
+            if (text.Length >= i + 3 && text.Substring(i, 3).StartsWith("__."))
             {
                 var startIndex = i;
                 var tokens = ParseTokens(text, ref i);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/976079d6/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
index 3d02533..7774907 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -333,6 +333,19 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
             const string expected = 
"{\"@type\":\"g:SubgraphStrategy\",\"@value\":{}}";
             Assert.Equal(expected, graphSon);
         }
+
+        [Fact]
+        public void ShouldSerializeLambda()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var lambda = Lambda.Groovy("{ it.get() }");
+
+            var graphSon = writer.WriteObject(lambda);
+
+            const string expected =
+                "{\"@type\":\"g:Lambda\",\"@value\":{\"script\":\"{ it.get() 
}\",\"language\":\"gremlin-groovy\",\"arguments\":-1}}";
+            Assert.Equal(expected, graphSon);
+        }
     }
 
     internal class TestGraphSONSerializer : IGraphSONSerializer

Reply via email to