jsonschema: resolve URIs for $id

Assign a base URI to every schema.

See the comment on resolveURIs for details.

Change-Id: I2332d825c486766832503cabdd0bf9d819171d53
Reviewed-on: https://go-review.googlesource.com/c/tools/+/669997
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Jonathan Amsterdam 2025-04-26 11:13:17 -04:00
commit 0a79e67c62

View file

@ -5,7 +5,10 @@
package jsonschema
import (
"maps"
"net/url"
"regexp"
"slices"
"testing"
)
@ -24,7 +27,7 @@ func TestCheckLocal(t *testing.T) {
"regexp",
},
} {
_, err := tt.s.Resolve()
_, err := tt.s.Resolve("")
if err == nil {
t.Errorf("%s: unexpectedly passed", tt.s.json())
continue
@ -35,3 +38,56 @@ func TestCheckLocal(t *testing.T) {
}
}
}
func TestResolveURIs(t *testing.T) {
for _, baseURI := range []string{"", "http://a.com"} {
t.Run(baseURI, func(t *testing.T) {
root := &Schema{
ID: "http://b.com",
Items: &Schema{
ID: "/foo.json",
},
Contains: &Schema{
ID: "/bar.json",
Anchor: "a",
Items: &Schema{
Anchor: "b",
Items: &Schema{
// An ID shouldn't be a query param, but this tests
// resolving an ID with its parent.
ID: "?items",
Anchor: "c",
},
},
},
}
base, err := url.Parse(baseURI)
if err != nil {
t.Fatal(err)
}
got, err := resolveURIs(root, base)
if err != nil {
t.Fatal(err)
}
want := map[string]*Schema{
baseURI: root,
"http://b.com/foo.json": root.Items,
"http://b.com/bar.json": root.Contains,
"http://b.com/bar.json?items": root.Contains.Items.Items,
}
if baseURI != root.ID {
want[root.ID] = root
}
gotKeys := slices.Sorted(maps.Keys(got))
wantKeys := slices.Sorted(maps.Keys(want))
if !slices.Equal(gotKeys, wantKeys) {
t.Errorf("ID keys:\ngot %q\nwant %q", gotKeys, wantKeys)
}
if !maps.Equal(got, want) {
t.Errorf("IDs:\ngot %+v\n\nwant %+v", got, want)
}
})
}
}