3 namespace Drupal\Tests\Core\Asset;
5 use Drupal\Core\Asset\CssOptimizer;
6 use Drupal\Tests\UnitTestCase;
9 * Tests the CSS asset optimizer.
13 class CssOptimizerUnitTest extends UnitTestCase {
18 protected $backupGlobals = FALSE;
21 * A CSS asset optimizer.
23 * @var \Drupal\Core\Asset\CssOptimizer object.
27 protected function setUp() {
30 $this->optimizer = new CssOptimizer();
34 * Provides data for the CSS asset optimizing test.
36 public function providerTestOptimize() {
37 $path = 'core/tests/Drupal/Tests/Core/Asset/css_test_files/';
38 $absolute_path = dirname(__FILE__) . '/css_test_files/';
41 // - Stripped comments and white-space.
42 // - Retain white-space in selectors. (https://www.drupal.org/node/472820)
43 // - Retain pseudo-selectors. (https://www.drupal.org/node/460448)
51 'data' => $path . 'css_input_without_import.css',
52 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
53 'basename' => 'css_input_without_import.css',
55 file_get_contents($absolute_path . 'css_input_without_import.css.optimized.css'),
58 // - Proper URLs in imported files. (https://www.drupal.org/node/265719)
59 // - A background image with relative paths, which must be rewritten.
60 // - The rewritten background image path must also be passed through
61 // file_create_url(). (https://www.drupal.org/node/1961340)
62 // - Imported files that are external (protocol-relative URL or not)
63 // should not be expanded. (https://www.drupal.org/node/2014851)
71 'data' => $path . 'css_input_with_import.css',
72 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
73 'basename' => 'css_input_with_import.css',
75 str_replace('url(images/icon.png)', 'url(' . file_url_transform_relative(file_create_url($path . 'images/icon.png')) . ')', file_get_contents($absolute_path . 'css_input_with_import.css.optimized.css')),
78 // - Retain comment hacks.
86 'data' => $path . 'comment_hacks.css',
87 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
88 'basename' => 'comment_hacks.css',
90 file_get_contents($absolute_path . 'comment_hacks.css.optimized.css'),
92 // File in subfolder. Tests:
93 // - CSS import path is properly interpreted.
94 // (https://www.drupal.org/node/1198904)
95 // - Don't adjust data URIs (https://www.drupal.org/node/2142441)
102 'preprocess' => TRUE,
103 'data' => $path . 'css_subfolder/css_input_with_import.css',
104 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
105 'basename' => 'css_input_with_import.css',
107 str_replace('url(../images/icon.png)', 'url(' . file_url_transform_relative(file_create_url($path . 'images/icon.png')) . ')', file_get_contents($absolute_path . 'css_subfolder/css_input_with_import.css.optimized.css')),
110 // - Any @charaset declaration at the beginning of a file should be
111 // removed without breaking subsequent CSS.
118 'preprocess' => TRUE,
119 'data' => $path . 'charset_sameline.css',
120 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
121 'basename' => 'charset_sameline.css',
123 file_get_contents($absolute_path . 'charset.css.optimized.css'),
131 'preprocess' => TRUE,
132 'data' => $path . 'charset_newline.css',
133 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
134 'basename' => 'charset_newline.css',
136 file_get_contents($absolute_path . 'charset.css.optimized.css'),
144 'preprocess' => TRUE,
145 'data' => $path . 'css_input_with_bom.css',
146 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
147 'basename' => 'css_input_with_bom.css',
149 '.byte-order-mark-test{content:"☃";}' . "\n",
157 'preprocess' => TRUE,
158 'data' => $path . 'css_input_with_charset.css',
159 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
160 'basename' => 'css_input_with_charset.css',
162 '.charset-test{content:"€";}' . "\n",
170 'preprocess' => TRUE,
171 'data' => $path . 'css_input_with_bom_and_charset.css',
172 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
173 'basename' => 'css_input_with_bom_and_charset.css',
175 '.byte-order-mark-charset-test{content:"☃";}' . "\n",
183 'preprocess' => TRUE,
184 'data' => $path . 'css_input_with_utf16_bom.css',
185 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
186 'basename' => 'css_input_with_utf16_bom.css',
188 '.utf16-byte-order-mark-test{content:"☃";}' . "\n",
196 'preprocess' => TRUE,
197 'data' => $path . 'quotes.css',
198 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
199 'basename' => 'quotes.css',
201 file_get_contents($absolute_path . 'quotes.css.optimized.css'),
207 * Tests optimizing a CSS asset group containing 'type' => 'file'.
209 * @dataProvider providerTestOptimize
211 public function testOptimize($css_asset, $expected) {
213 $original_base_path = $base_path;
216 // \Drupal\Core\Asset\CssOptimizer::loadFile() relies on the current working
217 // directory being the one that is used when index.php is the entry point.
218 // Note: PHPUnit automatically restores the original working directory.
219 chdir(realpath(__DIR__ . '/../../../../../../'));
221 $this->assertEquals($expected, $this->optimizer->optimize($css_asset), 'Group of file CSS assets optimized correctly.');
223 $base_path = $original_base_path;
227 * Tests a file CSS asset with preprocessing disabled.
229 public function testTypeFilePreprocessingDisabled() {
230 $this->setExpectedException('Exception', 'Only file CSS assets with preprocessing enabled can be optimized.');
237 // Preprocessing disabled.
238 'preprocess' => FALSE,
239 'data' => 'tests/Drupal/Tests/Core/Asset/foo.css',
240 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
241 'basename' => 'foo.css',
243 $this->optimizer->optimize($css_asset);
247 * Tests a CSS asset with 'type' => 'external'.
249 public function testTypeExternal() {
250 $this->setExpectedException('Exception', 'Only file CSS assets can be optimized.');
255 'type' => 'external',
258 'preprocess' => TRUE,
259 'data' => 'http://example.com/foo.js',
260 'browsers' => ['IE' => TRUE, '!IE' => TRUE],
262 $this->optimizer->optimize($css_asset);
268 * Temporary mock for file_create_url(), until that is moved into
271 if (!function_exists('Drupal\Tests\Core\Asset\file_create_url')) {
272 function file_create_url($uri) {
273 return 'file_create_url:' . $uri;
278 * Temporary mock of file_url_transform_relative, until that is moved into
281 if (!function_exists('Drupal\Tests\Core\Asset\file_url_transform_relative')) {
282 function file_url_transform_relative($uri) {
283 return 'file_url_transform_relative:' . $uri;
288 * CssCollectionRenderer uses file_create_url() & file_url_transform_relative(),
289 * which *are* available when using the Simpletest test runner, but not when
290 * using the PHPUnit test runner; hence this hack.
292 namespace Drupal\Core\Asset;
294 if (!function_exists('Drupal\Core\Asset\file_create_url')) {
297 * Temporary mock for file_create_url(), until that is moved into
300 function file_create_url($uri) {
301 return \Drupal\Tests\Core\Asset\file_create_url($uri);
305 if (!function_exists('Drupal\Core\Asset\file_url_transform_relative')) {
308 * Temporary mock of file_url_transform_relative, until that is moved into
311 function file_url_transform_relative($uri) {
312 return \Drupal\Tests\Core\Asset\file_url_transform_relative($uri);
316 if (!function_exists('Drupal\Core\Asset\file_uri_scheme')) {
318 function file_uri_scheme($uri) {