Followup r83885: add JSMin+ 1.3 to use its parser to verify output of JavaScriptMinif...
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / JavaScriptMinifierTest.php
1 <?php
2
3 class JavaScriptMinifierTest extends MediaWikiTestCase {
4
5 function provideCases() {
6 return array(
7 // Basic tokens
8 array( "\r\t\f \v\n\r", "" ),
9 array( "/* Foo *\n*bar\n*/", "" ),
10 /**
11 * ' Foo \' bar \
12 * baz \' quox ' .
13 */
14 array( "' Foo \\' bar \\\n baz \\' quox ' .length", "' Foo \\' bar \\\n baz \\' quox '.length" ),
15 array( "\" Foo \\\" bar \\\n baz \\\" quox \" .length", "\" Foo \\\" bar \\\n baz \\\" quox \".length" ),
16 array( "// Foo b/ar baz", "" ),
17 array( "/ Foo \\/ bar [ / \\] / ] baz / .length", "/ Foo \\/ bar [ / \\] / ] baz /.length" ),
18 // HTML comments
19 array( "<!-- Foo bar", "" ),
20 array( "<!-- Foo --> bar", "" ),
21 array( "--> Foo", "" ),
22 array( "x --> y", "x-->y" ),
23 // Semicolon insertion
24 array( "(function(){return\nx;})", "(function(){return\nx;})" ),
25 array( "throw\nx;", "throw\nx;" ),
26 array( "while(p){continue\nx;}", "while(p){continue\nx;}" ),
27 array( "while(p){break\nx;}", "while(p){break\nx;}" ),
28 array( "var\nx;", "var x;" ),
29 array( "x\ny;", "x\ny;" ),
30 array( "x\n++y;", "x\n++y;" ),
31 array( "x\n!y;", "x\n!y;" ),
32 array( "x\n{y}", "x\n{y}" ),
33 array( "x\n+y;", "x+y;" ),
34 array( "x\n(y);", "x(y);" ),
35 array( "5.\nx;", "5.\nx;" ),
36 array( "0xFF.\nx;", "0xFF.x;" ),
37 array( "5.3.\nx;", "5.3.x;" ),
38 // Token separation
39 array( "x in y", "x in y" ),
40 array( "/x/g in y", "/x/g in y" ),
41 array( "x in 30", "x in 30" ),
42 array( "x + ++ y", "x+ ++y" ),
43 array( "x / /y/.exec(z)", "x/ /y/.exec(z)" ),
44 // State machine
45 array( "/ x/g", "/ x/g" ),
46 array( "(function(){return/ x/g})", "(function(){return/ x/g})" ),
47 array( "+/ x/g", "+/ x/g" ),
48 array( "++/ x/g", "++/ x/g" ),
49 array( "x/ x/g", "x/x/g" ),
50 array( "(/ x/g)", "(/ x/g)" ),
51 array( "if(/ x/g);", "if(/ x/g);" ),
52 array( "(x/ x/g)", "(x/x/g)" ),
53 array( "([/ x/g])", "([/ x/g])" ),
54 array( "+x/ x/g", "+x/x/g" ),
55 array( "{}/ x/g", "{}/ x/g" ),
56 array( "+{}/ x/g", "+{}/x/g" ),
57 array( "(x)/ x/g", "(x)/x/g" ),
58 array( "if(x)/ x/g", "if(x)/ x/g" ),
59 array( "for(x;x;{}/ x/g);", "for(x;x;{}/x/g);" ),
60 array( "x;x;{}/ x/g", "x;x;{}/ x/g" ),
61 array( "x:{}/ x/g", "x:{}/ x/g" ),
62 array( "switch(x){case y?z:{}/ x/g:{}/ x/g;}", "switch(x){case y?z:{}/x/g:{}/ x/g;}" ),
63 array( "function x(){}/ x/g", "function x(){}/ x/g" ),
64 array( "+function x(){}/ x/g", "+function x(){}/x/g" ),
65
66 // Tests for things that broke in the past
67 // Multiline quoted string
68 array( "var foo=\"\\\nblah\\\n\";", "var foo=\"\\\nblah\\\n\";" ),
69 // Multiline quoted string followed by string with spaces
70 array( "var foo=\"\\\nblah\\\n\";\nvar baz = \" foo \";\n", "var foo=\"\\\nblah\\\n\";var baz=\" foo \";" ),
71 // URL in quoted string ( // is not a comment)
72 array( "aNode.setAttribute('href','http://foo.bar.org/baz');", "aNode.setAttribute('href','http://foo.bar.org/baz');" ),
73 // URL in quoted string after multiline quoted string
74 array( "var foo=\"\\\nblah\\\n\";\naNode.setAttribute('href','http://foo.bar.org/baz');", "var foo=\"\\\nblah\\\n\";aNode.setAttribute('href','http://foo.bar.org/baz');" ),
75 // Division vs. regex nastiness
76 array( "alert( (10+10) / '/'.charCodeAt( 0 ) + '//' );", "alert((10+10)/'/'.charCodeAt(0)+'//');" ),
77 array( "if(1)/a /g.exec('Pa ss');", "if(1)/a /g.exec('Pa ss');" ),
78
79 // newline insertion after 1000 chars: break after the "++", not before
80 array( str_repeat( ';', 996 ) . "if(x++);", str_repeat( ';', 996 ) . "if(x++\n);" ),
81 );
82 }
83
84 /**
85 * @dataProvider provideCases
86 */
87 function testJavaScriptMinifierOutput( $code, $expectedOutput ) {
88 $minified = JavaScriptMinifier::minify( $code );
89
90 // JSMin+'s parser will throw an exception if output is not valid JS.
91 // suppression of warnings needed for stupid crap
92 wfSuppressWarnings();
93 $parser = new JSParser();
94 wfRestoreWarnings();
95 $parser->parse( $minified, 'minify-test.js', 1 );
96
97 $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." );
98 }
99 }