summaryrefslogtreecommitdiff
path: root/tests/phpunit/includes/libs/CSSMinTest.php
blob: 57017a84ea8111f9050c0460c9d90eda18b7cf1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
 * This file test the CSSMin library shipped with Mediawiki.
 *
 * @author Timo Tijhof
 */

class CSSMinTest extends MediaWikiTestCase {

	protected function setUp() {
		parent::setUp();

		$server = 'http://doc.example.org';

		$this->setMwGlobals( array(
			'wgServer' => $server,
			'wgCanonicalServer' => $server,
		) );
	}

	/**
	 * @dataProvider provideMinifyCases
	 */
	function testMinify( $code, $expectedOutput ) {
		$minified = CSSMin::minify( $code );

		$this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' );
	}

	function provideMinifyCases() {
		return array(
			// Whitespace
			array( "\r\t\f \v\n\r", "" ),
			array( "foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),

			// Loose comments
			array( "/* foo */", "" ),
			array( "/*******\n foo\n *******/", "" ),
			array( "/*!\n foo\n */", "" ),

			// Inline comments in various different places
			array( "/* comment */foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
			array( "foo/* comment */, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
			array( "foo,/* comment */ bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
			array( "foo, bar/* comment */ {\n\tprop: value;\n}", "foo,bar{prop:value}" ),
			array( "foo, bar {\n\t/* comment */prop: value;\n}", "foo,bar{prop:value}" ),
			array( "foo, bar {\n\tprop: /* comment */value;\n}", "foo,bar{prop:value}" ),
			array( "foo, bar {\n\tprop: value /* comment */;\n}", "foo,bar{prop:value }" ),
			array( "foo, bar {\n\tprop: value; /* comment */\n}", "foo,bar{prop:value; }" ),

			// Keep track of things that aren't as minified as much as they
			// could be (bug 35493)
			array( 'foo { prop: value ;}', 'foo{prop:value }' ),
			array( 'foo { prop : value; }', 'foo{prop :value}' ),
			array( 'foo { prop: value ; }', 'foo{prop:value }' ),
			array( 'foo { font-family: "foo" , "bar"; }', 'foo{font-family:"foo" ,"bar"}' ),
			array( "foo { src:\n\turl('foo') ,\n\turl('bar') ; }", "foo{src:url('foo') ,url('bar') }" ),

			// Interesting cases with string values
			// - Double quotes, single quotes
			array( 'foo { content: ""; }', 'foo{content:""}' ),
			array( "foo { content: ''; }", "foo{content:''}" ),
			array( 'foo { content: "\'"; }', 'foo{content:"\'"}' ),
			array( "foo { content: '\"'; }", "foo{content:'\"'}" ),
			// - Whitespace in string values
			array( 'foo { content: " "; }', 'foo{content:" "}' ),
		);
	}

	/**
	 * @dataProvider provideRemapCases
	 */
	function testRemap( $message, $params, $expectedOutput ) {
		$remapped = call_user_func_array( 'CSSMin::remap', $params );

		$messageAdd = " Case: $message";
		$this->assertEquals( $expectedOutput, $remapped, 'CSSMin::remap should return the expected url form.' . $messageAdd );
	}

	function provideRemapCases() {
		// Parameter signature:
		// CSSMin::remap( $code, $local, $remote, $embedData = true )
		return array(
			array(
				'Simple case',
				array( 'foo { prop: url(bar.png); }', false, 'http://example.org', false ),
				'foo { prop: url(http://example.org/bar.png); }',
			),
			array(
				'Without trailing slash',
				array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux', false ),
				'foo { prop: url(http://example.org/quux/../bar.png); }',
			),
			array(
				'With trailing slash on remote (bug 27052)',
				array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux/', false ),
				'foo { prop: url(http://example.org/quux/../bar.png); }',
			),
			array(
				'Guard against stripping double slashes from query',
				array( 'foo { prop: url(bar.png?corge=//grault); }', false, 'http://example.org/quux/', false ),
				'foo { prop: url(http://example.org/quux/bar.png?corge=//grault); }',
			),
			array(
				'Expand absolute paths',
				array( 'foo { prop: url(/w/skin/images/bar.png); }', false, 'http://example.org/quux', false ),
				'foo { prop: url(http://doc.example.org/w/skin/images/bar.png); }',
			),
		);
	}

	/**
	 * Seperated because they are currently broken (bug 35492)
	 *
	 * @group Broken
	 * @dataProvider provideStringCases
	 */
	function testMinifyWithCSSStringValues( $code, $expectedOutput ) {
		$this->testMinifyOutput( $code, $expectedOutput );
	}

	function provideStringCases() {
		return array(
			// String values should be respected
			// - More than one space in a string value
			array( 'foo { content: "  "; }', 'foo{content:"  "}' ),
			// - Using a tab in a string value (turns into a space)
			array( "foo { content: '\t'; }", "foo{content:'\t'}" ),
			// - Using css-like syntax in string values
			array( 'foo::after { content: "{;}"; position: absolute; }', 'foo::after{content:"{;}";position:absolute}' ),
		);
	}
}