<?php /** * ThemeCompiler Test Class * * PHP version 5 * * Copyright (C) Villanova University 2017. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category VuFind * @package Tests * @author Demian Katz <demian.katz@villanova.edu> * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:testing:unit_tests Wiki */ namespace VuFindTest; use VuFindTheme\ThemeCompiler; use VuFindTheme\ThemeInfo; /** * ThemeCompiler Test Class * * @category VuFind * @package Tests * @author Demian Katz <demian.katz@villanova.edu> * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:testing:unit_tests Wiki */ class ThemeCompilerTest extends Unit\TestCase { /** * Path to theme fixtures * * @var string */ protected $fixturePath; /** * ThemeInfo object for tests * * @var ThemeInfo */ protected $info; /** * Path where new theme will be created * * @var string */ protected $targetPath; /** * Constructor */ public function __construct() { $this->fixturePath = realpath(__DIR__ . '/../../fixtures/themes'); $this->info = new ThemeInfo($this->fixturePath, 'parent'); $this->targetPath = $this->info->getBaseDir() . '/compiled'; } /** * Standard setup method. * * @return void */ public function setUp() { // Give up if the target directory already exists: if (is_dir($this->targetPath)) { return $this->markTestSkipped('compiled theme already exists.'); } } /** * Test the compiler. * * @return void */ public function testStandardCompilation() { $baseDir = $this->info->getBaseDir(); $parentDir = $baseDir . '/parent'; $childDir = $baseDir . '/child'; $compiler = $this->getThemeCompiler(); $result = $compiler->compile('child', 'compiled'); // Did the compiler report success? $this->assertEquals('', $compiler->getLastError()); $this->assertTrue($result); // Was the target directory created with the expected files? $this->assertTrue(is_dir($this->targetPath)); $this->assertTrue(file_exists("{$this->targetPath}/parent.txt")); $this->assertTrue(file_exists("{$this->targetPath}/child.txt")); // Did the right version of the file that exists in both parent and child // get copied over? $this->assertEquals( file_get_contents("$childDir/js/hello.js"), file_get_contents("{$this->targetPath}/js/hello.js") ); $this->assertNotEquals( file_get_contents("$parentDir/js/hello.js"), file_get_contents("{$this->targetPath}/js/hello.js") ); // Did the configuration merge correctly? $expectedConfig = [ 'extends' => false, 'css' => ['child.css'], 'js' => ['hello.js', 'extra.js'], 'helpers' => [ 'factories' => [ 'foo' => 'fooOverrideFactory', 'bar' => 'barFactory', ], 'invokables' => [ 'xyzzy' => 'Xyzzy', ] ], ]; $mergedConfig = include "{$this->targetPath}/theme.config.php"; $this->assertEquals($expectedConfig, $mergedConfig); } /** * Test the compiler with a mixin. * * @return void */ public function testStandardCompilationWithMixin() { $baseDir = $this->info->getBaseDir(); $parentDir = $baseDir . '/parent'; $childDir = $baseDir . '/child'; $mixinDir = $baseDir . '/mixin'; $compiler = $this->getThemeCompiler(); $result = $compiler->compile('mixin_user', 'compiled'); // Did the compiler report success? $this->assertEquals('', $compiler->getLastError()); $this->assertTrue($result); // Was the target directory created with the expected files? $this->assertTrue(is_dir($this->targetPath)); $this->assertTrue(file_exists("{$this->targetPath}/parent.txt")); $this->assertTrue(file_exists("{$this->targetPath}/child.txt")); $this->assertTrue(file_exists("{$this->targetPath}/js/mixin.js")); // Did the right version of the file that exists in both parent and child // get copied over? $this->assertEquals( file_get_contents("$mixinDir/js/hello.js"), file_get_contents("{$this->targetPath}/js/hello.js") ); $this->assertNotEquals( file_get_contents("$childDir/js/hello.js"), file_get_contents("{$this->targetPath}/js/hello.js") ); $this->assertNotEquals( file_get_contents("$parentDir/js/hello.js"), file_get_contents("{$this->targetPath}/js/hello.js") ); // Did the configuration merge correctly? $expectedConfig = [ 'extends' => false, 'css' => ['child.css'], 'js' => ['hello.js', 'extra.js', 'mixin.js'], 'helpers' => [ 'factories' => [ 'foo' => 'fooOverrideFactory', 'bar' => 'barFactory', ], 'invokables' => [ 'xyzzy' => 'Xyzzy', ] ], ]; $mergedConfig = include "{$this->targetPath}/theme.config.php"; $this->assertEquals($expectedConfig, $mergedConfig); } /** * Test overwrite protection. * * @return void */ public function testOverwriteProtection() { // First, compile the theme: $compiler = $this->getThemeCompiler(); $this->assertTrue($compiler->compile('child', 'compiled')); // Now confirm that by default, we're not allowed to recompile it on // top of itself... $this->assertFalse($compiler->compile('child', 'compiled')); $this->assertEquals( "Cannot overwrite {$this->targetPath} without --force switch!", $compiler->getLastError() ); // Write a file into the compiled theme so we can check that it gets // removed when we force a recompile: $markerFile = $this->targetPath . '/fake-marker.txt'; file_put_contents($markerFile, 'junk'); $this->assertTrue(file_exists($markerFile)); // Now recompile with "force" set to true, confirm that this succeeds, // and make sure the marker file is now gone: $this->assertTrue($compiler->compile('child', 'compiled', true)); $this->assertFalse(file_exists($markerFile)); } /** * Teardown method: clean up test directory. * * @return void */ public function tearDown() { $this->getThemeCompiler()->removeTheme('compiled'); } /** * Get a test ThemeCompiler object * * @return ThemeInfo */ protected function getThemeCompiler() { return new ThemeCompiler($this->info); } }