Skip to content
This repository has been archived by the owner on Aug 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from elboletaire/f/tests
Browse files Browse the repository at this point in the history
Adding tests + some fixes thanks to them
  • Loading branch information
elboletaire committed Feb 19, 2015
2 parents 40c79a6 + 7c9d4e8 commit 85b4bde
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
composer.lock
vendor/*
tests/test_files/webroot/css/*
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"license": "Apache-2.0",
"require": {
"php": ">=5.4.19",
"cakephp/plugin-installer": "*",
"cakephp/cakephp": "3.0.x-dev",
"oyejorge/less.php": "1.7.0.2"
},
Expand Down
11 changes: 11 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="./tests/bootstrap.php"
>

<testsuites>
<testsuite name="Less Test Cases">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
80 changes: 50 additions & 30 deletions src/View/Helper/LessHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
namespace Less\View\Helper;

use Cake\Core\Plugin;
use Cake\Core\Configure;
use Cake\Log\Log;
use Cake\View\View;
use Cake\Routing\Router;
use Cake\View\Helper;

class LessHelper extends Helper
{
/**
* {@inheritdoc}
*/
public $helpers = [
'Html', 'Url'
];
Expand Down Expand Up @@ -54,28 +58,32 @@ class LessHelper extends Helper

/**
* Initializes Lessc and cleans less and css paths
*
* {@inheritdoc}
*/
public function __construct(View $View, array $config = [])
{
parent::__construct($View, $config);

// Initialize oyejorge/less.php parser
require ROOT . DS . 'vendor' . DS . 'oyejorge' . DS . 'less.php' . DS . 'lib' . DS . 'Less' . DS . 'Autoloader.php';
require_once ROOT . DS . 'vendor' . DS . 'oyejorge' . DS . 'less.php' . DS . 'lib' . DS . 'Less' . DS . 'Autoloader.php';
\Less_Autoloader::register();

$this->css_path = trim($this->css_path, '/');
$this->css_path = WWW_ROOT . trim($this->css_path, '/');
}

/**
* Compile the less and return a css <link> tag.
* In case of error, it will load less with javascript
* instead of returning the resulting css <link> tag.
* Compiles any less files passed and returns the compiled css.
* In case of error, it will load less with the javascritp parser so you'll be
* able to see any errors on screen. If not, check out the error.log file in your
* CakePHP's logs folder.
*
* @param mixed $less The input .less file to be compiled or an array of .less files
* @param array $parser_options The options to be passed to the less php compiler
* @param array $lessjs_options An array of options to be passed as a json to the less javascript object.
* @return string The resulting <link> tag for the compiled css, or the <link> tag for the .less & less.min if compilation fails
* @throws Exception
* @param mixed $less The input .less file to be compiled or an array
* of .less files
* @param array $options Options in 'js' key will be pased to the less.js
* parser and options in 'parser' will be passed to the less.php parser
* @param array $modify_vars Array of modify vars
* @return string
*/
public function less($less = 'styles.less', array $options = [], array $modify_vars = [])
{
Expand All @@ -96,17 +104,21 @@ public function less($less = 'styles.less', array $options = [], array $modify_v
}
return $this->Html->css($css);
}
catch (Exception $e) {
$this->error = $e->getMessage();
catch (\Exception $e) {
// env must be development in order to see errors on-screen
if (Configure::read('debug')) {
$options['js']['env'] = 'development';
}

Log::write('warning', "Error compiling less file: " . $this->error);
$this->error = $e->getMessage();
Log::write('error', "Error compiling less file: " . $this->error);

return $this->jsBlock($less, $options);
}
}

