File size: 8,270 Bytes
119e586 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | (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)))))))
|