(ns snapkitty.lisp.test.emojiscript-tests "EmojiScript compiler + executor tests" (:require [cljs.test :refer [deftest is testing]] [snapkitty.lisp.emojiscript :as emoji])) ;; ============================================================================ ;; Compilation Tests ;; ============================================================================ (deftest test-compile-simple-arithmetic "Compile: đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸" (let [source "đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (= 4 (:instructions-count result))) (is (contains? #{:Push :Add :Ret} (map :op (:bytecode result)))))) (deftest test-compile-cap-gate "Compile: đŸ”ĸ3 đŸ”ĸ5 🔑 â†Šī¸ (capability check)" (let [source "đŸ”ĸ3 đŸ”ĸ5 🔑 â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (some #(= :CapGate (:op %)) (:bytecode result))))) (deftest test-compile-memory-ops "Compile: đŸ”ĸ64 đŸ”ĸ9 đŸ—ī¸ đŸ”ĸ0 📤 â†Šī¸ (alloc + load)" (let [source "đŸ”ĸ64 đŸ”ĸ9 đŸ—ī¸ đŸ”ĸ0 📤 â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (some #(= :Alloc (:op %)) (:bytecode result))) (is (some #(= :Load (:op %)) (:bytecode result))))) (deftest test-compile-jump "Compile: đŸ”ĸ10 âžĄī¸ (unconditional jump)" (let [source "đŸ”ĸ10 âžĄī¸ â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (some #(= :Jump (:op %)) (:bytecode result))))) (deftest test-compile-conditional-jump "Compile: đŸ”ĸ1 ❓ (conditional jump)" (let [source "đŸ”ĸ1 ❓ â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (some #(= :JumpIf (:op %)) (:bytecode result))))) (deftest test-compile-bitwise-ops "Compile: đŸ”ĸ7 đŸ”ĸ3 🤝 â†Šī¸ (bitwise AND)" (let [source "đŸ”ĸ7 đŸ”ĸ3 🤝 â†Šī¸" result (emoji/compile-emojiscript source)] (is (= true (:valid? result))) (is (some #(= :And (:op %)) (:bytecode result))))) (deftest test-compile-rejects-empty "Reject empty program" (is (thrown-with-msg? js/Error #"Empty program" (emoji/compile-emojiscript "")))) (deftest test-compile-rejects-whitespace-only "Reject whitespace-only program" (is (thrown-with-msg? js/Error #"Empty program" (emoji/compile-emojiscript " \n\t ")))) (deftest test-compile-rejects-unknown-emoji "Reject unknown emoji" (is (thrown-with-msg? js/Error #"Unknown emoji" (emoji/compile-emojiscript "đŸĨˇ")))) ;; ============================================================================ ;; Execution Tests ;; ============================================================================ (deftest test-execute-simple-addition "Execute: đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸ = 42" (let [source "đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= true (:halted? result))) (is (= 42 (:result result))) (is (= [42] (:stack result))))) (deftest test-execute-subtraction "Execute: đŸ”ĸ100 đŸ”ĸ40 ➖ â†Šī¸ = 60" (let [source "đŸ”ĸ100 đŸ”ĸ40 ➖ â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 60 (:result result))))) (deftest test-execute-multiplication "Execute: đŸ”ĸ6 đŸ”ĸ7 âœ–ī¸ â†Šī¸ = 42" (let [source "đŸ”ĸ6 đŸ”ĸ7 âœ–ī¸ â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 42 (:result result))))) (deftest test-execute-division "Execute: đŸ”ĸ84 đŸ”ĸ2 ➗ â†Šī¸ = 42" (let [source "đŸ”ĸ84 đŸ”ĸ2 ➗ â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 42 (:result result))))) (deftest test-execute-bitwise-and "Execute: đŸ”ĸ15 đŸ”ĸ7 🤝 â†Šī¸ = 7 (bitwise AND)" (let [source "đŸ”ĸ15 đŸ”ĸ7 🤝 â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 7 (:result result))))) (deftest test-execute-bitwise-or "Execute: đŸ”ĸ12 đŸ”ĸ5 👐 â†Šī¸ = 13 (bitwise OR)" (let [source "đŸ”ĸ12 đŸ”ĸ5 👐 â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 13 (:result result))))) (deftest test-execute-bitwise-xor "Execute: đŸ”ĸ12 đŸ”ĸ5 🌀 â†Šī¸ = 9 (bitwise XOR)" (let [source "đŸ”ĸ12 đŸ”ĸ5 🌀 â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (= 9 (:result result))))) (deftest test-execute-division-by-zero "Reject division by zero" (let [source "đŸ”ĸ10 đŸ”ĸ0 ➗ â†Šī¸" compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled))] (is (contains? result :error)) (is (clojure.string/includes? (:error result) "Division by zero")))) (deftest test-execute-max-steps "Enforce step limit (prevent infinite loops)" (let [source "đŸ”ĸ0 âžĄī¸" ; unconditional jump to 0 = infinite loop compiled (emoji/compile-emojiscript source) result (emoji/execute-emojiscript (:bytecode compiled) :max-steps 100)] (is (= 100 (:steps result))) (is (= false (:halted? result))))) ;; ============================================================================ ;; Integration Tests (MCP tools) ;; ============================================================================ ;; ============================================================================ ;; Semantic Passes (Phase 2) ;; ============================================================================ (deftest test-semantic-pass-stream "🌊 Stream — telemetry-bus integration" (let [compiled (emoji/compile-emojiscript "đŸ”ĸ42 🌊 â†Šī¸") result (emoji/execute-emojiscript (:bytecode compiled))] (is (:halted? result)) (is (= 42 (:result result))) (is (some #(= (:type %) :telemetry) (:events result))) (is (>= (count (filter #(= (:event %) :stream-push) (:events result))) 1)))) (deftest test-semantic-pass-policy-check "🧠 PolicyCheck — policy-immune routing" (let [compiled (emoji/compile-emojiscript "đŸ”ĸ100 🧠 â†Šī¸") result (emoji/execute-emojiscript (:bytecode compiled))] (is (:halted? result)) (is (= 100 (:result result))) (is (some #(= (:type %) :policy-route) (:events result))))) (deftest test-semantic-pass-seal "🔒 Seal — Bifrost WORM signing" (let [compiled (emoji/compile-emojiscript "đŸ”ĸ777 🔒 â†Šī¸") result (emoji/execute-emojiscript (:bytecode compiled) :worm-ledger {}) seal-event (first (filter #(= (:type %) :bifrost-seal) (:events result)))] (is (:halted? result)) (is (= 777 (:result result))) (is seal-event) (is (= 777 (:value seal-event))))) (deftest test-semantic-pass-readonly "🔓 ReadOnly — capability downgrade" (let [compiled (emoji/compile-emojiscript "đŸ”ĸ255 🔓 â†Šī¸") result (emoji/execute-emojiscript (:bytecode compiled))] (is (:halted? result)) (is (< (:result result) 255)) (is (some #(= (:type %) :capability-downgrade) (:events result))))) (deftest test-mcp-compile-tool "MCP compile_emojiscript tool" (let [source "đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸"] ; Would call: (tools/handle-compile-emojiscript {:source source}) ; For now, just verify compile works (is (truthy? (emoji/compile-emojiscript source))))) (deftest test-mcp-execute-tool "MCP execute_emojiscript tool" (let [source "đŸ”ĸ40 đŸ”ĸ2 ➕ â†Šī¸" compiled (emoji/compile-emojiscript source)] ; Would call: (tools/handle-execute-emojiscript {:source source :max-steps 10000}) (is (= 42 (:result (emoji/execute-emojiscript (:bytecode compiled)))))))