Fixes #124 - throws exception on broken @import statements.
authorGoalSmashers <jakub@goalsmashers.com>
Fri, 30 Aug 2013 07:55:25 +0000 (09:55 +0200)
committerGoalSmashers <jakub@goalsmashers.com>
Fri, 30 Aug 2013 07:55:25 +0000 (09:55 +0200)
History.md
lib/imports/inliner.js
test/binary-test.js
test/unit-test.js

index ebad7aa..fa8168a 100644 (file)
@@ -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+.
index ad0777d..5adf6f2 100644 (file)
@@ -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) {
index f5f3810..bd5d056 100644 (file)
@@ -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', {
index d6c6f74..68a1d8e 100644 (file)
@@ -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);",