-
Notifications
You must be signed in to change notification settings - Fork 8
/
compiler_test.go
186 lines (158 loc) · 5.34 KB
/
compiler_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package jsonschema
import (
"fmt"
"testing"
)
const (
remoteSchemaURL = "https://json-schema.org/draft/2020-12/schema"
)
func TestCompileWithID(t *testing.T) {
compiler := NewCompiler()
schemaJSON := createTestSchemaJSON("http://example.com/schema", map[string]string{"name": "string"}, []string{"name"})
schema, err := compiler.Compile([]byte(schemaJSON))
if err != nil {
t.Fatalf("Failed to compile schema with $id: %s", err)
}
if schema.ID != "http://example.com/schema" {
t.Errorf("Expected $id to be 'http://example.com/schema', got '%s'", schema.ID)
}
}
func TestGetSchema(t *testing.T) {
compiler := NewCompiler()
schemaJSON := createTestSchemaJSON("http://example.com/schema", map[string]string{"name": "string"}, []string{"name"})
_, err := compiler.Compile([]byte(schemaJSON))
if err != nil {
t.Fatalf("Failed to compile schema: %s", err)
}
schema, err := compiler.GetSchema("http://example.com/schema")
if err != nil {
t.Fatalf("Failed to retrieve compiled schema: %s", err)
}
if schema.ID != "http://example.com/schema" {
t.Errorf("Expected to retrieve schema with $id 'http://example.com/schema', got '%s'", schema.ID)
}
}
func TestValidateRemoteSchema(t *testing.T) {
compiler := NewCompiler()
// Load the meta-schema
metaSchema, err := compiler.GetSchema(remoteSchemaURL)
if err != nil {
t.Fatalf("Failed to load meta-schema: %v", err)
}
// Ensure that the schema is not nil
if metaSchema == nil {
t.Fatal("Meta-schema is nil")
}
// Verify the ID of the retrieved schema
expectedID := remoteSchemaURL
if metaSchema.ID != expectedID {
t.Errorf("Expected schema with ID %s, got %s", expectedID, metaSchema.ID)
}
}
func TestCompileCache(t *testing.T) {
compiler := NewCompiler()
schemaJSON := createTestSchemaJSON("http://example.com/schema", map[string]string{"name": "string"}, []string{"name"})
_, err := compiler.Compile([]byte(schemaJSON))
if err != nil {
t.Fatalf("Failed to compile schema: %s", err)
}
// Attempt to compile the same schema again
_, err = compiler.Compile([]byte(schemaJSON))
if err != nil {
t.Fatalf("Failed to compile schema a second time: %s", err)
}
if len(compiler.schemas) != 1 {
t.Errorf("Schema should be compiled once and cached, found %d entries in cache", len(compiler.schemas))
}
}
func TestResolveReferences(t *testing.T) {
compiler := NewCompiler()
// Assuming this schema is already compiled and cached
baseSchemaJSON := createTestSchemaJSON("http://example.com/base", map[string]string{"age": "integer"}, nil)
_, err := compiler.Compile([]byte(baseSchemaJSON))
if err != nil {
t.Fatalf("Failed to compile base schema: %s", err)
}
refSchemaJSON := `{
"$id": "http://example.com/ref",
"type": "object",
"properties": {
"userInfo": {"$ref": "http://example.com/base"}
}
}`
_, err = compiler.Compile([]byte(refSchemaJSON))
if err != nil {
t.Fatalf("Failed to resolve reference: %s", err)
}
}
func TestResolveReferencesCorrectly(t *testing.T) {
compiler := NewCompiler()
// Compile and cache the base schema which will be referenced.
baseSchemaJSON := `{
"$id": "http://example.com/base",
"type": "object",
"properties": {
"age": {"type": "integer"}
},
"required": ["age"]
}`
baseSchema, err := compiler.Compile([]byte(baseSchemaJSON))
if err != nil {
t.Fatalf("Failed to compile base schema: %s", err)
}
// Print base schema ID and check if cached correctly
cachedBaseSchema, cacheErr := compiler.GetSchema("http://example.com/base")
if cacheErr != nil || cachedBaseSchema == nil {
t.Fatalf("Base schema not cached correctly or cache retrieval failed: %s", cacheErr)
}
// Compile another schema that references the base schema.
refSchemaJSON := `{
"$id": "http://example.com/ref",
"type": "object",
"properties": {
"userInfo": {"$ref": "http://example.com/base"}
}
}`
refSchema, err := compiler.Compile([]byte(refSchemaJSON))
if err != nil {
t.Fatalf("Failed to compile schema with $ref: %s", err)
}
// Verify that the $ref in refSchema is correctly resolved to the base schema.
if refSchema.Properties == nil {
t.Fatal("Properties map should not be nil")
}
userInfoProp, exists := (*refSchema.Properties)["userInfo"]
if !exists || userInfoProp == nil {
t.Fatalf("userInfo property should exist and have a non-nil Schema")
}
// Assert that ResolvedRef is not nil and correctly points to the base schema
if userInfoProp.ResolvedRef == nil {
t.Fatalf("ResolvedRef for userInfo should not be nil, got nil instead")
} else if userInfoProp.ResolvedRef != baseSchema {
t.Fatalf("ResolvedRef for userInfo does not match the base schema")
}
}
// createTestSchemaJSON simplifies creating JSON schema strings for testing.
func createTestSchemaJSON(id string, properties map[string]string, required []string) string {
propsStr := ""
for propName, propType := range properties {
propsStr += fmt.Sprintf(`"%s": {"type": "%s"},`, propName, propType)
}
if len(propsStr) > 0 {
propsStr = propsStr[:len(propsStr)-1] // Remove the trailing comma
}
reqStr := "["
for _, req := range required {
reqStr += fmt.Sprintf(`"%s",`, req)
}
if len(reqStr) > 1 {
reqStr = reqStr[:len(reqStr)-1] // Remove the trailing comma
}
reqStr += "]"
return fmt.Sprintf(`{
"$id": "%s",
"type": "object",
"properties": {%s},
"required": %s
}`, id, propsStr, reqStr)
}