@@ -13,8 +13,14 @@ import (
13
13
"github.com/modelcontextprotocol/go-sdk/jsonschema"
14
14
)
15
15
16
- func forType [T any ]() * jsonschema.Schema {
17
- s , err := jsonschema .For [T ]()
16
+ func forType [T any ](lax bool ) * jsonschema.Schema {
17
+ var s * jsonschema.Schema
18
+ var err error
19
+ if lax {
20
+ s , err = jsonschema .ForLax [T ]()
21
+ } else {
22
+ s , err = jsonschema .For [T ]()
23
+ }
18
24
if err != nil {
19
25
panic (err )
20
26
}
@@ -28,104 +34,134 @@ func TestFor(t *testing.T) {
28
34
B int `jsonschema:"bdesc"`
29
35
}
30
36
31
- tests := [] struct {
37
+ type test struct {
32
38
name string
33
39
got * jsonschema.Schema
34
40
want * jsonschema.Schema
35
- }{
36
- {"string" , forType [string ](), & schema {Type : "string" }},
37
- {"int" , forType [int ](), & schema {Type : "integer" }},
38
- {"int16" , forType [int16 ](), & schema {Type : "integer" }},
39
- {"uint32" , forType [int16 ](), & schema {Type : "integer" }},
40
- {"float64" , forType [float64 ](), & schema {Type : "number" }},
41
- {"bool" , forType [bool ](), & schema {Type : "boolean" }},
42
- {"intmap" , forType [map [string ]int ](), & schema {
43
- Type : "object" ,
44
- AdditionalProperties : & schema {Type : "integer" },
45
- }},
46
- {"anymap" , forType [map [string ]any ](), & schema {
47
- Type : "object" ,
48
- AdditionalProperties : & schema {},
49
- }},
50
- {
51
- "struct" ,
52
- forType [struct {
53
- F int `json:"f" jsonschema:"fdesc"`
54
- G []float64
55
- P * bool `jsonschema:"pdesc"`
56
- Skip string `json:"-"`
57
- NoSkip string `json:",omitempty"`
58
- unexported float64
59
- unexported2 int `json:"No"`
60
- }](),
61
- & schema {
62
- Type : "object" ,
63
- Properties : map [string ]* schema {
64
- "f" : {Type : "integer" , Description : "fdesc" },
65
- "G" : {Type : "array" , Items : & schema {Type : "number" }},
66
- "P" : {Types : []string {"null" , "boolean" }, Description : "pdesc" },
67
- "NoSkip" : {Type : "string" },
41
+ }
42
+
43
+ tests := func (lax bool ) []test {
44
+ return []test {
45
+ {"string" , forType [string ](lax ), & schema {Type : "string" }},
46
+ {"int" , forType [int ](lax ), & schema {Type : "integer" }},
47
+ {"int16" , forType [int16 ](lax ), & schema {Type : "integer" }},
48
+ {"uint32" , forType [int16 ](lax ), & schema {Type : "integer" }},
49
+ {"float64" , forType [float64 ](lax ), & schema {Type : "number" }},
50
+ {"bool" , forType [bool ](lax ), & schema {Type : "boolean" }},
51
+ {"intmap" , forType [map [string ]int ](lax ), & schema {
52
+ Type : "object" ,
53
+ AdditionalProperties : & schema {Type : "integer" },
54
+ }},
55
+ {"anymap" , forType [map [string ]any ](lax ), & schema {
56
+ Type : "object" ,
57
+ AdditionalProperties : & schema {},
58
+ }},
59
+ {
60
+ "struct" ,
61
+ forType [struct {
62
+ F int `json:"f" jsonschema:"fdesc"`
63
+ G []float64
64
+ P * bool `jsonschema:"pdesc"`
65
+ Skip string `json:"-"`
66
+ NoSkip string `json:",omitempty"`
67
+ unexported float64
68
+ unexported2 int `json:"No"`
69
+ }](lax ),
70
+ & schema {
71
+ Type : "object" ,
72
+ Properties : map [string ]* schema {
73
+ "f" : {Type : "integer" , Description : "fdesc" },
74
+ "G" : {Type : "array" , Items : & schema {Type : "number" }},
75
+ "P" : {Types : []string {"null" , "boolean" }, Description : "pdesc" },
76
+ "NoSkip" : {Type : "string" },
77
+ },
78
+ Required : []string {"f" , "G" , "P" },
79
+ AdditionalProperties : falseSchema (),
68
80
},
69
- Required : []string {"f" , "G" , "P" },
70
- AdditionalProperties : falseSchema (),
71
81
},
72
- },
73
- {
74
- "no sharing" ,
75
- forType [struct { X , Y int }](),
76
- & schema {
77
- Type : "object" ,
78
- Properties : map [string ]* schema {
79
- "X" : {Type : "integer" },
80
- "Y" : {Type : "integer" },
82
+ {
83
+ "no sharing" ,
84
+ forType [struct { X , Y int }](lax ),
85
+ & schema {
86
+ Type : "object" ,
87
+ Properties : map [string ]* schema {
88
+ "X" : {Type : "integer" },
89
+ "Y" : {Type : "integer" },
90
+ },
91
+ Required : []string {"X" , "Y" },
92
+ AdditionalProperties : falseSchema (),
81
93
},
82
- Required : []string {"X" , "Y" },
83
- AdditionalProperties : falseSchema (),
84
94
},
85
- },
86
- {
87
- "nested and embedded" ,
88
- forType [struct {
89
- A S
90
- S
91
- }](),
92
- & schema {
93
- Type : "object" ,
94
- Properties : map [string ]* schema {
95
- "A" : {
96
- Type : "object" ,
97
- Properties : map [string ]* schema {
98
- "B" : {Type : "integer" , Description : "bdesc" },
95
+ {
96
+ "nested and embedded" ,
97
+ forType [struct {
98
+ A S
99
+ S
100
+ }](lax ),
101
+ & schema {
102
+ Type : "object" ,
103
+ Properties : map [string ]* schema {
104
+ "A" : {
105
+ Type : "object" ,
106
+ Properties : map [string ]* schema {
107
+ "B" : {Type : "integer" , Description : "bdesc" },
108
+ },
109
+ Required : []string {"B" },
110
+ AdditionalProperties : falseSchema (),
99
111
},
100
- Required : [] string { "B" },
101
- AdditionalProperties : falseSchema () ,
102
- },
103
- "S " : {
104
- Type : "object" ,
105
- Properties : map [ string ] * schema {
106
- "B" : { Type : "integer" , Description : "bdesc" } ,
112
+ "S" : {
113
+ Type : "object" ,
114
+ Properties : map [ string ] * schema {
115
+ "B " : {Type : "integer" , Description : "bdesc" },
116
+ } ,
117
+ Required : [] string { "B" },
118
+ AdditionalProperties : falseSchema () ,
107
119
},
108
- Required : []string {"B" },
109
- AdditionalProperties : falseSchema (),
110
120
},
121
+ Required : []string {"A" , "S" },
122
+ AdditionalProperties : falseSchema (),
111
123
},
112
- Required : []string {"A" , "S" },
113
- AdditionalProperties : falseSchema (),
114
124
},
115
- },
125
+ }
116
126
}
117
127
118
- for _ , test := range tests {
119
- t .Run (test .name , func (t * testing.T ) {
120
- if diff := cmp .Diff (test .want , test .got , cmpopts .IgnoreUnexported (jsonschema.Schema {})); diff != "" {
121
- t .Fatalf ("ForType mismatch (-want +got):\n %s" , diff )
122
- }
123
- // These schemas should all resolve.
124
- if _ , err := test .got .Resolve (nil ); err != nil {
125
- t .Fatalf ("Resolving: %v" , err )
126
- }
127
- })
128
+ run := func (t * testing.T , tt test ) {
129
+ if diff := cmp .Diff (tt .want , tt .got , cmpopts .IgnoreUnexported (jsonschema.Schema {})); diff != "" {
130
+ t .Fatalf ("ForType mismatch (-want +got):\n %s" , diff )
131
+ }
132
+ // These schemas should all resolve.
133
+ if _ , err := tt .got .Resolve (nil ); err != nil {
134
+ t .Fatalf ("Resolving: %v" , err )
135
+ }
128
136
}
137
+
138
+ t .Run ("strict" , func (t * testing.T ) {
139
+ for _ , test := range tests (false ) {
140
+ t .Run (test .name , func (t * testing.T ) { run (t , test ) })
141
+ }
142
+ })
143
+
144
+ laxTests := append (tests (true ), test {
145
+ "ignore" ,
146
+ forType [struct {
147
+ A int
148
+ B map [int ]int
149
+ C func ()
150
+ }](true ),
151
+ & schema {
152
+ Type : "object" ,
153
+ Properties : map [string ]* schema {
154
+ "A" : {Type : "integer" },
155
+ },
156
+ Required : []string {"A" },
157
+ AdditionalProperties : falseSchema (),
158
+ },
159
+ })
160
+ t .Run ("lax" , func (t * testing.T ) {
161
+ for _ , test := range laxTests {
162
+ t .Run (test .name , func (t * testing.T ) { run (t , test ) })
163
+ }
164
+ })
129
165
}
130
166
131
167
func forErr [T any ]() error {
0 commit comments