(defsuite "closure-isolation" (deftest "basic factory: two closures are independent" (let ((mk (fn (x) (fn () x))) (a (mk 1)) (b (mk 2))) (assert-equal (a) 1) (assert-equal (b) 2))) (deftest "factory with multiple params" (let ((mk (fn (x y) (fn (s) (str x s y)))) (a (mk "A" "1")) (b (mk "B" "2")) (c (mk "C" "3"))) (assert-equal (a "-") "A-1") (assert-equal (b "-") "B-2") (assert-equal (c "-") "C-3"))) (deftest "earlier closure unaffected by later factory call" (let ((mk (fn (x y) (fn (s) (str x s y)))) (a (mk "A" "1"))) (let ((b (mk "B" "2")) (c (mk "C" "3"))) (assert-equal (a "x") "Ax1") (assert-equal (b "x") "Bx2") (assert-equal (c "x") "Cx3")))) (deftest "factory with nil branch (make-page-fn pattern)" (let ((mk (fn (default prefix suffix) (fn (slug) (if (nil? slug) default (str prefix slug suffix))))) (examples (mk "EX-DEFAULT" "EX-" "")) (sxtp (mk "SX-DEFAULT" "SX-" "-content"))) (assert-equal (examples nil) "EX-DEFAULT") (assert-equal (examples "counter") "EX-counter") (assert-equal (sxtp nil) "SX-DEFAULT") (assert-equal (sxtp "overview") "SX-overview-content") (assert-equal (examples nil) "EX-DEFAULT"))) (deftest "ten closures from same factory all independent" (let ((mk (fn (tag) (fn () tag))) (fns (map mk (list "a" "b" "c" "d" "e" "f" "g" "h" "i" "j")))) (assert-equal (map (fn (f) (f)) fns) (list "a" "b" "c" "d" "e" "f" "g" "h" "i" "j")))) (deftest "nested factory: inner closures independent" (let ((outer (fn (x) (fn (y) (fn () (str x y)))))) (let ((a (outer "A")) (b (outer "B"))) (let ((a1 (a "1")) (a2 (a "2")) (b1 (b "1"))) (assert-equal (a1) "A1") (assert-equal (a2) "A2") (assert-equal (b1) "B1") (assert-equal (a1) "A1"))))) (deftest "closure captures survive across define" (do (define _ci-mk (fn (x y) (fn (s) (str x s y)))) (define _ci-f1 (_ci-mk "A" "1")) (define _ci-f2 (_ci-mk "B" "2")) (define _ci-f3 (_ci-mk "C" "3")) (assert-equal (_ci-f1 "-") "A-1") (assert-equal (_ci-f2 "-") "B-2") (assert-equal (_ci-f3 "-") "C-3") (assert-equal (_ci-f1 "x") "Ax1"))))