Skip to content

Commit eb8eb35

Browse files
committed
Add cburgmer/json-path-comparison test suite
Add `make` targets to download the suite and run the test, which is gated by the `compare` tag. Skip tests where the consensus is that a query is not supported, as well as a couple of ambiguous tests that need clarification, as well as one test that clearly conflicts with RFC 9535. Skip comparing the result of tests that have no consensus. Leave XXX comments where the behavior is unexpected or unexplained. Requires explicit gopkg.in/yaml.v3 import, so add a note to the README documenting no runtime dependencies.
1 parent deb0af2 commit eb8eb35

File tree

6 files changed

+121
-3
lines changed

6 files changed

+121
-3
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: actions/setup-go@v5
1919
with: { go-version: "${{ matrix.go }}", check-latest: true }
2020
- name: Run Tests
21-
run: make test
21+
run: make test-all
2222
- name: Setup TinyGo
2323
uses: acifani/setup-tinygo@v2
2424
with: { tinygo-version: 0.37.0 }

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ pub/
3232

3333
# Temp files
3434
*.tmp
35+
36+
# Generated files.
37+
/compare/regression_suite.yaml

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ cover: $(shell find . -name \*.go)
99
GOTOOLCHAIN=local $(GO) test -v -coverprofile=cover.out -covermode=count ./...
1010
@$(GO) tool cover -html=cover.out
1111

12+
compare/regression_suite.yaml:
13+
curl -so "$@" https://raw.githubusercontent.com/cburgmer/json-path-comparison/refs/heads/master/regression_suite/regression_suite.yaml
14+
15+
test-compare: compare/regression_suite.yaml
16+
GOTOOLCHAIN=local ${GO} test -tags=compare ./compare -count=1
17+
18+
test-all: compare/regression_suite.yaml
19+
GOTOOLCHAIN=local ${GO} test -tags=compare ./... -count=1
20+
1221
.PHONY: lint # Lint the project
1322
lint: .golangci.yaml
1423
@pre-commit run --show-diff-on-failure --color=always --all-files

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ A brief overview of [RFC 9535 JSONPath] syntax:
3333
| `?<logical-expr>` | filter selector: selects particular children using a logical expression |
3434
| `length(@.foo)` | function extension: invokes a function in a filter expression |
3535

36+
## Dependencies
37+
38+
This package has no runtime dependencies, only testing dependencies.
39+
3640
## Copyright
3741

3842
Copyright © 2024-2025 David E. Wheeler

compare/compare_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//go:build compare
2+
3+
// Package compare tests theory/jsonpath against the [json-path-comparison]
4+
// project's regression suite. It requires the file regression_suite.yaml to
5+
// be in this directory. The test only runs with the "compare" tag. Use make
6+
// for the easiest way to download regression_suite.yaml and run the tests:
7+
//
8+
// make test-compare
9+
//
10+
// [json-path-comparison]: https://github.com/cburgmer/json-path-comparison
11+
package compare
12+
13+
import (
14+
"os"
15+
"path/filepath"
16+
"runtime"
17+
"testing"
18+
19+
"github.com/stretchr/testify/assert"
20+
"github.com/stretchr/testify/require"
21+
"github.com/theory/jsonpath"
22+
"gopkg.in/yaml.v3"
23+
)
24+
25+
type Query struct {
26+
ID string `yaml:"id"`
27+
Selector string `yaml:"selector"`
28+
Document any `yaml:"document"`
29+
Consensus any `yaml:"consensus"`
30+
Ordered bool `yaml:"ordered"`
31+
// NotFoundConsensus string `yaml:"not-found-consensus"`
32+
// ScalarNotFoundConsensus string `yaml:"scalar-not-found-consensus"`
33+
}
34+
35+
func file(t *testing.T) string {
36+
t.Helper()
37+
_, fn, _, ok := runtime.Caller(0)
38+
assert.True(t, ok)
39+
return filepath.Clean(filepath.Join(
40+
filepath.Dir(fn),
41+
"regression_suite.yaml",
42+
))
43+
}
44+
45+
func queries(t *testing.T) []Query {
46+
t.Helper()
47+
data, err := os.ReadFile(file(t))
48+
require.NoError(t, err)
49+
var q struct {
50+
Queries []Query `yaml:"queries"`
51+
}
52+
require.NoError(t, yaml.Unmarshal(data, &q))
53+
return q.Queries
54+
}
55+
56+
func TestConsensus(t *testing.T) {
57+
t.Parallel()
58+
59+
skip := map[string]string{
60+
"array_slice_with_step_and_leading_zeros": "leading zeros disallowed integers; see RFC 9535 sections 2.3.3.1, 2.3.4.1",
61+
"dot_notation_with_number_on_object": "leading digits disallowed in shorthand names; see RFC 9535 section 2.5.1.1",
62+
"dot_notation_with_dash": "dash disallowed in shorthand hames; see RFC 9535 section 2.5.1.1",
63+
}
64+
65+
for _, q := range queries(t) {
66+
t.Run(q.ID, func(t *testing.T) {
67+
t.Parallel()
68+
69+
if q.Consensus == "NOT_SUPPORTED" {
70+
t.Skip(q.Consensus)
71+
}
72+
73+
if r, ok := skip[q.ID]; ok {
74+
t.Skip(r)
75+
}
76+
77+
path, err := jsonpath.Parse(q.Selector)
78+
// XXX Why is consensus empty?
79+
if q.Consensus != nil {
80+
require.NoError(t, err)
81+
}
82+
if err != nil {
83+
// XXX Why is there an error? TODOs?
84+
assert.Nil(t, path)
85+
return
86+
}
87+
result := []any(path.Select(q.Document))
88+
89+
switch {
90+
case q.Ordered:
91+
assert.Equal(t, q.Consensus, result)
92+
case q.Consensus == nil:
93+
// XXX What to do here?
94+
// assert.Empty(t, result)
95+
default:
96+
assert.ElementsMatch(t, q.Consensus, result)
97+
}
98+
})
99+
}
100+
}

go.mod

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ module github.com/theory/jsonpath
22

33
go 1.23
44

5-
require github.com/stretchr/testify v1.10.0
5+
require (
6+
github.com/stretchr/testify v1.10.0
7+
gopkg.in/yaml.v3 v3.0.1
8+
)
69

710
require (
811
github.com/davecgh/go-spew v1.1.1 // indirect
912
github.com/kr/pretty v0.3.0 // indirect
1013
github.com/pmezard/go-difflib v1.0.0 // indirect
1114
github.com/rogpeppe/go-internal v1.12.0 // indirect
1215
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
13-
gopkg.in/yaml.v3 v3.0.1 // indirect
1416
)

0 commit comments

Comments
 (0)