This is an automated email from the ASF dual-hosted git repository.

kenhuuu pushed a commit to branch 3.6-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.6-dev by this push:
     new 4230c97f83 Add support for testing sets in results for feature tests. 
(#2279)
4230c97f83 is described below

commit 4230c97f83f33adc87901b535c535d29def7cfe3
Author: kenhuuu <[email protected]>
AuthorDate: Mon Oct 16 15:08:39 2023 -0700

    Add support for testing sets in results for feature tests. (#2279)
---
 .../Gherkin/CommonSteps.cs                         | 12 ++++++++
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  1 +
 gremlin-go/driver/cucumber/cucumberSteps_test.go   | 33 ++++++++++++++++++++--
 gremlin-go/driver/cucumber/gremlin.go              |  1 +
 .../test/cucumber/feature-steps.js                 |  1 +
 .../gremlin-javascript/test/cucumber/gremlin.js    |  1 +
 gremlin-python/src/main/python/radish/gremlin.py   |  1 +
 .../tinkerpop/gremlin/features/StepDefinition.java |  7 ++---
 .../gremlin/test/features/filter/Dedup.feature     | 17 +++++++++++
 9 files changed, 68 insertions(+), 6 deletions(-)

diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index 6da7935bd5..29e6a1bea4 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -284,6 +284,18 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                                 }
                                 
Assert.True(expectedArrayContainsResultDictionary);
                             }
+                            else if (resultItem is HashSet<object> 
resultItemSet)
+                            {
+                                var expectedArrayContainsResultAsSet = false;
+                                foreach (var expectedItem in expectedArray)
+                                {
+                                    if (expectedItem is not HashSet<object> 
expectedItemSet) continue;
+                                    if 
(!expectedItemSet.SetEquals(resultItemSet)) continue;
+                                    expectedArrayContainsResultAsSet = true;
+                                    break;
+                                }
+                                Assert.True(expectedArrayContainsResultAsSet);
+                            }
                             else if (resultItem is double resultItemDouble &&
                                      expectedArray.Select(e => 
e.GetType()).Any(t => t == typeof(decimal)))
                             {
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 12a44358dc..54548866b9 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -137,6 +137,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                
{"g_VX1X_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_cyclicPath_fromXaX_toXbX_path",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V(p["vid1"]).As("a").Out("created").As("b").In("created").As("c").CyclicPath().From("a").To("b").Path()}},
 
                
{"g_injectX0X_V_both_coalesceXhasXname_markoX_both_constantX0XX_cyclicPath_path",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.Inject(0).V().Both().Coalesce<object>(__.Has("name","marko").Both(),__.Constant<object>(0)).CyclicPath().Path()}},
 
                {"g_V_out_in_valuesXnameX_fold_dedupXlocalX_unfold", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Out().In().Values<object>("name").Fold().Dedup(Scope.Local).Unfold<object>()}},
 
+               {"g_V_out_in_valuesXnameX_fold_dedupXlocalX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Out().Map<object>(__.In().Values<object>("name").Fold().Dedup(Scope.Local))}},
 
                
{"g_V_out_asXxX_in_asXyX_selectXx_yX_byXnameX_fold_dedupXlocal_x_yX_unfold", 
new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Out().As("x").In().As("y").Select<object>("x","y").By("name").Fold().Dedup(Scope.Local,"x","y").Unfold<object>()}},
 
                {"g_V_both_dedup_name", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.V().Both().Dedup().Values<object>("name")}}, 
                {"g_V_both_hasXlabel_softwareX_dedup_byXlangX_name", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Both().Has(T.Label,"software").Dedup().By("lang").Values<object>("name")}},
 
diff --git a/gremlin-go/driver/cucumber/cucumberSteps_test.go 
b/gremlin-go/driver/cucumber/cucumberSteps_test.go
index 73855c31d5..00653ea089 100644
--- a/gremlin-go/driver/cucumber/cucumberSteps_test.go
+++ b/gremlin-go/driver/cucumber/cucumberSteps_test.go
@@ -24,15 +24,17 @@ import (
        "encoding/json"
        "errors"
        "fmt"
-       "github.com/apache/tinkerpop/gremlin-go/v3/driver"
-       "github.com/cucumber/godog"
        "math"
        "reflect"
        "regexp"
+       "sort"
        "strconv"
        "strings"
        "sync"
        "testing"
+
+       gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
+       "github.com/cucumber/godog"
 )
 
 type tinkerPopGraph struct {
@@ -652,6 +654,23 @@ func compareListEqualsWithoutOrder(expected []interface{}, 
actual []interface{})
                                        break
                                }
                        }
