code wiki / _hdl_build / nx_ui_exec_gate.nx
nx_ui_exec_gate.nx source
↩ module page · 66 lines · 5378 B
1// nx_ui_exec_gate.nx -- EXECUTION verification (task #35, operator 2026-07-04: "the Nishi team should SEE
2// everything ... i shouldnt have to find bugs"). The static eyes prove a button is WIRED; this proves a
3// button WORKS: the sovereign JS engine now models DOM events (addEventListener + element.click()), so a
4// gate can WIRE a handler, FIRE it like a user tap, and assert the DOM actually CHANGED. This is the rung
5// that turns "wired" into "works" -- the difference that let the dead-buttons bug ship past serving+static
6// checks. Drives js_render_page (parse -> tree -> run scripts -> serialize) on the engine's real path.
7// NEG-CONTROLS prove the mutation is CAUSED by the fired click, not spurious. 0=GREEN / 1=RED.
8import "nx_syscalls.nx"
9import "nx_js_eval.nx"
10
11func r_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
12func r_pn(v: i64) -> i64 {
13 var m: i64 = v; if m < 0 { r_p("-\x00" as *u8); m = 0 - m }
14 let t: *u8 = sys_mmap(24); var k: i64 = 0
15 if m == 0 { t[0] = 48 as u8; k = 1 } else { while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } }
16 let o: *u8 = sys_mmap(24); var j: i64 = 0; while j < k { o[j] = t[k - 1 - j]; j = j + 1 }
17 sys_write(1, o, k); return 0 }
18func r_clen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
19func r_contains(buf: *u8, blen: i64, needle: *u8) -> i64 {
20 let nl: i64 = r_clen(needle); if nl == 0 { return 1 }
21 var i: i64 = 0
22 while (i + nl) <= blen { var j: i64 = 0; var ok: i64 = 1; while j < nl { if (buf[i + j] & 0xff) != (needle[j] & 0xff) { ok = 0; j = nl } else { j = j + 1 } } if ok == 1 { return 1 } i = i + 1 }
23 return 0 }
24func chk(cond: i64, name: *u8, pp: *i64, tp: *i64) -> i64 {
25 tp[0] = tp[0] + 1; r_p(name)
26 if cond == 1 { pp[0] = pp[0] + 1; r_p(" ok\n\x00" as *u8) } else { r_p(" FAIL\n\x00" as *u8) }
27 return 0 }
28
29func main() -> i64 {
30 r_p("=== nx_ui_exec_gate: EXECUTION verify -- wire a handler, FIRE it, assert the DOM changed ===\n\x00" as *u8)
31 let pp: *i64 = sys_mmap(8) as *i64; pp[0] = 0
32 let tp: *i64 = sys_mmap(8) as *i64; tp[0] = 0
33 let out: *u8 = sys_mmap(131072)
34
35 // R1: wire a click handler that mutates the DOM, then FIRE the click -> the mutation must render.
36 // This is the whole point: a click actually runs the handler and changes the page.
37 let p1: *u8 = "<html><body><button id=\"b\">off</button><script>var b=document.getElementById('b');b.addEventListener('click',function(e){document.getElementById('b').textContent='CLICKED';});b.click();</script></body></html>\x00" as *u8
38 let n1: i64 = js_render_page(p1, r_clen(p1), out, 131072)
39 // check the ELEMENT text form >CLICKED< -- the script's literal 'CLICKED' (in the serialized <script>)
40 // has no surrounding angle brackets, so this matches ONLY the mutated button, not the source text.
41 chk(r_contains(out, n1, ">CLICKED<\x00" as *u8), "R1 click FIRES handler -> DOM mutates\x00" as *u8, pp, tp)
42 chk(r_contains(out, n1, ">off<\x00" as *u8) == 0, "R1b old text replaced by the handler\x00" as *u8, pp, tp)
43
44 // R2 (NEG): wire the SAME handler but DO NOT click -> the mutation must NOT happen. Proves the change
45 // is caused by the FIRED event, not by wiring/parsing. (A checker that passed here = blind.)
46 let p2: *u8 = "<html><body><button id=\"b\">off</button><script>var b=document.getElementById('b');b.addEventListener('click',function(e){document.getElementById('b').textContent='CLICKED';});</script></body></html>\x00" as *u8
47 let n2: i64 = js_render_page(p2, r_clen(p2), out, 131072)
48 chk(r_contains(out, n2, ">CLICKED<\x00" as *u8) == 0, "R2 NEG: no click -> no mutation (teeth)\x00" as *u8, pp, tp)
49 chk(r_contains(out, n2, ">off<\x00" as *u8), "R2b NEG: button keeps original text\x00" as *u8, pp, tp)
50
51 // R3 (NEG): click an element with NO listener -> no crash, no mutation.
52 let p3: *u8 = "<html><body><button id=\"b\">off</button><script>document.getElementById('b').click();document.getElementById('b').textContent='ok';</script></body></html>\x00" as *u8
53 let n3: i64 = js_render_page(p3, r_clen(p3), out, 131072)
54 chk(r_contains(out, n3, ">ok<\x00" as *u8), "R3 NEG: click with no listener is a safe no-op\x00" as *u8, pp, tp)
55
56 // R4: TWO handlers on the same button both fire on one click (real dispatch, not first-only).
57 let p4: *u8 = "<html><body><button id=\"b\">x</button><span id=\"s\">x</span><script>var b=document.getElementById('b');b.addEventListener('click',function(e){document.getElementById('b').textContent='AA';});b.addEventListener('click',function(e){document.getElementById('s').textContent='BB';});b.click();</script></body></html>\x00" as *u8
58 let n4: i64 = js_render_page(p4, r_clen(p4), out, 131072)
59 chk(r_contains(out, n4, ">AA<\x00" as *u8), "R4 first listener fired\x00" as *u8, pp, tp)
60 chk(r_contains(out, n4, ">BB<\x00" as *u8), "R4b second listener fired (both, in order)\x00" as *u8, pp, tp)
61
62 r_p(" SCORE: \x00" as *u8); r_pn(pp[0]); r_p("/\x00" as *u8); r_pn(tp[0]); r_p("\n\x00" as *u8)
63 if pp[0] == tp[0] { r_p("UI-EXEC-GATE verdict=GREEN -- the engine EXECUTES clicks: wired handlers fire + mutate the DOM\n\x00" as *u8); return 0 }
64 r_p("UI-EXEC-GATE verdict=RED -- event execution broken\n\x00" as *u8)
65 return 1
66}