Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 49s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
140 lines
4.9 KiB
Plaintext
140 lines
4.9 KiB
Plaintext
;; String / Char tests — Phase 7 items 1-4.
|
|
;;
|
|
;; Covers:
|
|
;; hk-str? / hk-str-head / hk-str-tail / hk-str-null? (runtime helpers)
|
|
;; chr / ord / toUpper / toLower (builtins in eval)
|
|
;; cons-pattern on strings via match.sx (":"-intercept)
|
|
;; empty-list pattern on strings via match.sx ("[]"-intercept)
|
|
|
|
;; ── hk-str? predicate ────────────────────────────────────────────────────
|
|
(hk-test "hk-str? native string" (hk-str? "hello") true)
|
|
|
|
(hk-test "hk-str? empty string" (hk-str? "") true)
|
|
|
|
(hk-test "hk-str? view dict" (hk-str? {:hk-off 1 :hk-str "hi"}) true)
|
|
|
|
(hk-test "hk-str? rejects number" (hk-str? 42) false)
|
|
|
|
;; ── hk-str-null? predicate ───────────────────────────────────────────────
|
|
(hk-test "hk-str-null? empty string" (hk-str-null? "") true)
|
|
|
|
(hk-test "hk-str-null? non-empty" (hk-str-null? "a") false)
|
|
|
|
(hk-test "hk-str-null? exhausted view" (hk-str-null? {:hk-off 2 :hk-str "hi"}) true)
|
|
|
|
(hk-test "hk-str-null? live view" (hk-str-null? {:hk-off 1 :hk-str "hi"}) false)
|
|
|
|
;; ── hk-str-head ──────────────────────────────────────────────────────────
|
|
(hk-test "hk-str-head native string" (hk-str-head "hello") 104)
|
|
|
|
(hk-test "hk-str-head view at offset" (hk-str-head {:hk-off 1 :hk-str "hello"}) 101)
|
|
|
|
;; ── hk-str-tail ──────────────────────────────────────────────────────────
|
|
(hk-test "hk-str-tail of single char is nil" (hk-str-tail "h") (list "[]"))
|
|
|
|
(hk-test
|
|
"hk-str-tail of two-char string is live view"
|
|
(hk-str-null? (hk-str-tail "hi"))
|
|
false)
|
|
|
|
(hk-test
|
|
"hk-str-tail head of tail of hi is i"
|
|
(hk-str-head (hk-str-tail "hi"))
|
|
105)
|
|
|
|
;; ── chr / ord ────────────────────────────────────────────────────────────
|
|
(hk-test "chr 65 = A" (hk-eval-expr-source "chr 65") "A")
|
|
|
|
(hk-test "chr 104 = h" (hk-eval-expr-source "chr 104") "h")
|
|
|
|
(hk-test "ord char literal 'A' = 65" (hk-eval-expr-source "ord 'A'") 65)
|
|
|
|
(hk-test "ord char literal 'a' = 97" (hk-eval-expr-source "ord 'a'") 97)
|
|
|
|
(hk-test
|
|
"ord of head string = char code"
|
|
(hk-eval-expr-source "ord (head \"hello\")")
|
|
104)
|
|
|
|
;; ── toUpper / toLower ────────────────────────────────────────────────────
|
|
(hk-test "toUpper 97 = 65 (a->A)" (hk-eval-expr-source "toUpper 97") 65)
|
|
|
|
(hk-test
|
|
"toUpper 65 = 65 (already upper)"
|
|
(hk-eval-expr-source "toUpper 65")
|
|
65)
|
|
|
|
(hk-test
|
|
"toUpper 48 = 48 (digit unchanged)"
|
|
(hk-eval-expr-source "toUpper 48")
|
|
48)
|
|
|
|
(hk-test "toLower 65 = 97 (A->a)" (hk-eval-expr-source "toLower 65") 97)
|
|
|
|
(hk-test
|
|
"toLower 97 = 97 (already lower)"
|
|
(hk-eval-expr-source "toLower 97")
|
|
97)
|
|
|
|
(hk-test
|
|
"toLower 48 = 48 (digit unchanged)"
|
|
(hk-eval-expr-source "toLower 48")
|
|
48)
|
|
|
|
;; ── Pattern matching on strings ──────────────────────────────────────────
|
|
(hk-test
|
|
"cons pattern: head of hello = 104"
|
|
(hk-eval-expr-source "case \"hello\" of { (x:_) -> x }")
|
|
104)
|
|
|
|
(hk-test
|
|
"cons pattern: tail is traversable"
|
|
(hk-eval-expr-source "case \"hi\" of { (_:xs) -> case xs of { (y:_) -> y } }")
|
|
105)
|
|
|
|
(hk-test
|
|
"empty list pattern matches empty string"
|
|
(hk-eval-expr-source "case \"\" of { [] -> True; _ -> False }")
|
|
(list "True"))
|
|
|
|
(hk-test
|
|
"empty list pattern fails on non-empty"
|
|
(hk-eval-expr-source "case \"a\" of { [] -> True; _ -> False }")
|
|
(list "False"))
|
|
|
|
(hk-test
|
|
"cons pattern fails on empty string"
|
|
(hk-eval-expr-source "case \"\" of { (_:_) -> True; _ -> False }")
|
|
(list "False"))
|
|
|
|
;; ── Haskell programs using string traversal ──────────────────────────────
|
|
(hk-test
|
|
"null prelude on empty string"
|
|
(hk-eval-expr-source "null \"\"")
|
|
(list "True"))
|
|
|
|
(hk-test
|
|
"null prelude on non-empty string"
|
|
(hk-eval-expr-source "null \"abc\"")
|
|
(list "False"))
|
|
|
|
(hk-test
|
|
"length of string via cons recursion"
|
|
(hk-eval-expr-source "let { f [] = 0; f (_:xs) = 1 + f xs } in f \"hello\"")
|
|
5)
|
|
|
|
(hk-test
|
|
"map ord over string gives char codes"
|
|
(hk-deep-force (hk-eval-expr-source "map ord \"abc\""))
|
|
(list ":" 97 (list ":" 98 (list ":" 99 (list "[]")))))
|
|
|
|
(hk-test
|
|
"map toUpper over char codes then chr"
|
|
(hk-eval-expr-source "chr (toUpper (ord (head \"abc\")))")
|
|
"A")
|
|
|
|
(hk-test
|
|
"head then ord using prelude head"
|
|
(hk-eval-expr-source "ord (head \"hello\")")
|
|
104)
|