edn / tests / read.scm

(use lazy-seq (prefix numbers numbers-))

(test-begin "reading")

(define-syntax test-read
  (syntax-rules ()
    ((_ in out rem)
     (receive (result remainder) (read-edn in)
       (test in result out)
       (parameterize ((current-test-comparator equal?))
         (test (string-append "remainder: " rem)
               (string->list rem)
               (lazy-seq->list remainder)))))
    ((_ in out)
     (test-read in out ""))))

(define-syntax test-read-fail
  (syntax-rules ()
    ((_ in)
     (test-read in #f in))))

(define-syntax test-read-error
  (syntax-rules ()
    ((_ in)
     (test-error in (read-edn in)))))

(test-group "booleans & nil"
  (test-read "true" #t)
  (test-read "false" #f))

(test-group "strings"
  (test-read "\"x\"" "x")
  (test-read "\"\nx\t\"" "\nx\t")
  (test-read-error "\"x"))

(test-group "chars"
  (test-read "\\x" #\x)
  (test-read "\\)" #\))
  (test-read "\\newline" #\newline)
  (test-read "\\\\" #\\)
  (test-read-error "\\)x"))

(test-group "symbols"
  (test-read "foo" 'foo)
  (test-read ".foo" '.foo)
  (test-read ".." '..)
  (test-read "foo#bar" 'foo#bar)
  (test-read "foo::bar" 'foo::bar)
  (test-read "foo/bar" 'foo/bar)
  (test-read "/" '/)
  (test-read-error "/foo")
  (test-read-error "foo/")
  (test-read-error "foo///bar")
  (test-read-error ".2oo"))

(test-group "keywords"
  (test-read ":fred" #:fred)
  (test-read ":my/fred" #:my/fred)
  (test-read-error ":123")
  (test-read-error ":"))

(test-group "integers"
  (test-read "123" 123)
  (test-read "999999999999999999999999999999999999" 1e+36)
  (test-read "999999999999999999999999999999999999N"
             999999999999999999999999999999999999)
  (test-read "-10" -10)
  (test-read-error "832134foo"))

(test-group "floats"
  (test-read "10.0" 10.0)
  (test-read "3.2e2" 320.0)
  (test-read "12.3M" (numbers-string->number "12.3"))
  (test-read "12.3e4M" (numbers-string->number "12.3e4"))
  (test-read "100M" (numbers-string->number "100.0"))
  (test-read-error "100.10xxx"))

(test-group "lists"
  (test-read "()" '(list))
  (test-read "(  x y z  )" '(list x y z))
  (test-read "(\\))" '(list #\)))
  (test-read "(:foo (:bar (:baz ())))" '(list foo: (list bar: (list baz: (list)))))
  (test-read-error "(x"))

(test-group "vectors"
  (test-read "[]" '(vector))
  (test-read "[1 [2] [3]]" '(vector 1 (vector 2) (vector 3))))

(test-group "maps"
  (test-read "{}" '(map))
  (test-read "{:foo \"bar\"}"
               '(map (#:foo . "bar")))
  (test-read "{:foo \"bar\" [99] {}}"
               '(map
                 (#:foo . "bar")
                 ((vector 99) . (map))))
  (test-read-error "{123}")
  (test-read-error "{:foo 123 :bar}")
  (test-read-error "{]"))

(define (set-equal? a b)
  (lset= (lambda (a b)
           (if (and (pair? a) (pair? b)
                    (eq? 'set (car a))
                    (eq? 'set (car b)))
               (set-equal? a b)
               (equal? a b)))
         a b))

(test-group "sets"
  (parameterize ((current-test-comparator set-equal?))
    (test-read "#{}" '(set))
    (test-read "#{1 2 3}" '(set 3 1 2))
    (test-read "#{#{1} #{2}}" '(set (set 1) (set 2)))))

(test-group "tags"
  (test-read "#inst \"1985-04-12T23:20:50.52Z\""
             '(tag (#f . inst) "1985-04-12T23:20:50.52Z"))
  (test-read "#uuid \"f81d4fae-7dec-11d0-a765-00a0c91e6bf6\""
             '(tag (#f . uuid) "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"))
  (test-read "#yak/sie masz" '(tag (yak . sie) masz))
  (parameterize ((handle-unknown-edn-tags? #f))
    (test-read-error "#yak/sie masz")))

(test-group "custom tags"
  (register-edn-tag!
   'nice 'string (lambda (x) (string-append x " is nice!")))
  (test-read "#nice/string \"edn\"" "edn is nice!"))

(test-end)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.