Skip to content

Commit 8a214d8

Browse files
committed
feat: improve component html formatting, allow ints/floats as attribute values
1 parent 42d14db commit 8a214d8

6 files changed

Lines changed: 313 additions & 337 deletions

File tree

clover.xml

Lines changed: 236 additions & 244 deletions
Large diffs are not rendered by default.

src/TemplateGenerator/HTMLGenerator.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,7 @@ public function renderDocument(HTMLDocumentDelegatorInterface $document): string
6868
return '';
6969
}
7070

71-
$body = $doc->getElementsByTagName('body')
72-
->item(0);
73-
$container = $body ?? $doc->documentElement;
74-
$html = '';
75-
76-
foreach ($container->childNodes as $child) {
77-
if ($body === null && $child instanceof Element && strtolower($child->tagName) === 'head') {
78-
continue;
79-
}
80-
81-
$html .= $doc->saveHTML($child);
82-
}
83-
84-
return $this->formatHtml($html);
71+
return (string) $doc->saveHTML();
8572
}
8673

8774
private function formatHtml(string $html): string

tests/TemplateGenerator/BladeGeneratorTest.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040

4141
test('can render documents', function () {
4242
expect($this->generator->canRenderDocuments())
43-
->toBeFalse();
43+
->toBeTrue();
4444
});
4545

4646
test('is templated', function () {
4747
expect($this->generator->isTemplated())
48-
->toBeFalse();
48+
->toBeTrue();
4949
});
5050

5151
test('render element', function () {
@@ -60,7 +60,7 @@
6060
expect($result)
6161
->toContain('href');
6262
expect($result)
63-
->toContain('@section');
63+
->toContain('@php');
6464
});
6565

6666
test('render document', function () {
@@ -69,7 +69,9 @@
6969
$document->appendChild($element);
7070
$result = $this->generator->render($document);
7171
expect($result)
72-
->toBeNull();
72+
->toBeString();
73+
expect($result)
74+
->toContain('This file is auto-generated');
7375
});
7476

7577
test('render invalid', function () {
@@ -150,7 +152,7 @@
150152
expect($result)
151153
->toContain('/>');
152154
expect($result)
153-
->toContain('@section');
155+
->toContain('@php');
154156
});
155157

156158
test('render composed element with empty parentOf', function () {

tests/TemplateGenerator/HTMLGeneratorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
$body->appendChild($element);
6262

6363
expect($this->generator->render($document))
64-
->toBe('<div id="component"></div>');
64+
->toBe('<html><body><div id="component"></div></body></html>');
6565
});
6666

6767
test('render document with html wrapper only', function () {
@@ -70,7 +70,7 @@
7070
);
7171

7272
expect($this->generator->render($document))
73-
->toBe('<div id="component"></div>');
73+
->toBe('<!DOCTYPE html><html><head></head><body><div id="component"></div></body></html>');
7474
});
7575

