text.test.ts
1 import { StandardFonts, TextAlignment } from "@cantoo/pdf-lib"; 2 import { describe, expect, mock, test } from "bun:test"; 3 import { Text, text } from "~/elements/text"; 4 import { font } from "~/utils/fonts"; 5 6 // Mock PDFPage and PDFFont for testing 7 const mockPDFFont = { 8 heightAtSize: mock((size: number) => size), 9 widthOfTextAtSize: mock((t: string, size: number) => t.length * size * 0.6) 10 }; 11 12 const mockPDFPage = { 13 doc: { 14 defaultWordBreaks: /\s/g 15 }, 16 drawText: mock(() => {}), 17 getFont: mock(() => [mockPDFFont]), 18 getHeight: mock(() => 800) 19 }; 20 21 describe("Text", () => { 22 describe("constructor", () => { 23 test("should create Text instance with value", () => { 24 const textElement = new Text("Hello World"); 25 expect(textElement).toBeInstanceOf(Text); 26 }); 27 }); 28 29 describe("text helper function", () => { 30 test("should create Text instance", () => { 31 const textElement = text("Hello World"); 32 expect(textElement).toBeInstanceOf(Text); 33 }); 34 35 test("should work with empty string", () => { 36 const textElement = text(""); 37 expect(textElement).toBeInstanceOf(Text); 38 }); 39 40 test("should work with multiline text", () => { 41 const textElement = text("Line 1\nLine 2\nLine 3"); 42 expect(textElement).toBeInstanceOf(Text); 43 }); 44 }); 45 46 describe("font method", () => { 47 test("should set font and return instance for chaining", () => { 48 const memoryFont = font(StandardFonts.Helvetica); 49 const textElement = text("Hello"); 50 const result = textElement.font(memoryFont); 51 52 expect(result).toBe(textElement); 53 }); 54 }); 55 56 describe("text alignment methods", () => { 57 test("should set text center alignment", () => { 58 const textElement = text("Hello"); 59 const result = textElement.textCenter(); 60 61 expect(result).toBe(textElement); 62 }); 63 64 test("should set text left alignment", () => { 65 const textElement = text("Hello"); 66 const result = textElement.textLeft(); 67 68 expect(result).toBe(textElement); 69 }); 70 71 test("should set text right alignment", () => { 72 const textElement = text("Hello"); 73 const result = textElement.textRight(); 74 75 expect(result).toBe(textElement); 76 }); 77 78 test("should chain alignment methods", () => { 79 const textElement = text("Hello") 80 .textCenter() 81 .textLeft() 82 .textRight(); 83 84 expect(textElement).toBeInstanceOf(Text); 85 }); 86 }); 87 88 describe("leading methods", () => { 89 test("should set line height with leading method", () => { 90 const textElement = text("Hello"); 91 const result = textElement.leading(1.5); 92 93 expect(result).toBe(textElement); 94 }); 95 96 test("should set line height to 1 with leadingNone", () => { 97 const textElement = text("Hello"); 98 const result = textElement.leadingNone(); 99 100 expect(result).toBe(textElement); 101 }); 102 103 test("should chain leading methods", () => { 104 const textElement = text("Hello") 105 .leading(2.0) 106 .leadingNone() 107 .leading(1.2); 108 109 expect(textElement).toBeInstanceOf(Text); 110 }); 111 }); 112 113 describe("getLayoutNode", () => { 114 test("should create and return layout node", () => { 115 const textElement = text("Hello World"); 116 const fonts = new Map(); 117 118 const node = textElement.getLayoutNode(mockPDFPage as any, fonts); 119 120 expect(node).toBeDefined(); 121 expect(typeof node.free).toBe("function"); 122 123 node.free(); 124 }); 125 126 test("should return same node on subsequent calls", () => { 127 const textElement = text("Hello World"); 128 const fonts = new Map(); 129 130 const node1 = textElement.getLayoutNode(mockPDFPage as any, fonts); 131 const node2 = textElement.getLayoutNode(mockPDFPage as any, fonts); 132 133 expect(node1).toBe(node2); 134 135 node1.free(); 136 }); 137 138 test("should handle empty text", () => { 139 const textElement = text(""); 140 const fonts = new Map(); 141 142 const node = textElement.getLayoutNode(mockPDFPage as any, fonts); 143 144 expect(node).toBeDefined(); 145 146 node.free(); 147 }); 148 }); 149 150 describe("draw", () => { 151 test("should call drawText on page", () => { 152 const textElement = text("Hello World"); 153 const fonts = new Map(); 154 155 // Create layout node first 156 const node = textElement.getLayoutNode(mockPDFPage as any, fonts); 157 158 // Mock the computed dimensions 159 node.getComputedWidth = mock(() => 200); 160 node.getComputedHeight = mock(() => 50); 161 162 textElement.draw(mockPDFPage as any, fonts); 163 164 expect(mockPDFPage.drawText).toHaveBeenCalled(); 165 166 node.free(); 167 }); 168 }); 169 170 describe("method chaining", () => { 171 test("should support complete method chaining", () => { 172 const memoryFont = font(StandardFonts.Helvetica); 173 174 const textElement = text("Hello World") 175 .font(memoryFont) 176 .textCenter() 177 .leading(1.5) 178 .leadingNone() 179 .textLeft() 180 .textRight(); 181 182 expect(textElement).toBeInstanceOf(Text); 183 }); 184 }); 185 });