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