jsonschema: resolve refs

Implement the $ref keyword, except for remote references (those
pointing outside the root schema).

Change-Id: Ia5ca88464e62e9c613970d8d9fcd1512ab288934
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670775
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Jonathan Amsterdam 2025-04-26 11:26:58 -04:00 • committed by Gopher Robot
commit 12fa054310

View file

@ -5,6 +5,7 @@
package jsonschema
import (
"errors"
"maps"
"net/url"
"regexp"
@ -27,7 +28,7 @@ func TestCheckLocal(t *testing.T) {
"regexp",
},
} {
_, err := tt.s.Resolve("")
_, err := tt.s.Resolve("", nil)
if err == nil {
t.Errorf("%s: unexpectedly passed", tt.s.json())
continue
@ -104,3 +105,37 @@ func TestResolveURIs(t *testing.T) {
})
}
}
func TestRefCycle(t *testing.T) {
// Verify that cycles of refs are OK.
// The test suite doesn't check this, suprisingly.
schemas := map[string]*Schema{
"root": {Ref: "a"},
"a": {Ref: "b"},
"b": {Ref: "a"},
}
loader := func(uri *url.URL) (*Schema, error) {
s, ok := schemas[uri.Path[1:]]
if !ok {
return nil, errors.New("not found")
}
return s, nil
}
rs, err := schemas["root"].Resolve("", loader)
if err != nil {
t.Fatal(err)
}
check := func(s *Schema, key string) {
t.Helper()
if s.resolvedRef != schemas[key] {
t.Errorf("%s resolvedRef != schemas[%q]", s.json(), key)
}
}
check(rs.root, "a")
check(schemas["a"], "b")
check(schemas["b"], "a")
}