code wiki / (root) / nx_css_apply_test.nx

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}