+               } else if actualSet, ok := a.(*gremlingo.SimpleSet); ok {
+                       // Set is a special case here because there is no 
TypeOf().Kind() for sets.
+                       actualStringArray := 
makeSortedStringArrayFromSet(actualSet)
+
+                       for i := len(expectedCopy) - 1; i >= 0; i-- {
+                               curExpected := expectedCopy[i]
+                               expectedSet, ok := 
curExpected.(*gremlingo.SimpleSet)
+                               if ok {
+                                       expectedStringArray := 
makeSortedStringArrayFromSet(expectedSet)
+
+                                       if reflect.DeepEqual(actualStringArray, 
expectedStringArray) {
+                                               expectedCopy = 
append(expectedCopy[:i], expectedCopy[i+1:]...)
+                                               found = true
+                                               break
+                                       }
+                               }
+                       }
                } else {
                        switch reflect.TypeOf(a).Kind() {
                        case reflect.Array, reflect.Slice:
@@ -761,6 +780,16 @@ func compareListEqualsWithOf(expected []interface{}, 
actual []interface{}) bool
        return true
 }
 
+func makeSortedStringArrayFromSet(set *gremlingo.SimpleSet) []string {
+       var sortedStrings []string
+       for _, element := range set.ToSlice() {
+               sortedStrings = append(sortedStrings, fmt.Sprintf("%v", 
element))
+       }
+       sort.Sort(sort.StringSlice(sortedStrings))
+
+       return sortedStrings
+}
+
 func (tg *tinkerPopGraph) theTraversalOf(arg1 *godog.DocString) error {
        traversal, err := GetTraversal(tg.scenario.Name, tg.g, tg.parameters)
        if err != nil {
diff --git a/gremlin-go/driver/cucumber/gremlin.go 
b/gremlin-go/driver/cucumber/gremlin.go
index 33aac6730e..e3b4c6aba7 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -108,6 +108,7 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     
"g_VX1X_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_cyclicPath_fromXaX_toXbX_path":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V(p["vid1"]).As("a").Out("created").As("b").In("created").As("c").CyclicPath().From("a").To("b").Path()}},
 
     
"g_injectX0X_V_both_coalesceXhasXname_markoX_both_constantX0XX_cyclicPath_path":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.Inject(0).V().Both().Coalesce(gremlingo.T__.Has("name", "marko").Both(), 
gremlingo.T__.Constant(0)).CyclicPath().Path()}}, 
     "g_V_out_in_valuesXnameX_fold_dedupXlocalX_unfold": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Out().In().Values("name").Fold().Dedup(gremlingo.Scope.Local).Unfold()}}, 
