(define _mock-form (dict)) (define _mock-args (dict)) (define _mock-state (dict)) (define _mock-body "") (define _mock-content-type "") (define _mock-headers (dict)) (define _mock-now "12:00:00") (define reset-mocks! (fn () (do (set! _mock-form (dict)) (set! _mock-args (dict)) (set! _mock-state (dict)) (set! _mock-body "") (set! _mock-content-type "") (set! _mock-headers (dict))))) (define helper (fn (name a1 a2) (cond (= name "request-form") (let ((key (or a1 "")) (default (if (nil? a2) "" a2))) (let ((val (get _mock-form key))) (if (nil? val) default val))) (= name "request-arg") (let ((key (or a1 "")) (default a2)) (let ((val (get _mock-args key))) (if (nil? val) default val))) (= name "state-get") (let ((key (or a1 "")) (default a2)) (let ((val (get _mock-state key))) (if (nil? val) default val))) (= name "state-set!") (do (set! _mock-state (assoc _mock-state a1 a2)) nil) (= name "now") _mock-now (= name "component-source") (str "(defcomp " a1 " () (div))") (= name "request-json") _mock-body (= name "request-content-type") _mock-content-type (= name "request-form-list") (or (get _mock-form a1) (list)) (= name "request-args-all") _mock-args (= name "request-headers-all") _mock-headers (= name "request-form-all") _mock-form (= name "request-header") (or (get _mock-headers a1) a2) (= name "request-file-name") (or (get _mock-form a1) "") (= name "into") (let ((coll (if (nil? a2) a1 a2))) (if (dict? coll) (map (fn (key) (list key (get coll key))) (keys coll)) (if (nil? coll) (list) coll))) :else nil))) (define sleep (fn (ms) nil)) (define set-response-status (fn (code) nil)) (define json-encode (fn (val) (inspect val))) (define run-handler (fn (hdef) (let ((result (aser (get hdef "body") (get hdef "closure")))) (if (sx-expr? result) (sx-expr-source result) (if (string? result) result (str result)))))) (defsuite "swap:click-to-load" (deftest "innerHTML replaces target content" (reset-mocks!) (let ((page "(div :id \"click-result\" (p \"Click the button\"))") (response (run-handler handler:ex-click))) (let ((result (sx-swap page "innerHTML" "click-result" response))) (do (assert-true (contains? result "~examples/click-result")) (assert-true (contains? result "12:00:00")) (assert-false (contains? result "Click the button"))))))) (defsuite "swap:form-submission" (deftest "innerHTML replaces with greeting" (reset-mocks!) (set! _mock-form {:name "Alice"}) (let ((page "(div :id \"form-result\" (p \"Submit the form\"))") (response (run-handler handler:ex-form))) (let ((result (sx-swap page "innerHTML" "form-result" response))) (do (assert-true (contains? result "Alice")) (assert-false (contains? result "Submit the form"))))))) (defsuite "swap:polling" (deftest "innerHTML shows counter after increment" (reset-mocks!) (let ((page "(div :id \"poll-result\" (p \"Waiting...\"))") (response (run-handler handler:ex-poll))) (let ((result (sx-swap page "innerHTML" "poll-result" response))) (do (assert-true (contains? result "1")) (assert-false (contains? result "Waiting"))))))) (defsuite "swap:oob-updates" (deftest "primary + OOB both update" (reset-mocks!) (let ((page "(div (div :id \"oob-box-a\" (p \"A old\")) (div :id \"oob-box-b\" (p \"B old\")))") (response (run-handler handler:ex-oob))) (let ((result (apply-response page response "innerHTML" "oob-box-a"))) (do (assert-true (contains? result "Box A updated!")) (assert-true (contains? result "Box B updated!")) (assert-false (contains? result "A old")) (assert-false (contains? result "B old"))))))) (defsuite "swap:search" (deftest "innerHTML replaces search results" (reset-mocks!) (set! _mock-args {:q "Python"}) (let ((page "(div :id \"search-result\" (p \"Type to search\"))") (response (run-handler handler:ex-search))) (let ((result (sx-swap page "innerHTML" "search-result" response))) (do (assert-true (contains? result "Python")) (assert-false (contains? result "Type to search"))))))) (defsuite "swap:delete-row" (deftest "outerHTML removes element" (let ((page "(table (tr :id \"row-1\" (td \"Item 1\")) (tr :id \"row-2\" (td \"Item 2\")))") (response "")) (let ((result (sx-swap page "outerHTML" "row-1" response))) (do (assert-false (contains? result "Item 1")) (assert-true (contains? result "Item 2"))))))) (defsuite "swap:beforeend" (deftest "appends new item to list" (let ((page "(ul :id \"items\" (li \"first\"))") (response "(li \"second\")")) (let ((result (sx-swap page "beforeend" "items" response))) (do (assert-true (contains? result "first")) (assert-true (contains? result "second"))))))) (defsuite "swap:state-across-calls" (deftest "counter increments across handler calls" (reset-mocks!) (let ((r1 (run-handler handler:ex-poll))) (let ((r2 (run-handler handler:ex-poll))) (let ((page "(div :id \"counter\" (span \"0\"))") (result (sx-swap page "innerHTML" "counter" r2))) (assert-true (contains? result "2")))))))