Skip to content

Commit 2087e9e

Browse files
committed
fixup pass down variable feature + add missing tests
1 parent 11c2dff commit 2087e9e

10 files changed

+224
-17
lines changed

Diff for: src/CustomTag.php

+7-4
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,22 @@ public function __construct(
2222
public array $attributes,
2323
public string $innerContent = ''
2424
) {
25+
// Overwrite properties with what is given in the attributes
26+
foreach ($attributes as $key => $value) {
27+
if (isset($this->$key)) {
28+
$this->$key = $value;
29+
}
30+
}
2531
}
2632

2733
/**
28-
* Magic Method to return readonly properties
34+
* Magic Method to return properties
2935
*
3036
* @param string $var property name
3137
* @return mixed property
3238
*/
3339
public function __get(string $var): mixed
3440
{
35-
if (isset($this->$var)) {
36-
return $this->$var;
37-
}
3841
if (isset($this->attributes[$var])) {
3942
return $this->attributes[$var];
4043
}

Diff for: src/Error/ConfigException.php

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace LordSimal\CustomHtmlElements\Error;
5+
6+
use Exception;
7+
8+
class ConfigException extends Exception
9+
{
10+
}

Diff for: src/SimpleTag.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class SimpleTag extends CustomTag
1010
*/
1111
public function render(): string
1212
{
13-
return "<{$this->tag}>{$this->innerContent}</{$this->tag}>";
13+
$tag = self::$tag;
14+
15+
return "<$tag>$this->innerContent</$tag>";
1416
}
1517
}

Diff for: src/TagEngine.php

+7-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace LordSimal\CustomHtmlElements;
55

6-
use Exception;
6+
use LordSimal\CustomHtmlElements\Error\ConfigException;
77
use LordSimal\CustomHtmlElements\Error\TagNotFoundException;
88
use Spatie\StructureDiscoverer\Discover;
99

@@ -52,13 +52,10 @@ public function __construct(array $options = [])
5252

5353
if ($this->options['enable_cache']) {
5454
if (empty($this->options['cache_dir'])) {
55-
throw new Exception('Please set a `cache_dir` config');
55+
throw new ConfigException('Please set a `cache_dir` config');
5656
}
57-
if (!is_dir($this->options['cache_dir'])) {
58-
throw new Exception('Cache directory does not exist');
59-
}
60-
if (!is_writable($this->options['cache_dir'])) {
61-
throw new Exception('Cache directory is not writable');
57+
if (!is_dir($this->options['cache_dir']) || !is_writable($this->options['cache_dir'])) {
58+
throw new ConfigException('Cache directory does not exist or is not writable');
6259
}
6360
}
6461
}
@@ -134,7 +131,7 @@ protected function replaceComponent(array $matches): string
134131
protected function parseAttributes(string $attributesString): array
135132
{
136133
// Regex to match attributes (both static and dynamic)
137-
$pattern = '/(\w+)=["\']([^"\']+)["\']/';
134+
$pattern = '/(:?\w+)=["\']([^"\']+)["\']/';
138135
preg_match_all($pattern, $attributesString, $matches, PREG_SET_ORDER);
139136

140137
$attributes = [];
@@ -145,7 +142,8 @@ protected function parseAttributes(string $attributesString): array
145142
// Check if it's a dynamic attribute (starts with ":")
146143
if (str_starts_with($name, ':')) {
147144
$varName = substr($name, 1); // remove the leading ":"
148-
$attributes[$varName] = $this->data[$value] ?? null;
145+
$dataName = substr($value, 1); // remove the leading "$"
146+
$attributes[$varName] = $this->data[$dataName] ?? null;
149147
} else {
150148
// Static attribute
151149
$attributes[$name] = $value;

Diff for: tests/TagEngine/CacheTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace LordSimal\CustomHtmlElements\Test\TagEngine;
55

66
use FilesystemIterator;
7+
use LordSimal\CustomHtmlElements\Error\ConfigException;
78
use LordSimal\CustomHtmlElements\TagEngine;
89
use PHPUnit\Framework\TestCase;
910
use RecursiveDirectoryIterator;
@@ -76,4 +77,31 @@ public function testCacheWillBeFilledAndRead(): void
7677
$result = $this->tagEngine->parse($element);
7778
$this->assertSame($expected, $result);
7879
}
80+
81+
public function testCacheWillThrowIfCacheDirIsEmpty(): void
82+
{
83+
$this->expectException(ConfigException::class);
84+
$this->expectExceptionMessage('Please set a `cache_dir` config');
85+
new TagEngine([
86+
'tag_directories' => [
87+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Tags' . DIRECTORY_SEPARATOR,
88+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR,
89+
],
90+
'enable_cache' => true,
91+
]);
92+
}
93+
94+
public function testCacheWillThrowIfCacheDirIsNotExistent(): void
95+
{
96+
$this->expectException(ConfigException::class);
97+
$this->expectExceptionMessage('Cache directory does not exist or is not writable');
98+
new TagEngine([
99+
'tag_directories' => [
100+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Tags' . DIRECTORY_SEPARATOR,
101+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR,
102+
],
103+
'enable_cache' => true,
104+
'cache_dir' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'non-existent',
105+
]);
106+
}
79107
}

