@@ -212,20 +212,34 @@ func TestFor(t *testing.T) {
212212}
213213
214214func TestForType (t * testing.T ) {
215+ // This tests embedded structs with a custom schema in addition to ForType.
215216 type schema = jsonschema.Schema
216217
217- // ForType is virtually identical to For. Just test that options are handled properly.
218- opts := & jsonschema.ForOptions {
219- IgnoreInvalidTypes : true ,
220- TypeSchemas : map [reflect.Type ]* jsonschema.Schema {
221- reflect .TypeFor [custom ](): {Type : "custom" },
222- },
218+ type E struct {
219+ G float64 // promoted into S
220+ B int // hidden by S.B
223221 }
224222
225223 type S struct {
226224 I int
227225 F func ()
228226 C custom
227+ E
228+ B bool
229+ }
230+
231+ opts := & jsonschema.ForOptions {
232+ IgnoreInvalidTypes : true ,
233+ TypeSchemas : map [reflect.Type ]* schema {
234+ reflect .TypeFor [custom ](): {Type : "custom" },
235+ reflect .TypeFor [E ](): {
236+ Type : "object" ,
237+ Properties : map [string ]* schema {
238+ "G" : {Type : "integer" },
239+ "B" : {Type : "integer" },
240+ },
241+ },
242+ },
229243 }
230244 got , err := jsonschema .ForType (reflect .TypeOf (S {}), opts )
231245 if err != nil {
@@ -236,15 +250,80 @@ func TestForType(t *testing.T) {
236250 Properties : map [string ]* schema {
237251 "I" : {Type : "integer" },
238252 "C" : {Type : "custom" },
253+ "G" : {Type : "integer" },
254+ "B" : {Type : "boolean" },
239255 },
240- Required : []string {"I" , "C" },
256+ Required : []string {"I" , "C" , "B" },
241257 AdditionalProperties : falseSchema (),
242258 }
243259 if diff := cmp .Diff (want , got , cmpopts .IgnoreUnexported (schema {})); diff != "" {
244260 t .Fatalf ("ForType mismatch (-want +got):\n %s" , diff )
245261 }
246262}
247263
264+ func TestCustomEmbeddedError (t * testing.T ) {
265+ // Disallow anything but "type" and "properties".
266+ type schema = jsonschema.Schema
267+
268+ type (
269+ E struct { G int }
270+ S struct { E }
271+ )
272+
273+ for _ , tt := range []struct {
274+ name string
275+ override * schema
276+ }{
277+ {
278+ "missing type" ,
279+ & schema {},
280+ },
281+ {
282+ "wrong type" ,
283+ & schema {Type : "number" },
284+ },
285+ {
286+ "extra string field" ,
287+ & schema {
288+ Type : "object" ,
289+ Title : "t" ,
290+ },
291+ },
292+ {
293+ "extra pointer field" ,
294+ & schema {
295+ Type : "object" ,
296+ MinProperties : jsonschema .Ptr (1 ),
297+ },
298+ },
299+ {
300+ "extra array field" ,
301+ & schema {
302+ Type : "object" ,
303+ Required : []string {"G" },
304+ },
305+ },
306+ {
307+ "extra schema field" ,
308+ & schema {
309+ Type : "object" ,
310+ AdditionalProperties : falseSchema (),
311+ },
312+ },
313+ } {
314+ t .Run (tt .name , func (t * testing.T ) {
315+ opts := & jsonschema.ForOptions {
316+ TypeSchemas : map [reflect.Type ]* schema {
317+ reflect .TypeFor [E ](): tt .override ,
318+ },
319+ }
320+ if _ , err := jsonschema .ForType (reflect .TypeOf (S {}), opts ); err == nil {
321+ t .Error ("got nil, want error" )
322+ }
323+ })
324+ }
325+ }
326+
248327func forErr [T any ]() error {
249328 _ , err := jsonschema.For [T ](nil )
250329 return err
0 commit comments