/**
* Returns the initialization string for less (javascript based)
* Returns the required script and link tags to get less.js working
*
* @param string $less The input .less file to be loaded
* @param array $options An array of options to be passed to the `less` configuration var
Expand All @@ -132,16 +144,18 @@ public function jsBlock($less, array $options = [])

/**
* Compiles an input less file to an output css file using the PHP compiler
*
* @param string $input The input .less file to be compiled
* @param string $output The output .css file, resulting from the compilation
* @return boolean true on success, false otherwise
* @param array $input The input .less files to be compiled
* @param array $options Options to be passed to the php parser
* @param array $modify_vars Less modify_vars
* @param boolean $cache Whether to cache or not
* @return string If cache is not enabled will return the full CSS compiled.
* Otherwise it will return the resulting filename from the compilation.
*/
public function compile($input, array $options = [], array $modify_vars = [], $cache = true)
public function compile(array $input, array $options = [], array $modify_vars = [], $cache = true)
{
$to_parse = [];
foreach ($input as $in) {
$less = realpath($in);
$less = realpath(WWW_ROOT . $in);
// If we have plugin notation, ensure to properly load the files
list($plugin, $name) = $this->_View->pluginSplit($in, false);
if (!empty($plugin)) {
Expand All @@ -159,11 +173,14 @@ public function compile($input, array $options = [], array $modify_vars = [], $c
}

$lessc = new \Less_Parser($options);
$lessc->ModifyVars($modify_vars);

foreach ($to_parse as $file => $path) {
$lessc->parseFile($file, $path);
}
// ModifyVars must be called at the bottom of the parsing,
// this way we're ensuring they override their default values.
// http://lesscss.org/usage/#command-line-usage-modify-variable
$lessc->ModifyVars($modify_vars);

return $lessc->getCss();
}
Expand All @@ -172,6 +189,9 @@ public function compile($input, array $options = [], array $modify_vars = [], $c
* Sets the less configuration var options based on the ones given by the user
* and our default ones.
*
* Here's also where we define the import_callback used by less.php parser,
* so it can find files successfully even if they're on plugin folders.
*
* @param array $options An array of options containing our options combined with the ones for the parsers
* @return array $options The resulting $options array
*/
Expand Down Expand Up @@ -226,17 +246,17 @@ private function setOptions(array $options)
return $options;
}

/**
* Returns tha full base url for the given asset
*
* @param string $asset The asset path
* @param string $plugin Plugin where the asset resides
* @return string
*/
private function assetBaseUrl($asset, $plugin = 'Bootstrap')
/**
* Returns tha full base url for the given asset
*
* @param string $asset The asset path
* @param string $plugin Plugin where the asset resides
* @return string
*/
private function assetBaseUrl($asset, $plugin)
{
$dir = dirname($asset);
$path = !empty($dir) ? "/$dir" : null;
$path = !empty($dir) && $dir != '.' ? "/$dir" : null;

return $this->Url->assetUrl($plugin . $path, [
'fullBase' => true
Expand Down
119 changes: 119 additions & 0 deletions tests/TestCase/View/Helper/LessHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
namespace Less\Test\TestCase\View\Helper;

use Less\View\Helper\LessHelper;
use Cake\TestSuite\TestCase;
use Cake\View\View;

class LessHelperTest extends TestCase
{
private $Less;

public function setUp()
{
parent::setUp();
$View = new View();
$this->Less = new LessHelper($View);
}

public function testLess()
{
$options = [
'cache' => false
];

// [Less.php] Basic compiling
$result = $this->Less->less('less/test.less', $options, ['bgcolor' => 'red']);
$this->assertHtml([
['style' => true],
'body{background-color: #f00}',
'/style'
], $result);

// [Less.php] Compiling using cache (here we only check for the
// resulting tag, as the compilation checks are made in testCompile)
$result = $this->Less->less('less/test.less');
$this->assertHtml([
'link' => [
'rel' => 'stylesheet',
'href' => 'preg:/\/css\/lessphp_[0-9a-z]+\.css/'
]
], $result);

// Trying the js fallback
$result = $this->Less->less('less/test_error.less');
$this->assertHtml([
'link' => [
'rel' => 'stylesheet/less',
'href' => '/less/test_error.less'
],
/*['script' => true],
// Need some help here :p
'/script',
'script' => [
'src' => '/less/js/less.min.js'
]*/
], $result);
}

// public function testJsBlock()
// {

// }

public function testCompile()
{
$options = [
'compress' => true
];

// Basic compiling
$result = $this->Less->compile(['less/test.less'], $options, [], false);
$this->assertTextEquals('body{background-color: #000}', $result);

// Changing the bgcolor var
$result = $this->Less->compile(['less/test.less'], $options, ['bgcolor' => 'magenta'], false);
$this->assertTextEquals('body{background-color: #f0f}', $result);

// Compiling with cache
$result = $this->Less->compile(['less/test.less'], $options);
$this->assertRegExp('/lessphp_[a-z0-9]+\.css/', $result);
$result = file_get_contents(WWW_ROOT . 'css' . DS . $result);
$this->assertTextEquals('body{background-color: #000}', $result);

// Compiling with cache and modify_vars
$result = $this->Less->compile(['less/test.less'], $options, ['bgcolor' => 'darkorange']);
$this->assertRegExp('/lessphp_[a-z0-9]+\.css/', $result);
$result = file_get_contents(WWW_ROOT . 'css' . DS . $result);
$this->assertTextEquals('body{background-color: #ff8c00}', $result);
}

public function testAssetBaseUrl()
{
$assetBaseUrl = self::getProtectedMethod('assetBaseUrl');
$result = $assetBaseUrl->invokeArgs($this->Less, [
'less/styles.less',
'Less'
]);
$this->assertEquals('http://localhost/Less/less', $result);

$result = $assetBaseUrl->invokeArgs($this->Less, [
'css/whatever.less',
'Bootstrap'
]);
$this->assertEquals('http://localhost/Bootstrap/css', $result);

$result = $assetBaseUrl->invokeArgs($this->Less, [
'whatever.less',
'Less'
]);
$this->assertEquals('http://localhost/Less', $result);
}

protected static function getProtectedMethod($name) {
$class = new \ReflectionClass('Less\View\Helper\LessHelper');
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}
}
65 changes: 65 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Datasource\ConnectionManager;
use Cake\I18n\I18n;

require_once 'vendor/autoload.php';

if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}

define('ROOT', dirname(__DIR__) . DS);
define('CAKE_CORE_INCLUDE_PATH', ROOT . 'vendor' . DS . 'cakephp' . DS . 'cakephp');
define('CORE_PATH', ROOT . 'vendor' . DS . 'cakephp' . DS . 'cakephp' . DS);
define('CAKE', CORE_PATH . 'src' . DS);
define('TESTS', ROOT . 'tests');
define('APP', ROOT . 'tests' . DS . 'test_files' . DS . 'app' . DS);
define('APP_DIR', 'app');
define('WEBROOT_DIR', 'webroot');
define('WWW_ROOT', dirname(APP) . DS . 'webroot' . DS);
define('TMP', sys_get_temp_dir() . DS);
define('CONFIG', APP . 'config' . DS);
define('CACHE', TMP);
define('LOGS', TMP);

require_once CORE_PATH . 'config/bootstrap.php';

date_default_timezone_set('UTC');
mb_internal_encoding('UTF-8');

Configure::write('debug', true);
Configure::write('App', [
'namespace' => 'App',
'encoding' => 'UTF-8',
'base' => false,
'baseUrl' => false,
'dir' => 'src',
'webroot' => WEBROOT_DIR,
'www_root' => WWW_ROOT,
'fullBaseUrl' => 'http://localhost',
'imageBaseUrl' => 'img/',
'jsBaseUrl' => 'js/',
'cssBaseUrl' => 'css/',
'paths' => [
'plugins' => [dirname(APP) . DS . 'plugins' . DS],
'templates' => [APP . 'Template' . DS]
]
]);

Cache::config([
'_cake_core_' => [
'engine' => 'File',
'prefix' => 'cake_core_',
'serialize' => true
],
'_cake_model_' => [
'engine' => 'File',
'prefix' => 'cake_model_',
'serialize' => true
]
]);

Plugin::load('Less', ['path' => ROOT]);
Empty file.
5 changes: 5 additions & 0 deletions tests/test_files/webroot/less/test.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@bgcolor: black;

body {
background-color: @bgcolor;
}
3 changes: 3 additions & 0 deletions tests/test_files/webroot/less/test_error.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
buggy {


0 comments on commit 85b4bde

Please sign in to comment.