winter/modules/cms/tests/classes/CodeParserTest.php

323 lines
10 KiB
PHP
Raw Normal View History

2014-05-14 23:24:20 +10:00
<?php
namespace Cms\Tests\Classes;
use System\Tests\Bootstrap\TestCase;
use Cms\Classes\CodeParser;
use Cms\Classes\Controller;
use Cms\Classes\Layout;
use Cms\Classes\LayoutCode;
2014-05-14 23:24:20 +10:00
use Cms\Classes\Page;
use Cms\Classes\PageCode;
2014-05-14 23:24:20 +10:00
use Cms\Classes\Theme;
use File;
use ReflectionClass;
2014-05-14 23:24:20 +10:00
class CodeParserTest extends TestCase
2014-05-14 23:24:20 +10:00
{
public function setUp(): void
{
parent::setup();
/*
* Clear cache
*/
foreach (File::directories(storage_path() . '/cms/cache') as $directory) {
File::deleteDirectory($directory);
}
}
2014-05-14 23:24:20 +10:00
public static function getProperty($name)
{
$class = new ReflectionClass(CodeParser::class);
2014-05-14 23:24:20 +10:00
$property = $class->getProperty($name);
$property->setAccessible(true);
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();
$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);
$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);
$expectedContent = '<?php ' . PHP_EOL;
2014-05-14 23:24:20 +10: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();
$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();
$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();
$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.
*/
$this->assertTrue(@touch($layout->getFilePath()));
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();
$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();
$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']);
$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;
$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();
$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(PageCode::class, $obj);
2014-05-14 23:24:20 +10:00
$body = preg_replace('/^\s*function/m', 'public function', $page->code);
$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();
$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);
$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();
$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(PageCode::class, $obj);
2014-05-14 23:24:20 +10:00
$body = preg_replace('/^\s*function/m', 'public function', $page->code);
$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();
$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(PageCode::class, $obj);
2014-05-14 23:24:20 +10:00
$referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces.php.stub';
2014-05-14 23:24:20 +10:00
$this->assertFileExists($referenceFilePath);
$referenceContents = $this->getContents($referenceFilePath);
2014-05-14 23:24:20 +10:00
$referenceContents = str_replace('{className}', $info['className'], $referenceContents);
$this->assertEquals($referenceContents, $this->getContents($info['filePath']));
2014-05-14 23:24:20 +10: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();
$this->assertIsArray($info);
$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(PageCode::class, $obj);
$referenceFilePath = base_path() . '/modules/cms/tests/fixtures/reference/namespaces-aliases.php.stub';
$this->assertFileExists($referenceFilePath);
$referenceContents = $this->getContents($referenceFilePath);
$referenceContents = str_replace('{className}', $info['className'], $referenceContents);
$this->assertEquals($referenceContents, $this->getContents($info['filePath']));
}
//
// Helpers
//
protected function getContents($path)
{
$content = file_get_contents($path);
$content = preg_replace('~\R~u', PHP_EOL, $content); // Normalize EOL
return $content;
}
}