7676
test('render invalid', function () {

tests/TemplateGenerator/TwigComponentsGeneratorTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@
4141

4242
test('can render documents', function () {
4343
expect($this->generator->canRenderDocuments())
44-
->toBeFalse();
44+
->toBeTrue();
4545
});
4646

4747
test('is templated', function () {
4848
expect($this->generator->isTemplated())
49-
->toBeFalse();
49+
->toBeTrue();
5050
});
5151

5252
test('render element', function () {
@@ -70,7 +70,9 @@
7070
$document->appendChild($element);
7171
$result = $this->generator->render($document);
7272
expect($result)
73-
->toBeNull();
73+
->toBeString();
74+
expect($result)
75+
->toContain('Strict mode: component');
7476
});
7577

7678
test('render invalid', function () {

tests/TemplateGenerator/TwigGeneratorTest.php

Lines changed: 62 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838

3939
test('can render documents', function () {
4040
expect($this->generator->canRenderDocuments())
41-
->toBeFalse();
41+
->toBeTrue();
4242
});
4343

4444
test('is templated', function () {
4545
expect($this->generator->isTemplated())
46-
->toBeFalse();
46+
->toBeTrue();
4747
});
4848

4949
test('render element', function () {
@@ -121,7 +121,9 @@
121121
$document->appendChild($element);
122122
$result = $this->generator->render($document);
123123
expect($result)
124-
->toBeNull();
124+
->toBeString();
125+
expect($result)
126+
->toContain('This file is auto-generated');
125127
});
126128

127129
test('render invalid', function () {
@@ -261,72 +263,79 @@
261263
}
262264
});
263265

264-
test('render head', function () {
266+
test('set document render mode normalizes and validates values', function () {
265267
$reflection = new ReflectionClass($this->generator);
266-
$method = $reflection->getMethod('renderHead');
267-
$method->setAccessible(true);
268+
$property = $reflection->getProperty('documentRenderMode');
269+
$property->setAccessible(true);
268270

269-
$document = HTMLDocumentDelegator::createEmpty();
270-
$result = $method->invoke($this->generator, $document);
271+
$this->generator->setDocumentRenderMode(' include ');
272+
expect($property->getValue($this->generator))
273+
->toBe('include');
271274

272-
// Since getDocumentMetadata returns empty array, renderHead should return null
273-
expect($result)
274-
->toBeNull();
275+
$this->generator->setDocumentRenderMode('unsupported');
276+
expect($property->getValue($this->generator))
277+
->toBe('raw');
275278
});
276279

277-
test('render body', function () {
278-
$reflection = new ReflectionClass($this->generator);
279-
$method = $reflection->getMethod('renderBody');
280-
$method->setAccessible(true);
280+
test('render document include mode uses include/embed templates', function () {
281+
$this->generator->setDocumentRenderMode('include');
281282

282283
$document = HTMLDocumentDelegator::createEmpty();
283284
$body = Body::create($document);
285+
$anchor = Anchor::create($document);
286+
$anchor->setHref('https://example.com');
287+
$anchor->append('Example');
288+
$body->appendChild($anchor);
284289
$document->appendChild($body);
285290

286-
$result = $method->invoke($this->generator, $document);
291+
$result = $this->generator->render($document);
287292

288293
expect($result)
289294
->toBeString();
290295
expect($result)
291-
->toContain('{% block body %}');
296+
->toContain('Strict mode: include');
297+
expect($result)
298+
->toContain("{% embed 'inline/a/a.twig'");
292299
});
293300

294-
test('get document metadata', function () {
301+
test('extract twig expression helper', function () {
295302
$reflection = new ReflectionClass($this->generator);
296-
$method = $reflection->getMethod('getDocumentMetadata');
303+
$method = $reflection->getMethod('extractTwigExpression');
297304
$method->setAccessible(true);
298305

299-
$document = HTMLDocumentDelegator::createEmpty();
300-
$result = $method->invoke($this->generator, $document);
301-
302-
expect($result)
303-
->toBeArray();
304-
expect($result)
305-
->toBeEmpty();
306+
expect($method->invoke($this->generator, '{{ user.name }}'))
307+
->toBe('user.name');
308+
expect($method->invoke($this->generator, 'plain-text'))
309+
->toBeNull();
306310
});
307311

308-
test('render twig template', function () {
312+
test('build twig map string helper', function () {
309313
$reflection = new ReflectionClass($this->generator);
310-
$method = $reflection->getMethod('renderTwigTemplate');
314+
$method = $reflection->getMethod('buildTwigMapString');
311315
$method->setAccessible(true);
312316

313-
$result = $method->invoke($this->generator, 'head', [
314-
'test' => 'data',
317+
$result = $method->invoke($this->generator, [
318+
'id' => 'main',
319+
'class' => 'hero',
320+
'content' => ['__twig_expr' => 'user.name'],
315321
]);
316322

317-
// Since loadTwigTemplate returns null, renderTwigTemplate should return null
318323
expect($result)
319-
->toBeNull();
324+
->toContain('id:');
325+
expect($result)
326+
->toContain('class:');
327+
expect($result)
328+
->toContain('content: user.name');
320329
});
321330

322-
test('load twig template', function () {
331+
test('resolve twig template path helper', function () {
323332
$reflection = new ReflectionClass($this->generator);
324-
$method = $reflection->getMethod('loadTwigTemplate');
333+
$method = $reflection->getMethod('resolveTwigTemplatePath');
325334
$method->setAccessible(true);
326335

327-
$result = $method->invoke($this->generator, 'head');
328-
329-
expect($result)
336+
expect($method->invoke($this->generator, 'a'))
337+
->toBe('inline/a/a.twig');
338+
expect($method->invoke($this->generator, 'not-a-real-tag'))
330339
->toBeNull();
331340
});
332341

@@ -344,46 +353,30 @@
344353
expect($result)
345354
->toBeString();
346355
expect($result)
347-
->toContain('<?xml version="1.0" encoding="UTF-8"?>');
348-
expect($result)
349-
->toContain('<!DOCTYPE html>');
350-
expect($result)
351-
->toContain('<html lang="en">');
352-
expect($result)
353-
->toContain('<body>');
354-
expect($result)
355-
->toContain('</body>');
356+
->toContain('This file is auto-generated');
356357
expect($result)
357-
->toContain('</html>');
358+
->toContain('Component: component');
358359
});
359360

360-
test('render head with metadata', function () {
361-
$reflection = new ReflectionClass($this->generator);
362-
363-
// Mock getDocumentMetadata to return data
364-
$metadataMethod = $reflection->getMethod('getDocumentMetadata');
365-
$metadataMethod->setAccessible(true);
361+
test('render document use mode falls back to embed strategy', function () {
362+
$this->generator->setDocumentRenderMode('use');
366363

367-
// Create a document with a title
368364
$document = HTMLDocumentDelegator::createEmpty();
369-
$title = $document->createElement('title');
370-
$title->textContent = 'Test Document';
371-
$head = $document->createElement('head');
372-
$head->appendChild($title);
373-
$document->appendChild($head);
374-
375-
// Test getDocumentMetadata
376-
$metadata = $metadataMethod->invoke($this->generator, $document);
377-
expect($metadata)
378-
->toBeArray();
365+
$body = Body::create($document);
366+
$anchor = Anchor::create($document);
367+
$anchor->setHref('https://example.com');
368+
$anchor->append('Go');
369+
$body->appendChild($anchor);
370+
$document->appendChild($body);
379371

380-
// Test renderHead - it will still return null since renderTwigTemplate returns null
381-
$headMethod = $reflection->getMethod('renderHead');
382-
$headMethod->setAccessible(true);
372+
$result = $this->generator->render($document);
383373

384-
$result = $headMethod->invoke($this->generator, $document);
385374
expect($result)
386-
->toBeNull();
375+
->toBeString();
376+
expect($result)
377+
->toContain('Strict mode: use');
378+
expect($result)
379+
->toContain('{% embed');
387380
});
388381

389382
test('camel to kebab', function () {

0 commit comments

Comments
 (0)