nx_css_apply_test.nx source
↩ module page · 210 lines · 7696 B
1// nx_css_apply_test.nx -- smoke for the Phase-2 cascade primitive.
2// Hand-builds CssRule + CssDeclaration + CssElement arrays into a
3// shared source buffer (so byte equality is well-defined), runs the
4// O(R x E) match-and-emit loop, then exercises the property lookup
5// helper.
6//
7// Fixture stylesheet (semantically):
8// body { color: #ff0000; }
9// .head { font-size: 16px; }
10//
11// Fixture elements:
12// el0: <body> (TAG body)
13// el1: <span class="head"> (CLASS head)
14// el2: <span class="other"> (CLASS other -- no match)
15//
16// Expected cascade output:
17// 3 computed entries:
18// (el0, color = #ff0000)
19// (el1, font-size = DIMENSION 16 px)
20//
21// Wait -- el2 contributes zero entries; el0 contributes 1; el1
22// contributes 1. Total = 2 entries. Let's also verify the lookup
23// helper returns correct values per element.
24
25import "nx_syscalls.nx"
26import "nx_css_tokenize.nx"
27import "nx_css_parse.nx"
28import "nx_css_selector_match.nx"
29import "nx_css_apply.nx"
30
31func _put_byte(buf: *u8, i: i64, v: i64) -> i64 {
32 buf[i] = v as u8
33 return 0
34}
35
36// Shared source buffer layout (offsets used to build rules + elements):
37// [0..3] "body" (tag selector AND el0's tag)
38// [5..8] "head" (class selector AND token in el1's class attr)
39// [10..14] "color" (decl 0 property)
40// [16..21] "ff0000" (decl 0 value -- hex body)
41// [23..31] "font-size" (decl 1 property)
42// [33..34] "16" (decl 1 number body)
43// [36..37] "px" (decl 1 unit body)
44// [39..42] "span" (el1, el2 tag)
45// [44..48] "other" (el2 class)
46func _build_src() -> *u8 {
47 let s: *u8 = (sys_mmap(64)) as *u8
48 // [0..3] "body"
49 _put_byte(s, 0, 98)
50 _put_byte(s, 1, 111)
51 _put_byte(s, 2, 100)
52 _put_byte(s, 3, 121)
53 _put_byte(s, 4, 32) // ' '
54 // [5..8] "head"
55 _put_byte(s, 5, 104)
56 _put_byte(s, 6, 101)
57 _put_byte(s, 7, 97)
58 _put_byte(s, 8, 100)
59 _put_byte(s, 9, 32) // ' '
60 // [10..14] "color"
61 _put_byte(s, 10, 99)
62 _put_byte(s, 11, 111)
63 _put_byte(s, 12, 108)
64 _put_byte(s, 13, 111)
65 _put_byte(s, 14, 114)
66 _put_byte(s, 15, 32)
67 // [16..21] "ff0000"
68 _put_byte(s, 16, 102)
69 _put_byte(s, 17, 102)
70 _put_byte(s, 18, 48)
71 _put_byte(s, 19, 48)
72 _put_byte(s, 20, 48)
73 _put_byte(s, 21, 48)
74 _put_byte(s, 22, 32)
75 // [23..31] "font-size"
76 _put_byte(s, 23, 102)
77 _put_byte(s, 24, 111)
78 _put_byte(s, 25, 110)
79 _put_byte(s, 26, 116)
80 _put_byte(s, 27, 45)
81 _put_byte(s, 28, 115)
82 _put_byte(s, 29, 105)
83 _put_byte(s, 30, 122)
84 _put_byte(s, 31, 101)
85 _put_byte(s, 32, 32)
86 // [33..34] "16"
87 _put_byte(s, 33, 49)
88 _put_byte(s, 34, 54)
89 _put_byte(s, 35, 32)
90 // [36..37] "px"
91 _put_byte(s, 36, 112)
92 _put_byte(s, 37, 120)
93 _put_byte(s, 38, 32)
94 // [39..42] "span"
95 _put_byte(s, 39, 115)
96 _put_byte(s, 40, 112)
97 _put_byte(s, 41, 97)
98 _put_byte(s, 42, 110)
99 _put_byte(s, 43, 32)
100 // [44..48] "other"
101 _put_byte(s, 44, 111)
102 _put_byte(s, 45, 116)
103 _put_byte(s, 46, 104)
104 _put_byte(s, 47, 101)
105 _put_byte(s, 48, 114)
106 return s
107}
108
109func main() -> i64 {
110 let src: *u8 = _build_src()
111
112 // Build 2 rules.
113 let rules: *CssRule = (sys_mmap((2 * NX_CSS_RULE_BYTES) as nx_size)) as *CssRule
114 let r0: *CssRule = rules
115 r0.sel_kind = NX_CSS_SEL_TAG
116 r0.sel_off = 0 // "body"
117 r0.sel_len = 4
118 r0.decl_first = 0
119 r0.decl_count = 1 // one decl: color
120
121 let r1: *CssRule = (rules as *u8 + (1 as nx_size) * (NX_CSS_RULE_BYTES as nx_size)) as *CssRule
122 r1.sel_kind = NX_CSS_SEL_CLASS
123 r1.sel_off = 5 // "head"
124 r1.sel_len = 4
125 r1.decl_first = 1
126 r1.decl_count = 1 // one decl: font-size
127
128 // Build 2 declarations.
129 let decls: *CssDeclaration = (sys_mmap((2 * NX_CSS_DECLARATION_BYTES) as nx_size)) as *CssDeclaration
130 let d0: *CssDeclaration = decls
131 d0.prop_off = 10 // "color"
132 d0.prop_len = 5
133 d0.val_kind = NX_CSS_VAL_HEXCOLOR
134 d0.val_off = 16 // "ff0000"
135 d0.val_len = 6
136 d0.unit_off = 0
137 d0.unit_len = 0
138
139 let d1: *CssDeclaration = (decls as *u8 + (1 as nx_size) * (NX_CSS_DECLARATION_BYTES as nx_size)) as *CssDeclaration
140 d1.prop_off = 23 // "font-size"
141 d1.prop_len = 9
142 d1.val_kind = NX_CSS_VAL_DIMENSION
143 d1.val_off = 33 // "16"
144 d1.val_len = 2
145 d1.unit_off = 36 // "px"
146 d1.unit_len = 2
147
148 // Build 3 elements.
149 let elements: *CssElement = (sys_mmap((3 * NX_CSS_ELEMENT_BYTES) as nx_size)) as *CssElement
150 let el0: *CssElement = elements
151 nx_css_element_init(el0, src, 0, 4, 0, 0, 0, 0) // <body>
152
153 let el1: *CssElement = (elements as *u8 + (1 as nx_size) * (NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
154 nx_css_element_init(el1, src, 39, 4, 0, 0, 5, 4) // <span class="head">
155
156 let el2: *CssElement = (elements as *u8 + (2 as nx_size) * (NX_CSS_ELEMENT_BYTES as nx_size)) as *CssElement
157 nx_css_element_init(el2, src, 39, 4, 0, 0, 44, 5) // <span class="other">
158
159 // Run cascade.
160 let max_computed: i64 = 16
161 let computed: *CssComputedDecl = (sys_mmap((max_computed * NX_CSS_COMPUTED_DECL_BYTES) as nx_size)) as *CssComputedDecl
162 let count_box: *i64 = (sys_mmap(8)) as *i64
163
164 let rc: i64 = nx_css_apply(src, rules, 2, decls, 2, elements, 3,
165 computed, max_computed, count_box)
166 if rc != 1 { return 1 }
167 if count_box[0] != 2 { return 2 } // el0 + el1 each contribute 1 decl
168
169 // Entry 0 should belong to el0, property = "color".
170 let c0: *CssComputedDecl = computed
171 if c0.element_idx != 0 { return 10 }
172 if c0.prop_off != 10 { return 11 }
173 if c0.prop_len != 5 { return 12 }
174 if c0.val_kind != NX_CSS_VAL_HEXCOLOR { return 13 }
175 if c0.val_off != 16 { return 14 }
176 if c0.val_len != 6 { return 15 }
177
178 // Entry 1 should belong to el1, property = "font-size".
179 let c1: *CssComputedDecl = (computed as *u8 + (1 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
180 if c1.element_idx != 1 { return 20 }
181 if c1.prop_off != 23 { return 21 }
182 if c1.prop_len != 9 { return 22 }
183 if c1.val_kind != NX_CSS_VAL_DIMENSION { return 23 }
184 if c1.val_off != 33 { return 24 }
185 if c1.val_len != 2 { return 25 }
186 if c1.unit_off != 36 { return 26 }
187 if c1.unit_len != 2 { return 27 }
188
189 // Lookup helper: el0 color -> entry 0.
190 let lookup_color_el0: *CssComputedDecl = nx_css_lookup_property(src, computed, 2, 0, 10, 5)
191 if lookup_color_el0 == (0 as *CssComputedDecl) { return 30 }
192 if lookup_color_el0.val_kind != NX_CSS_VAL_HEXCOLOR { return 31 }
193 if lookup_color_el0.val_off != 16 { return 32 }
194
195 // Lookup helper: el1 font-size -> entry 1.
196 let lookup_fs_el1: *CssComputedDecl = nx_css_lookup_property(src, computed, 2, 1, 23, 9)
197 if lookup_fs_el1 == (0 as *CssComputedDecl) { return 40 }
198 if lookup_fs_el1.val_kind != NX_CSS_VAL_DIMENSION { return 41 }
199 if lookup_fs_el1.unit_off != 36 { return 42 }
200
201 // Lookup helper: el2 color -> nothing (no match).
202 let lookup_color_el2: *CssComputedDecl = nx_css_lookup_property(src, computed, 2, 2, 10, 5)
203 if lookup_color_el2 != (0 as *CssComputedDecl) { return 50 }
204
205 // Lookup helper: el0 font-size -> nothing (rule didn't match).
206 let lookup_fs_el0: *CssComputedDecl = nx_css_lookup_property(src, computed, 2, 0, 23, 9)
207 if lookup_fs_el0 != (0 as *CssComputedDecl) { return 60 }
208
209 return 0
210}