MediaWiki  1.23.8
CSSMinTest.php
Go to the documentation of this file.
1 <?php
9 
10  protected function setUp() {
11  parent::setUp();
12 
13  $server = 'http://doc.example.org';
14 
15  $this->setMwGlobals( array(
16  'wgServer' => $server,
17  'wgCanonicalServer' => $server,
18  ) );
19  }
20 
25  public function testMinify( $code, $expectedOutput ) {
26  $minified = CSSMin::minify( $code );
27 
28  $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' );
29  }
30 
31  public static function provideMinifyCases() {
32  return array(
33  // Whitespace
34  array( "\r\t\f \v\n\r", "" ),
35  array( "foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
36 
37  // Loose comments
38  array( "/* foo */", "" ),
39  array( "/*******\n foo\n *******/", "" ),
40  array( "/*!\n foo\n */", "" ),
41 
42  // Inline comments in various different places
43  array( "/* comment */foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
44  array( "foo/* comment */, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
45  array( "foo,/* comment */ bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
46  array( "foo, bar/* comment */ {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
47  array( "foo, bar {\n\t/* comment */prop: value;\n}", "foo,bar{prop:value}" ),
48  array( "foo, bar {\n\tprop: /* comment */value;\n}", "foo,bar{prop:value}" ),
49  array( "foo, bar {\n\tprop: value /* comment */;\n}", "foo,bar{prop:value }" ),
50  array( "foo, bar {\n\tprop: value; /* comment */\n}", "foo,bar{prop:value; }" ),
51 
52  // Keep track of things that aren't as minified as much as they
53  // could be (bug 35493)
54  array( 'foo { prop: value ;}', 'foo{prop:value }' ),
55  array( 'foo { prop : value; }', 'foo{prop :value}' ),
56  array( 'foo { prop: value ; }', 'foo{prop:value }' ),
57  array( 'foo { font-family: "foo" , "bar"; }', 'foo{font-family:"foo" ,"bar"}' ),
58  array( "foo { src:\n\turl('foo') ,\n\turl('bar') ; }", "foo{src:url('foo') ,url('bar') }" ),
59 
60  // Interesting cases with string values
61  // - Double quotes, single quotes
62  array( 'foo { content: ""; }', 'foo{content:""}' ),
63  array( "foo { content: ''; }", "foo{content:''}" ),
64  array( 'foo { content: "\'"; }', 'foo{content:"\'"}' ),
65  array( "foo { content: '\"'; }", "foo{content:'\"'}" ),
66  // - Whitespace in string values
67  array( 'foo { content: " "; }', 'foo{content:" "}' ),
68  );
69  }
70 
77  public function testRemap( $message, $params, $expectedOutput ) {
78  $remapped = call_user_func_array( 'CSSMin::remap', $params );
79 
80  $messageAdd = " Case: $message";
81  $this->assertEquals( $expectedOutput, $remapped, 'CSSMin::remap should return the expected url form.' . $messageAdd );
82  }
83 
84  public static function provideRemapCases() {
85  // Parameter signature:
86  // CSSMin::remap( $code, $local, $remote, $embedData = true )
87  return array(
88  array(
89  'Simple case',
90  array( 'foo { prop: url(bar.png); }', false, 'http://example.org', false ),
91  'foo { prop: url(http://example.org/bar.png); }',
92  ),
93  array(
94  'Without trailing slash',
95  array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux', false ),
96  'foo { prop: url(http://example.org/quux/../bar.png); }',
97  ),
98  array(
99  'With trailing slash on remote (bug 27052)',
100  array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux/', false ),
101  'foo { prop: url(http://example.org/quux/../bar.png); }',
102  ),
103  array(
104  'Guard against stripping double slashes from query',
105  array( 'foo { prop: url(bar.png?corge=//grault); }', false, 'http://example.org/quux/', false ),
106  'foo { prop: url(http://example.org/quux/bar.png?corge=//grault); }',
107  ),
108  array(
109  'Expand absolute paths',
110  array( 'foo { prop: url(/w/skin/images/bar.png); }', false, 'http://example.org/quux', false ),
111  'foo { prop: url(http://doc.example.org/w/skin/images/bar.png); }',
112  ),
113  );
114  }
115 
122  public function testRemapRemapping( $message, $input, $expectedOutput ) {
123  $localPath = __DIR__ . '/../../data/cssmin/';
124  $remotePath = 'http://localhost/w/';
125 
126  $realOutput = CSSMin::remap( $input, $localPath, $remotePath );
127 
128  $this->assertEquals(
129  $expectedOutput,
130  preg_replace( '/\d+-\d+-\d+T\d+:\d+:\d+Z/', 'timestamp', $realOutput ),
131  "CSSMin::remap: $message"
132  );
133  }
134 
135  public static function provideRemapRemappingCases() {
136  // red.gif and green.gif are one-pixel 35-byte GIFs.
137  // large.png is a 35K PNG that should be non-embeddable.
138  // Full paths start with http://localhost/w/.
139  // Timestamps in output are replaced with 'timestamp'.
140 
141  // data: URIs for red.gif and green.gif
142  $red = 'data:image/gif;base64,R0lGODlhAQABAIAAAP8AADAAACwAAAAAAQABAAACAkQBADs=';
143  $green = 'data:image/gif;base64,R0lGODlhAQABAIAAAACAADAAACwAAAAAAQABAAACAkQBADs=';
144 
145  return array(
146  array(
147  'Regular file',
148  'foo { background: url(red.gif); }',
149  'foo { background: url(http://localhost/w/red.gif?timestamp); }',
150  ),
151  array(
152  'Regular file (missing)',
153  'foo { background: url(theColorOfHerHair.gif); }',
154  'foo { background: url(http://localhost/w/theColorOfHerHair.gif); }',
155  ),
156  array(
157  'Remote URL',
158  'foo { background: url(http://example.org/w/foo.png); }',
159  'foo { background: url(http://example.org/w/foo.png); }',
160  ),
161  array(
162  'Protocol-relative remote URL',
163  'foo { background: url(//example.org/w/foo.png); }',
164  'foo { background: url(//example.org/w/foo.png); }',
165  ),
166  array(
167  'Remote URL with query',
168  'foo { background: url(http://example.org/w/foo.png?query=yes); }',
169  'foo { background: url(http://example.org/w/foo.png?query=yes); }',
170  ),
171  array(
172  'Protocol-relative remote URL with query',
173  'foo { background: url(//example.org/w/foo.png?query=yes); }',
174  'foo { background: url(//example.org/w/foo.png?query=yes); }',
175  ),
176  array(
177  'Domain-relative URL',
178  'foo { background: url(/static/foo.png); }',
179  'foo { background: url(http://doc.example.org/static/foo.png); }',
180  ),
181  array(
182  'Domain-relative URL with query',
183  'foo { background: url(/static/foo.png?query=yes); }',
184  'foo { background: url(http://doc.example.org/static/foo.png?query=yes); }',
185  ),
186  array(
187  'Remote URL (unnecessary quotes not preserved)',
188  'foo { background: url("http://example.org/w/foo.png"); }',
189  'foo { background: url(http://example.org/w/foo.png); }',
190  ),
191  array(
192  'Embedded file',
193  'foo { /* @embed */ background: url(red.gif); }',
194  "foo { background: url($red); background: url(http://localhost/w/red.gif?timestamp)!ie; }",
195  ),
196  array(
197  'Can not embed remote URLs',
198  'foo { /* @embed */ background: url(http://example.org/w/foo.png); }',
199  'foo { background: url(http://example.org/w/foo.png); }',
200  ),
201  array(
202  'Embedded file (inline @embed)',
203  'foo { background: /* @embed */ url(red.gif); }',
204  "foo { background: url($red); background: url(http://localhost/w/red.gif?timestamp)!ie; }",
205  ),
206  array(
207  'Can not embed large files',
208  'foo { /* @embed */ background: url(large.png); }',
209  "foo { background: url(http://localhost/w/large.png?timestamp); }",
210  ),
211  array(
212  'Two regular files in one rule',
213  'foo { background: url(red.gif), url(green.gif); }',
214  'foo { background: url(http://localhost/w/red.gif?timestamp), url(http://localhost/w/green.gif?timestamp); }',
215  ),
216  array(
217  'Two embedded files in one rule',
218  'foo { /* @embed */ background: url(red.gif), url(green.gif); }',
219  "foo { background: url($red), url($green); background: url(http://localhost/w/red.gif?timestamp), url(http://localhost/w/green.gif?timestamp)!ie; }",
220  ),
221  array(
222  'Two embedded files in one rule (inline @embed)',
223  'foo { background: /* @embed */ url(red.gif), /* @embed */ url(green.gif); }',
224  "foo { background: url($red), url($green); background: url(http://localhost/w/red.gif?timestamp), url(http://localhost/w/green.gif?timestamp)!ie; }",
225  ),
226  array(
227  'Two embedded files in one rule (inline @embed), one too large',
228  'foo { background: /* @embed */ url(red.gif), /* @embed */ url(large.png); }',
229  "foo { background: url($red), url(http://localhost/w/large.png?timestamp); background: url(http://localhost/w/red.gif?timestamp), url(http://localhost/w/large.png?timestamp)!ie; }",
230  ),
231  array(
232  'Practical example with some noise',
233  'foo { /* @embed */ background: #f9f9f9 url(red.gif) 0 0 no-repeat; }',
234  "foo { background: #f9f9f9 url($red) 0 0 no-repeat; background: #f9f9f9 url(http://localhost/w/red.gif?timestamp) 0 0 no-repeat!ie; }",
235  ),
236  array(
237  'Does not mess with other properties',
238  'foo { color: red; background: url(red.gif); font-size: small; }',
239  'foo { color: red; background: url(http://localhost/w/red.gif?timestamp); font-size: small; }',
240  ),
241  array(
242  'Spacing and miscellanea not changed (1)',
243  'foo { background: url(red.gif); }',
244  'foo { background: url(http://localhost/w/red.gif?timestamp); }',
245  ),
246  array(
247  'Spacing and miscellanea not changed (2)',
248  'foo {background:url(red.gif)}',
249  'foo {background:url(http://localhost/w/red.gif?timestamp)}',
250  ),
251  array(
252  'Spaces within url() parentheses are ignored',
253  'foo { background: url( red.gif ); }',
254  'foo { background: url(http://localhost/w/red.gif?timestamp); }',
255  ),
256  array(
257  '@import rule to local file (should we remap this?)',
258  '@import url(/styles.css)',
259  '@import url(http://doc.example.org/styles.css)',
260  ),
261  array(
262  '@import rule to URL (should we remap this?)',
263  '@import url(//localhost/styles.css?query=yes)',
264  '@import url(//localhost/styles.css?query=yes)',
265  ),
266  );
267  }
268 
275  public function testBuildUrlValue( $message, $input, $expectedOutput ) {
276  $this->assertEquals(
277  $expectedOutput,
278  CSSMin::buildUrlValue( $input ),
279  "CSSMin::buildUrlValue: $message"
280  );
281  }
282 
283  public static function provideBuildUrlValueCases() {
284  return array(
285  array(
286  'Full URL',
287  'scheme://user@domain:port/~user/fi%20le.png?query=yes&really=y+s',
288  'url(scheme://user@domain:port/~user/fi%20le.png?query=yes&really=y+s)',
289  ),
290  array(
291  'data: URI',
292  'data:image/png;base64,R0lGODlh/+==',
293  'url(data:image/png;base64,R0lGODlh/+==)',
294  ),
295  array(
296  'URL with quotes',
297  "https://en.wikipedia.org/wiki/Wendy's",
298  "url(\"https://en.wikipedia.org/wiki/Wendy's\")",
299  ),
300  array(
301  'URL with parentheses',
302  'https://en.wikipedia.org/wiki/Boston_(band)',
303  'url("https://en.wikipedia.org/wiki/Boston_(band)")',
304  ),
305  );
306  }
307 
315  public function testMinifyWithCSSStringValues( $code, $expectedOutput ) {
316  $this->testMinifyOutput( $code, $expectedOutput );
317  }
318 
319  public static function provideStringCases() {
320  return array(
321  // String values should be respected
322  // - More than one space in a string value
323  array( 'foo { content: " "; }', 'foo{content:" "}' ),
324  // - Using a tab in a string value (turns into a space)
325  array( "foo { content: '\t'; }", "foo{content:'\t'}" ),
326  // - Using css-like syntax in string values
327  array( 'foo::after { content: "{;}"; position: absolute; }', 'foo::after{content:"{;}";position:absolute}' ),
328  );
329  }
330 }
CSSMinTest\setUp
setUp()
Definition: CSSMinTest.php:10
CSSMin\buildUrlValue
static buildUrlValue( $url)
Build a CSS 'url()' value for the given URL, quoting parentheses (and other funny characters) and esc...
Definition: CSSMin.php:166
CSSMin\minify
static minify( $css)
Removes whitespace from CSS data.
Definition: CSSMin.php:306
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
CSSMinTest\provideBuildUrlValueCases
static provideBuildUrlValueCases()
Definition: CSSMinTest.php:283
CSSMin\remap
static remap( $source, $local, $remote, $embedData=true)
Remaps CSS URL paths and automatically embeds data URIs for CSS rules or url() values preceded by an ...
Definition: CSSMin.php:187
CSSMinTest\provideMinifyCases
static provideMinifyCases()
Definition: CSSMinTest.php:31
$params
$params
Definition: styleTest.css.php:40
CSSMinTest
This file test the CSSMin library shipped with Mediawiki.
Definition: CSSMinTest.php:8
CSSMinTest\testRemap
testRemap( $message, $params, $expectedOutput)
This tests funky parameters to CSSMin::remap.
Definition: CSSMinTest.php:77
CSSMinTest\provideStringCases
static provideStringCases()
Definition: CSSMinTest.php:319
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Definition: MediaWikiTestCase.php:302
MediaWikiTestCase
Definition: MediaWikiTestCase.php:6
CSSMinTest\provideRemapCases
static provideRemapCases()
Definition: CSSMinTest.php:84
CSSMinTest\testMinify
testMinify( $code, $expectedOutput)
@dataProvider provideMinifyCases @covers CSSMin::minify
Definition: CSSMinTest.php:25
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
CSSMinTest\testBuildUrlValue
testBuildUrlValue( $message, $input, $expectedOutput)
This tests basic functionality of CSSMin::buildUrlValue.
Definition: CSSMinTest.php:275
CSSMinTest\testMinifyWithCSSStringValues
testMinifyWithCSSStringValues( $code, $expectedOutput)
Seperated because they are currently broken (bug 35492)
Definition: CSSMinTest.php:315
CSSMinTest\testRemapRemapping
testRemapRemapping( $message, $input, $expectedOutput)
This tests basic functionality of CSSMin::remap.
Definition: CSSMinTest.php:122
CSSMinTest\provideRemapRemappingCases
static provideRemapRemappingCases()
Definition: CSSMinTest.php:135