;; ========================================================================== ;; test-regexp.sx — Tests for regexp primitives ;; ========================================================================== ;; -------------------------------------------------------------------------- ;; make-regexp / regexp? ;; -------------------------------------------------------------------------- (defsuite "regexp:create" (deftest "make-regexp returns regexp" (assert (regexp? (make-regexp "abc")))) (deftest "make-regexp with flags" (assert (regexp? (make-regexp "[a-z]+" "i")))) (deftest "regexp? true for regexp" (assert (regexp? (make-regexp "x")))) (deftest "regexp? false for string" (assert (not (regexp? "abc")))) (deftest "regexp? false for nil" (assert (not (regexp? nil)))) (deftest "regexp-source" (assert= (regexp-source (make-regexp "hello")) "hello")) (deftest "regexp-flags" (assert= (regexp-flags (make-regexp "x" "im")) "im")) (deftest "regexp-flags empty string" (assert= (regexp-flags (make-regexp "x")) ""))) ;; -------------------------------------------------------------------------- ;; regexp-match — basic ;; -------------------------------------------------------------------------- (defsuite "regexp:match" (deftest "match returns dict" (let ((m (regexp-match (make-regexp "hel+o") "hello world"))) (assert (dict? m)))) (deftest "match :match key" (let ((m (regexp-match (make-regexp "hel+o") "say hello"))) (assert= (get m "match") "hello"))) (deftest "match :start key" (let ((m (regexp-match (make-regexp "lo") "hello"))) (assert= (get m "start") 3))) (deftest "match :end key" (let ((m (regexp-match (make-regexp "lo") "hello"))) (assert= (get m "end") 5))) (deftest "no match returns nil" (assert-nil (regexp-match (make-regexp "xyz") "hello"))) (deftest "match at start" (let ((m (regexp-match (make-regexp "^hel") "hello"))) (assert= (get m "start") 0))) (deftest "match digit pattern" (let ((m (regexp-match (make-regexp "[0-9]+") "abc 123 def"))) (assert= (get m "match") "123")))) ;; -------------------------------------------------------------------------- ;; regexp-match — groups ;; -------------------------------------------------------------------------- (defsuite "regexp:groups" (deftest "no capture groups → empty list" (let ((m (regexp-match (make-regexp "hello") "hello world"))) (assert= (length (get m "groups")) 0))) (deftest "one capture group" (let ((m (regexp-match (make-regexp "([0-9]+)") "price: 42"))) (assert= (first (get m "groups")) "42"))) (deftest "two capture groups" (let ((m (regexp-match (make-regexp "([a-z]+)=([0-9]+)") "x=10"))) (let ((gs (get m "groups"))) (assert (and (= (first gs) "x") (= (first (rest gs)) "10"))))))) ;; -------------------------------------------------------------------------- ;; regexp-match-all ;; -------------------------------------------------------------------------- (defsuite "regexp:match-all" (deftest "match-all returns list" (let ((ms (regexp-match-all (make-regexp "[0-9]+") "1 and 2 and 3"))) (assert (list? ms)))) (deftest "match-all count" (assert= (length (regexp-match-all (make-regexp "[0-9]+") "1 and 2 and 3")) 3)) (deftest "match-all first match" (let ((ms (regexp-match-all (make-regexp "[0-9]+") "10 20 30"))) (assert= (get (first ms) "match") "10"))) (deftest "match-all empty when no match" (assert= (length (regexp-match-all (make-regexp "xyz") "hello")) 0))) ;; -------------------------------------------------------------------------- ;; regexp-replace / regexp-replace-all ;; -------------------------------------------------------------------------- (defsuite "regexp:replace" (deftest "replace first match" (assert= (regexp-replace (make-regexp "o+") "foobar boo" "0") "f0bar boo")) (deftest "replace no match returns original" (assert= (regexp-replace (make-regexp "xyz") "hello" "X") "hello")) (deftest "replace-all all matches" (assert= (regexp-replace-all (make-regexp "o") "foo boo" "0") "f00 b00")) (deftest "replace with $& (whole match)" (assert= (regexp-replace (make-regexp "[0-9]+") "price 42" "[$&]") "price [42]")) (deftest "replace-all removes digits" (assert= (regexp-replace-all (make-regexp "[0-9]") "a1b2c3" "") "abc"))) ;; -------------------------------------------------------------------------- ;; regexp-split ;; -------------------------------------------------------------------------- (defsuite "regexp:split" (deftest "split on whitespace" (let ((parts (regexp-split (make-regexp " +") "hello world foo"))) (assert= (length parts) 3))) (deftest "split first part" (let ((parts (regexp-split (make-regexp ",") "a,b,c"))) (assert= (first parts) "a"))) (deftest "split last part" (let ((parts (regexp-split (make-regexp ",") "a,b,c"))) (assert= (first (rest (rest parts))) "c"))) (deftest "split no match → single element" (let ((parts (regexp-split (make-regexp ",") "hello"))) (assert= (length parts) 1)))) ;; -------------------------------------------------------------------------- ;; flags ;; -------------------------------------------------------------------------- (defsuite "regexp:flags" (deftest "case-insensitive flag" (let ((m (regexp-match (make-regexp "HELLO" "i") "hello world"))) (assert (not (nil? m))))) (deftest "case-sensitive without flag" (assert-nil (regexp-match (make-regexp "HELLO") "hello world"))) (deftest "multiline ^ matches line starts" (let ((ms (regexp-match-all (make-regexp "^[a-z]" "m") "a\nb\nc"))) (assert= (length ms) 3))))