diff --git a/min/lib/Minify/ClosureCompiler.php b/min/lib/Minify/ClosureCompiler.php index bdcdc7e..928bc80 100644 --- a/min/lib/Minify/ClosureCompiler.php +++ b/min/lib/Minify/ClosureCompiler.php @@ -33,6 +33,11 @@ */ class Minify_ClosureCompiler { + const OPTION_CHARSET = 'charset'; + const OPTION_COMPILATION_LEVEL = 'compilation_level'; + + public static $isDebug = false; + /** * Filepath of the Closure Compiler jar file. This must be set before * calling minifyJs(). @@ -70,13 +75,21 @@ class Minify_ClosureCompiler { { self::_prepare(); if (! ($tmpFile = tempnam(self::$tempDir, 'cc_'))) { - throw new Exception('Minify_ClosureCompiler : could not create temp file in "'.self::$tempDir.'".'); + throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : could not create temp file in "'.self::$tempDir.'".'); } file_put_contents($tmpFile, $js); - exec(self::_getCmd($options, $tmpFile), $output, $result_code); + $cmd = self::_getCmd($options, $tmpFile); + $result = exec($cmd, $output, $result_code); unlink($tmpFile); if ($result_code != 0) { - throw new Exception('Minify_ClosureCompiler : Closure Compiler execution failed.'); + $message = 'Minify_ClosureCompiler : Closure Compiler execution failed.'; + if (self::$isDebug) { + exec($cmd . ' 2>&1', $error); + if ($error) { + $message .= "\nReason:\n" . join("\n", $error); + } + } + throw new Minify_ClosureCompiler_Exception($message); } return implode("\n", $output); } @@ -85,17 +98,18 @@ class Minify_ClosureCompiler { { $o = array_merge( array( - 'charset' => 'utf-8', - 'compilation_level' => 'SIMPLE_OPTIMIZATIONS', + self::OPTION_CHARSET => 'utf-8', + self::OPTION_COMPILATION_LEVEL => 'SIMPLE_OPTIMIZATIONS', ), $userOptions ); + $charsetOption = $o[self::OPTION_CHARSET]; $cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile) - . (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $o['charset']) - ? " --charset {$o['charset']}" + . (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $charsetOption) + ? " --charset {$charsetOption}" : ''); - foreach (array('compilation_level') as $opt) { + foreach (array(self::OPTION_COMPILATION_LEVEL) as $opt) { if ($o[$opt]) { $cmd .= " --{$opt} ". escapeshellarg($o[$opt]); } @@ -106,18 +120,18 @@ class Minify_ClosureCompiler { private static function _prepare() { if (! is_file(self::$jarFile)) { - throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not a valid file.'); + throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not a valid file.'); } if (! is_readable(self::$jarFile)) { - throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not readable.'); + throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not readable.'); } if (! is_dir(self::$tempDir)) { - throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not a valid direcotry.'); + throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not a valid direcotry.'); } if (! is_writable(self::$tempDir)) { - throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not writable.'); + throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not writable.'); } } } -/* vim:ts=4:sw=4:et */ +class Minify_ClosureCompiler_Exception extends Exception {} diff --git a/min_unit_tests/test_Minify_ClosureCompiler.php b/min_unit_tests/test_Minify_ClosureCompiler.php new file mode 100644 index 0000000..ee3467d --- /dev/null +++ b/min_unit_tests/test_Minify_ClosureCompiler.php @@ -0,0 +1,75 @@ +getMessage(), 1) . "\n\n\n"; + } + + $compiler_jar_path = __DIR__ . DIRECTORY_SEPARATOR . 'compiler.jar'; + if (is_file($compiler_jar_path)) { + + // set minimum necessary settings + Minify_ClosureCompiler::$jarFile = $compiler_jar_path; + Minify_ClosureCompiler::$tempDir = sys_get_temp_dir(); + + + // --- Test minification with the minimum necessary settings --- + + $src = " + (function (window, undefined){ + function addOne(input) { + return 1 + input; + } + window.addOne = addOne; + window.undefined = undefined; + })(window); + "; + $minExpected = "(function(a,b){a.addOne=function(a){return 1+a};a.undefined=b})(window);"; + $minOutput = Minify_ClosureCompiler::minify($src); + $passed = assertTrue($minExpected == $minOutput, 'Minify_ClosureCompiler : minimum necessary settings'); + if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) { + echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n"; + echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n"; + echo "---Source: " .countBytes($src). " bytes\n\n{$src}\n\n\n"; + } + + + // --- Test minifaction with advanced compilation level --- + + $src = "function unused() {};"; + $minExpected = ''; + $minOutput = Minify_ClosureCompiler::minify($src, array( + Minify_ClosureCompiler::OPTION_COMPILATION_LEVEL => 'ADVANCED_OPTIMIZATIONS' + )); + $passed = assertTrue($minExpected == $minOutput, 'Minify_ClosureCompiler : advanced optimizations'); + if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) { + echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n"; + echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n"; + echo "---Source: " .countBytes($src). " bytes\n\n{$src}\n\n\n"; + } + + } else { + echo "NONE: Minify_ClosureCompiler : Please download a compiler.jar from + https://code.google.com/p/closure-compiler/wiki/BinaryDownloads + put it under '${compiler_jar_path}' and make it readable by your webserver + to test more functionality\n"; + } +} + +test_Minify_ClosureCompiler(); diff --git a/min_unit_tests/test_all.php b/min_unit_tests/test_all.php index caba028..c654b6a 100644 --- a/min_unit_tests/test_all.php +++ b/min_unit_tests/test_all.php @@ -9,6 +9,7 @@ require 'test_Minify_Cache_Memcache.php'; require 'test_Minify_Cache_ZendPlatform.php'; require 'test_Minify_CSS.php'; require 'test_Minify_CSS_UriRewriter.php'; +require 'test_Minify_ClosureCompiler.php'; require 'test_Minify_JS_ClosureCompiler.php'; require 'test_Minify_YuiCSS.php'; require 'test_Minify_CommentPreserver.php';