;; Tests for character type (Phase 13)
;; Uses (make-char n) and (char-code "x") instead of #\x literals
;; (char literal parser syntax tested via sx-parse call)

(deftest
  "make-char produces a char"
  (assert= true (char? (make-char 97))))

(deftest "char? false for string" (assert= false (char? "a")))

(deftest "char? false for number" (assert= false (char? 65)))

(deftest "char? false for nil" (assert= false (char? nil)))

(deftest
  "char->integer extracts codepoint"
  (assert= 97 (char->integer (make-char 97))))

(deftest
  "integer->char alias for make-char"
  (assert= 65 (char->integer (integer->char 65))))

(deftest
  "char->integer round-trip"
  (assert= 122 (char->integer (make-char 122))))

(deftest
  "char=? equal"
  (assert= true (char=? (make-char 97) (make-char 97))))

(deftest
  "char=? unequal"
  (assert= false (char=? (make-char 97) (make-char 98))))

(deftest
  "char<? ordering"
  (assert= true (char<? (make-char 97) (make-char 98))))

(deftest
  "char>? ordering"
  (assert= true (char>? (make-char 98) (make-char 97))))

(deftest
  "char<=? equal"
  (assert= true (char<=? (make-char 65) (make-char 65))))

(deftest
  "char>=? greater"
  (assert= true (char>=? (make-char 90) (make-char 65))))

(deftest
  "char-ci=? ignores case (a vs A)"
  (assert= true (char-ci=? (make-char 97) (make-char 65))))

(deftest
  "char-ci<? a < b case-insensitive"
  (assert= true (char-ci<? (make-char 97) (make-char 98))))

(deftest
  "char-ci>? b > a case-insensitive"
  (assert= true (char-ci>? (make-char 66) (make-char 65))))

(deftest
  "char-alphabetic? true for a"
  (assert= true (char-alphabetic? (make-char 97))))

(deftest
  "char-alphabetic? true for Z"
  (assert= true (char-alphabetic? (make-char 90))))

(deftest
  "char-alphabetic? false for digit"
  (assert= false (char-alphabetic? (make-char 48))))

(deftest
  "char-numeric? true for 0"
  (assert= true (char-numeric? (make-char 48))))

(deftest
  "char-numeric? true for 9"
  (assert= true (char-numeric? (make-char 57))))

(deftest
  "char-numeric? false for letter"
  (assert= false (char-numeric? (make-char 65))))

(deftest
  "char-whitespace? true for space"
  (assert= true (char-whitespace? (make-char 32))))

(deftest
  "char-whitespace? true for newline"
  (assert= true (char-whitespace? (make-char 10))))

(deftest
  "char-whitespace? false for letter"
  (assert= false (char-whitespace? (make-char 65))))

(deftest
  "char-upper-case? true for A"
  (assert= true (char-upper-case? (make-char 65))))

(deftest
  "char-upper-case? false for a"
  (assert= false (char-upper-case? (make-char 97))))

(deftest
  "char-lower-case? true for a"
  (assert= true (char-lower-case? (make-char 97))))

(deftest
  "char-lower-case? false for A"
  (assert= false (char-lower-case? (make-char 65))))

(deftest
  "char-upcase converts a to A"
  (assert= 65 (char->integer (char-upcase (make-char 97)))))

(deftest
  "char-downcase converts A to a"
  (assert=
    97
    (char->integer (char-downcase (make-char 65)))))

(deftest
  "char-upcase idempotent on uppercase"
  (assert= 65 (char->integer (char-upcase (make-char 65)))))

(deftest
  "string->list returns list of chars"
  (assert= 3 (len (string->list "abc"))))

(deftest
  "string->list element 0 is char"
  (assert= true (char? (get (string->list "abc") 0))))

(deftest
  "string->list codepoints correct"
  (assert= 97 (char->integer (get (string->list "abc") 0))))

(deftest
  "list->string from chars produces string"
  (assert=
    "abc"
    (list->string
      (list
        (make-char 97)
        (make-char 98)
        (make-char 99)))))

(deftest
  "string->list list->string round-trip"
  (let ((s "hello")) (assert= s (list->string (string->list s)))))

(deftest
  "char literal parsed via sx-parse"
  (let
    ((ast (sx-parse "#\\a")))
    (assert= true (char? (get ast 0)))))

(deftest
  "char literal codepoint via sx-parse"
  (let
    ((ast (sx-parse "#\\a")))
    (assert= 97 (char->integer (get ast 0)))))

(deftest
  "named char space via sx-parse"
  (let
    ((ast (sx-parse "#\\space")))
    (assert= 32 (char->integer (get ast 0)))))

(deftest
  "named char newline via sx-parse"
  (let
    ((ast (sx-parse "#\\newline")))
    (assert= 10 (char->integer (get ast 0)))))

(deftest
  "char-ci<=? equal case-insensitive"
  (assert= true (char-ci<=? (make-char 65) (make-char 97))))

(deftest
  "char-ci>=? equal case-insensitive"
  (assert= true (char-ci>=? (make-char 97) (make-char 65))))
