div.test.ts
1 import { describe, expect, mock, test } from "bun:test"; 2 import { Align, Display, FlexDirection, Justify, Overflow, PositionType } from "yoga-layout"; 3 import { Div, div } from "~/elements/div"; 4 5 // Mock PDFPage for testing 6 const mockPDFPage = { 7 drawRectangle: mock(() => {}), 8 getHeight: mock(() => 800) 9 }; 10 11 describe("Div", () => { 12 describe("constructor and helper function", () => { 13 test("should create Div instance", () => { 14 const divElement = new Div(); 15 expect(divElement).toBeInstanceOf(Div); 16 }); 17 18 test("should create Div instance with helper function", () => { 19 const divElement = div(); 20 expect(divElement).toBeInstanceOf(Div); 21 }); 22 }); 23 24 describe("children management", () => { 25 test("should have empty children array initially", () => { 26 const divElement = div(); 27 expect(divElement.children).toEqual([]); 28 }); 29 30 test("should add child and return instance for chaining", () => { 31 const parent = div(); 32 const child = div(); 33 34 const result = parent.child(child); 35 36 expect(result).toBe(parent); 37 expect(parent.children).toContain(child); 38 }); 39 40 test("should add multiple children", () => { 41 const parent = div(); 42 const child1 = div(); 43 const child2 = div(); 44 45 parent.child(child1).child(child2); 46 47 expect(parent.children).toEqual([child1, child2]); 48 }); 49 }); 50 51 describe("positioning methods", () => { 52 test("should set absolute positioning", () => { 53 const divElement = div(); 54 const result = divElement.absolute(); 55 56 expect(result).toBe(divElement); 57 }); 58 59 test("should set relative positioning", () => { 60 const divElement = div(); 61 const result = divElement.relative(); 62 63 expect(result).toBe(divElement); 64 }); 65 }); 66 67 describe("background color", () => { 68 test("should set background color", () => { 69 const divElement = div(); 70 const result = divElement.bg(0xFF0000); // Red 71 72 expect(result).toBe(divElement); 73 }); 74 75 test("should chain background color calls", () => { 76 const divElement = div() 77 .bg(0xFF0000) 78 .bg(0x00FF00) 79 .bg(0x0000FF); 80 81 expect(divElement).toBeInstanceOf(Div); 82 }); 83 }); 84 85 describe("display methods", () => { 86 test("should set flex display", () => { 87 const divElement = div(); 88 const result = divElement.flex(); 89 90 expect(result).toBe(divElement); 91 }); 92 }); 93 94 describe("flex direction methods", () => { 95 test("should set flex row direction", () => { 96 const divElement = div(); 97 const result = divElement.flexRow(); 98 99 expect(result).toBe(divElement); 100 }); 101 102 test("should set flex row reverse direction", () => { 103 const divElement = div(); 104 const result = divElement.flexRowReverse(); 105 106 expect(result).toBe(divElement); 107 }); 108 109 test("should set flex column direction", () => { 110 const divElement = div(); 111 const result = divElement.flexCol(); 112 113 expect(result).toBe(divElement); 114 }); 115 116 test("should set flex column reverse direction", () => { 117 const divElement = div(); 118 const result = divElement.flexColReverse(); 119 120 expect(result).toBe(divElement); 121 }); 122 }); 123 124 describe("alignment methods", () => { 125 test("should set items center alignment", () => { 126 const divElement = div(); 127 const result = divElement.itemsCenter(); 128 129 expect(result).toBe(divElement); 130 }); 131 132 test("should set items start alignment", () => { 133 const divElement = div(); 134 const result = divElement.itemsStart(); 135 136 expect(result).toBe(divElement); 137 }); 138 139 test("should set justify center", () => { 140 const divElement = div(); 141 const result = divElement.justifyCenter(); 142 143 expect(result).toBe(divElement); 144 }); 145 146 test("should set justify start", () => { 147 const divElement = div(); 148 const result = divElement.justifyStart(); 149 150 expect(result).toBe(divElement); 151 }); 152 }); 153 154 describe("size methods", () => { 155 test("should set width", () => { 156 const divElement = div(); 157 const result = divElement.w(200); 158 159 expect(result).toBe(divElement); 160 }); 161 162 test("should set full width", () => { 163 const divElement = div(); 164 const result = divElement.wFull(); 165 166 expect(result).toBe(divElement); 167 }); 168 169 test("should set height", () => { 170 const divElement = div(); 171 const result = divElement.h(150); 172 173 expect(result).toBe(divElement); 174 }); 175 176 test("should set full height", () => { 177 const divElement = div(); 178 const result = divElement.hFull(); 179 180 expect(result).toBe(divElement); 181 }); 182 }); 183 184 describe("flex properties", () => { 185 test("should set grow to 1", () => { 186 const divElement = div(); 187 const result = divElement.grow1(); 188 189 expect(result).toBe(divElement); 190 }); 191 192 test("should set shrink to 0", () => { 193 const divElement = div(); 194 const result = divElement.shrink0(); 195 196 expect(result).toBe(divElement); 197 }); 198 199 test("should set shrink to 1", () => { 200 const divElement = div(); 201 const result = divElement.shrink1(); 202 203 expect(result).toBe(divElement); 204 }); 205 }); 206 207 describe("overflow methods", () => { 208 test("should set overflow hidden", () => { 209 const divElement = div(); 210 const result = divElement.overflowHidden(); 211 212 expect(result).toBe(divElement); 213 }); 214 }); 215 216 describe("getLayoutNode", () => { 217 test("should create and return layout node", () => { 218 const divElement = div(); 219 const fonts = new Map(); 220 221 const node = divElement.getLayoutNode(mockPDFPage as any, fonts); 222 223 expect(node).toBeDefined(); 224 expect(typeof node.free).toBe("function"); 225 226 node.free(); 227 }); 228 229 test("should return same node on subsequent calls", () => { 230 const divElement = div(); 231 const fonts = new Map(); 232 233 const node1 = divElement.getLayoutNode(mockPDFPage as any, fonts); 234 const node2 = divElement.getLayoutNode(mockPDFPage as any, fonts); 235 236 expect(node1).toBe(node2); 237 238 node1.free(); 239 }); 240 241 test("should handle children layout nodes", () => { 242 const parent = div(); 243 const child = div(); 244 parent.child(child); 245 246 const fonts = new Map(); 247 const node = parent.getLayoutNode(mockPDFPage as any, fonts); 248 249 expect(node).toBeDefined(); 250 expect(node.getChildCount()).toBe(1); 251 252 node.free(); 253 }); 254 }); 255 256 describe("draw", () => { 257 test("should call drawRectangle when background color is set", () => { 258 const divElement = div().bg(0xFF0000); 259 const fonts = new Map(); 260 261 // Create layout node first 262 const node = divElement.getLayoutNode(mockPDFPage as any, fonts); 263 264 // Mock the computed dimensions 265 node.getComputedWidth = mock(() => 200); 266 node.getComputedHeight = mock(() => 100); 267 268 divElement.draw(mockPDFPage as any, fonts); 269 270 expect(mockPDFPage.drawRectangle).toHaveBeenCalled(); 271 272 node.free(); 273 }); 274 275 test("should draw children elements", () => { 276 const parent = div(); 277 const child = div().bg(0x00FF00); 278 parent.child(child); 279 280 const fonts = new Map(); 281 282 // Create layout nodes 283 const parentNode = parent.getLayoutNode(mockPDFPage as any, fonts); 284 parentNode.getComputedWidth = mock(() => 300); 285 parentNode.getComputedHeight = mock(() => 200); 286 287 parent.draw(mockPDFPage as any, fonts); 288 289 // Should be called at least once for the child 290 expect(mockPDFPage.drawRectangle).toHaveBeenCalled(); 291 292 parentNode.free(); 293 }); 294 }); 295 296 describe("method chaining", () => { 297 test("should support complex method chaining", () => { 298 const divElement = div() 299 .flex() 300 .flexRow() 301 .itemsCenter() 302 .justifyCenter() 303 .w(200) 304 .h(100) 305 .bg(0x123456) 306 .grow1() 307 .shrink0() 308 .absolute() 309 .overflowHidden(); 310 311 expect(divElement).toBeInstanceOf(Div); 312 }); 313 314 test("should chain with children", () => { 315 const child1 = div().w(50).h(50).bg(0xFF0000); 316 const child2 = div().w(50).h(50).bg(0x00FF00); 317 318 const parent = div() 319 .flex() 320 .flexRow() 321 .child(child1) 322 .child(child2) 323 .w(200) 324 .h(100); 325 326 expect(parent).toBeInstanceOf(Div); 327 expect(parent.children).toHaveLength(2); 328 }); 329 }); 330 });