code wiki / (root) / nx_css_selector_match_test.nx

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}