2024-09-13 21:59:25 +00:00
|
|
|
(import (chicken string))
|
|
|
|
(import test
|
|
|
|
(chicken base)
|
|
|
|
(chicken format)
|
|
|
|
(chicken port)
|
|
|
|
(chicken string)
|
|
|
|
(chicken io)
|
|
|
|
(srfi-34) ;;Exception Handling
|
|
|
|
(srfi-35) ;;Exception Types
|
|
|
|
(srfi-158) ;;Generators
|
|
|
|
)
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(include-relative "../srfi-180.impl.scm")
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Whitespace predicate"
|
|
|
|
(test "#\\space"
|
|
|
|
#t (is-whitespace? #\space)))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "JSON Generator"
|
|
|
|
(test "Basic test"
|
|
|
|
'(array-start 1 2 3 "Hello" object-start "a" 1 object-end array-end)
|
|
|
|
(with-input-from-string "[1, 2, 3, \"Hello\", {\"a\", 1}] true [5 4 3 2]"
|
|
|
|
(lambda ()
|
|
|
|
(let ((generator (json-generator)))
|
|
|
|
(let loop ((accu '()))
|
|
|
|
(let ((token (generator)))
|
|
|
|
(if (not (eof-object? token))
|
|
|
|
(loop (cons token accu))
|
|
|
|
(reverse accu)))))))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Array delimiter reading"
|
|
|
|
(test "Start delimiter"
|
|
|
|
'(array-start " " 1)
|
|
|
|
(let-values (((val input charcount nesting-delta) (read-array-start 0 "[" (lambda () " "))))
|
|
|
|
(list val input charcount)))
|
|
|
|
(test "End delimiter"
|
|
|
|
'(array-end " " 9)
|
|
|
|
(let-values (((val input charcount nesting-delta) (read-array-end 8 "]" (lambda () " "))))
|
|
|
|
(list val input charcount))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Object delimiter reading"
|
|
|
|
(test "Start delimiter"
|
|
|
|
'(object-start " " 1)
|
|
|
|
(let-values (((val input charcount nesting-delta) (read-object-start 0 "{" (lambda () " "))))
|
|
|
|
(list val input charcount)))
|
|
|
|
(test "End delimiter"
|
|
|
|
'(object-end " " 5)
|
|
|
|
(let-values (((val input charcount nesting-delta) (read-object-end 4 "}" (lambda () " "))))
|
|
|
|
(list val input charcount))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Null reading"
|
|
|
|
(let ((input '(#\u #\l #\l #\space)))
|
|
|
|
(test "Null reading"
|
|
|
|
'(null #\space 4)
|
|
|
|
(let-values (((val input charcount nesting-delta)
|
|
|
|
(read-null-sym 0 #\n (lambda () (let ((next (car input)))
|
|
|
|
(set! input (cdr input))
|
|
|
|
next)))))
|
|
|
|
(list val input charcount)))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Boolean reading"
|
|
|
|
(let ((input '(#\r #\u #\e #\space)))
|
|
|
|
(test "True values"
|
|
|
|
'(#t #\space 4)
|
|
|
|
(let-values (((val input charcount nesting-delta)
|
|
|
|
(read-boolean 0 #\t (lambda () (let ((next (car input)))
|
|
|
|
(set! input (cdr input))
|
|
|
|
next)))))
|
|
|
|
(list val input charcount)))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "Number reading"
|
|
|
|
(let ((input '(#\2 #\3 #\4 #\space)))
|
|
|
|
(test "Integer"
|
|
|
|
'(1234 #\space 4)
|
|
|
|
(let-values (((val input charcount nesting-delta)
|
|
|
|
(read-number 0 #\1 (lambda () (let ((next (car input)))
|
|
|
|
(set! input (cdr input))
|
|
|
|
next)))))
|
|
|
|
(list val input charcount)))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "String reading"
|
2024-09-14 12:53:27 +00:00
|
|
|
(let ((input '(#\T #\e #\s #\t #\space #\T #\e #\s #\\ #\" #\t #\" #\space)))
|
2024-09-13 21:59:25 +00:00
|
|
|
(test "String"
|
2024-09-14 12:53:27 +00:00
|
|
|
'("Test Tes\"t" #\space 13)
|
2024-09-13 21:59:25 +00:00
|
|
|
(let-values (((val input charcount nesting-delta)
|
|
|
|
(read-string 0 #\" (lambda () (let ((next (car input)))
|
|
|
|
(set! input (cdr input))
|
|
|
|
next)))))
|
|
|
|
(list val input charcount)))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "JSON folding"
|
|
|
|
(test "Single value"
|
|
|
|
42
|
|
|
|
(with-input-from-string "42 25"
|
|
|
|
(lambda ()
|
|
|
|
(json-fold json-proc array-start array-end object-start object-end '()))))
|
|
|
|
(test "Simple array"
|
|
|
|
#(24 42 43)
|
|
|
|
(with-input-from-string "[24 42 43]"
|
|
|
|
(lambda ()
|
|
|
|
(json-fold json-proc array-start array-end object-start object-end '()))))
|
|
|
|
(test "Nested array"
|
|
|
|
#(24 #(42 24) 42)
|
|
|
|
(with-input-from-string "[24 [42 24] 42]"
|
|
|
|
(lambda ()
|
|
|
|
(json-fold json-proc array-start array-end object-start object-end '()))))
|
|
|
|
(test "Nested object"
|
|
|
|
'(("a" . 1) ("b" . 2) ("c" . (("d" . 4))))
|
|
|
|
(with-input-from-string "{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}"
|
|
|
|
(lambda ()
|
|
|
|
(json-fold json-proc array-start array-end object-start object-end '())))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-group "JSON Accumulator"
|
|
|
|
(test "Accumulate a number"
|
|
|
|
"1234"
|
|
|
|
(with-output-to-string
|
|
|
|
(lambda ()
|
|
|
|
((json-accumulator) 1234))))
|
|
|
|
(test "Accumulate a string"
|
|
|
|
"\"Accumulator\""
|
|
|
|
(with-output-to-string
|
|
|
|
(lambda ()
|
|
|
|
((json-accumulator) "Accumulator"))))
|
|
|
|
(test "Accumulate a boolean"
|
|
|
|
"true"
|
|
|
|
(with-output-to-string
|
|
|
|
(lambda ()
|
|
|
|
((json-accumulator) #t))))
|
|
|
|
(test "Accumulate an array"
|
|
|
|
"[1, 2, 3, true, null, \"Test\"]"
|
|
|
|
(with-output-to-string
|
|
|
|
(lambda ()
|
|
|
|
((json-accumulator)
|
|
|
|
#(1 2 3 #t null "Test")))))
|
|
|
|
(test "Accumulate an alist"
|
|
|
|
"{\"a\": 1, \"b\": 2}"
|
|
|
|
(with-output-to-string
|
|
|
|
(lambda ()
|
|
|
|
((json-accumulator)
|
|
|
|
'((a . 1) (b . 2)))))))
|
2022-02-28 13:48:23 +00:00
|
|
|
|
2024-09-13 21:59:25 +00:00
|
|
|
(test-exit)
|