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

Adding tests + some fixes thanks to them #2

Merged
merged 1 commit into from
Feb 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {