nx_css_selector_match_test.nx source
↩ module page · 125 lines · 4947 B
1// nx_css_selector_match_test.nx -- smoke for the Phase-2 selector
2// matcher. Builds three CssRule fixtures (tag/class/id) and three
3// CssElement fixtures, then enumerates every (rule, element) pair
4// and asserts the diagonal positive matches and off-diagonal negatives.
5
6import "nx_syscalls.nx"
7import "nx_css_tokenize.nx"
8import "nx_css_parse.nx"
9import "nx_css_selector_match.nx"
10
11func _put_byte(buf: *u8, i: i64, v: i64) -> i64 {
12 buf[i] = v as u8
13 return 0
14}
15
16// Shared source bytes contain:
17// offset 0..3 "body" (TAG selector / element tag)
18// offset 4..7 "head" (CLASS selector / class value content)
19// offset 8..11 "main" (ID selector / element id)
20// offset 12..27 "head sidebar" (multi-class element class attribute)
21// offset 28..30 "div" (negative-test element tag)
22func _build_src(out_len: *i64) -> *u8 {
23 let s: *u8 = (sys_mmap(64)) as *u8
24 var i: i64 = 0
25 // "body"
26 _put_byte(s, i, 98); i = i + 1
27 _put_byte(s, i, 111); i = i + 1
28 _put_byte(s, i, 100); i = i + 1
29 _put_byte(s, i, 121); i = i + 1
30 // "head"
31 _put_byte(s, i, 104); i = i + 1
32 _put_byte(s, i, 101); i = i + 1
33 _put_byte(s, i, 97); i = i + 1
34 _put_byte(s, i, 100); i = i + 1
35 // "main"
36 _put_byte(s, i, 109); i = i + 1
37 _put_byte(s, i, 97); i = i + 1
38 _put_byte(s, i, 105); i = i + 1
39 _put_byte(s, i, 110); i = i + 1
40 // "head sidebar"
41 _put_byte(s, i, 104); i = i + 1 // h
42 _put_byte(s, i, 101); i = i + 1 // e
43 _put_byte(s, i, 97); i = i + 1 // a
44 _put_byte(s, i, 100); i = i + 1 // d
45 _put_byte(s, i, 32); i = i + 1 // ' '
46 _put_byte(s, i, 115); i = i + 1 // s
47 _put_byte(s, i, 105); i = i + 1 // i
48 _put_byte(s, i, 100); i = i + 1 // d
49 _put_byte(s, i, 101); i = i + 1 // e
50 _put_byte(s, i, 98); i = i + 1 // b
51 _put_byte(s, i, 97); i = i + 1 // a
52 _put_byte(s, i, 114); i = i + 1 // r
53 // "div"
54 _put_byte(s, i, 100); i = i + 1 // d
55 _put_byte(s, i, 105); i = i + 1 // i
56 _put_byte(s, i, 118); i = i + 1 // v
57 out_len[0] = i
58 return s
59}
60
61func main() -> i64 {
62 let len_box: *i64 = (sys_mmap(8)) as *i64
63 let src: *u8 = _build_src(len_box)
64
65 // Build three rule fixtures pointing into the shared source.
66 let rules: *CssRule = (sys_mmap((3 * NX_CSS_RULE_BYTES) as nx_size)) as *CssRule
67
68 // rule 0: TAG selector "body" at offset 0 len 4
69 let r0: *CssRule = rules
70 r0.sel_kind = NX_CSS_SEL_TAG
71 r0.sel_off = 0
72 r0.sel_len = 4
73 r0.decl_first = 0
74 r0.decl_count = 0
75
76 // rule 1: CLASS selector "head" at offset 4 len 4
77 let r1: *CssRule = (rules as *u8 + (1 as nx_size) * (NX_CSS_RULE_BYTES as nx_size)) as *CssRule
78 r1.sel_kind = NX_CSS_SEL_CLASS
79 r1.sel_off = 4
80 r1.sel_len = 4
81 r1.decl_first = 0
82 r1.decl_count = 0
83
84 // rule 2: ID selector "main" at offset 8 len 4
85 let r2: *CssRule = (rules as *u8 + (2 as nx_size) * (NX_CSS_RULE_BYTES as nx_size)) as *CssRule
86 r2.sel_kind = NX_CSS_SEL_ID
87 r2.sel_off = 8
88 r2.sel_len = 4
89 r2.decl_first = 0
90 r2.decl_count = 0
91
92 // Element A: tag "body", no id, no class.
93 let el_a: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
94 nx_css_element_init(el_a, src, 0, 4, 0, 0, 0, 0)
95
96 // Element B: tag "div", no id, class "head sidebar" (matches r1 via class list).
97 let el_b: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
98 nx_css_element_init(el_b, src, 28, 3, 0, 0, 12, 12)
99
100 // Element C: tag "div", id "main", no class.
101 let el_c: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
102 nx_css_element_init(el_c, src, 28, 3, 8, 4, 0, 0)
103
104 // Element D: tag "div", no id, class "sidebar" (does NOT contain "head").
105 let el_d: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
106 nx_css_element_init(el_d, src, 28, 3, 0, 0, 17, 7)
107
108 // Diagonal positives.
109 if nx_css_selector_match(r0, el_a) != 1 { return 1 } // body TAG matches el_a
110 if nx_css_selector_match(r1, el_b) != 1 { return 2 } // .head matches el_b's class list
111 if nx_css_selector_match(r2, el_c) != 1 { return 3 } // #main matches el_c's id
112
113 // Off-diagonal negatives.
114 if nx_css_selector_match(r0, el_b) != 0 { return 11 } // body TAG does NOT match div
115 if nx_css_selector_match(r0, el_c) != 0 { return 12 }
116 if nx_css_selector_match(r0, el_d) != 0 { return 13 }
117 if nx_css_selector_match(r1, el_a) != 0 { return 14 } // .head does NOT match body without class
118 if nx_css_selector_match(r1, el_c) != 0 { return 15 }
119 if nx_css_selector_match(r1, el_d) != 0 { return 16 } // class "sidebar" doesn't contain "head"
120 if nx_css_selector_match(r2, el_a) != 0 { return 17 }
121 if nx_css_selector_match(r2, el_b) != 0 { return 18 }
122 if nx_css_selector_match(r2, el_d) != 0 { return 19 }
123
124 return 0
125}