Diff for: tests/TagEngine/CustomTagsTest.php

+79-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected function setUp(): void
3030
*/
3131
public function testTagWithAttribute(): void
3232
{
33-
$element = '<c-youtube src="RLdsCL4RDf8"></c-youtube>';
33+
$element = '<c-youtube src="RLdsCL4RDf8" />';
3434
$result = $this->tagEngine->parse($element);
3535
$expected = <<<HTML
3636
<iframe width="560" height="315"
@@ -131,14 +131,52 @@ public function testTagWithInnerContent(): void
131131
$this->assertSame($expected, $result);
132132
}
133133

134+
/**
135+
* Test inner content is passed down to the tag and can be outputted
136+
*
137+
* @return void
138+
*/
139+
public function testTagWithInnerContentNested(): void
140+
{
141+
$element = <<<HTML
142+
<div class="outer">
143+
<c-github>
144+
Outer Content
145+
<div class="inner">
146+
Inner Content
147+
<c-github>
148+
Inner Inner Content
149+
</c-github>
150+
</div>
151+
</c-github>
152+
</div>
153+
HTML;
154+
$result = $this->tagEngine->parse($element);
155+
$expected = <<<HTML
156+
<div class="outer">
157+
This is a render from a plugin tag
158+
159+
Outer Content
160+
<div class="inner">
161+
Inner Content
162+
<c-github>
163+
Inner Inner Content
164+
165+
</div>
166+
</c-github>
167+
</div>
168+
HTML;
169+
$this->assertSame($expected, $result);
170+
}
171+
134172
/**
135173
* Test tag variant and normal HTML
136174
*
137175
* @return void
138176
*/
139177
public function testTagWithAttributeAndNormalHTML(): void
140178
{
141-
$element = '<c-youtube src="RLdsCL4RDf8"></c-youtube><div>Test</div>';
179+
$element = '<c-youtube src="RLdsCL4RDf8" /><div>Test</div>';
142180
$result = $this->tagEngine->parse($element);
143181
$expected = <<<HTML
144182
<iframe width="560" height="315"
@@ -189,7 +227,7 @@ public function testDisabledTag(): void
189227
*/
190228
public function testOutputBuffered(): void
191229
{
192-
$element = '<c-github></c-github>';
230+
$element = '<c-github />';
193231
ob_start();
194232
echo $element;
195233
$result = $this->tagEngine->parse();
@@ -222,4 +260,42 @@ public function testWithDivWrapped(): void
222260
HTML;
223261
$this->assertSame($expected, $result);
224262
}
263+
264+
/**
265+
* Test default class properties are rendered correctly
266+
*
267+
* @return void
268+
*/
269+
public function testClassProperties(): void
270+
{
271+
$element = '<c-class-properties src="RLdsCL4RDf8" />';
272+
$result = $this->tagEngine->parse($element);
273+
$expected = <<<HTML
274+
<div class="default"></div>
275+
HTML;
276+
$this->assertSame($expected, $result);
277+
}
278+
279+
/**
280+
* Test class properties can be overwritten
281+
*
282+
* @return void
283+
*/
284+
public function testClassPropertiesOverwritten(): void
285+
{
286+
$element = '<c-class-properties src="RLdsCL4RDf8" test="overwritten" />';
287+
$result = $this->tagEngine->parse($element);
288+
$expected = <<<HTML
289+
<div class="overwritten"></div>
290+
HTML;
291+
$this->assertSame($expected, $result);
292+
}
293+
294+
public function testUnknownTag(): void
295+
{
296+
$element = '<c-unknown>Test inner</c-unknown>';
297+
$result = $this->tagEngine->parse($element);
298+
$expected = '<unknown>Test inner</unknown>';
299+
$this->assertSame($expected, $result);
300+
}
225301
}

