Source

comparse / tests / run.scm

Full commit
(use comparse test lazy-seq)

(define-syntax test-parse
  (syntax-rules ()
    ((_ expect parser input)
     (test expect (parse parser input)))))

(define-syntax test-parse*
  (syntax-rules ()
    ((_ expect parser input)
     (test-parse expect (as-string parser) input))))

(test-group "tests one-or-more / zero-or-more"
  (test-parse* "ooooo" (one-or-more (is #\o)) "ooooom")
  (test-parse* #f (one-or-more (is #\o)) "m")
  (test-parse* "oo" (zero-or-more (is #\o)) "oommm")
  (test-parse* "" (zero-or-more (is #\o)) "m"))

(test-group "char-seq"
  (test-parse "" (char-seq "") "hey")
  (test-parse "hey" (char-seq "hey") "heyyy")
  (test-parse #f (char-seq "hey") "he"))

(test-group "followed-by"
  (let ((lol (preceded-by (followed-by item (is #\o) (is #\l)) item)))
    (test #\o (parse lol "lol"))
    (test #f  (parse lol "lxl"))))

(test-group "preceded-by"
  (test-parse 3 (preceded-by (is 1) (is 2) (is 3)) '(1 2 3)))

(test-group "sequence"
  (test-parse* "ab" (sequence (is #\a) (is #\b)) "abc")
  (test-parse* "ab" (sequence (list (is #\a) (is #\b))) "abc"))

(test-group "maybe"
  (let ((foo (preceded-by (maybe (is #\x)) (char-seq "foo"))))
    (test-parse* "foo" foo "foo")
    (test-parse* "foo" foo "xfoo")))

(test-group "repeated"
  (test-parse* "hohoho" (repeated (char-seq "ho")) "hohoho")
  (test-parse* "ho    ho ho "
               (repeated (sequence (char-seq "ho")
                                   (zero-or-more (is #\space)))
                         min: 2)
               "ho    ho ho rofl")
  (test-parse* "foo" (repeated item until: (is #\.)) "foo.")

  (let ((ok (repeated item min: 3 until: (is #\k))))
    (test-parse* "oko" ok "okok")
    (test-parse* #f ok "ooko"))

  (let ((ok (repeated item max: 2 until: (is #\k))))
    (test-parse* "oo" ok "ookay")
    (test-parse* #f ok "ooookay")))

(test-group "all-of"
  (test-parse #\b (all-of (none-of (is #\a)) (is #\b)) "b")
  (test-parse #f (all-of (none-of (is #\a)) (is #\b)) "a"))

(test-group "enclosed-by"
  (let ((parenthesized (enclosed-by (is #\() (is #\x) (is #\)))))
    (test-parse #\x parenthesized "(x)")
    (test-parse #f parenthesized "(x/")
    (test-parse #f parenthesized "()")))

(test-group "none-of"
  (let ((not-xy (preceded-by (none-of (is #\x) (is #\y)) item)))
    (test-parse #\a not-xy "a")
    (test-parse #f not-xy "x")
    (test-parse #f not-xy "y")))

(test-group "none-of*"
  (let ((not-xy (none-of* (is #\x) (is #\y) item)))
    (test-parse #\a not-xy "a")
    (test-parse #f not-xy "x")
    (test-parse #f not-xy "y")))

(test-group "misc"
  (test-parse* "aaba" (repeated (satisfies (char-set #\a #\b))) "aabac")
  (test-parse* "   " (repeated (is #\space) max: 3) "      ")
  (test-parse* "" (repeated (is #\f)) "x")
  (test-parse* #f (repeated (is #\a) min: 1) "b")
  (test-parse #\a (preceded-by (none-of (is #\b) (is #\c)) item) "a")
  (test-parse* "b52" (zero-or-more (any-of (satisfies char-set:digit) (is #\b))) "b52s")

  (test-parse #f (none-of (is #\b) (is #\a)) "a")

  (test-parse* "ab"
               (sequence* 
                   ((a (is #\a)) (b (is #\b)))
                 (result (list a b)))
               "abc"))

(test-group "quoted string"
  (define (quoted-string #!key
                         (delimiter (satisfies (char-set #\" #\')))
                         (escape (is #\\)))
    (let ((escaped-char (preceded-by escape item)))
      (sequence* ((_ (zero-or-more (satisfies char-set:whitespace)))
                  (actual-delimiter delimiter)
                  (chars (zero-or-more
                          (any-of escaped-char
                                  (preceded-by (none-of escape (is actual-delimiter))
                                               item))))
                  (_ (is actual-delimiter)))
        (result (list->string chars)))))

  (test-assert (not (parse (quoted-string) "this ain't a string")))
  (test "nice" (parse (quoted-string) "\"nice\""))


  (receive (result rest) (parse (quoted-string) "\"string 1\" 'string 2'  some trailing ")
    (test "string 1" result)
    (receive (result rest) (parse (quoted-string) rest)
      (test "string 2" result)
      (receive (result rest) (parse (quoted-string) rest)
        (test-assert (not result))
        (test "  some trailing " (list->string (lazy-seq->list rest))))))

  (define singly-quoted-bang-string (quoted-string delimiter: (is #\') escape: (is #\!)))
  (test "this 'is' a string" (parse singly-quoted-bang-string "'this !'is!' a string'"))
  (test "ok\\" (parse singly-quoted-bang-string "'ok\\'"))
  (test-assert (not (parse singly-quoted-bang-string "\"check\""))))

(test-exit)