diff --git a/integration/cypher_test.go b/integration/cypher_test.go index 86d7d20..bd1f11a 100644 --- a/integration/cypher_test.go +++ b/integration/cypher_test.go @@ -25,6 +25,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "testing" "github.com/specterops/dawgs/graph" @@ -33,20 +34,20 @@ import ( // caseFile represents one JSON test case file. type caseFile struct { - Dataset string `json:"dataset"` - Skip string `json:"skip,omitempty"` - Cases []testCase `json:"cases"` + Dataset string `json:"dataset"` + SkipDrivers []string `json:"skip_drivers,omitempty"` + Cases []testCase `json:"cases"` } // testCase is a single test: a Cypher query and an assertion on its result. // Cases with a "fixture" field run in a write transaction that rolls back, // so the inline data doesn't persist. type testCase struct { - Name string `json:"name"` - Skip string `json:"skip,omitempty"` - Cypher string `json:"cypher"` - Assert json.RawMessage `json:"assert"` - Fixture *opengraph.Graph `json:"fixture,omitempty"` + Name string `json:"name"` + SkipDrivers []string `json:"skip_drivers,omitempty"` + Cypher string `json:"cypher"` + Assert json.RawMessage `json:"assert"` + Fixture *opengraph.Graph `json:"fixture,omitempty"` } func TestCypher(t *testing.T) { @@ -91,24 +92,29 @@ func TestCypher(t *testing.T) { db, ctx := SetupDB(t, datasetNames...) + driver := *driverFlag + for _, g := range groups { ClearGraph(t, db, ctx) LoadDataset(t, db, ctx, g.dataset) for _, cf := range g.files { - if cf.Skip != "" { - t.Run(cf.Skip, func(t *testing.T) { - t.Skipf("skipped: %s", cf.Skip) - }) + if slices.Contains(cf.SkipDrivers, driver) { continue } for _, tc := range cf.Cases { t.Run(tc.Name, func(t *testing.T) { - if tc.Skip != "" { - t.Skipf("skipped: %s", tc.Skip) + if slices.Contains(tc.SkipDrivers, driver) { + t.Skipf("skipped for driver %s", driver) } + defer func() { + if r := recover(); r != nil { + t.Fatalf("panic: %v", r) + } + }() + check := parseAssertion(t, tc.Assert) if tc.Fixture != nil { @@ -327,11 +333,3 @@ func assertContainsNodeWithProp(key, expected string) func(*testing.T, graph.Res } } -// formatCaseSummary is used for logging. -func formatCaseSummary(files []string) string { - total := 0 - for range files { - total++ - } - return fmt.Sprintf("%d case files", total) -} diff --git a/integration/testdata/cases/expansion_inline.json b/integration/testdata/cases/expansion_inline.json index f046467..57c51bc 100644 --- a/integration/testdata/cases/expansion_inline.json +++ b/integration/testdata/cases/expansion_inline.json @@ -18,6 +18,7 @@ }, { "name": "unbounded traversal filtering every traversed edge by a property", + "skip_drivers": ["neo4j"], "cypher": "match (n)-[r*..]->(e:NodeKind1) where n.name = 'n1' and r.prop = 'a' return e", "fixture": { "nodes": [ diff --git a/integration/testdata/cases/nodes.json b/integration/testdata/cases/nodes.json index 6a3ae37..1bdbe02 100644 --- a/integration/testdata/cases/nodes.json +++ b/integration/testdata/cases/nodes.json @@ -63,6 +63,7 @@ }, { "name": "filter typed node where array property overlaps a literal list", + "skip_drivers": ["neo4j"], "cypher": "match (n:NodeKind1) where ['DES-CBC-CRC', 'DES-CBC-MD5', 'RC4-HMAC-MD5'] in n.arrayProperty return n", "assert": "non_empty" }, @@ -218,6 +219,7 @@ }, { "name": "filter typed node where toInt of a property appears in a literal integer list", + "skip_drivers": ["neo4j"], "cypher": "match (n:NodeKind1) where toInt(n.value) in [1, 2, 3, 4] return n", "assert": "non_empty" }, @@ -238,6 +240,7 @@ }, { "name": "filter node where a property equals date plus a duration string", + "skip_drivers": ["neo4j"], "cypher": "match (s) where s.created_at = date() + duration('4 hours') return s", "assert": "no_error" }, diff --git a/integration/testdata/cases/nodes_inline.json b/integration/testdata/cases/nodes_inline.json index 9d47894..707d573 100644 --- a/integration/testdata/cases/nodes_inline.json +++ b/integration/testdata/cases/nodes_inline.json @@ -15,7 +15,7 @@ }, { "name": "cross-product filter where two nodes match different typed properties", - "skip": "PG type inference bug: mixed string/int cross-product properties (see zinic/testing fork)", + "skip_drivers": ["pg"], "cypher": "match (s), (e) where s.name = '1234' and e.other = 1234 return s", "fixture": { "nodes": [ @@ -97,7 +97,7 @@ }, { "name": "filter cross-product where either node satisfies a different property predicate", - "skip": "PG type inference bug: mixed string/int cross-product properties (see zinic/testing fork)", + "skip_drivers": ["pg"], "cypher": "match (s), (e) where s.name = '1234' or e.other = 1234 return s", "fixture": { "nodes": [ diff --git a/integration/testdata/cases/shortest_paths.json b/integration/testdata/cases/shortest_paths.json index b9d3537..ce1e978 100644 --- a/integration/testdata/cases/shortest_paths.json +++ b/integration/testdata/cases/shortest_paths.json @@ -18,6 +18,7 @@ }, { "name": "shortest path to self returns empty", + "skip_drivers": ["neo4j"], "cypher": "MATCH p = allShortestPaths((s)-[*1..]->(e)) WHERE s.name = 'SOME NAME' AND e.name = 'SOME NAME' RETURN p", "assert": "empty" }