@tkeron/html-parser 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,587 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { parseHTML } from "../index.js";
3
+ import { NodeType } from "../src/dom-simulator.js";
4
+
5
+ describe("cloneNode functionality", () => {
6
+ describe("cloneNode(true) - deep cloning", () => {
7
+ it("should clone a simple element with text content", () => {
8
+ const html = `<div id="original">Hello World</div>`;
9
+ const doc = parseHTML(html);
10
+ const original = doc.querySelector("#original")!;
11
+
12
+ const cloned = original.cloneNode(true);
13
+
14
+
15
+ expect(cloned).toBeTruthy();
16
+ expect(cloned.nodeName).toBe("DIV");
17
+
18
+
19
+ expect(cloned.getAttribute("id")).toBe("original");
20
+
21
+
22
+ expect(cloned.textContent).toBe("Hello World");
23
+
24
+
25
+ expect(cloned.childNodes.length).toBeGreaterThan(0);
26
+ });
27
+
28
+ it("should clone nested elements with multiple levels", () => {
29
+ const html = `
30
+ <div id="parent">
31
+ <div class="child">
32
+ <span>Nested Text</span>
33
+ </div>
34
+ </div>
35
+ `;
36
+ const doc = parseHTML(html);
37
+ const parent = doc.querySelector("#parent")!;
38
+
39
+ const cloned = parent.cloneNode(true);
40
+
41
+
42
+ expect(cloned.nodeName).toBe("DIV");
43
+ expect(cloned.getAttribute("id")).toBe("parent");
44
+
45
+
46
+ expect(cloned.childNodes.length).toBeGreaterThan(0);
47
+
48
+
49
+ const childDiv = cloned.querySelector(".child");
50
+ expect(childDiv).toBeTruthy();
51
+ expect(childDiv?.nodeName).toBe("DIV");
52
+ expect(childDiv?.getAttribute("class")).toBe("child");
53
+
54
+
55
+ const span = cloned.querySelector("span");
56
+ expect(span).toBeTruthy();
57
+ expect(span?.textContent).toBe("Nested Text");
58
+ });
59
+
60
+ it("should clone element with multiple children", () => {
61
+ const html = `
62
+ <ul id="list">
63
+ <li>Item 1</li>
64
+ <li>Item 2</li>
65
+ <li>Item 3</li>
66
+ </ul>
67
+ `;
68
+ const doc = parseHTML(html);
69
+ const list = doc.querySelector("#list")!;
70
+
71
+ const cloned = list.cloneNode(true);
72
+
73
+
74
+ const items = cloned.querySelectorAll("li");
75
+ expect(items.length).toBe(3);
76
+ expect(items[0]?.textContent).toBe("Item 1");
77
+ expect(items[1]?.textContent).toBe("Item 2");
78
+ expect(items[2]?.textContent).toBe("Item 3");
79
+ });
80
+
81
+ it("should preserve innerHTML after cloning", () => {
82
+ const html = `
83
+ <div id="container">
84
+ <h1>Title</h1>
85
+ <p>Paragraph 1</p>
86
+ <p>Paragraph 2</p>
87
+ </div>
88
+ `;
89
+ const doc = parseHTML(html);
90
+ const container = doc.querySelector("#container")!;
91
+
92
+
93
+ const originalInnerHTML = container.innerHTML;
94
+ expect(originalInnerHTML).toBeTruthy();
95
+ expect(originalInnerHTML.length).toBeGreaterThan(0);
96
+
97
+ const cloned = container.cloneNode(true);
98
+
99
+
100
+ expect(cloned.innerHTML).toBeTruthy();
101
+ expect(cloned.innerHTML.length).toBeGreaterThan(0);
102
+
103
+
104
+ expect(cloned.innerHTML).toContain("<h1>Title</h1>");
105
+ expect(cloned.innerHTML).toContain("<p>Paragraph 1</p>");
106
+ expect(cloned.innerHTML).toContain("<p>Paragraph 2</p>");
107
+ });
108
+
109
+ it("should clone element with mixed content (elements and text nodes)", () => {
110
+ const html = `<div id="mixed">Text before<strong>bold text</strong>Text after</div>`;
111
+ const doc = parseHTML(html);
112
+ const mixed = doc.querySelector("#mixed")!;
113
+
114
+
115
+ const originalChildCount = mixed.childNodes.length;
116
+ expect(originalChildCount).toBeGreaterThan(0);
117
+
118
+ const cloned = mixed.cloneNode(true);
119
+
120
+
121
+ expect(cloned.childNodes.length).toBe(originalChildCount);
122
+
123
+
124
+ expect(cloned.textContent).toBe("Text beforebold textText after");
125
+
126
+
127
+ const strong = cloned.querySelector("strong");
128
+ expect(strong).toBeTruthy();
129
+ expect(strong?.textContent).toBe("bold text");
130
+ });
131
+
132
+ it("should clone all attributes including custom ones", () => {
133
+ const html = `<div id="attrs" class="test" data-value="123" data-custom="abc">Content</div>`;
134
+ const doc = parseHTML(html);
135
+ const element = doc.querySelector("#attrs")!;
136
+
137
+ const cloned = element.cloneNode(true);
138
+
139
+
140
+ expect(cloned.getAttribute("id")).toBe("attrs");
141
+ expect(cloned.getAttribute("class")).toBe("test");
142
+ expect(cloned.getAttribute("data-value")).toBe("123");
143
+ expect(cloned.getAttribute("data-custom")).toBe("abc");
144
+ expect(cloned.textContent).toBe("Content");
145
+ });
146
+
147
+ it("should clone complex structure with different node types", () => {
148
+ const html = `
149
+ <article id="article">
150
+ <h2>Article Title</h2>
151
+ <!-- This is a comment -->
152
+ <p>First paragraph</p>
153
+ <div class="highlight">
154
+ <span>Highlighted</span> text
155
+ </div>
156
+ <p>Last paragraph</p>
157
+ </article>
158
+ `;
159
+ const doc = parseHTML(html);
160
+ const article = doc.querySelector("#article")!;
161
+
162
+ const cloned = article.cloneNode(true);
163
+
164
+
165
+ expect(cloned.nodeName).toBe("ARTICLE");
166
+ expect(cloned.getAttribute("id")).toBe("article");
167
+
168
+
169
+ expect(cloned.querySelector("h2")?.textContent).toBe("Article Title");
170
+
171
+ const paragraphs = cloned.querySelectorAll("p");
172
+ expect(paragraphs.length).toBe(2);
173
+ expect(paragraphs[0]?.textContent).toBe("First paragraph");
174
+ expect(paragraphs[1]?.textContent).toBe("Last paragraph");
175
+
176
+
177
+ const highlight = cloned.querySelector(".highlight");
178
+ expect(highlight).toBeTruthy();
179
+ expect(highlight?.querySelector("span")?.textContent).toBe("Highlighted");
180
+
181
+
182
+ const hasComment = Array.from(cloned.childNodes).some(
183
+ (node: any) => node.nodeType === NodeType.COMMENT_NODE
184
+ );
185
+ expect(hasComment).toBe(true);
186
+ });
187
+
188
+ it("should clone element with empty children", () => {
189
+ const html = `<div id="container"><p></p><span></span></div>`;
190
+ const doc = parseHTML(html);
191
+ const container = doc.querySelector("#container")!;
192
+
193
+ const cloned = container.cloneNode(true);
194
+
195
+ expect(cloned.querySelector("p")).toBeTruthy();
196
+ expect(cloned.querySelector("span")).toBeTruthy();
197
+ });
198
+
199
+ it("should maintain outerHTML structure in cloned node", () => {
200
+ const html = `<section class="main"><h1>Title</h1><p>Text</p></section>`;
201
+ const doc = parseHTML(html);
202
+ const section = doc.querySelector("section")!;
203
+
204
+ const cloned = section.cloneNode(true);
205
+
206
+
207
+ expect(cloned.outerHTML).toBeTruthy();
208
+ expect(cloned.outerHTML).toContain("section");
209
+ expect(cloned.outerHTML).toContain("class=\"main\"");
210
+ expect(cloned.outerHTML).toContain("<h1>Title</h1>");
211
+ expect(cloned.outerHTML).toContain("<p>Text</p>");
212
+ });
213
+ });
214
+
215
+ describe("cloneNode(false) - shallow cloning", () => {
216
+ it("should clone element without children when deep is false", () => {
217
+ const html = `<div id="parent"><p>Child</p></div>`;
218
+ const doc = parseHTML(html);
219
+ const parent = doc.querySelector("#parent")!;
220
+
221
+ const cloned = parent.cloneNode(false);
222
+
223
+
224
+ expect(cloned.nodeName).toBe("DIV");
225
+ expect(cloned.getAttribute("id")).toBe("parent");
226
+ expect(cloned.childNodes.length).toBe(0);
227
+ expect(cloned.querySelector("p")).toBeNull();
228
+ });
229
+
230
+ it("should preserve attributes in shallow clone", () => {
231
+ const html = `<div id="test" class="container" data-value="123"><span>Content</span></div>`;
232
+ const doc = parseHTML(html);
233
+ const element = doc.querySelector("#test")!;
234
+
235
+ const cloned = element.cloneNode(false);
236
+
237
+
238
+ expect(cloned.getAttribute("id")).toBe("test");
239
+ expect(cloned.getAttribute("class")).toBe("container");
240
+ expect(cloned.getAttribute("data-value")).toBe("123");
241
+
242
+
243
+ expect(cloned.childNodes.length).toBe(0);
244
+ expect(cloned.innerHTML).toBe("");
245
+ });
246
+ });
247
+
248
+ describe("cloneNode independence", () => {
249
+ it("cloned node should be independent from original", () => {
250
+ const html = `<div id="original">Original</div>`;
251
+ const doc = parseHTML(html);
252
+ const original = doc.querySelector("#original")!;
253
+
254
+ const cloned = original.cloneNode(true);
255
+
256
+
257
+ cloned.setAttribute("id", "cloned");
258
+ cloned.setAttribute("data-modified", "true");
259
+
260
+ expect(original.getAttribute("id")).toBe("original");
261
+ expect(original.hasAttribute("data-modified")).toBe(false);
262
+ expect(cloned.getAttribute("id")).toBe("cloned");
263
+ expect(cloned.getAttribute("data-modified")).toBe("true");
264
+ });
265
+
266
+ it("modifying cloned children should not affect original", () => {
267
+ const html = `<div id="parent"><p id="child">Text</p></div>`;
268
+ const doc = parseHTML(html);
269
+ const parent = doc.querySelector("#parent")!;
270
+
271
+ const cloned = parent.cloneNode(true);
272
+ const clonedChild = cloned.querySelector("#child");
273
+
274
+ expect(clonedChild).toBeTruthy();
275
+
276
+
277
+ clonedChild?.setAttribute("data-cloned", "yes");
278
+
279
+
280
+ const originalChild = parent.querySelector("#child");
281
+ expect(originalChild?.hasAttribute("data-cloned")).toBe(false);
282
+ });
283
+ });
284
+
285
+ describe("cloneNode edge cases", () => {
286
+ it("should handle cloning of self-closing tags", () => {
287
+ const html = `<div><img src="test.jpg" alt="Test" /><br /></div>`;
288
+ const doc = parseHTML(html);
289
+ const div = doc.querySelector("div")!;
290
+
291
+ const cloned = div.cloneNode(true);
292
+
293
+ const img = cloned.querySelector("img");
294
+ expect(img).toBeTruthy();
295
+ expect(img?.getAttribute("src")).toBe("test.jpg");
296
+ expect(img?.getAttribute("alt")).toBe("Test");
297
+ });
298
+
299
+ it("should clone elements with special characters in content", () => {
300
+ const html = `<div id="special">Text with &amp; &lt; &gt; entities</div>`;
301
+ const doc = parseHTML(html);
302
+ const element = doc.querySelector("#special")!;
303
+
304
+ const cloned = element.cloneNode(true);
305
+
306
+ expect(cloned.textContent).toBeTruthy();
307
+ expect(cloned.textContent.length).toBeGreaterThan(0);
308
+ });
309
+
310
+ it("should handle deeply nested structures", () => {
311
+ const html = `
312
+ <div id="level1">
313
+ <div id="level2">
314
+ <div id="level3">
315
+ <div id="level4">
316
+ <div id="level5">Deep Content</div>
317
+ </div>
318
+ </div>
319
+ </div>
320
+ </div>
321
+ `;
322
+ const doc = parseHTML(html);
323
+ const level1 = doc.querySelector("#level1")!;
324
+
325
+ const cloned = level1.cloneNode(true);
326
+
327
+
328
+ expect(cloned.querySelector("#level2")).toBeTruthy();
329
+ expect(cloned.querySelector("#level3")).toBeTruthy();
330
+ expect(cloned.querySelector("#level4")).toBeTruthy();
331
+ const level5 = cloned.querySelector("#level5");
332
+ expect(level5).toBeTruthy();
333
+ expect(level5?.textContent).toBe("Deep Content");
334
+ });
335
+ });
336
+
337
+ describe("cloneNode internal properties", () => {
338
+ it("should verify _internalInnerHTML is properly set in clone", () => {
339
+ const html = `<div id="container"><p>Paragraph 1</p><p>Paragraph 2</p></div>`;
340
+ const doc = parseHTML(html);
341
+ const container = doc.querySelector("#container")!;
342
+
343
+
344
+ const originalInnerHTML = container.innerHTML;
345
+ expect(originalInnerHTML).toBeTruthy();
346
+
347
+ const cloned = container.cloneNode(true);
348
+
349
+
350
+ const clonedInnerHTML = cloned.innerHTML;
351
+ expect(clonedInnerHTML).toBeTruthy();
352
+ expect(clonedInnerHTML.length).toBeGreaterThan(0);
353
+
354
+
355
+ expect(clonedInnerHTML).toContain("<p>Paragraph 1</p>");
356
+ expect(clonedInnerHTML).toContain("<p>Paragraph 2</p>");
357
+
358
+
359
+ expect(typeof cloned.innerHTML).toBe("string");
360
+ });
361
+
362
+ it("should maintain proper childNodes structure after clone", () => {
363
+ const html = `<div id="parent">Text<span>Span</span>More text</div>`;
364
+ const doc = parseHTML(html);
365
+ const parent = doc.querySelector("#parent")!;
366
+
367
+ const originalChildCount = parent.childNodes.length;
368
+ expect(originalChildCount).toBeGreaterThan(0);
369
+
370
+ const cloned = parent.cloneNode(true);
371
+
372
+
373
+ expect(cloned.childNodes.length).toBe(originalChildCount);
374
+
375
+
376
+ for (let i = 0; i < cloned.childNodes.length; i++) {
377
+ expect(cloned.childNodes[i]).toBeTruthy();
378
+ expect(cloned.childNodes[i].nodeType).toBeDefined();
379
+ }
380
+ });
381
+
382
+ it("should properly initialize children array in cloned element", () => {
383
+ const html = `<div id="container"><span>1</span><span>2</span><span>3</span></div>`;
384
+ const doc = parseHTML(html);
385
+ const container = doc.querySelector("#container")!;
386
+
387
+ const cloned = container.cloneNode(true);
388
+
389
+
390
+ expect(cloned.children).toBeTruthy();
391
+ expect(Array.isArray(cloned.children)).toBe(true);
392
+ expect(cloned.children.length).toBe(3);
393
+
394
+
395
+ for (const child of cloned.children) {
396
+ expect(child.nodeType).toBe(NodeType.ELEMENT_NODE);
397
+ }
398
+ });
399
+
400
+ it("should clone and maintain firstChild and lastChild references", () => {
401
+ const html = `<ul id="list"><li>First</li><li>Middle</li><li>Last</li></ul>`;
402
+ const doc = parseHTML(html);
403
+ const list = doc.querySelector("#list")!;
404
+
405
+ const cloned = list.cloneNode(true);
406
+
407
+
408
+ expect(cloned.firstChild).toBeTruthy();
409
+ expect(cloned.lastChild).toBeTruthy();
410
+
411
+
412
+
413
+ expect(cloned.firstElementChild).toBeTruthy();
414
+ expect(cloned.lastElementChild).toBeTruthy();
415
+
416
+ const firstLi = cloned.firstElementChild;
417
+ const lastLi = cloned.lastElementChild;
418
+
419
+ expect(firstLi?.textContent).toContain("First");
420
+ expect(lastLi?.textContent).toContain("Last");
421
+ });
422
+ });
423
+
424
+ describe("cloneNode with innerHTML manipulation", () => {
425
+ it("should clone element after innerHTML was modified", () => {
426
+ const html = `<div id="dynamic"></div>`;
427
+ const doc = parseHTML(html);
428
+ const dynamic = doc.querySelector("#dynamic")!;
429
+
430
+
431
+ dynamic.innerHTML = "<p>Dynamic content</p><span>More content</span>";
432
+
433
+ const cloned = dynamic.cloneNode(true);
434
+
435
+
436
+ expect(cloned.querySelector("p")).toBeTruthy();
437
+ expect(cloned.querySelector("p")?.textContent).toBe("Dynamic content");
438
+ expect(cloned.querySelector("span")).toBeTruthy();
439
+ expect(cloned.querySelector("span")?.textContent).toBe("More content");
440
+ });
441
+
442
+ it("should clone element and allow innerHTML manipulation on clone", () => {
443
+ const html = `<div id="original"><p>Original</p></div>`;
444
+ const doc = parseHTML(html);
445
+ const original = doc.querySelector("#original")!;
446
+
447
+ const cloned = original.cloneNode(true);
448
+
449
+
450
+ expect(cloned.querySelector("p")?.textContent).toBe("Original");
451
+
452
+
453
+ cloned.innerHTML = "<span>Modified</span>";
454
+
455
+
456
+ expect(original.querySelector("p")?.textContent).toBe("Original");
457
+ expect(original.querySelector("span")).toBeNull();
458
+
459
+
460
+ expect(cloned.querySelector("span")?.textContent).toBe("Modified");
461
+ expect(cloned.querySelector("p")).toBeNull();
462
+ });
463
+ });
464
+
465
+ describe("cloneNode real-world scenarios", () => {
466
+ it("should clone a complete card component", () => {
467
+ const html = `
468
+ <div class="card" data-id="123">
469
+ <div class="card-header">
470
+ <h3 class="card-title">Card Title</h3>
471
+ <button class="close">×</button>
472
+ </div>
473
+ <div class="card-body">
474
+ <p>This is the card content with <strong>bold</strong> text.</p>
475
+ <ul>
476
+ <li>Item 1</li>
477
+ <li>Item 2</li>
478
+ </ul>
479
+ </div>
480
+ <div class="card-footer">
481
+ <button class="btn-primary">Save</button>
482
+ <button class="btn-secondary">Cancel</button>
483
+ </div>
484
+ </div>
485
+ `;
486
+ const doc = parseHTML(html);
487
+ const card = doc.querySelector(".card")!;
488
+
489
+ const cloned = card.cloneNode(true);
490
+
491
+
492
+ expect(cloned.getAttribute("data-id")).toBe("123");
493
+ expect(cloned.querySelector(".card-header")).toBeTruthy();
494
+ expect(cloned.querySelector(".card-body")).toBeTruthy();
495
+ expect(cloned.querySelector(".card-footer")).toBeTruthy();
496
+
497
+
498
+ expect(cloned.querySelector(".card-title")?.textContent).toBe("Card Title");
499
+ expect(cloned.querySelector("strong")?.textContent).toBe("bold");
500
+
501
+ const items = cloned.querySelectorAll("li");
502
+ expect(items.length).toBe(2);
503
+
504
+ const buttons = cloned.querySelectorAll("button");
505
+ expect(buttons.length).toBe(3);
506
+ });
507
+
508
+ it("should clone a form with various input types", () => {
509
+ const html = `
510
+ <form id="user-form">
511
+ <input type="text" name="username" value="john" />
512
+ <input type="email" name="email" value="john@example.com" />
513
+ <textarea name="bio">User bio</textarea>
514
+ <select name="country">
515
+ <option value="us">USA</option>
516
+ <option value="uk" selected>UK</option>
517
+ </select>
518
+ </form>
519
+ `;
520
+ const doc = parseHTML(html);
521
+ const form = doc.querySelector("#user-form")!;
522
+
523
+ const cloned = form.cloneNode(true);
524
+
525
+
526
+ const textInput = cloned.querySelector('[name="username"]');
527
+ expect(textInput).toBeTruthy();
528
+ expect(textInput?.getAttribute("value")).toBe("john");
529
+
530
+ const emailInput = cloned.querySelector('[name="email"]');
531
+ expect(emailInput).toBeTruthy();
532
+ expect(emailInput?.getAttribute("value")).toBe("john@example.com");
533
+
534
+ const textarea = cloned.querySelector("textarea");
535
+ expect(textarea).toBeTruthy();
536
+ expect(textarea?.textContent).toBe("User bio");
537
+
538
+ const select = cloned.querySelector("select");
539
+ expect(select).toBeTruthy();
540
+ const options = select?.querySelectorAll("option");
541
+ expect(options?.length).toBe(2);
542
+ });
543
+
544
+ it("should clone a table structure", () => {
545
+ const html = `
546
+ <table id="data-table">
547
+ <thead>
548
+ <tr>
549
+ <th>Name</th>
550
+ <th>Age</th>
551
+ </tr>
552
+ </thead>
553
+ <tbody>
554
+ <tr>
555
+ <td>John</td>
556
+ <td>30</td>
557
+ </tr>
558
+ <tr>
559
+ <td>Jane</td>
560
+ <td>25</td>
561
+ </tr>
562
+ </tbody>
563
+ </table>
564
+ `;
565
+ const doc = parseHTML(html);
566
+ const table = doc.querySelector("#data-table")!;
567
+
568
+ const cloned = table.cloneNode(true);
569
+
570
+ expect(cloned.querySelector("thead")).toBeTruthy();
571
+ expect(cloned.querySelector("tbody")).toBeTruthy();
572
+
573
+ const headers = cloned.querySelectorAll("th");
574
+ expect(headers.length).toBe(2);
575
+ expect(headers[0]?.textContent).toBe("Name");
576
+ expect(headers[1]?.textContent).toBe("Age");
577
+
578
+ const rows = cloned.querySelectorAll("tbody tr");
579
+ expect(rows.length).toBe(2);
580
+
581
+ const firstRowCells = rows[0]?.querySelectorAll("td");
582
+ expect(firstRowCells?.length).toBe(2);
583
+ expect(firstRowCells?.[0]?.textContent).toBe("John");
584
+ expect(firstRowCells?.[1]?.textContent).toBe("30");
585
+ });
586
+ });
587
+ });
@@ -210,7 +210,7 @@ describe('Custom Elements Support', () => {
210
210
  const ast = parse(tokens);
211
211
 
212
212
  const element = ast.children![0]!;
213
- // nodeName should also be uppercase
213
+
214
214
  if (element.nodeName) {
215
215
  expect(element.nodeName.toUpperCase()).toBe('MY-COMP');
216
216
  }
@@ -382,11 +382,11 @@ describe('Custom Elements Support', () => {
382
382
  const tokens = tokenize(html);
383
383
  const ast = parse(tokens);
384
384
 
385
- // Find first element (skip whitespace text nodes)
385
+
386
386
  const userProfile = ast.children!.find(node => node.type === ASTNodeType.ELEMENT)!;
387
387
  expect(userProfile.tagName).toBe('user-profile');
388
388
 
389
- // Should have proper nesting
389
+
390
390
  expect(userProfile.children).toBeDefined();
391
391
  expect(userProfile.children!.length).toBeGreaterThan(0);
392
392
  });
@@ -412,7 +412,7 @@ describe('Custom Elements Support', () => {
412
412
  const tokens = tokenize(html);
413
413
  const ast = parse(tokens);
414
414
 
415
- // Find first element (skip whitespace text nodes)
415
+
416
416
  const appRoot = ast.children!.find(node => node.type === ASTNodeType.ELEMENT)!;
417
417
  expect(appRoot.tagName).toBe('app-root');
418
418
  });
@@ -471,12 +471,12 @@ describe('Custom Elements Support', () => {
471
471
  test('tokenizer should capture full custom element name', () => {
472
472
  const tokens = tokenize('<my-component-123></my-component-123>');
473
473
 
474
- // Find the opening tag token
474
+
475
475
  const openTag = tokens.find(t => t.type === 'TAG_OPEN');
476
476
  expect(openTag).toBeDefined();
477
477
  expect(openTag!.value).toBe('my-component-123');
478
478
 
479
- // Find the closing tag token
479
+
480
480
  const closeTag = tokens.find(t => t.type === 'TAG_CLOSE');
481
481
  expect(closeTag).toBeDefined();
482
482
  expect(closeTag!.value).toBe('my-component-123');
@@ -642,7 +642,7 @@ describe('Custom Elements Support', () => {
642
642
  const tokens = tokenize(html);
643
643
  const ast = parse(tokens);
644
644
 
645
- // Should have comment, element, comment
645
+
646
646
  const myComp = ast.children!.find(node => node.type === ASTNodeType.ELEMENT)!;
647
647
  expect(myComp.tagName).toBe('my-comp');
648
648
  });
@@ -700,7 +700,7 @@ describe('Custom Elements Support', () => {
700
700
  const tokens = tokenize('<table><tr><td><my-cell>content</my-cell></td></tr></table>');
701
701
  const ast = parse(tokens);
702
702
 
703
- // Find the custom element
703
+
704
704
  const table = ast.children![0]!;
705
705
  expect(table.tagName).toBe('table');
706
706
  });
@@ -233,7 +233,7 @@ describe('Performance Benchmarks', () => {
233
233
  const end = performance.now();
234
234
 
235
235
  expect(ast).toBeDefined();
236
- expect(end - start).toBeLessThan(10); // Should be very fast
236
+ expect(end - start).toBeLessThan(10);
237
237
  });
238
238
 
239
239
  it('should handle medium-sized HTML', () => {
@@ -245,7 +245,7 @@ describe('Performance Benchmarks', () => {
245
245
  const end = performance.now();
246
246
 
247
247
  expect(ast).toBeDefined();
248
- expect(end - start).toBeLessThan(100); // Should still be fast
248
+ expect(end - start).toBeLessThan(100);
249
249
  });
250
250
 
251
251
  it('should handle large HTML documents', () => {
@@ -257,7 +257,7 @@ describe('Performance Benchmarks', () => {
257
257
  const end = performance.now();
258
258
 
259
259
  expect(ast).toBeDefined();
260
- expect(end - start).toBeLessThan(1000); // Should complete within 1 second
260
+ expect(end - start).toBeLessThan(1000);
261
261
  });
262
262
 
263
263
  it('should handle deeply nested HTML', () => {
@@ -276,7 +276,7 @@ describe('Performance Benchmarks', () => {
276
276
  const end = performance.now();
277
277
 
278
278
  expect(ast).toBeDefined();
279
- expect(end - start).toBeLessThan(500); // Should handle deep nesting
279
+ expect(end - start).toBeLessThan(500);
280
280
  });
281
281
  });
282
282
 
@@ -284,14 +284,14 @@ describe('Memory Usage Tests', () => {
284
284
  it('should not leak memory on repeated parsing', () => {
285
285
  const testHtml = '<div><p>Memory test</p></div>';
286
286
 
287
- // Parse the same HTML multiple times
287
+
288
288
  for (let i = 0; i < 1000; i++) {
289
289
  const tokens = tokenize(testHtml);
290
290
  const ast = parse(tokens);
291
291
  expect(ast).toBeDefined();
292
292
  }
293
293
 
294
- // If we get here without crashing, memory is likely managed well
294
+
295
295
  expect(true).toBe(true);
296
296
  });
297
297