From 4aa915a33d4e1bea4bff3c0d86e9977813cf7055 Mon Sep 17 00:00:00 2001 From: GoalSmashers Date: Fri, 30 Aug 2013 09:55:25 +0200 Subject: [PATCH] Fixes #124 - throws exception on broken @import statements. --- History.md | 1 + lib/imports/inliner.js | 38 ++++++++++++++++++++------------------ test/binary-test.js | 3 ++- test/unit-test.js | 19 +++++++++++++------ 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/History.md b/History.md index ebad7aa4..fa8168a5 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,7 @@ * Fixed issue [#65](https://github.com/GoalSmashers/clean-css/issues/65) - full color name / hex shortening. * Fixed issue [#84](https://github.com/GoalSmashers/clean-css/issues/84) - support for @import with media queries. +* Fixed issue [#124](https://github.com/GoalSmashers/clean-css/issues/124) - raise error on broken imports. * Fixed issue [#126](https://github.com/GoalSmashers/clean-css/issues/126) - proper CSS expressions handling. * Fixed issue [#130](https://github.com/GoalSmashers/clean-css/issues/130) - better code modularity. * Fixed issue [#135](https://github.com/GoalSmashers/clean-css/issues/135) - require node.js 0.8+. diff --git a/lib/imports/inliner.js b/lib/imports/inliner.js index ad0777dc..5adf6f24 100644 --- a/lib/imports/inliner.js +++ b/lib/imports/inliner.js @@ -54,25 +54,27 @@ module.exports = function Inliner() { var fullPath = path.resolve(path.join(relativeTo, importedFile)); - if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile() && options.visited.indexOf(fullPath) == -1) { - options.visited.push(fullPath); - - var importedData = fs.readFileSync(fullPath, 'utf8'); - var importRelativeTo = path.dirname(fullPath); - importedData = rebaseRelativeURLs(importedData, importRelativeTo, options._baseRelativeTo); - - var inlinedData = process(importedData, { - root: options.root, - relativeTo: importRelativeTo, - _baseRelativeTo: options.baseRelativeTo, - visited: options.visited - }); - return mediaQuery.length > 0 ? - '@media ' + mediaQuery + '{' + inlinedData + '}' : - inlinedData; - } else { + if (!fs.existsSync(fullPath) || !fs.statSync(fullPath).isFile()) + throw new Error('Broken @import declaration of "' + importedFile + '"'); + + if (options.visited.indexOf(fullPath) != -1) return ''; - } + + options.visited.push(fullPath); + + var importedData = fs.readFileSync(fullPath, 'utf8'); + var importRelativeTo = path.dirname(fullPath); + importedData = rebaseRelativeURLs(importedData, importRelativeTo, options._baseRelativeTo); + + var inlinedData = process(importedData, { + root: options.root, + relativeTo: importRelativeTo, + _baseRelativeTo: options.baseRelativeTo, + visited: options.visited + }); + return mediaQuery.length > 0 ? + '@media ' + mediaQuery + '{' + inlinedData + '}' : + inlinedData; }; var rebaseRelativeURLs = function(data, fromBase, toBase) { diff --git a/test/binary-test.js b/test/binary-test.js index f5f3810d..bd5d056f 100644 --- a/test/binary-test.js +++ b/test/binary-test.js @@ -80,7 +80,8 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({ }), 'no relative to path': binaryContext('./test/data/partials-absolute/base.css', { 'should not be able to resolve it fully': function(error, stdout) { - assert.equal(stdout, '.sub{padding:0}.base{margin:0}'); + assert.equal(stdout, ''); + assert.notEqual(error, null); } }), 'relative to path': binaryContext('-r ./test/data ./test/data/partials-absolute/base.css', { diff --git a/test/unit-test.js b/test/unit-test.js index d6c6f74c..68a1d8e4 100644 --- a/test/unit-test.js +++ b/test/unit-test.js @@ -7,9 +7,16 @@ var ColorShortener = require('../lib/colors/shortener'); var lineBreak = process.platform == 'win32' ? '\r\n' : '\n'; var cssContext = function(groups, options) { var context = {}; - var clean = function(cleanedCSS) { + var clean = function(expectedCSS) { return function(css) { - assert.equal(cleanCSS.process(css, options), cleanedCSS); + var cleanedCSS = null; + try { + cleanedCSS = cleanCSS.process(css, options); + } catch (e) { + // swallow - cleanedCSS is set to null and that's the new expected value + } + + assert.equal(cleanedCSS, expectedCSS); }; }; @@ -810,11 +817,11 @@ title']", '@import': cssContext({ 'empty': [ "@import url();", - "" + null ], 'of an unknown file': [ "@import url('fake.css');", - "" + null ], 'of a http file': "@import url(http://pro.goalsmashers.com/test.css);", 'of a https file': [ @@ -829,7 +836,7 @@ title']", 'of a remote file via // url with media': "@import url(//pro.goalsmashers.com/test.css) screen,tv;", 'of a directory': [ "@import url(test/data/partials);", - "" + null ], 'of a real file': [ "@import url(test/data/partials/one.css);", @@ -915,7 +922,7 @@ title']", '@import with absolute paths': cssContext({ 'of an unknown file': [ "@import url(/fake.css);", - "" + null ], 'of a real file': [ "@import url(/partials/one.css);", -- 2.34.1