diff --git a/spec/tests/test-let-match.sx b/spec/tests/test-let-match.sx new file mode 100644 index 00000000..5919f80c --- /dev/null +++ b/spec/tests/test-let-match.sx @@ -0,0 +1,47 @@ +;; Tests for let-match — CEK special form and bytecode compiler desugaring +;; let-match destructures a dict: (let-match {:key var} expr body...) + +(deftest "let-match destructures dict" + (let-match {:name n :age a} (dict :name "alice" :age 30) + (assert= n "alice") + (assert= a 30))) + +(deftest "let-match inside let" + (let ((data (dict :status "ok" :value 42))) + (let-match {:status s :value v} data + (assert= s "ok") + (assert= v 42)))) + +(deftest "let-match missing key gives nil" + (let-match {:present p :missing m} (dict :present "yes") + (assert= p "yes") + (assert= m nil))) + +(deftest "let-match body evaluates all expressions" + (let ((result nil)) + (let-match {:a a} (dict :a 1) + (set! result a) + (assert= result 1)))) + +;; In function body — tests bytecode compiler desugaring path +(define lm-add (fn (d) (let-match {:x x :y y} d (+ x y)))) + +(deftest "let-match in compiled function" + (assert= (lm-add (dict :x 3 :y 7)) 10)) + +(define lm-format (fn (input) (let-match {:type t :value v} input (str t ":" v)))) + +(deftest "let-match variant 2 in compiled function" + (assert= (lm-format (dict :type "num" :value 5)) "num:5")) + +;; Nested let-match +(deftest "nested let-match" + (let-match {:outer o} (dict :outer (dict :inner 99)) + (let-match {:inner i} o + (assert= i 99)))) + +;; let-match with computed expression +(deftest "let-match with function call as expr" + (let-match {:a a :b b} (dict :a (+ 1 2) :b (* 3 4)) + (assert= a 3) + (assert= b 12)))