+    "g_V_out_in_valuesXnameX_fold_dedupXlocalX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Out().Map(gremlingo.T__.In().Values("name").Fold().Dedup(gremlingo.Scope.Local))}},
 
     
"g_V_out_asXxX_in_asXyX_selectXx_yX_byXnameX_fold_dedupXlocal_x_yX_unfold": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.V().Out().As("x").In().As("y").Select("x", 
"y").By("name").Fold().Dedup(gremlingo.Scope.Local, "x", "y").Unfold()}}, 
     "g_V_both_dedup_name": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Both().Dedup().Values("name")}}, 
     "g_V_both_hasXlabel_softwareX_dedup_byXlangX_name": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.V().Both().Has(gremlingo.T.Label, 
"software").Dedup().By("lang").Values("name")}}, 
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 8ce00869ad..9e25f187fe 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
@@ -72,6 +72,7 @@ const ignoredScenarios = {
   // An associative array containing the scenario name as key, for example:
   'g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX': new 
IgnoreError(ignoreReason.setNotSupported),
   'g_withSideEffectXa_setX_V_both_name_aggregateXlocal_aX_capXaX': new 
IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_in_valuesXnameX_fold_dedupXlocalX': new 
IgnoreError(ignoreReason.setNotSupported),
   'g_withStrategiesXProductiveByStrategyX_V_groupCount_byXageX': new 
IgnoreError(ignoreReason.nullKeysInMapNotSupportedWell),
   'g_V_shortestPath_edgesIncluded': new 
IgnoreError(ignoreReason.needsFurtherInvestigation),
   'g_V_shortestPath_edgesIncluded_edgesXoutEX': new 
IgnoreError(ignoreReason.needsFurtherInvestigation),
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index 262429e3d0..43c96bad3a 100644
--- 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -127,6 +127,7 @@ const gremlins = {
     
g_VX1X_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_cyclicPath_fromXaX_toXbX_path:
 [function({g, vid1}) { return 
g.V(vid1).as("a").out("created").as("b").in_("created").as("c").cyclicPath().from_("a").to("b").path()
 }], 
     
g_injectX0X_V_both_coalesceXhasXname_markoX_both_constantX0XX_cyclicPath_path: 
[function({g}) { return 
g.inject(0).V().both().coalesce(__.has("name","marko").both(),__.constant(0)).cyclicPath().path()
 }], 
     g_V_out_in_valuesXnameX_fold_dedupXlocalX_unfold: [function({g}) { return 
g.V().out().in_().values("name").fold().dedup(Scope.local).unfold() }], 
+    g_V_out_in_valuesXnameX_fold_dedupXlocalX: [function({g}) { return 
g.V().out().map(__.in_().values("name").fold().dedup(Scope.local)) }], 
     g_V_out_asXxX_in_asXyX_selectXx_yX_byXnameX_fold_dedupXlocal_x_yX_unfold: 
[function({g}) { return 
g.V().out().as("x").in_().as("y").select("x","y").by("name").fold().dedup(Scope.local,"x","y").unfold()
 }], 
     g_V_both_dedup_name: [function({g}) { return 
g.V().both().dedup().values("name") }], 
     g_V_both_hasXlabel_softwareX_dedup_byXlangX_name: [function({g}) { return 
g.V().both().has(T.label,"software").dedup().by("lang").values("name") }], 
diff --git a/gremlin-python/src/main/python/radish/gremlin.py 
b/gremlin-python/src/main/python/radish/gremlin.py
index d833c06cab..6f4ca7db75 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -109,6 +109,7 @@ world.gremlins = {
     
'g_VX1X_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_cyclicPath_fromXaX_toXbX_path':
 [(lambda g, 
vid1=None:g.V(vid1).as_('a').out('created').as_('b').in_('created').as_('c').cyclicPath().from_('a').to('b').path())],
 
     
'g_injectX0X_V_both_coalesceXhasXname_markoX_both_constantX0XX_cyclicPath_path':
 [(lambda 
g:g.inject(0).V().both().coalesce(__.has('name','marko').both(),__.constant(0)).cyclicPath().path())],
 
     'g_V_out_in_valuesXnameX_fold_dedupXlocalX_unfold': [(lambda 
g:g.V().out().in_().name.fold().dedup(Scope.local).unfold())], 
+    'g_V_out_in_valuesXnameX_fold_dedupXlocalX': [(lambda 
g:g.V().out().map(__.in_().name.fold().dedup(Scope.local)))], 
     
'g_V_out_asXxX_in_asXyX_selectXx_yX_byXnameX_fold_dedupXlocal_x_yX_unfold': 
[(lambda 
g:g.V().out().as_('x').in_().as_('y').select('x','y').by('name').fold().dedup(Scope.local,'x','y').unfold())],
 
     'g_V_both_dedup_name': [(lambda g:g.V().both().dedup().name)], 
     'g_V_both_hasXlabel_softwareX_dedup_byXlangX_name': [(lambda 
g:g.V().both().has(T.label,'software').dedup().by('lang').name)], 
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index 5d8c8cdd9b..c1d726c642 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -221,14 +221,13 @@ public final class StepDefinition {
         add(Pair.with(Pattern.compile("D\\[(.*)\\]"), Direction::valueOf));
         add(Pair.with(Pattern.compile("M\\[(.*)\\]"), Merge::valueOf));
 
-        add(Pair.with(Pattern.compile("c\\[(.*)\\]"), s -> {
-            throw new AssumptionViolatedException("This test uses a lambda as 
a parameter which is not supported by gremlin-language");
-        }));
+        add(Pair.with(Pattern.compile("c\\[(.*)\\]"), s -> 
Collections.emptySet()));
         add(Pair.with(Pattern.compile("s\\[\\]"), s -> {
             throw new AssumptionViolatedException("This test uses a empty Set 
as a parameter which is not supported by gremlin-language");
         }));
         add(Pair.with(Pattern.compile("s\\[(.*)\\]"), s -> {
-            throw new AssumptionViolatedException("This test uses a Set as a 
parameter which is not supported by gremlin-language");
+            final String[] items = s.split(",");
+            return Stream.of(items).map(String::trim).map(x -> 
convertToObject(x)).collect(Collectors.toSet());
         }));
 
         add(Pair.with(Pattern.compile("(null)"), s -> null));
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Dedup.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Dedup.feature
index 6c950d7faf..bae90ba858 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Dedup.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Dedup.feature
@@ -31,6 +31,23 @@ Feature: Step - dedup()
       | josh  |
       | peter |
 
+  @GraphComputerVerificationStarGraphExceeded
+  Scenario: g_V_out_in_valuesXnameX_fold_dedupXlocalX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().map(__.in().values("name").fold().dedup(Scope.local))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[peter,marko,josh] |
+      | s[marko,peter,josh] |
+      | s[josh,marko,peter] |
+      | s[marko] |
+      | s[josh] |
+      | s[marko] |
+
   Scenario: 
g_V_out_asXxX_in_asXyX_selectXx_yX_byXnameX_fold_dedupXlocal_x_yX_unfold
     Given the modern graph
     And the traversal of

Reply via email to