code wiki / (root) / nx_layout_from_dom_test.nx

nx_layout_from_dom_test.nx source

↩ module page · 141 lines · 6582 B

1// nx_layout_from_dom_test.nx -- end-to-end smoke proving HTML token 2// stream produces a correct LayoutBox tree. 3// 4// Fixture: "<body><h1>Hi</h1><p>Yo</p></body>" 5// 6// Expected token stream from nx_html_next_token: 7// START_TAG body / START_TAG h1 / TEXT "Hi" / END_TAG h1 / 8// START_TAG p / TEXT "Yo" / END_TAG p / END_TAG body / EOF 9// 10// Expected LayoutBox tree (6 boxes total): 11// box 0: synthetic root (BLOCK, source=-1) 12// box 1: body (BLOCK, parent=0) 13// box 2: h1 (BLOCK, parent=1) 14// box 3: text "Hi" (TEXT, parent=2) 15// box 4: p (BLOCK, parent=1) 16// box 5: text "Yo" (TEXT, parent=4) 17 18import "nx_syscalls.nx" 19import "nx_html_tokenizer.nx" 20import "nx_layout_box.nx" 21import "nx_layout_default_display.nx" 22import "nx_layout_from_dom.nx" 23 24func _put_byte(buf: *u8, i: i64, v: i64) -> i64 { 25 buf[i] = v as u8 26 return 0 27} 28 29func main() -> i64 { 30 // Build fixture: "<body><h1>Hi</h1><p>Yo</p></body>" (32 bytes) 31 let src: *u8 = (sys_mmap(64)) as *u8 32 var p: i64 = 0 33 _put_byte(src, p, 60) p = p + 1 // '<' 34 _put_byte(src, p, 98) p = p + 1 // 'b' 35 _put_byte(src, p, 111) p = p + 1 // 'o' 36 _put_byte(src, p, 100) p = p + 1 // 'd' 37 _put_byte(src, p, 121) p = p + 1 // 'y' 38 _put_byte(src, p, 62) p = p + 1 // '>' 39 _put_byte(src, p, 60) p = p + 1 // '<' 40 _put_byte(src, p, 104) p = p + 1 // 'h' 41 _put_byte(src, p, 49) p = p + 1 // '1' 42 _put_byte(src, p, 62) p = p + 1 // '>' 43 _put_byte(src, p, 72) p = p + 1 // 'H' 44 _put_byte(src, p, 105) p = p + 1 // 'i' 45 _put_byte(src, p, 60) p = p + 1 // '<' 46 _put_byte(src, p, 47) p = p + 1 // '/' 47 _put_byte(src, p, 104) p = p + 1 // 'h' 48 _put_byte(src, p, 49) p = p + 1 // '1' 49 _put_byte(src, p, 62) p = p + 1 // '>' 50 _put_byte(src, p, 60) p = p + 1 // '<' 51 _put_byte(src, p, 112) p = p + 1 // 'p' 52 _put_byte(src, p, 62) p = p + 1 // '>' 53 _put_byte(src, p, 89) p = p + 1 // 'Y' 54 _put_byte(src, p, 111) p = p + 1 // 'o' 55 _put_byte(src, p, 60) p = p + 1 // '<' 56 _put_byte(src, p, 47) p = p + 1 // '/' 57 _put_byte(src, p, 112) p = p + 1 // 'p' 58 _put_byte(src, p, 62) p = p + 1 // '>' 59 _put_byte(src, p, 60) p = p + 1 // '<' 60 _put_byte(src, p, 47) p = p + 1 // '/' 61 _put_byte(src, p, 98) p = p + 1 // 'b' 62 _put_byte(src, p, 111) p = p + 1 // 'o' 63 _put_byte(src, p, 100) p = p + 1 // 'd' 64 _put_byte(src, p, 121) p = p + 1 // 'y' 65 _put_byte(src, p, 62) p = p + 1 // '>' 66 let src_len: i64 = p // 33 67 68 // Allocate LayoutTree + parent stack. 69 let max_boxes: i64 = 16 70 let boxes: *LayoutBox = (sys_mmap((max_boxes * NX_LAYOUT_BOX_BYTES) as nx_size)) as *LayoutBox 71 let tree: *LayoutTree = (sys_mmap(NX_LAYOUT_TREE_BYTES as nx_size)) as *LayoutTree 72 nx_layout_tree_init(tree, boxes, max_boxes) 73 74 let stack_cap: i64 = 16 75 let stk_indices: *i64 = (sys_mmap((stack_cap * 8) as nx_size)) as *i64 76 let stk: *LayoutFromDomStack = (sys_mmap(NX_LAYOUT_FROM_DOM_STACK_BYTES as nx_size)) as *LayoutFromDomStack 77 nx_layout_from_dom_stack_init(stk, stk_indices, stack_cap) 78 79 // Run. 80 let root_idx: i64 = nx_layout_from_dom(src, src_len, tree, stk) 81 if root_idx != 0 { return 1 } 82 if tree.count != 6 { return 2 } 83 84 // Root (box 0): BLOCK, parent=-1, source=-1, first_child=1. 85 let root: *LayoutBox = boxes 86 if root.kind != NX_LAYOUT_BOX_BLOCK { return 10 } 87 if root.parent_idx != -1 { return 11 } 88 if root.source_node_idx != -1 { return 12 } 89 if root.first_child_idx != 1 { return 13 } 90 91 // box 1: body, BLOCK, parent=0, first_child=2, next_sibling=-1. 92 let b1: *LayoutBox = (boxes as *u8 + (1 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 93 if b1.kind != NX_LAYOUT_BOX_BLOCK { return 20 } 94 if b1.parent_idx != 0 { return 21 } 95 if b1.first_child_idx != 2 { return 22 } 96 if b1.next_sibling_idx != -1 { return 23 } 97 98 // box 2: h1, BLOCK, parent=1, first_child=3, next_sibling=4. 99 let b2: *LayoutBox = (boxes as *u8 + (2 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 100 if b2.kind != NX_LAYOUT_BOX_BLOCK { return 30 } 101 if b2.parent_idx != 1 { return 31 } 102 if b2.first_child_idx != 3 { return 32 } 103 if b2.next_sibling_idx != 4 { return 33 } 104 105 // box 3: TEXT "Hi", parent=2, text_len=2, body bytes match "Hi". 106 let b3: *LayoutBox = (boxes as *u8 + (3 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 107 if b3.kind != NX_LAYOUT_BOX_TEXT { return 40 } 108 if b3.parent_idx != 2 { return 41 } 109 if b3.text_len != 2 { return 42 } 110 if (src[b3.text_off] as i64) & 255 != 72 { return 43 } // 'H' 111 if (src[b3.text_off + 1] as i64) & 255 != 105 { return 44 } // 'i' 112 113 // box 4: p, BLOCK, parent=1, first_child=5, next_sibling=-1. 114 let b4: *LayoutBox = (boxes as *u8 + (4 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 115 if b4.kind != NX_LAYOUT_BOX_BLOCK { return 50 } 116 if b4.parent_idx != 1 { return 51 } 117 if b4.first_child_idx != 5 { return 52 } 118 if b4.next_sibling_idx != -1 { return 53 } 119 120 // box 5: TEXT "Yo", parent=4. 121 let b5: *LayoutBox = (boxes as *u8 + (5 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 122 if b5.kind != NX_LAYOUT_BOX_TEXT { return 60 } 123 if b5.parent_idx != 4 { return 61 } 124 if b5.text_len != 2 { return 62 } 125 if (src[b5.text_off] as i64) & 255 != 89 { return 63 } // 'Y' 126 if (src[b5.text_off + 1] as i64) & 255 != 111 { return 64 } // 'o' 127 128 // Stack should be at depth 1 (only root left after walk). 129 if stk.depth != 1 { return 70 } 130 if stk.indices[0] != 0 { return 71 } 131 132 // Child-count checks via the helper from nx_layout_box. 133 if nx_layout_box_child_count(tree, 0) != 1 { return 80 } // root has 1 child (body) 134 if nx_layout_box_child_count(tree, 1) != 2 { return 81 } // body has 2 children (h1, p) 135 if nx_layout_box_child_count(tree, 2) != 1 { return 82 } // h1 has 1 child (text) 136 if nx_layout_box_child_count(tree, 3) != 0 { return 83 } // text leaf 137 if nx_layout_box_child_count(tree, 4) != 1 { return 84 } // p has 1 child (text) 138 if nx_layout_box_child_count(tree, 5) != 0 { return 85 } // text leaf 139 140 return 0 141}