code wiki / (root) / nx_uxcx_grade_test.nx

nx_uxcx_grade_test.nx source

↩ module page · 70 lines · 4100 B

1// nx_uxcx_grade_test.nx -- sovereign gate for the UX/CX grader. 2// 3// Proves the byte-scan detectors catch the two operator-reported bug classes 4// (browser-only back nav; &amp; double-encoding) and pass clean input, and 5// that the combined permil moves. Same verdicts as the nishilib.uxcx Python 6// benchmark on the same fixtures. Exit code = failed assertion #; 0 = all pass. 7 8import "nx_syscalls.nx" 9import "nx_uxcx_grade.nx" 10 11func main() -> i64 { 12 // buggy JS: back button wired inline to history.back(), no fallback 13 let js_bug: *u8 = "$(\"back\").addEventListener(\"click\", () => history.back());" as *u8 14 // fixed JS: named goBack() with an in-app fallback 15 let js_fix: *u8 = "function goBack(){ if (userNavigated) history.back(); else location.hash=lastListHash; }" as *u8 16 // double-encoded title (the &amp; bug as the reader sees it) 17 let html_bad: *u8 = "<div class=\"title\">Cats &amp;amp; Dogs &amp;lt;i&amp;gt;</div>" as *u8 18 // correctly single-encoded title 19 let html_ok: *u8 = "<div class=\"title\">Cats &amp; Dogs</div>" as *u8 20 // a page with viewport + skip-link 21 let page_ok: *u8 = "<meta name=\"viewport\" content=\"width=device-width\"><a class=\"skip-link\" href=\"#m\">skip</a>" as *u8 22 // a page missing both 23 let page_bad: *u8 = "<head><title>x</title></head>" as *u8 24 25 // back-nav (operator bug #1) 26 if uxg_back_ok(js_bug, uxg_len(js_bug)) != 0 { return 1 } 27 if uxg_back_ok(js_fix, uxg_len(js_fix)) != 1 { return 2 } 28 // escaping / &amp; (operator bug #2) 29 if uxg_escaping_ok(html_bad, uxg_len(html_bad)) != 0 { return 3 } 30 if uxg_escaping_ok(html_ok, uxg_len(html_ok)) != 1 { return 4 } 31 // mobile viewport 32 if uxg_viewport_ok(page_ok, uxg_len(page_ok)) != 1 { return 5 } 33 if uxg_viewport_ok(page_bad, uxg_len(page_bad)) != 0 { return 6 } 34 // skip link 35 if uxg_skiplink_ok(page_ok, uxg_len(page_ok)) != 1 { return 7 } 36 if uxg_skiplink_ok(page_bad, uxg_len(page_bad)) != 0 { return 8 } 37 38 // combined permil: clean page+fixed-js = 1000, buggy page+buggy-js = 250 39 if uxg_permil(page_ok, uxg_len(page_ok), js_fix, uxg_len(js_fix)) != 1000 { return 9 } 40 if uxg_permil(page_bad, uxg_len(page_bad), js_bug, uxg_len(js_bug)) != 250 { return 10 } 41 42 // ---- expanded dimension checks ---- 43 let page_full: *u8 = "<html lang=\"en\"><head><title>X</title><meta name=\"viewport\" content=\"width=device-width\"></head><body><nav></nav><a class=\"skip-link\" href=\"#m\">skip</a></body></html>" as *u8 44 let page_ext: *u8 = "<script src=\"https://cdn.example.com/x.js\"></script>" as *u8 45 let js_full: *u8 = "out.innerHTML='loading'; try{x}catch(e){ out.innerHTML='failed'; } if(!r){ out.innerHTML='no matches'; } function goBack(){}" as *u8 46 let js_bare: *u8 = "doStuff();" as *u8 47 48 if uxg_lang_ok(page_full, uxg_len(page_full)) != 1 { return 11 } 49 if uxg_lang_ok(page_bad, uxg_len(page_bad)) != 0 { return 12 } 50 if uxg_title_ok(page_full, uxg_len(page_full)) != 1 { return 13 } 51 if uxg_nav_ok(page_full, uxg_len(page_full)) != 1 { return 14 } 52 if uxg_sovereign_ok(page_full, uxg_len(page_full)) != 1 { return 15 } 53 if uxg_sovereign_ok(page_ext, uxg_len(page_ext)) != 0 { return 16 } 54 if uxg_loading_ok(js_full, uxg_len(js_full)) != 1 { return 17 } 55 if uxg_loading_ok(js_bare, uxg_len(js_bare)) != 0 { return 18 } 56 if uxg_error_ok(js_full, uxg_len(js_full)) != 1 { return 19 } 57 if uxg_error_ok(js_bare, uxg_len(js_bare)) != 0 { return 20 } 58 if uxg_empty_ok(js_full, uxg_len(js_full)) != 1 { return 21 } 59 if uxg_empty_ok(js_bare, uxg_len(js_bare)) != 0 { return 22 } 60 61 // full 11-check grade: clean = 1000, and degraded < clean (monotonic) 62 let g_hi: i64 = uxg_grade_full(page_full, uxg_len(page_full), js_full, uxg_len(js_full)) 63 let g_lo: i64 = uxg_grade_full(page_bad, uxg_len(page_bad), js_bare, uxg_len(js_bare)) 64 if g_hi != 1000 { return 23 } 65 if g_lo >= g_hi { return 24 } 66 67 let msg: *u8 = "nx_uxcx_grade: 24/24 sovereign assertions PASS (native, hardware-up)\n" as *u8 68 sys_write(1, msg, uxg_len(msg)) 69 return 0 70}