225
225
end
226
226
output = function_call_signature (MyMeasurement2)# |> JSON3.pretty
227
227
expected_output = Dict {String, Any} (" name" => " MyMeasurement2_extractor" ,
228
- " parameters" => Dict {String, Any} (" properties" => Dict {String, Any} (" height" => Dict{
228
+ " parameters" => Dict {String, Any} (
229
+ " properties" => Dict {String, Any} (
230
+ " height" => Dict{
229
231
String,
230
- Any,
232
+ Any
231
233
}(" type" => " integer" ),
232
234
" weight" => Dict {String, Any} (" type" => " number" ),
233
235
" age" => Dict {String, Any} (" type" => " integer" )),
@@ -240,3 +242,123 @@ end
240
242
schema = function_call_signature (MaybeExtract{MyMeasurement2})
241
243
@test schema[" name" ] == " MaybeExtractMyMeasurement2_extractor"
242
244
end
245
+ @testset " to_json_schema-primitive_types" begin
246
+ @test to_json_schema (Int) == Dict (" type" => " integer" )
247
+ @test to_json_schema (Float64) == Dict (" type" => " number" )
248
+ @test to_json_schema (Bool) == Dict (" type" => " boolean" )
249
+ @test to_json_schema (String) == Dict (" type" => " string" )
250
+ @test_throws ArgumentError to_json_schema (Any) # Type Any is not supported
251
+ end
252
+ @testset " to_json_schema-structs" begin
253
+ # Function to check the equivalence of two JSON strings, since Dict is
254
+ # unordered, we need to sort keys before comparison.
255
+ function check_json_equivalence (json1:: AbstractString , json2:: AbstractString )
256
+ println (" \n check_json_equivalence\n ===json1===" )
257
+ println (json1)
258
+ println (" ===json2===" )
259
+ println (json2)
260
+ println ()
261
+ # JSON dictionary
262
+ d1 = JSON3. read (json1)
263
+ d2 = JSON3. read (json2)
264
+
265
+ # Get all the keys
266
+ k1 = sort (collect (keys (d1)))
267
+ k2 = sort (collect (keys (d2)))
268
+
269
+ # Test that all the keys are present
270
+ @test setdiff (k1, k2) == []
271
+ @test setdiff (k2, k1) == []
272
+
273
+ # Test that all the values are equivalent
274
+ for (k, v) in d1
275
+ @test d2[k] == v
276
+ end
277
+
278
+ # @test JSON3.write(JSON3.read(json1)) == JSON3.write(JSON3.read(json2))
279
+ end
280
+ function check_json_equivalence (d:: Dict , s:: AbstractString )
281
+ return check_json_equivalence (JSON3. write (d), s)
282
+ end
283
+
284
+ # Simple flat structure where each field is a primitive type
285
+ struct SimpleSingleton
286
+ singleton_value:: Int
287
+ end
288
+
289
+ check_json_equivalence (
290
+ JSON3. write (typed_json_schema (SimpleSingleton)),
291
+ " {\" singleton_value\" :\" integer\" }"
292
+ )
293
+
294
+ # Test a struct that contains another struct.
295
+ struct Nested
296
+ inside_element:: SimpleSingleton
297
+ end
298
+
299
+ check_json_equivalence (
300
+ JSON3. write (typed_json_schema (Nested)),
301
+ " {\" inside_element\" :{\" singleton_value\" :\" integer\" }}"
302
+ )
303
+
304
+ # Test a struct with two primitive types
305
+ struct IntFloatFlat
306
+ int_value:: Int
307
+ float_value:: Float64
308
+ end
309
+ check_json_equivalence (
310
+ typed_json_schema (IntFloatFlat),
311
+ " {\" int_value\" :\" integer\" ,\" float_value\" :\" number\" }"
312
+ )
313
+
314
+ # Test a struct that contains all primitive types
315
+ struct AllJSONPrimitives
316
+ int:: Integer
317
+ float:: Real
318
+ string:: AbstractString
319
+ bool:: Bool
320
+ nothing :: Nothing
321
+ missing :: Missing
322
+
323
+ # Array types
324
+ array_of_strings:: Vector{String}
325
+ array_of_ints:: Vector{Int}
326
+ array_of_floats:: Vector{Float64}
327
+ array_of_bools:: Vector{Bool}
328
+ array_of_nothings:: Vector{Nothing}
329
+ array_of_missings:: Vector{Missing}
330
+ end
331
+
332
+ check_json_equivalence (
333
+ typed_json_schema (AllJSONPrimitives),
334
+ " {\" int\" :\" integer\" ,\" float\" :\" number\" ,\" string\" :\" string\" ,\" bool\" :\" boolean\" ,\" nothing\" :\" null\" ,\" missing\" :\" null\" ,\" array_of_strings\" :\" string[]\" ,\" array_of_ints\" :\" integer[]\" ,\" array_of_floats\" :\" number[]\" ,\" array_of_bools\" :\" boolean[]\" ,\" array_of_nothings\" :\" null[]\" ,\" array_of_missings\" :\" null[]\" }"
335
+ )
336
+
337
+ # Test a struct with a vector of primitives
338
+ struct ABunchOfVectors
339
+ strings:: Vector{String}
340
+ ints:: Vector{Int}
341
+ floats:: Vector{Float64}
342
+ nested_vector:: Vector{Nested}
343
+ end
344
+
345
+ check_json_equivalence (
346
+ typed_json_schema (ABunchOfVectors),
347
+ " {\" strings\" :\" string[]\" ,\" ints\" :\" integer[]\" ,\" nested_vector\" :{\" list[Object]\" :\" {\\\" inside_element\\\" :{\\\" singleton_value\\\" :\\\" integer\\\" }}\" },\" floats\" :\" number[]\" }"
348
+ )
349
+
350
+ # Weird struct with a bunch of different types
351
+ struct Monster
352
+ name:: String
353
+ age:: Int
354
+ height:: Float64
355
+ friends:: Vector{String}
356
+ nested:: Nested
357
+ flat:: IntFloatFlat
358
+ end
359
+
360
+ check_json_equivalence (
361
+ typed_json_schema (Monster),
362
+ " {\" flat\" :{\" float_value\" :\" number\" ,\" int_value\" :\" integer\" },\" nested\" :{\" inside_element\" :{\" singleton_value\" :\" integer\" }},\" age\" :\" integer\" ,\" name\" :\" string\" ,\" height\" :\" number\" ,\" friends\" :\" string[]\" }"
363
+ )
364
+ end ;
0 commit comments