2014-05-14 23:24:20 +10:00
|
|
|
<?php
|
|
|
|
|
2022-06-22 01:30:30 +01:00
|
|
|
namespace Cms\Tests\Classes;
|
|
|
|
|
|
|
|
use System\Tests\Bootstrap\TestCase;
|
|
|
|
use Cms\Classes\CodeParser;
|
|
|
|
use Cms\Classes\Controller;
|
|
|
|
use Cms\Classes\Layout;
|
2018-03-22 19:55:13 +03:00
|
|
|
use Cms\Classes\LayoutCode;
|
2014-05-14 23:24:20 +10:00
|
|
|
use Cms\Classes\Page;
|
2022-06-22 01:30:30 +01:00
|
|
|
use Cms\Classes\PageCode;
|
2014-05-14 23:24:20 +10:00
|
|
|
use Cms\Classes\Theme;
|
2022-06-22 01:30:30 +01:00
|
|
|
use File;
|
|
|
|
use ReflectionClass;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2020-02-07 16:59:39 +08:00
|
|
|
class CodeParserTest extends TestCase
|
2014-05-14 23:24:20 +10:00
|
|
|
{
|
2022-06-22 01:30:30 +01:00
|
|
|
public function setUp(): void
|
2017-05-12 07:20:59 +10:00
|
|
|
{
|
|
|
|
parent::setup();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear cache
|
|
|
|
*/
|
2018-03-22 19:55:13 +03:00
|
|
|
foreach (File::directories(storage_path() . '/cms/cache') as $directory) {
|
2017-05-12 07:20:59 +10:00
|
|
|
File::deleteDirectory($directory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
public static function getProperty($name)
|
|
|
|
{
|
2018-03-22 19:55:13 +03:00
|
|
|
$class = new ReflectionClass(CodeParser::class);
|
2014-05-14 23:24:20 +10:00
|
|
|
$property = $class->getProperty($name);
|
|
|
|
$property->setAccessible(true);
|
2015-11-04 20:41:53 +01:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
return $property;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testParser()
|
|
|
|
{
|
2014-12-10 17:42:50 +11:00
|
|
|
$theme = Theme::load('test');
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$layout = Layout::load($theme, 'php-parser-test.htm');
|
|
|
|
$this->assertNotEmpty($layout);
|
|
|
|
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source(null, $layout, $controller);
|
2018-03-22 19:55:13 +03:00
|
|
|
$this->assertInstanceOf(LayoutCode::class, $obj);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Test the file contents
|
|
|
|
*/
|
|
|
|
|
|
|
|
$body = preg_replace('/^\s*function/m', 'public function', $layout->code);
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent = '<?php ' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent .= 'class ' . $info['className'] . ' extends ' . LayoutCode::class . PHP_EOL;
|
|
|
|
$expectedContent .= '{' . PHP_EOL;
|
|
|
|
$expectedContent .= $body . PHP_EOL;
|
|
|
|
$expectedContent .= '}' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$this->assertEquals($expectedContent, file_get_contents($info['filePath']));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test caching - the first time the file should be parsed
|
|
|
|
*/
|
|
|
|
|
|
|
|
$this->assertEquals('parser', $info['source']);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test caching - the second time the file should be loaded from the request-wide cache
|
|
|
|
*/
|
|
|
|
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$info = $parser->parse();
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertEquals('request-cache', $info['source']);
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test caching - reset the request-wide cache and let the parser to load the file from the cache
|
|
|
|
*/
|
|
|
|
|
|
|
|
$property = $this->getProperty('cache');
|
|
|
|
$property->setValue($parser, []);
|
|
|
|
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$info = $parser->parse();
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertEquals('cache', $info['source']);
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test caching - the cached data should now be stored in the request-wide cache again
|
|
|
|
*/
|
|
|
|
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$info = $parser->parse();
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertEquals('request-cache', $info['source']);
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test caching - update the file modification time and reset the internal cache. The file should be parsed.
|
|
|
|
*/
|
|
|
|
|
2016-03-17 07:58:42 +11:00
|
|
|
$this->assertTrue(@touch($layout->getFilePath()));
|
2020-08-06 02:00:22 +08:00
|
|
|
clearstatcache();
|
2014-05-14 23:24:20 +10:00
|
|
|
$layout = Layout::load($theme, 'php-parser-test.htm');
|
|
|
|
$this->assertNotEmpty($layout);
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$property->setValue($parser, []);
|
|
|
|
|
|
|
|
$info = $parser->parse();
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertEquals('parser', $info['source']);
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testParseNoPhp()
|
|
|
|
{
|
2014-12-10 17:42:50 +11:00
|
|
|
$theme = Theme::load('test');
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$layout = Layout::load($theme, 'no-php.htm');
|
|
|
|
$this->assertNotEmpty($layout);
|
|
|
|
|
|
|
|
$parser = new CodeParser($layout);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent = '<?php ' . PHP_EOL;
|
|
|
|
$expectedContent .= 'class ' . $info['className'] . ' extends ' . LayoutCode::class . PHP_EOL;
|
|
|
|
$expectedContent .= '{' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
$expectedContent .= PHP_EOL;
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent .= '}' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$this->assertEquals($expectedContent, file_get_contents($info['filePath']));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testParsePage()
|
|
|
|
{
|
2014-12-10 17:42:50 +11:00
|
|
|
$theme = Theme::load('test');
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$page = Page::load($theme, 'cycle-test.htm');
|
|
|
|
$this->assertNotEmpty($page);
|
|
|
|
|
|
|
|
$parser = new CodeParser($page);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source($page, null, $controller);
|
2018-03-22 19:55:13 +03:00
|
|
|
$this->assertInstanceOf(PageCode::class, $obj);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$body = preg_replace('/^\s*function/m', 'public function', $page->code);
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent = '<?php ' . PHP_EOL;
|
|
|
|
$expectedContent .= 'class ' . $info['className'] . ' extends ' . PageCode::class . PHP_EOL;
|
|
|
|
$expectedContent .= '{' . PHP_EOL;
|
|
|
|
$expectedContent .= $body . PHP_EOL;
|
|
|
|
$expectedContent .= '}' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$this->assertEquals($expectedContent, file_get_contents($info['filePath']));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testOptionalPhpTags()
|
|
|
|
{
|
2014-12-10 17:42:50 +11:00
|
|
|
$theme = Theme::load('test');
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Test short PHP tags
|
|
|
|
*/
|
|
|
|
|
|
|
|
$page = Page::load($theme, 'optional-short-php-tags.htm');
|
|
|
|
$this->assertNotEmpty($page);
|
|
|
|
|
|
|
|
$parser = new CodeParser($page);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source($page, null, $controller);
|
|
|
|
$this->assertInstanceOf('\Cms\Classes\PageCode', $obj);
|
|
|
|
|
|
|
|
$body = preg_replace('/^\s*function/m', 'public function', $page->code);
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent = '<?php ' . PHP_EOL;
|
|
|
|
$expectedContent .= 'class ' . $info['className'] . ' extends ' . PageCode::class . PHP_EOL;
|
|
|
|
$expectedContent .= '{' . PHP_EOL;
|
|
|
|
$expectedContent .= $body . PHP_EOL;
|
|
|
|
$expectedContent .= '}' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$this->assertEquals($expectedContent, file_get_contents($info['filePath']));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test full PHP tags
|
|
|
|
*/
|
|
|
|
|
|
|
|
$page = Page::load($theme, 'optional-full-php-tags.htm');
|
|
|
|
$this->assertNotEmpty($page);
|
|
|
|
|
|
|
|
$parser = new CodeParser($page);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source($page, null, $controller);
|
2018-03-22 19:55:13 +03:00
|
|
|
$this->assertInstanceOf(PageCode::class, $obj);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$body = preg_replace('/^\s*function/m', 'public function', $page->code);
|
2018-03-22 19:55:13 +03:00
|
|
|
$expectedContent = '<?php ' . PHP_EOL;
|
|
|
|
$expectedContent .= 'class ' . $info['className'] . ' extends ' . PageCode::class . PHP_EOL;
|
|
|
|
$expectedContent .= '{' . PHP_EOL;
|
|
|
|
$expectedContent .= $body . PHP_EOL;
|
|
|
|
$expectedContent .= '}' . PHP_EOL;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$this->assertEquals($expectedContent, file_get_contents($info['filePath']));
|
|
|
|
}
|
|
|
|
|
2015-03-02 19:05:03 +11:00
|
|
|
// public function testSyntaxErrors()
|
|
|
|
// {
|
|
|
|
// $this->markTestIncomplete('Test PHP parsing errors here.');
|
|
|
|
// }
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
public function testNamespaces()
|
|
|
|
{
|
2014-12-10 17:42:50 +11:00
|
|
|
$theme = Theme::load('test');
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$page = Page::load($theme, 'code-namespaces.htm');
|
|
|
|
$this->assertNotEmpty($page);
|
|
|
|
|
|
|
|
$parser = new CodeParser($page);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source($page, null, $controller);
|
2018-03-22 19:55:13 +03:00
|
|
|
$this->assertInstanceOf(PageCode::class, $obj);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2022-06-22 01:30:30 +01:00
|
|
|
$referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces.php.stub';
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->assertFileExists($referenceFilePath);
|
2015-01-05 12:37:04 +11:00
|
|
|
$referenceContents = $this->getContents($referenceFilePath);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$referenceContents = str_replace('{className}', $info['className'], $referenceContents);
|
|
|
|
|
2015-01-05 12:37:04 +11:00
|
|
|
$this->assertEquals($referenceContents, $this->getContents($info['filePath']));
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
2015-01-05 12:37:04 +11:00
|
|
|
|
2016-05-21 16:20:51 +02:00
|
|
|
public function testNamespacesAliases()
|
|
|
|
{
|
|
|
|
$theme = Theme::load('test');
|
|
|
|
|
|
|
|
$page = Page::load($theme, 'code-namespaces-aliases.htm');
|
|
|
|
$this->assertNotEmpty($page);
|
|
|
|
|
|
|
|
$parser = new CodeParser($page);
|
|
|
|
$info = $parser->parse();
|
|
|
|
|
2020-01-19 17:27:38 +08:00
|
|
|
$this->assertIsArray($info);
|
2016-05-21 16:20:51 +02:00
|
|
|
$this->assertArrayHasKey('filePath', $info);
|
|
|
|
$this->assertArrayHasKey('className', $info);
|
|
|
|
$this->assertArrayHasKey('source', $info);
|
|
|
|
|
|
|
|
$this->assertFileExists($info['filePath']);
|
|
|
|
$controller = new Controller($theme);
|
|
|
|
$obj = $parser->source($page, null, $controller);
|
2018-03-22 19:55:13 +03:00
|
|
|
$this->assertInstanceOf(PageCode::class, $obj);
|
2016-05-21 16:20:51 +02:00
|
|
|
|
2022-06-22 01:30:30 +01:00
|
|
|
$referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces-aliases.php.stub';
|
2016-05-21 16:20:51 +02:00
|
|
|
$this->assertFileExists($referenceFilePath);
|
|
|
|
$referenceContents = $this->getContents($referenceFilePath);
|
|
|
|
|
|
|
|
$referenceContents = str_replace('{className}', $info['className'], $referenceContents);
|
|
|
|
|
|
|
|
$this->assertEquals($referenceContents, $this->getContents($info['filePath']));
|
|
|
|
}
|
|
|
|
|
2018-03-22 19:55:13 +03:00
|
|
|
//
|
|
|
|
// Helpers
|
|
|
|
//
|
2015-01-05 12:37:04 +11:00
|
|
|
|
2018-03-22 19:55:13 +03:00
|
|
|
protected function getContents($path)
|
|
|
|
{
|
2015-01-05 12:37:04 +11:00
|
|
|
$content = file_get_contents($path);
|
|
|
|
$content = preg_replace('~\R~u', PHP_EOL, $content); // Normalize EOL
|
|
|
|
return $content;
|
2018-03-22 19:55:13 +03:00
|
|
|
}
|
2015-11-04 20:41:53 +01:00
|
|
|
}
|