Diff for: tests/TagEngine/PassVariablesTest.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace LordSimal\CustomHtmlElements\Test\TagEngine;
5+
6+
use LordSimal\CustomHtmlElements\TagEngine;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @see \LordSimal\CustomHtmlElements\TagEngine
11+
*/
12+
class PassVariablesTest extends TestCase
13+
{
14+
protected TagEngine $tagEngine;
15+
16+
protected function setUp(): void
17+
{
18+
$this->tagEngine = new TagEngine([
19+
'tag_directories' => [
20+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Tags' . DIRECTORY_SEPARATOR,
21+
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR,
22+
],
23+
]);
24+
}
25+
26+
/**
27+
* Test a taf with a variable reference
28+
*
29+
* @return void
30+
*/
31+
public function testPassVariableWorks(): void
32+
{
33+
$tagEngine = $this->tagEngine;
34+
$element = '<c-variable :myVar="$tagEngine" />';
35+
$result = $this->tagEngine->parse($element, compact('tagEngine'));
36+
$expected = <<<HTML
37+
The passed down class was: LordSimal\CustomHtmlElements\TagEngine
38+
HTML;
39+
$this->assertSame($expected, $result);
40+
}
41+
}

Diff for: tests/TagRegistryTest.php

+7
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,11 @@ public function testGetUnknownTag(): void
3333
$this->expectExceptionMessage('Tag Unknown was not found.');
3434
TagRegistry::getTag('Unknown');
3535
}
36+
37+
public function testHasTag(): void
38+
{
39+
TagRegistry::register(Button::class);
40+
$this->assertTrue(TagRegistry::hasTag('c-button'));
41+
$this->assertFalse(TagRegistry::hasTag('Unknown'));
42+
}
3643
}

Diff for: tests/Tags/ClassProperties.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace LordSimal\CustomHtmlElements\Test\Tags;
5+
6+
use LordSimal\CustomHtmlElements\CustomTag;
7+
8+
/**
9+
* @property string $src
10+
*/
11+
class ClassProperties extends CustomTag
12+
{
13+
public static string $tag = 'c-class-properties';
14+
15+
public string $test = 'default';
16+
17+
public function render(): string
18+
{
19+
return <<< HTML
20+
<div class="$this->test"></div>
21+
HTML;
22+
}
23+
}

Diff for: tests/Tags/Variable.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace LordSimal\CustomHtmlElements\Test\Tags;
5+
6+
use LordSimal\CustomHtmlElements\CustomTag;
7+
8+
/**
9+
* @property string $src
10+
*/
11+
class Variable extends CustomTag
12+
{
13+
public static string $tag = 'c-variable';
14+
15+
public function render(): string
16+
{
17+
return 'The passed down class was: ' . get_class($this->myVar);
18+
}
19+
}

0 commit comments

Comments
 (0)