mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-05 17:51:40 +09:00
Add loop variable and dump directive; reorganize template v2 unit tests
This commit is contained in:
parent
fe804163bf
commit
a6afa3a61d
7 changed files with 394 additions and 41 deletions
|
|
@ -27,6 +27,8 @@ class Template
|
|||
public $cache_enabled = true;
|
||||
public $ob_level = 0;
|
||||
public $vars;
|
||||
protected $_fragments = [];
|
||||
protected static $_loopvars = [];
|
||||
|
||||
/**
|
||||
* Static properties
|
||||
|
|
@ -388,4 +390,85 @@ class Template
|
|||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a fragment of the executed output.
|
||||
*
|
||||
* @param string $name
|
||||
* @return ?string
|
||||
*/
|
||||
public function getFragment(string $name): ?string
|
||||
{
|
||||
if (isset($this->_fragments[$name]))
|
||||
{
|
||||
return $this->_fragments[$name];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* =================== HELPER FUNCTIONS FOR TEMPLATE v2 ===================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize v2 loop variable.
|
||||
*
|
||||
* @param string $stack_id
|
||||
* @param array|Traversable &$array
|
||||
* @return object
|
||||
*/
|
||||
protected function _v2_initLoopVar(string $stack_id, &$array): object
|
||||
{
|
||||
// Create the data structure.
|
||||
$loop = new \stdClass;
|
||||
$loop->index = 0;
|
||||
$loop->iteration = 1;
|
||||
$loop->count = is_countable($array) ? count($array) : countobj($array);
|
||||
$loop->remaining = $loop->count - 1;
|
||||
$loop->first = true;
|
||||
$loop->last = ($loop->count === 1);
|
||||
$loop->even = false;
|
||||
$loop->odd = true;
|
||||
$loop->depth = count(self::$_loopvars) + 1;
|
||||
$loop->parent = count(self::$_loopvars) ? end(self::$_loopvars) : null;
|
||||
|
||||
// Append to stack and return.
|
||||
return self::$_loopvars[$stack_id] = $loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment v2 loop variable.
|
||||
*
|
||||
* @param object $loopvar
|
||||
* @return void
|
||||
*/
|
||||
protected function _v2_incrLoopVar(object $loop): void
|
||||
{
|
||||
// Update properties.
|
||||
$loop->index++;
|
||||
$loop->iteration++;
|
||||
$loop->remaining--;
|
||||
$loop->first = ($loop->count === 1);
|
||||
$loop->last = ($loop->iteration === $loop->count);
|
||||
$loop->even = ($loop->iteration % 2 === 0);
|
||||
$loop->odd = !$loop->even;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove v2 loop variable.
|
||||
*
|
||||
* @param object $loopvar
|
||||
* @return void
|
||||
*/
|
||||
protected function _v2_removeLoopVar(object $loop): void
|
||||
{
|
||||
// Remove from stack.
|
||||
if ($loop === end(self::$_loopvars))
|
||||
{
|
||||
array_pop(self::$_loopvars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ class TemplateParser_v2
|
|||
'while' => ['while (%s):', 'endwhile;'],
|
||||
'switch' => ['switch (%s):', 'endswitch;'],
|
||||
'foreach' => [
|
||||
'$__tmp_%uniq = %array ?? []; foreach ($__tmp_%uniq as %remainder):',
|
||||
'endforeach;',
|
||||
'$__tmp_%uniq = %array ?? []; $__loop_%uniq = $this->_v2_initLoopVar("%uniq", $__tmp_%uniq); foreach ($__tmp_%uniq as %remainder):',
|
||||
'$this->_v2_incrLoopVar($__loop_%uniq); endforeach; $this->_v2_removeLoopVar($__loop_%uniq); unset($__loop_%uniq);',
|
||||
],
|
||||
'forelse' => [
|
||||
'$__tmp_%uniq = %array ?? []; if($__tmp_%uniq): foreach ($__tmp_%uniq as %remainder):',
|
||||
'endforeach; else:',
|
||||
'$__tmp_%uniq = %array ?? []; if($__tmp_%uniq): $__loop_%uniq = $this->_v2_initLoopVar("%uniq", $__tmp_%uniq); foreach ($__tmp_%uniq as %remainder):',
|
||||
'$this->_v2_incrLoopVar($__loop_%uniq); endforeach; $this->_v2_removeLoopVar($__loop_%uniq); unset($__loop_%uniq); else:',
|
||||
'endif;',
|
||||
],
|
||||
'once' => [
|
||||
|
|
@ -670,7 +670,9 @@ class TemplateParser_v2
|
|||
// Handle intermediate directives first.
|
||||
if ($directive === 'empty' && !$args && !$stack && end($this->_stack)['directive'] === 'forelse')
|
||||
{
|
||||
$stack = end($this->_stack);
|
||||
$code = self::$_loopdef['forelse'][1];
|
||||
$code = strtr($code, ['%uniq' => $stack['uniq'], '%array' => $stack['array'], '%remainder' => $stack['remainder']]);
|
||||
}
|
||||
|
||||
// Single directives.
|
||||
|
|
@ -807,9 +809,9 @@ class TemplateParser_v2
|
|||
return '<input type="hidden" name="_rx_csrf_token" value="<?php echo \Rhymix\Framework\Session::getGenericToken(); ?>" />';
|
||||
}, $content);
|
||||
|
||||
// Insert JSON and lang codes.
|
||||
// Insert JSON, lang codes, and dumps.
|
||||
$parentheses = self::_getRegexpForParentheses(2);
|
||||
$content = preg_replace_callback('#(?<!@)@(json|lang)\x20?('. $parentheses . ')#', function($match) {
|
||||
$content = preg_replace_callback('#(?<!@)@(json|lang|dump)\x20?('. $parentheses . ')#', function($match) {
|
||||
$args = self::_convertVariableScope(substr($match[2], 1, strlen($match[2]) - 2));
|
||||
if ($match[1] === 'json')
|
||||
{
|
||||
|
|
@ -817,10 +819,18 @@ class TemplateParser_v2
|
|||
'json_encode(%s, \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES | \JSON_HEX_TAG | \JSON_HEX_QUOT) : ' .
|
||||
'htmlspecialchars(json_encode(%s, \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES | \JSON_HEX_TAG | \JSON_HEX_QUOT), \ENT_QUOTES, \'UTF-8\', false); ?>', $args, $args);
|
||||
}
|
||||
else
|
||||
elseif ($match[1] === 'lang')
|
||||
{
|
||||
return sprintf('<?php echo $this->config->context === \'JS\' ? escape_js(lang(%s)) : lang(%s); ?>', $args, $args);
|
||||
}
|
||||
elseif ($match[1] === 'dump')
|
||||
{
|
||||
return sprintf('<?php ob_start(); var_dump(%s); \$__dump = ob_get_clean(); echo rtrim(\$__dump); ?>', $args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $match[0];
|
||||
}
|
||||
}, $content);
|
||||
|
||||
return $content;
|
||||
|
|
@ -1098,10 +1108,14 @@ class TemplateParser_v2
|
|||
|
||||
// Replace all other variables with Context attributes.
|
||||
$content = preg_replace_callback('#(?<!::|\\\\|\$__Context->|\')\$([a-zA-Z_][a-zA-Z0-9_]*)#', function($match) {
|
||||
if (preg_match('/^(?:GLOBALS|_SERVER|_COOKIE|_ENV|_GET|_POST|_REQUEST|_SESSION|__Context|this|loop)$/', $match[1]))
|
||||
if (preg_match('/^(?:GLOBALS|_SERVER|_COOKIE|_ENV|_GET|_POST|_REQUEST|_SESSION|__Context|this)$/', $match[1]))
|
||||
{
|
||||
return '$' . $match[1];
|
||||
}
|
||||
elseif ($match[1] === 'loop')
|
||||
{
|
||||
return 'end(self::$_loopvars)';
|
||||
}
|
||||
else
|
||||
{
|
||||
return '$__Context->' . $match[1];
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@
|
|||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php $__tmp_8eaec5a37bc467 = Context::get('bar') ?? []; if($__tmp_8eaec5a37bc467): foreach ($__tmp_8eaec5a37bc467 as $__Context->k => $__Context->val): ?>
|
||||
<?php $__tmp_RANDOM_LOOP_ID = Context::get('bar') ?? []; if($__tmp_RANDOM_LOOP_ID): $__loop_RANDOM_LOOP_ID = $this->_v2_initLoopVar("RANDOM_LOOP_ID", $__tmp_RANDOM_LOOP_ID); foreach ($__tmp_RANDOM_LOOP_ID as $__Context->k => $__Context->val): ?>
|
||||
<div>
|
||||
<?php if (empty($__Context->nosuchvar)): ?>
|
||||
<img src="/rhymix/tests/_data/template/bar/rhymix.svg" alt="unit tests are cool" />
|
||||
<span <?php if ($__Context->k >= 2): ?>class="<?php echo htmlspecialchars($__Context->val ?? '', \ENT_QUOTES, 'UTF-8', false); ?>"<?php endif; ?>></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; else: ?><div>Nothing here...</div><?php endif; ?>
|
||||
<?php $this->_v2_incrLoopVar($__loop_RANDOM_LOOP_ID); endforeach; $this->_v2_removeLoopVar($__loop_RANDOM_LOOP_ID); unset($__loop_RANDOM_LOOP_ID); else: ?><div>Nothing here...</div><?php endif; ?>
|
||||
|
||||
<?php (function($__dir, $__path, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__path = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): $__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html"); $__tpl->setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', $__Context->bar, 'var'); ?>
|
||||
<?php (function($__dir, $__path, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__path = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): $__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html"); $__tpl->setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', [], 'anything', 'incl/empty'); ?>
|
||||
179
tests/_data/template/v2loops.executed.html
Normal file
179
tests/_data/template/v2loops.executed.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<h1>Pets</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<span>A red dog</span>
|
||||
<span>current index 0 of 5</span>
|
||||
<span>parent index 0 of 5</span>
|
||||
<span>first: bool(true)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A red cat</span>
|
||||
<span>current index 1 of 5</span>
|
||||
<span>parent index 0 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A red rabbit</span>
|
||||
<span>current index 2 of 5</span>
|
||||
<span>parent index 0 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A red panda</span>
|
||||
<span>current index 3 of 5</span>
|
||||
<span>parent index 0 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A red otter</span>
|
||||
<span>current index 4 of 5</span>
|
||||
<span>parent index 0 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(true)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A blue dog</span>
|
||||
<span>current index 0 of 5</span>
|
||||
<span>parent index 1 of 5</span>
|
||||
<span>first: bool(true)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A blue cat</span>
|
||||
<span>current index 1 of 5</span>
|
||||
<span>parent index 1 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A blue rabbit</span>
|
||||
<span>current index 2 of 5</span>
|
||||
<span>parent index 1 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A blue panda</span>
|
||||
<span>current index 3 of 5</span>
|
||||
<span>parent index 1 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A blue otter</span>
|
||||
<span>current index 4 of 5</span>
|
||||
<span>parent index 1 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(true)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A yellow dog</span>
|
||||
<span>current index 0 of 5</span>
|
||||
<span>parent index 2 of 5</span>
|
||||
<span>first: bool(true)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A yellow cat</span>
|
||||
<span>current index 1 of 5</span>
|
||||
<span>parent index 2 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A yellow rabbit</span>
|
||||
<span>current index 2 of 5</span>
|
||||
<span>parent index 2 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A yellow panda</span>
|
||||
<span>current index 3 of 5</span>
|
||||
<span>parent index 2 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A yellow otter</span>
|
||||
<span>current index 4 of 5</span>
|
||||
<span>parent index 2 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(true)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A black dog</span>
|
||||
<span>current index 0 of 5</span>
|
||||
<span>parent index 3 of 5</span>
|
||||
<span>first: bool(true)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A black cat</span>
|
||||
<span>current index 1 of 5</span>
|
||||
<span>parent index 3 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A black rabbit</span>
|
||||
<span>current index 2 of 5</span>
|
||||
<span>parent index 3 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A black panda</span>
|
||||
<span>current index 3 of 5</span>
|
||||
<span>parent index 3 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A black otter</span>
|
||||
<span>current index 4 of 5</span>
|
||||
<span>parent index 3 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(true)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A white dog</span>
|
||||
<span>current index 0 of 5</span>
|
||||
<span>parent index 4 of 5</span>
|
||||
<span>first: bool(true)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A white cat</span>
|
||||
<span>current index 1 of 5</span>
|
||||
<span>parent index 4 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A white rabbit</span>
|
||||
<span>current index 2 of 5</span>
|
||||
<span>parent index 4 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A white panda</span>
|
||||
<span>current index 3 of 5</span>
|
||||
<span>parent index 4 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(false)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>A white otter</span>
|
||||
<span>current index 4 of 5</span>
|
||||
<span>parent index 4 of 5</span>
|
||||
<span>first: bool(false)</span>
|
||||
<span>last: bool(true)</span>
|
||||
</li>
|
||||
</ul>
|
||||
22
tests/_data/template/v2loops.html
Normal file
22
tests/_data/template/v2loops.html
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
@version(2)
|
||||
|
||||
@php
|
||||
$foo = ['red', 'blue', 'yellow', 'black', 'white'];
|
||||
$bar = ['dog', 'cat', 'rabbit', 'panda', 'otter'];
|
||||
@endphp
|
||||
|
||||
<h1>Pets</h1>
|
||||
|
||||
<ul>
|
||||
@foreach ($foo as $color)
|
||||
@foreach ($bar as $animal)
|
||||
<li>
|
||||
<span>A {{ $color }} {{ $animal }}</span>
|
||||
<span>current index {{ $loop->index }} of {{ $loop->count }}</span>
|
||||
<span>parent index {{ $loop->parent->index }} of {{ $loop->parent->count }}</span>
|
||||
<span>first: @dump($loop->first)</span>
|
||||
<span>last: @dump($loop->last)</span>
|
||||
</li>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</ul>
|
||||
|
|
@ -11,7 +11,7 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
$this->baseurl = '/' . basename(dirname(dirname(dirname(dirname(__DIR__))))) . '/';
|
||||
}
|
||||
|
||||
public function testVersion()
|
||||
public function testVersionDetection()
|
||||
{
|
||||
// Extension is .html and config is explicitly declared
|
||||
$source = '<config version="2" />' . "\n" . '<div>{{ RX_VERSION|noescape }}</div>';
|
||||
|
|
@ -529,7 +529,7 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
|
||||
// $loop
|
||||
$source = "{!! \$loop->first !!}";
|
||||
$target = "<?php echo \$loop->first ?? ''; ?>";
|
||||
$target = "<?php echo end(self::\$_loopvars)->first; ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Escaped dollar sign
|
||||
|
|
@ -713,13 +713,13 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
'<!--@endforeach -->',
|
||||
]);
|
||||
$target = implode("\n", [
|
||||
'<?php $__tmp = $__Context->list ?? []; foreach ($__tmp as $__Context->key => $__Context->val): ?>',
|
||||
'<?php $__tmp = $__Context->list ?? []; $__loop = $this->_v2_initLoopVar("%uniq", $__tmp); foreach ($__tmp as $__Context->key => $__Context->val): ?>',
|
||||
'<p>Hello World</p>',
|
||||
'<?php endforeach; ?>',
|
||||
'<?php $this->_v2_incrLoopVar($__loop); endforeach; $this->_v2_removeLoopVar($__loop); unset($__loop); ?>',
|
||||
]);
|
||||
$parsed = $this->_parse($source);
|
||||
$tmpvar = preg_match('/(\$__tmp_[0-9a-f]{14})/', $parsed, $m) ? $m[1] : '';
|
||||
$target = strtr($target, ['$__tmp' => $tmpvar]);
|
||||
$tmpvar = preg_match('/(\$__(?:tmp|loop)_)([0-9a-f]{14})/', $parsed, $m) ? $m[2] : '';
|
||||
$target = preg_replace(['/(\$__(?:tmp|loop))/', '/%uniq/'], ['$1_' . $tmpvar, $tmpvar], $target);
|
||||
$this->assertEquals($target, $parsed);
|
||||
|
||||
// @forelse with @empty
|
||||
|
|
@ -731,15 +731,15 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
'@end',
|
||||
]);
|
||||
$target = implode("\n", [
|
||||
'<?php $__tmp = $__Context->list ?? []; if($__tmp): foreach ($__tmp as $__Context->key => $__Context->val): ?>',
|
||||
'<?php $__tmp = $__Context->list ?? []; if($__tmp): $__loop = $this->_v2_initLoopVar("%uniq", $__tmp); foreach ($__tmp as $__Context->key => $__Context->val): ?>',
|
||||
'<p>Hello World</p>',
|
||||
'<?php endforeach; else: ?>',
|
||||
'<?php $this->_v2_incrLoopVar($__loop); endforeach; $this->_v2_removeLoopVar($__loop); unset($__loop); else: ?>',
|
||||
'<p>Nothing Here!</p>',
|
||||
'<?php endif; ?>',
|
||||
]);
|
||||
$parsed = $this->_parse($source);
|
||||
$tmpvar = preg_match('/(\$__tmp_[0-9a-f]{14})/', $parsed, $m) ? $m[1] : '';
|
||||
$target = strtr($target, ['$__tmp' => $tmpvar]);
|
||||
$tmpvar = preg_match('/(\$__(?:tmp|loop)_)([0-9a-f]{14})/', $parsed, $m) ? $m[2] : '';
|
||||
$target = preg_replace(['/(\$__(?:tmp|loop))/', '/%uniq/'], ['$1_' . $tmpvar, $tmpvar], $target);
|
||||
$this->assertEquals($target, $parsed);
|
||||
|
||||
// @once
|
||||
|
|
@ -865,6 +865,16 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
$source = '<input type="text" @readonly(!!false) @required($member_info->require_title) />';
|
||||
$target = '<input type="text"<?php if (!!false): ?> readonly="readonly"<?php endif; ?><?php if ($__Context->member_info->require_title): ?> required="required"<?php endif; ?> />';
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// @class
|
||||
$source = "<span @class(['a-1', 'font-normal' => \$foo, 'text-blue' => false, 'bg-white' => true])></span>";
|
||||
$this->assertStringContainsString("implode(' ', \$__values)", $this->_parse($source));
|
||||
$this->assertStringContainsString("\$__Context->foo", $this->_parse($source));
|
||||
|
||||
// @style
|
||||
$source = "<span @style(['border-radius: 0.25rem', 'margin: 1rem' => Context::get('bar')])></span>";
|
||||
$this->assertStringContainsString("implode('; ', \$__values)", $this->_parse($source));
|
||||
$this->assertStringContainsString("if (is_numeric(\$__key)):", $this->_parse($source));
|
||||
}
|
||||
|
||||
public function testMiscDirectives()
|
||||
|
|
@ -907,15 +917,15 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
$target = "\n" . '<p><?php echo $this->config->context === \'JS\' ? escape_js(lang(Rhymix\Framework\Lang::getLang())) : lang(Rhymix\Framework\Lang::getLang()); ?></p>';
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// @class
|
||||
$source = "<span @class(['a-1', 'font-normal' => \$foo, 'text-blue' => false, 'bg-white' => true])></span>";
|
||||
$this->assertStringContainsString("implode(' ', \$__values)", $this->_parse($source));
|
||||
$this->assertStringContainsString("\$__Context->foo", $this->_parse($source));
|
||||
// Dump one variable
|
||||
$source = '@dump($foo)';
|
||||
$target = '<?php ob_start(); var_dump($__Context->foo); $__dump = ob_get_clean(); echo rtrim($__dump); ?>';
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// @style
|
||||
$source = "<span @style(['border-radius: 0.25rem', 'margin: 1rem' => Context::get('bar')])></span>";
|
||||
$this->assertStringContainsString("implode('; ', \$__values)", $this->_parse($source));
|
||||
$this->assertStringContainsString("if (is_numeric(\$__key)):", $this->_parse($source));
|
||||
// Dump more than one variable, some literal
|
||||
$source = '@dump($foo, Context::get("var"), (object)["foo" => "bar"])';
|
||||
$target = '<?php ob_start(); var_dump($__Context->foo, Context::get("var"), (object)["foo" => "bar"]); $__dump = ob_get_clean(); echo rtrim($__dump); ?>';
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
}
|
||||
|
||||
public function testComments()
|
||||
|
|
@ -997,27 +1007,50 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
|
||||
public function testCompile()
|
||||
{
|
||||
// General example
|
||||
$tmpl = new \Rhymix\Framework\Template('./tests/_data/template', 'v2example.html');
|
||||
$tmpl->disableCache();
|
||||
|
||||
$compiled_output = $tmpl->compileDirect('./tests/_data/template', 'v2example.html');
|
||||
$tmpvar = preg_match('/(\$__tmp_[0-9a-f]{14})/', $compiled_output, $m) ? $m[1] : '';
|
||||
//Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2result1.php', $compiled_output);
|
||||
|
||||
$expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2result1.php');
|
||||
$expected = preg_replace('/(\$__tmp_[0-9a-f]{14})/', $tmpvar, $expected);
|
||||
$this->assertEquals($expected, $compiled_output);
|
||||
$tmpvar = preg_match('/\$__tmp_([0-9a-f]{14})/', $compiled_output, $m) ? $m[1] : '';
|
||||
//Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2example.compiled.html', $compiled_output);
|
||||
$expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2example.compiled.html');
|
||||
$expected = preg_replace('/RANDOM_LOOP_ID/', $tmpvar, $expected);
|
||||
$this->assertEquals(
|
||||
$this->_normalizeWhitespace($expected),
|
||||
$this->_normalizeWhitespace($compiled_output)
|
||||
);
|
||||
|
||||
$executed_output = $tmpl->compile();
|
||||
$executed_output = preg_replace('/<!--#Template(Start|End):.+?-->\n/', '', $executed_output);
|
||||
$tmpvar = preg_match('/(\$__tmp_[0-9a-f]{14})/', $executed_output, $m) ? $m[1] : '';
|
||||
//Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2result2.php', $executed_output);
|
||||
//Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2example.executed.html', $executed_output);
|
||||
$expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2example.executed.html');
|
||||
$expected = preg_replace('/RANDOM_LOOP_ID/', $tmpvar, $expected);
|
||||
$this->assertEquals(
|
||||
$this->_normalizeWhitespace($expected),
|
||||
$this->_normalizeWhitespace($executed_output)
|
||||
);
|
||||
|
||||
$expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2result2.php');
|
||||
$expected = preg_replace('/(\$__tmp_[0-9a-f]{14})/', $tmpvar, $expected);
|
||||
$this->assertEquals($expected, $executed_output);
|
||||
// Loop variable
|
||||
$tmpl = new \Rhymix\Framework\Template('./tests/_data/template', 'v2loops.html');
|
||||
$tmpl->disableCache();
|
||||
|
||||
$executed_output = $tmpl->compile();
|
||||
//Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2loops.executed.html', $executed_output);
|
||||
$expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2loops.executed.html');
|
||||
$this->assertEquals(
|
||||
$this->_normalizeWhitespace($expected),
|
||||
$this->_normalizeWhitespace($executed_output)
|
||||
);
|
||||
}
|
||||
|
||||
protected function _parse($source, $force_v2 = true)
|
||||
/**
|
||||
* Utility function to compile an arbitrary string and return the results.
|
||||
*
|
||||
* @param string $source
|
||||
* @param bool $force_v2 Disable version detection
|
||||
* @return string
|
||||
*/
|
||||
protected function _parse(string $source, bool $force_v2 = true): string
|
||||
{
|
||||
$tmpl = new \Rhymix\Framework\Template('./tests/_data/template', 'empty.html');
|
||||
if ($force_v2)
|
||||
|
|
@ -1031,4 +1064,26 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to remove empty lines and leading/trailing whitespace.
|
||||
*
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
protected function _normalizeWhitespace(string $content): string
|
||||
{
|
||||
$content = preg_replace('/<!--#Template(Start|End):.+?-->\n/', '', $content);
|
||||
|
||||
$result = [];
|
||||
foreach (explode("\n", $content) as $line)
|
||||
{
|
||||
$line = trim($line);
|
||||
if ($line !== '')
|
||||
{
|
||||
$result[] = $line;
|
||||
}
|
||||
}
|
||||
return implode("\n", $result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue