From 36807f5f92870c7c611e093029e8035e10a2e32b Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Wed, 9 Jan 2013 11:47:01 -0800 Subject: [PATCH] added UglifyJs2Filter --- src/Assetic/Filter/UglifyJs2Filter.php | 105 ++++++++++++++++ .../Test/Filter/UglifyJs2FilterTest.php | 116 ++++++++++++++++++ .../Test/Filter/UglifyJsFilterTest.php | 38 +++--- .../Test/Filter/fixtures/uglifyjs/script.js | 7 ++ 4 files changed, 248 insertions(+), 18 deletions(-) create mode 100644 src/Assetic/Filter/UglifyJs2Filter.php create mode 100644 tests/Assetic/Test/Filter/UglifyJs2FilterTest.php diff --git a/src/Assetic/Filter/UglifyJs2Filter.php b/src/Assetic/Filter/UglifyJs2Filter.php new file mode 100644 index 000000000..94ce627ad --- /dev/null +++ b/src/Assetic/Filter/UglifyJs2Filter.php @@ -0,0 +1,105 @@ + + */ +class UglifyJs2Filter extends BaseNodeFilter +{ + private $uglifyjsBin; + private $nodeBin; + private $compress; + private $beautify; + private $mangle; + + public function __construct($uglifyjsBin = '/usr/bin/uglifyjs', $nodeBin = null) + { + $this->uglifyjsBin = $uglifyjsBin; + $this->nodeBin = $nodeBin; + } + + public function setCompress($compress) + { + $this->compress = $compress; + } + + public function setBeautify($beautify) + { + $this->beautify = $beautify; + } + + public function setMangle($mangle) + { + $this->mangle = $mangle; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = $this->createProcessBuilder($this->nodeBin + ? array($this->nodeBin, $this->uglifyjsBin) + : array($this->uglifyjsBin)); + + if ($this->compress) { + $pb->add('--compress'); + } + + if ($this->beautify) { + $pb->add('--beautify'); + } + + if ($this->mangle) { + $pb->add('--mangle'); + } + + // input and output files + $input = tempnam(sys_get_temp_dir(), 'input'); + $output = tempnam(sys_get_temp_dir(), 'output'); + + file_put_contents($input, $asset->getContent()); + $pb->add('-o')->add($output)->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + if (file_exists($output)) { + unlink($output); + } + + if (127 === $code) { + throw new \RuntimeException('Path to node executable could not be resolved.'); + } + + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + if (!file_exists($output)) { + throw new \RuntimeException('Error creating output file.'); + } + + $asset->setContent(file_get_contents($output)); + + unlink($output); + } +} diff --git a/tests/Assetic/Test/Filter/UglifyJs2FilterTest.php b/tests/Assetic/Test/Filter/UglifyJs2FilterTest.php new file mode 100644 index 000000000..ba0c74858 --- /dev/null +++ b/tests/Assetic/Test/Filter/UglifyJs2FilterTest.php @@ -0,0 +1,116 @@ +findExecutable('uglifyjs', 'UGLIFYJS2_BIN'); + $nodeBin = $this->findExecutable('node', 'NODE_BIN'); + if (!$uglifyjsBin) { + $this->markTestSkipped('Unable to find `uglifyjs` executable.'); + } + + // verify uglifyjs version + $pb = new ProcessBuilder($nodeBin ? array($nodeBin, $uglifyjsBin) : array($uglifyjsBin)); + $pb->add('--version'); + if (isset($_SERVER['NODE_PATH'])) { + $pb->setEnv('NODE_PATH', $_SERVER['NODE_PATH']); + } + if (0 !== $pb->getProcess()->run()) { + $this->markTestSkipped('Incorrect version of UglifyJs'); + } + + $this->asset = new FileAsset(__DIR__.'/fixtures/uglifyjs/script.js'); + $this->asset->load(); + + $this->filter = new UglifyJs2Filter($uglifyjsBin, $nodeBin); + } + + protected function tearDown() + { + $this->asset = null; + $this->filter = null; + } + + public function testUglify() + { + $this->filter->filterDump($this->asset); + + $expected = '(function(){var foo=new Array(1,2,3,4);var bar=Array(a,b,c);var var1=new Array(5);var var2=new Array(a);function bar(foo){var2.push(foo);return foo}var foo=function(var1){return var1};foo("abc123");bar("abc123")})();'; + $this->assertEquals($expected, $this->asset->getContent()); + } + + public function testCompress() + { + $this->filter->setCompress(true); + $this->filter->filterDump($this->asset); + + $expected = '(function(){function bar(foo){return var2.push(foo),foo}var foo=[1,2,3,4],bar=[a,b,c];Array(5);var var2=Array(a),foo=function(var1){return var1};foo("abc123"),bar("abc123")})();'; + $this->assertEquals($expected, $this->asset->getContent()); + } + + public function testMangle() + { + $this->filter->setMangle(true); + $this->filter->filterDump($this->asset); + + $expected = '(function(){var r=new Array(1,2,3,4);var n=Array(a,b,c);var u=new Array(5);var e=new Array(a);function n(r){e.push(r);return r}var r=function(r){return r};r("abc123");n("abc123")})();'; + $this->assertEquals($expected, $this->asset->getContent()); + } + + public function testCompressAndMangle() + { + $this->filter->setCompress(true); + $this->filter->setMangle(true); + $this->filter->filterDump($this->asset); + + $expected = '(function(){function r(r){return u.push(r),r}var n=[1,2,3,4],r=[a,b,c];Array(5);var u=Array(a),n=function(r){return r};n("abc123"),r("abc123")})();'; + $this->assertEquals($expected, $this->asset->getContent()); + } + + public function testBeautify() + { + $this->filter->setBeautify(true); + $this->filter->filterDump($this->asset); + + $expected = <<assertEquals($expected, $this->asset->getContent()); + } +} diff --git a/tests/Assetic/Test/Filter/UglifyJsFilterTest.php b/tests/Assetic/Test/Filter/UglifyJsFilterTest.php index 9cace4ded..c27e8a71f 100644 --- a/tests/Assetic/Test/Filter/UglifyJsFilterTest.php +++ b/tests/Assetic/Test/Filter/UglifyJsFilterTest.php @@ -60,9 +60,9 @@ public function testUglify() $expected = <<assertSame($expected, $this->asset->getContent()); + $this->assertEquals($expected, $this->asset->getContent()); } public function testUnsafeUglify() @@ -73,9 +73,9 @@ public function testUnsafeUglify() $expected = <<assertSame($expected, $this->asset->getContent()); + $this->assertEquals($expected, $this->asset->getContent()); } public function testBeautifyUglify() @@ -86,30 +86,32 @@ public function testBeautifyUglify() $expected = <<assertSame($expected, $this->asset->getContent()); + $this->assertEquals($expected, $this->asset->getContent()); } - public function testMangleUglify() + public function testNoMangleUglify() { - $this->filter->setMangle(true); + $this->filter->setMangle(false); $this->filter->filterDump($this->asset); $expected = <<assertSame($expected, $this->asset->getContent()); + $this->assertEquals($expected, $this->asset->getContent()); } public function testNoCopyrightUglify() @@ -117,7 +119,7 @@ public function testNoCopyrightUglify() $this->filter->setNoCopyright(true); $this->filter->filterDump($this->asset); - $expected = 'function bar(e){return var2.push(e),e}var foo=new Array(1,2,3,4),bar=Array(a,b,c),var1=new Array(5),var2=new Array(a),foo=function(e){return e};'; - $this->assertSame($expected, $this->asset->getContent()); + $expected = '(function(){function t(e){return r.push(e),e}var e=new Array(1,2,3,4),t=Array(a,b,c),n=new Array(5),r=new Array(a),e=function(e){return e};e("abc123"),t("abc123")})();'; + $this->assertEquals($expected, $this->asset->getContent()); } } diff --git a/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js b/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js index a7c223337..7d0843367 100644 --- a/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js +++ b/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js @@ -2,6 +2,8 @@ * Copyright */ +(function() { + var foo = new Array(1, 2, 3, 4); var bar = Array(a, b, c); var var1 = new Array(5); @@ -16,3 +18,8 @@ function bar(foo) { var foo = function (var1) { return var1; } + +foo('abc123') +bar('abc123') + +})()