nx_ux_triangulate_w3c_kat_test.nx source
↩ module page · 150 lines · 7787 B
1// nx_ux_triangulate_w3c_kat_test.nx -- standalone KAT for the new
2// W3C/MS clauses + per-cluster triangulation.
3//
4// Builds a SYNTHETIC RenderJournal that emulates the browser-demo's
5// paint pattern (background + url_bar + buttons + a11y_role_* + focus
6// + status_bar + content text), runs nx_ux_score_clause across every
7// new clause id, then runs nx_ux_triangulate_cluster per cluster.
8//
9// Non-interactive -- no X11 window, no event loop. This is the
10// substrate-honest validation of the scoring + triangulation engine
11// independent of the GUI demo.
12//
13// Asserts (each via dump_dec):
14// 1. NX_UX_W3C_HTML_SEMANTIC scores >= 5
15// 2. NX_UX_W3C_ARIA_ROLES scores >= 7 (>=3 a11y_role entries)
16// 3. NX_UX_W3C_ARIA_LABELS scores >= 2
17// 4. NX_UX_W3C_DOM_TREE scores >= 7 (>=10 journal entries)
18// 5. NX_UX_W3C_CSS_CONTRAST scores >= 5
19// 6. NX_UX_MS_INCL_EXCLUSION scores >= 6 (a11y + focus + status)
20// 7. accessibility cluster verdict == VALIDATED_S_CLASS or UNVERIFIED
21// (NOT CONFLICTED -- per-cluster scope means weak NN5 doesn't
22// poison accessibility cluster)
23//
24// license_tier: ORIGINAL
25// lineage_id: nishi_ux_triangulate_w3c_kat_q10
26
27import "nx_syscalls.nx"
28import "nx_render_journal.nx"
29import "nx_ux_standard.nx"
30import "nx_ux_score.nx"
31import "nx_ux_triangulate.nx"
32
33func dump_dec(label_a: i64, label_b: i64, v: i64) -> i64 {
34 let buf: *u8 = sys_mmap(32)
35 buf[0] = label_a as u8; buf[1] = label_b as u8; buf[2] = 0x3D
36 var n: i64 = 3
37 var x: i64 = v
38 if x < 0 { buf[n] = 0x2D; n = n + 1; x = 0 - x }
39 if x == 0 { buf[n] = 0x30; n = n + 1 }
40 else {
41 let tmp: *u8 = sys_mmap(24)
42 var k: i64 = 0
43 while x > 0 { tmp[k] = (0x30 + (x % 10)) as u8; x = x / 10; k = k + 1 }
44 while k > 0 { k = k - 1; buf[n] = tmp[k]; n = n + 1 }
45 }
46 buf[n] = 0x0A; n = n + 1
47 sys_write(1, buf, n)
48 return 0
49}
50
51func main() -> i64 {
52 let j: *RenderJournal = nx_journal_new()
53
54 // Emulate the browser demo's paint pattern.
55 nx_journal_log_rect(j, "background" as *u8, 0, 0, 800, 600, 0x00FFFFFF)
56 nx_journal_log_rect(j, "url_bar_bg" as *u8, 0, 0, 800, 30, 0x00334455)
57 nx_journal_log_rect(j, "back_button" as *u8, 10, 5, 30, 20, 0x004488CC)
58 nx_journal_log_rect(j, "forward_button" as *u8, 45, 5, 30, 20, 0x004488CC)
59 nx_journal_log_rect(j, "reload_button" as *u8, 80, 5, 30, 20, 0x004488CC)
60 nx_journal_log_rect(j, "url_text" as *u8, 120, 8, 400, 14, 0x00000000)
61 nx_journal_log_rect(j, "title" as *u8, 20, 50, 400, 40, 0x00224488)
62 nx_journal_log_rect(j, "content_text_line_1" as *u8, 20, 100, 760, 14, 0x00111111)
63 nx_journal_log_rect(j, "content_text_line_2" as *u8, 20, 120, 760, 14, 0x00111111)
64 nx_journal_log_rect(j, "breadcrumb_current" as *u8, 20, 580, 300, 14, 0x00666666)
65 nx_journal_log_rect(j, "status_bar" as *u8, 0, 580, 800, 20, 0x00DDDDDD)
66 nx_journal_log_rect(j, "focus_indicator" as *u8, 10, 5, 30, 20, 0x00FFFF00)
67 nx_journal_log_rect(j, "a11y_role_button_back" as *u8, 0, 0, 0, 0, 0)
68 nx_journal_log_rect(j, "a11y_role_button_forward" as *u8, 0, 0, 0, 0, 0)
69 nx_journal_log_rect(j, "a11y_role_button_reload" as *u8, 0, 0, 0, 0, 0)
70 nx_journal_log_rect(j, "a11y_role_textbox_url" as *u8, 0, 0, 0, 0, 0)
71 nx_journal_log_rect(j, "a11y_role_region_content" as *u8, 0, 0, 0, 0, 0)
72 nx_journal_log_rect(j, "a11y_role_status_bar" as *u8, 0, 0, 0, 0, 0)
73 nx_journal_log_rect(j, "flash_indicator" as *u8, 50, 50, 100, 30, 0x0000FF00)
74 nx_journal_log_rect(j, "label_back" as *u8, 12, 8, 26, 16, 0x00FFFFFF)
75 nx_journal_log_rect(j, "label_forward" as *u8, 47, 8, 26, 16, 0x00FFFFFF)
76 nx_journal_log_rect(j, "label_reload" as *u8, 82, 8, 26, 16, 0x00FFFFFF)
77
78 // Score every clause we expect to be exercised.
79 let note: *u8 = sys_mmap(256)
80
81 let s_html: i64 = nx_ux_score_clause(j, NX_UX_W3C_HTML_SEMANTIC, note, 256)
82 let s_aria_r: i64 = nx_ux_score_clause(j, NX_UX_W3C_ARIA_ROLES, note, 256)
83 let s_aria_l: i64 = nx_ux_score_clause(j, NX_UX_W3C_ARIA_LABELS, note, 256)
84 let s_dom: i64 = nx_ux_score_clause(j, NX_UX_W3C_DOM_TREE, note, 256)
85 let s_css: i64 = nx_ux_score_clause(j, NX_UX_W3C_CSS_CONTRAST, note, 256)
86 let s_ms: i64 = nx_ux_score_clause(j, NX_UX_MS_INCL_EXCLUSION, note, 256)
87 let s_wcag_kbd: i64 = nx_ux_score_clause(j, NX_UX_WCAG_2_1_1_KEYBOARD, note, 256)
88 let s_wcag_focus: i64 = nx_ux_score_clause(j, NX_UX_WCAG_2_4_7_FOCUS, note, 256)
89 let s_wcag_nrv: i64 = nx_ux_score_clause(j, NX_UX_WCAG_4_1_2_NRV, note, 256)
90 let s_nn6: i64 = nx_ux_score_clause(j, NX_UX_NN6_RECOGNITION, note, 256)
91
92 dump_dec(0x48, 0x4D, s_html) // HM=html-semantic
93 dump_dec(0x41, 0x52, s_aria_r) // AR=aria roles
94 dump_dec(0x41, 0x4C, s_aria_l) // AL=aria labels
95 dump_dec(0x44, 0x4F, s_dom) // DO=dom tree
96 dump_dec(0x43, 0x53, s_css) // CS=css contrast
97 dump_dec(0x4D, 0x53, s_ms) // MS=ms inclusive
98 dump_dec(0x57, 0x4B, s_wcag_kbd) // WK=wcag keyboard
99 dump_dec(0x57, 0x46, s_wcag_focus) // WF=wcag focus
100 dump_dec(0x57, 0x4E, s_wcag_nrv) // WN=wcag name/role/value
101 dump_dec(0x4E, 0x36, s_nn6) // N6=nng #6
102
103 if s_html < 5 { return 1 }
104 if s_aria_r < 7 { return 2 }
105 if s_aria_l < 2 { return 3 }
106 if s_dom < 7 { return 4 }
107 if s_css < 5 { return 5 }
108 if s_ms < 6 { return 6 }
109
110 // Per-cluster triangulation. Build a 10-entry scores[] array.
111 let raw: *u8 = sys_mmap(10 * NX_UX_SCORE_BYTES + 16)
112 let scores: *UxScore = raw as *UxScore
113 var i: i64 = 0
114 while i < 10 {
115 let sx: *UxScore = _ux_at(scores, i)
116 sx.clause_id = 0; sx.score = 0
117 i = i + 1
118 }
119 let s0: *UxScore = _ux_at(scores, 0); s0.clause_id = NX_UX_W3C_ARIA_ROLES; s0.score = s_aria_r
120 let s1: *UxScore = _ux_at(scores, 1); s1.clause_id = NX_UX_W3C_ARIA_LABELS; s1.score = s_aria_l
121 let s2: *UxScore = _ux_at(scores, 2); s2.clause_id = NX_UX_WCAG_2_1_1_KEYBOARD; s2.score = s_wcag_kbd
122 let s3: *UxScore = _ux_at(scores, 3); s3.clause_id = NX_UX_WCAG_2_4_7_FOCUS; s3.score = s_wcag_focus
123 let s4: *UxScore = _ux_at(scores, 4); s4.clause_id = NX_UX_WCAG_4_1_2_NRV; s4.score = s_wcag_nrv
124 let s5: *UxScore = _ux_at(scores, 5); s5.clause_id = NX_UX_MS_INCL_EXCLUSION; s5.score = s_ms
125 let s6: *UxScore = _ux_at(scores, 6); s6.clause_id = NX_UX_NN6_RECOGNITION; s6.score = s_nn6
126 let s7: *UxScore = _ux_at(scores, 7); s7.clause_id = NX_UX_NN5_ERROR_PREVENTION; s7.score = 0
127 let s8: *UxScore = _ux_at(scores, 8); s8.clause_id = NX_UX_W3C_HTML_SEMANTIC; s8.score = s_html
128 let s9: *UxScore = _ux_at(scores, 9); s9.clause_id = NX_UX_W3C_DOM_TREE; s9.score = s_dom
129
130 let acc_v: i64 = nx_ux_triangulate_cluster(scores, 10, NX_UX_CLUSTER_ACCESSIBILITY)
131 let sem_v: i64 = nx_ux_triangulate_cluster(scores, 10, NX_UX_CLUSTER_SEMANTIC)
132 let err_v: i64 = nx_ux_triangulate_cluster(scores, 10, NX_UX_CLUSTER_ERROR_PREVENT)
133
134 dump_dec(0x41, 0x56, acc_v) // AV=accessibility verdict
135 dump_dec(0x53, 0x56, sem_v) // SV=semantic verdict
136 dump_dec(0x45, 0x56, err_v) // EV=error-prevention verdict
137
138 // Accessibility cluster MUST be VALIDATED_S_CLASS -- 4+ independent
139 // sources (W3C-ARIA, WCAG, NN/g, MS-Inclusive) all score >= 7.
140 if acc_v != NX_UX_VERDICT_VALIDATED_S_CLASS { return 7 }
141
142 // Error-prevention cluster MUST NOT be VALIDATED -- only score is 0.
143 if err_v == NX_UX_VERDICT_VALIDATED_S_CLASS { return 8 }
144
145 // Semantic cluster has W3C_HTML + W3C_DOM (both W3C-flavoured but
146 // distinct sources) -- expect VALIDATED with 2-source softer gate.
147 if sem_v == NX_UX_VERDICT_CONFLICTED { return 9 }
148
149 return 0
150}