Skip to content

Commit f1db270

Browse files
committed
Simplify partial testing
Also added regression test for `@data` variables in partial block context.
1 parent 89f681b commit f1db270

3 files changed

Lines changed: 137 additions & 195 deletions

File tree

tests/ErrorTest.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,32 @@
1010

1111
/**
1212
* @phpstan-type RenderTest array{
13-
* template: string, options?: Options, helpers?: array<string, \Closure>, data?: array<mixed>, expected: string,
13+
* template: string, expected: string, data?: mixed, options?: Options,
14+
* helpers?: array<string, \Closure>, partials?: array<string, string>,
1415
* }
1516
* @phpstan-type ErrorCase array{template: string, options?: Options, expected: string}
1617
*/
1718
class ErrorTest extends TestCase
1819
{
1920
/**
2021
* @param array<string, \Closure> $helpers
21-
* @param array<mixed> $data
22+
* @param array<string, string> $partials
2223
*/
2324
#[DataProvider("renderErrorProvider")]
2425
public function testRenderingException(
2526
string $template,
2627
string $expected,
2728
?Options $options = null,
2829
array $helpers = [],
29-
array $data = [],
30+
array $partials = [],
31+
mixed $data = null,
3032
): void {
31-
$php = Handlebars::precompile($template, $options ?? new Options());
33+
$options ??= new Options();
34+
$php = Handlebars::precompile($template, $options);
3235
$renderer = Handlebars::template($php);
3336
try {
34-
$result = $renderer($data, ['helpers' => $helpers]);
37+
$partials = array_map(fn($p) => Handlebars::compile($p, $options), $partials);
38+
$result = $renderer($data, ['helpers' => $helpers, 'partials' => $partials]);
3539
$this->fail("Expected exception: {$expected}\nRendered: $result\nPHP code:\n$php");
3640
} catch (\Exception $e) {
3741
$this->assertSame($expected, $e->getMessage(), "PHP code:\n$php");
@@ -50,12 +54,10 @@ public static function renderErrorProvider(): array
5054
],
5155
'partial-block not found in nested partials' => [
5256
'template' => "{{#> testPartial}}\n {{#> innerPartial}}\n {{> @partial-block}}\n {{/innerPartial}}\n{{/testPartial}}",
53-
'options' => new Options(
54-
partials: [
55-
'testPartial' => 'testPartial => {{> @partial-block}} <=',
56-
'innerPartial' => 'innerPartial -> {{> @partial-block}} <-',
57-
],
58-
),
57+
'partials' => [
58+
'testPartial' => 'testPartial => {{> @partial-block}} <=',
59+
'innerPartial' => 'innerPartial -> {{> @partial-block}} <-',
60+
],
5961
'expected' => "The partial @partial-block could not be found",
6062
],
6163
'partial-block not found at top level' => [
@@ -95,6 +97,7 @@ public static function renderErrorProvider(): array
9597
'strict mode null property access in if' => [
9698
'template' => '{{#if foo.bar}}bad{{else}}OK{{/if}}',
9799
'options' => new Options(strict: true),
100+
'data' => [],
98101
'expected' => 'Cannot access property "bar" on null',
99102
],
100103
'strict mode missing variable' => [

tests/HandlebarsSpecTest.php

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,49 +54,41 @@ public function testSpecs(array $spec): void
5454
}
5555
self::addDataHelpers($spec);
5656

57-
// setup helpers
57+
$options = new Options(
58+
compat: $spec['compileOptions']['compat'] ?? false,
59+
knownHelpers: $spec['compileOptions']['knownHelpers'] ?? [],
60+
knownHelpersOnly: $spec['compileOptions']['knownHelpersOnly'] ?? false,
61+
strict: $spec['compileOptions']['strict'] ?? false,
62+
assumeObjects: $spec['compileOptions']['assumeObjects'] ?? false,
63+
preventIndent: $spec['compileOptions']['preventIndent'] ?? false,
64+
ignoreStandalone: $spec['compileOptions']['ignoreStandalone'] ?? false,
65+
explicitPartialContext: $spec['compileOptions']['explicitPartialContext'] ?? false,
66+
);
67+
5868
$helpers = [];
59-
$helpersList = '[';
69+
$helpersList = [];
70+
$partials = [];
71+
6072
foreach ($spec['helpers'] as $name => $func) {
6173
if (!isset($func['php'])) {
6274
continue;
6375
}
6476
$helper = self::patchHelperCode($func['php']);
65-
$helpersList .= "\n '$name' => $helper,\n";
77+
$helpersList[$name] = $helper;
6678
eval('$helpers[\'' . $name . '\'] = ' . $helper . ';');
6779
}
68-
$helpersList .= ']';
6980

70-
// Convert "!code" partials (callable PHP strings) into actual callables.
71-
$partials = [];
72-
$stringPartials = [];
7381
foreach ($spec['partials'] as $name => $partial) {
82+
// Convert "!code" partials (callable PHP strings) into actual callables.
7483
if (is_array($partial) && isset($partial['!code'], $partial['php'])) {
7584
$partials[$name] = eval('return ' . $partial['php'] . ';');
7685
} else {
77-
$stringPartials[$name] = $partial;
86+
$partials[$name] = Handlebars::compile($partial, $options);
7887
}
7988
}
8089

8190
try {
82-
$knownHelpersOnly = $spec['compileOptions']['knownHelpersOnly'] ?? false;
83-
$strict = $spec['compileOptions']['strict'] ?? false;
84-
$assumeObjects = $spec['compileOptions']['assumeObjects'] ?? false;
85-
$preventIndent = $spec['compileOptions']['preventIndent'] ?? false;
86-
$ignoreStandalone = $spec['compileOptions']['ignoreStandalone'] ?? false;
87-
$explicitPartialContext = $spec['compileOptions']['explicitPartialContext'] ?? false;
88-
89-
$php = Handlebars::precompile($spec['template'], new Options(
90-
compat: $spec['compileOptions']['compat'] ?? false,
91-
knownHelpers: $spec['compileOptions']['knownHelpers'] ?? [],
92-
knownHelpersOnly: $knownHelpersOnly,
93-
strict: $strict,
94-
assumeObjects: $assumeObjects,
95-
preventIndent: $preventIndent,
96-
ignoreStandalone: $ignoreStandalone,
97-
explicitPartialContext: $explicitPartialContext,
98-
partials: $stringPartials,
99-
));
91+
$php = Handlebars::precompile($spec['template'], $options);
10092
} catch (\Exception $e) {
10193
if ($spec['exception']) {
10294
$this->expectNotToPerformAssertions();
@@ -127,20 +119,27 @@ public function testSpecs(array $spec): void
127119
$this->expectNotToPerformAssertions();
128120
return;
129121
}
130-
$this->fail("Rendering error: {$e->getMessage()}\n\n" . self::getSpecDetails($php, $helpersList));
122+
$this->fail("Rendering error: {$e->getMessage()}\n\n" . self::getSpecDetails($php, $helpersList, $spec['partials']));
131123
}
132124

133125
if ($spec['exception']) {
134126
$details = $spec['exception'] === true ? '.' : ": {$spec['exception']}\n";
135-
$this->fail("Expected exception{$details}\nResult: $result\n\n" . self::getSpecDetails($php, $helpersList));
127+
$this->fail("Expected exception{$details}\nResult: $result\n\n" . self::getSpecDetails($php, $helpersList, $spec['partials']));
136128
}
137129

138-
$this->assertSame($spec['expected'], $result, self::getSpecDetails($php, $helpersList));
130+
$this->assertSame($spec['expected'], $result, self::getSpecDetails($php, $helpersList, $spec['partials']));
139131
}
140132

141-
private static function getSpecDetails(string $code, string $helpers): string
133+
/**
134+
* @param array<mixed> $helpers
135+
* @param array<mixed> $partials
136+
*/
137+
private static function getSpecDetails(string $code, array $helpers, array $partials): string
142138
{
143-
return "Helpers: $helpers\nPHP code:\n$code";
139+
$flags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT;
140+
$partials = json_encode($partials, $flags);
141+
$helpers = json_encode($helpers, $flags);
142+
return "Partials: $partials\nHelpers: $helpers\nPHP code:\n$code";
144143
}
145144

146145
/**

0 commit comments

Comments
 (0)