Refactors source map tracking to allow multiple origins.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 12 Apr 2015 15:47:56 +0000 (16:47 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 12 Apr 2015 16:58:57 +0000 (17:58 +0100)
See https://github.com/jakubpawlowicz/clean-css/issues/414#issuecomment-71010841
as a reference.

It allows introduced properties to have a mapping to many individual components.

lib/properties/optimizer.js
lib/properties/shorthand-compactor.js
lib/selectors/tokenizer.js
lib/stringifier/source-maps.js
test/properties/shorthand-compacting-source-maps-test.js [new file with mode: 0644]
test/selectors/tokenizer-source-maps-test.js
test/source-map-test.js

index 83e60a7..f777a52 100644 (file)
@@ -187,7 +187,7 @@ function optimize(selector, properties, mergeAdjacent, withCompacting, options,
 
   if (withCompacting && options.shorthandCompacting) {
     compactOverrides(_properties, options.compatibility, validator);
-    compactShorthands(_properties, options.compatibility, validator);
+    compactShorthands(_properties, options.sourceMap, validator);
   }
 
   restoreShorthands(_properties);
index 3c87a3c..303c9da 100644 (file)
@@ -17,7 +17,22 @@ function mixedImportance(components) {
   return false;
 }
 
-function replaceWithShorthand(properties, candidateComponents, name, validator) {
+function componentSourceMaps(components) {
+  var sourceMapping = [];
+
+  for (var name in components) {
+    var component = components[name];
+    var originalValue = component.all[component.position];
+    var mapping = originalValue[0][originalValue[0].length - 1];
+
+    if (Array.isArray(mapping))
+      Array.prototype.push.apply(sourceMapping, mapping);
+  }
+
+  return sourceMapping;
+}
+
+function replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator) {
   var descriptor = compactable[name];
   var newValuePlaceholder = [[name, false, false], [descriptor.defaultValue]];
   var all;
@@ -48,6 +63,12 @@ function replaceWithShorthand(properties, candidateComponents, name, validator)
     candidateComponents[componentName].unused = true;
   }
 
+  if (sourceMaps) {
+    var sourceMapping = componentSourceMaps(candidateComponents);
+    if (sourceMapping.length > 0)
+      newValuePlaceholder[0].push(sourceMapping);
+  }
+
   newProperty.position = all.length;
   newProperty.all = all;
   newProperty.all.push(newValuePlaceholder);
@@ -56,7 +77,7 @@ function replaceWithShorthand(properties, candidateComponents, name, validator)
   properties.push(newProperty);
 }
 
-function invalidateOrCompact(properties, position, candidates, validator) {
+function invalidateOrCompact(properties, position, candidates, sourceMaps, validator) {
   var property = properties[position];
 
   for (var name in candidates) {
@@ -73,11 +94,11 @@ function invalidateOrCompact(properties, position, candidates, validator) {
     if (mixedImportance(candidateComponents))
       continue;
 
-    replaceWithShorthand(properties, candidateComponents, name, validator);
+    replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator);
   }
 }
 
-function compactShortands(properties, compatibility, validator) {
+function compactShortands(properties, sourceMaps, validator) {
   var candidates = {};
 
   if (properties.length < 3)
@@ -93,7 +114,7 @@ function compactShortands(properties, compatibility, validator) {
       continue;
 
     if (property.shorthand) {
-      invalidateOrCompact(properties, i, candidates, validator);
+      invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
     } else {
       var componentOf = descriptor.componentOf;
       candidates[componentOf] = candidates[componentOf] || {};
@@ -101,7 +122,7 @@ function compactShortands(properties, compatibility, validator) {
     }
   }
 
-  invalidateOrCompact(properties, i, candidates, validator);
+  invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
 }
 
 module.exports = compactShortands;
index 28ff533..c83c06c 100644 (file)
@@ -25,7 +25,7 @@ Tokenizer.prototype.toTokens = function (data) {
     chunk: chunker.next(),
     outer: this.minifyContext,
     track: this.sourceMaps ?
-      function (data, snapshotMetadata, fallbacks) { return track(data, context, snapshotMetadata, fallbacks); } :
+      function (data, snapshotMetadata, fallbacks) { return [[track(data, context, snapshotMetadata, fallbacks)]]; } :
       function () { return []; },
     sourceMaps: this.sourceMaps,
     state: [],
index 5e16ac7..7276664 100644 (file)
@@ -4,10 +4,6 @@ var all = require('./helpers').all;
 var unknownSource = '$stdin';
 
 function store(element, context) {
-  // handles defaults and values like `,` or `/` which do not have mapping
-  if (Array.isArray(element) && element.length == 1)
-    element = element[0];
-
   var fromString = typeof element == 'string';
   var value = fromString ? element : element[0];
 
@@ -20,22 +16,26 @@ function store(element, context) {
 
 function track(value, element, context) {
   if (element)
-    trackMetadata(element, context);
+    trackAllMappings(element, context);
 
   var parts = value.split('\n');
   context.line += parts.length - 1;
   context.column = parts.length > 1 ? 0 : (context.column + parts.pop().length);
 }
 
-function trackMetadata(element, context) {
-  var sourceAt = element.length - 1;
-  if (typeof element[sourceAt] == 'object')
-    sourceAt--;
+function trackAllMappings(element, context) {
+  var mapping = element[element.length - 1];
 
-  if (typeof element[sourceAt - 1] != 'number')
+  if (!Array.isArray(mapping))
     return;
 
-  var source = element[sourceAt] || unknownSource;
+  for (var i = 0, l = mapping.length; i < l; i++) {
+    trackMapping(mapping[i], context);
+  }
+}
+
+function trackMapping(mapping, context) {
+  var source = mapping[2] || unknownSource;
 
   context.outputMap.addMapping({
     generated: {
@@ -44,13 +44,13 @@ function trackMetadata(element, context) {
     },
     source: source,
     original: {
-      line: element[sourceAt - 2],
-      column: element[sourceAt - 1]
+      line: mapping[0],
+      column: mapping[1]
     }
   });
 
-  if (element[sourceAt + 1])
-    context.outputMap.setSourceContent(source, element[sourceAt + 1][element[sourceAt]]);
+  if (mapping[3])
+    context.outputMap.setSourceContent(source, mapping[3][mapping[2]]);
 }
 
 function stringify(tokens, options, restoreCallback, inputMapTracker) {
diff --git a/test/properties/shorthand-compacting-source-maps-test.js b/test/properties/shorthand-compacting-source-maps-test.js
new file mode 100644 (file)
index 0000000..b55b8d7
--- /dev/null
@@ -0,0 +1,59 @@
+var vows = require('vows');
+var assert = require('assert');
+
+var optimize = require('../../lib/properties/optimizer');
+
+var Tokenizer = require('../../lib/selectors/tokenizer');
+var SourceTracker = require('../../lib/utils/source-tracker');
+var SourceReader = require('../../lib/utils/source-reader');
+var InputSourceMapTracker = require('../../lib/utils/input-source-map-tracker');
+
+var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
+var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
+
+function _optimize(source) {
+  var inputSourceMapTracker = new InputSourceMapTracker({
+    options: { inliner: {} },
+    errors: {},
+    sourceTracker: new SourceTracker()
+  });
+  var tokens = new Tokenizer({
+    options: {},
+    inputSourceMapTracker: inputSourceMapTracker,
+    sourceReader: new SourceReader(),
+    sourceTracker: new SourceTracker(),
+    warnings: []
+  }, true).toTokens(source);
+
+  var compatibility = new Compatibility().toOptions();
+  var validator = new Validator(compatibility);
+  var options = {
+    aggressiveMerging: true,
+    compatibility: compatibility,
+    sourceMap: true,
+    shorthandCompacting: true
+  };
+  addOptimizationMetadata(tokens);
+  optimize(tokens[0][1], tokens[0][2], false, true, options, validator);
+
+  return tokens[0][2];
+}
+
+vows.describe(optimize)
+  .addBatch({
+    'with source map': {
+      topic: 'a{margin-top:10px;margin-bottom:4px;margin-left:5px;margin-right:5px}',
+      'into': function(topic) {
+        assert.deepEqual(_optimize(topic), [
+          [
+            ['margin', false, false, [[1, 2, undefined], [1, 18, undefined], [1, 36, undefined], [1, 52, undefined]]],
+            [ '10px', [[1, 13, undefined]]],
+            [ '5px', [[1, 65, undefined]]],
+            [ '4px', [[1, 32, undefined]]]
+          ]
+        ]);
+      }
+    }
+  })
+  .export(module);
index cfabed9..fc41da7 100644 (file)
@@ -59,7 +59,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             []
           ]
         ]
@@ -70,8 +70,8 @@ vows.describe('source-maps/analyzer')
           [
             'selector',
             [
-              ['a', 1, 0, undefined],
-              ['div', 1, 2, undefined]
+              ['a', [[1, 0, undefined]]],
+              ['div', [[1, 2, undefined]]]
             ],
             []
           ]
@@ -82,7 +82,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 1, undefined], ['div', 3, 0, undefined]],
+            [['a', [[1, 1, undefined]]], ['div', [[3, 0, undefined]]]],
             []
           ]
         ]
@@ -92,7 +92,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined], ['div', 1, 2, undefined], ['p', 1, 6, undefined]],
+            [['a', [[1, 0, undefined]]], ['div', [[1, 2, undefined]]], ['p', [[1, 6, undefined]]]],
             []
           ]
         ]
@@ -102,7 +102,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 1, undefined], ['div\na', 3, 0, undefined], ['p', 5, 1, undefined]],
+            [['a', [[1, 1, undefined]]], ['div\na', [[3, 0, undefined]]], ['p', [[5, 1, undefined]]]],
             []
           ]
         ]
@@ -112,12 +112,12 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             []
           ],
           [
             'selector',
-            [['div', 1, 3, undefined]],
+            [['div', [[1, 3, undefined]]]],
             []
           ]
         ]
@@ -127,17 +127,17 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             []
           ],
           [
             'selector',
-            [['div', 3, 0, undefined]],
+            [['div', [[3, 0, undefined]]]],
             []
           ],
           [
             'selector',
-            [['p', 5, 2, undefined]],
+            [['p', [[5, 2, undefined]]]],
             []
           ]
         ]
@@ -151,8 +151,8 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
-            [[['color', 1, 2, undefined], ['red', 1, 8, undefined]]]
+            [['a', [[1, 0, undefined]]]],
+            [[['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]]]
           ]
         ]
       ],
@@ -161,10 +161,10 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             [
-              [['color', 1, 2, undefined], ['red', 1, 8, undefined]],
-              [['border', 1, 12, undefined], ['none', 1, 19, undefined]]
+              [['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]],
+              [['border', [[1, 12, undefined]]], ['none', [[1, 19, undefined]]]]
             ]
           ]
         ]
@@ -174,11 +174,11 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             [
-              [['color', 1, 2, undefined], ['red', 1, 8, undefined]],
-              [['border', 2, 0, undefined], ['none', 3, 0, undefined]],
-              [['display', 5, 2, undefined], ['block', 5, 10, undefined]]
+              [['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]],
+              [['border', [[2, 0, undefined]]], ['none', [[3, 0, undefined]]]],
+              [['display', [[5, 2, undefined]]], ['block', [[5, 10, undefined]]]]
             ]
           ]
         ]
@@ -188,13 +188,13 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
-            [[['color', 1, 2, undefined], ['red', 1, 8, undefined]]]
+            [['a', [[1, 0, undefined]]]],
+            [[['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]]]
           ],
           [
             'selector',
-            [['div', 1, 12, undefined]],
-            [[['color', 1, 16, undefined], ['blue', 1, 22, undefined]]]
+            [['div', [[1, 12, undefined]]]],
+            [[['color', [[1, 16, undefined]]], ['blue', [[1, 22, undefined]]]]]
           ]
         ]
       ],
@@ -203,13 +203,13 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
-            [[['color', 1, 2, undefined], ['red', 1, 8, undefined]]]
+            [['a', [[1, 0, undefined]]]],
+            [[['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]]]
           ],
           [
             'selector',
-            [['div', 2, 1, undefined]],
-            [[['color', 2, 5, undefined], ['blue', 2, 11, undefined]]]
+            [['div', [[2, 1, undefined]]]],
+            [[['color', [[2, 5, undefined]]], ['blue', [[2, 11, undefined]]]]]
           ]
         ]
       ],
@@ -218,13 +218,13 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
-            [[['color', 1, 2, undefined], ['red', 1, 8, undefined]]]
+            [['a', [[1, 0, undefined]]]],
+            [[['color', [[1, 2, undefined]]], ['red', [[1, 8, undefined]]]]]
           ],
           [
             'selector',
-            [['div', 3, 1, undefined]],
-            [[['color', 3, 5, undefined], ['blue', 3, 11, undefined]]]
+            [['div', [[3, 1, undefined]]]],
+            [[['color', [[3, 5, undefined]]], ['blue', [[3, 11, undefined]]]]]
           ]
         ]
       ]
@@ -237,17 +237,17 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, undefined]],
+            [['a', [[1, 0, undefined]]]],
             []
           ],
           [
             'at-rule',
-            ['@import \n"test.css";', 1, 3, undefined]
+            ['@import \n"test.css";', [[1, 3, undefined]]]
           ],
           [
             'selector',
-            [['a', 4, 0, undefined]],
-            [[['color', 4, 2, undefined], ['red', 4, 8, undefined]]]
+            [['a', [[4, 0, undefined]]]],
+            [[['color', [[4, 2, undefined]]], ['red', [[4, 8, undefined]]]]]
           ]
         ]
       ],
@@ -256,12 +256,12 @@ vows.describe('source-maps/analyzer')
         [
           [
             'at-rule',
-            ['@charset "utf-8";', 1, 0, undefined]
+            ['@charset "utf-8";', [[1, 0, undefined]]]
           ],
           [
             'selector',
-            [['a', 1, 18, undefined]],
-            [[['color', 1, 20, undefined], ['red', 1, 26, undefined]]]
+            [['a', [[1, 18, undefined]]]],
+            [[['color', [[1, 20, undefined]]], ['red', [[1, 26, undefined]]]]]
           ]
         ]
       ]
@@ -274,12 +274,12 @@ vows.describe('source-maps/analyzer')
         [
           [
             'block',
-            ['@media (min-width:980px)', 1, 0, undefined],
+            ['@media (min-width:980px)', [[1, 0, undefined]]],
             [
               [
                 'selector',
-                [['a', 1, 25, undefined]],
-                [[['color', 1, 27, undefined], ['red', 1, 33, undefined]]]
+                [['a', [[1, 25, undefined]]]],
+                [[['color', [[1, 27, undefined]]], ['red', [[1, 33, undefined]]]]]
               ]
             ]
           ]
@@ -290,16 +290,16 @@ vows.describe('source-maps/analyzer')
         [
           [
             'block',
-            ['@media (\nmin-width:980px)', 1, 0, undefined],
+            ['@media (\nmin-width:980px)', [[1, 0, undefined]]],
             [
               [
                 'selector',
-                [['a', 4, 0, undefined]],
-                [[['color', 5, 0, undefined], ['red', 6, 0, undefined]]]
+                [['a', [[4, 0, undefined]]]],
+                [[['color', [[5, 0, undefined]]], ['red', [[6, 0, undefined]]]]]
               ],
               [
                 'selector',
-                [['p', 6, 4, undefined]],
+                [['p', [[6, 4, undefined]]]],
                 []
               ]
             ]
@@ -311,19 +311,19 @@ vows.describe('source-maps/analyzer')
         [
           [
             'block',
-            ['@media (min-width:980px)', 1, 0, undefined],
+            ['@media (min-width:980px)', [[1, 0, undefined]]],
             [
               [
                 'selector',
-                [['a', 1, 25, undefined]],
-                [[['color', 1, 27, undefined], ['red', 1, 33, undefined]]]
+                [['a', [[1, 25, undefined]]]],
+                [[['color', [[1, 27, undefined]]], ['red', [[1, 33, undefined]]]]]
               ]
             ]
           ],
           [
             'selector',
-            [['p', 1, 39, undefined]],
-            [[['color', 1, 41, undefined], ['red', 1, 47, undefined]]]
+            [['p', [[1, 39, undefined]]]],
+            [[['color', [[1, 41, undefined]]], ['red', [[1, 47, undefined]]]]]
           ]
         ]
       ],
@@ -332,17 +332,17 @@ vows.describe('source-maps/analyzer')
         [
           [
             'flat-block',
-            ['@font-face', 1, 0, undefined],
+            ['@font-face', [[1, 0, undefined]]],
             [
-              [['font-family', 1, 11, undefined], ['"Font"', 1, 24, undefined]],
-              [['src', 2, 0, undefined], ['url("font.ttf")', 2, 5, undefined]],
-              [['font-weight', 3, 0, undefined], ['normal', 3, 13, undefined]],
-              [['font-style', 3, 20, undefined], ['normal', 3, 32, undefined]]
+              [['font-family', [[1, 11, undefined]]], ['"Font"', [[1, 24, undefined]]]],
+              [['src', [[2, 0, undefined]]], ['url("font.ttf")', [[2, 5, undefined]]]],
+              [['font-weight', [[3, 0, undefined]]], ['normal', [[3, 13, undefined]]]],
+              [['font-style', [[3, 20, undefined]]], ['normal', [[3, 32, undefined]]]]
             ]
           ],
           [
             'selector',
-            [['a', 3, 39, undefined]],
+            [['a', [[3, 39, undefined]]]],
             []
           ]
         ]
@@ -352,9 +352,9 @@ vows.describe('source-maps/analyzer')
         [
           [
             'flat-block',
-            ['@font-face', 2, 0, undefined],
+            ['@font-face', [[2, 0, undefined]]],
             [
-              [['font-family', 3, 1, undefined], ['"Font"', 3, 14, undefined]]
+              [['font-family', [[3, 1, undefined]]], ['"Font"', [[3, 14, undefined]]]]
             ]
           ]
         ]
@@ -368,7 +368,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 5, undefined]],
+            [['a', [[1, 5, undefined]]]],
             []
           ]
         ]
@@ -378,7 +378,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 3, 5, undefined]],
+            [['a', [[3, 5, undefined]]]],
             []
           ]
         ]
@@ -389,10 +389,10 @@ vows.describe('source-maps/analyzer')
           [
             'selector',
             [
-              ['div[data-type=__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__]', 1, 0, undefined],
-              ['div[data-id=__ESCAPED_FREE_TEXT_CLEAN_CSS1(0,7)__]', 2, 5, undefined]
+              ['div[data-type=__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__]', [[1, 0, undefined]]],
+              ['div[data-id=__ESCAPED_FREE_TEXT_CLEAN_CSS1(0,7)__]', [[2, 5, undefined]]]
             ],
-            [[['color', 2, 26, undefined], ['red', 2, 32, undefined]]]
+            [[['color', [[2, 26, undefined]]], ['red', [[2, 32, undefined]]]]]
           ]
         ]
       ],
@@ -401,19 +401,19 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['div', 1, 0, undefined]],
+            [['div', [[1, 0, undefined]]]],
             [
               '__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS0(2,5)__',
-              [['background', 3, 5, undefined], ['__ESCAPED_URL_CLEAN_CSS0(0,20)__', 3, 16, undefined]],
-              [['color', 3, 37, undefined], ['blue', 3, 43, undefined]]
+              [['background', [[3, 5, undefined]]], ['__ESCAPED_URL_CLEAN_CSS0(0,20)__', [[3, 16, undefined]]]],
+              [['color', [[3, 37, undefined]]], ['blue', [[3, 43, undefined]]]]
             ]
           ],
           [
             'selector',
-            [['a', 3, 48, undefined]],
+            [['a', [[3, 48, undefined]]]],
             [
-              [['font-family', 3, 50, undefined], ['__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__', 3, 62, undefined]],
-              [['color', 4, 4, undefined], ['red', 4, 10, undefined]]
+              [['font-family', [[3, 50, undefined]]], ['__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__', [[3, 62, undefined]]]],
+              [['color', [[4, 4, undefined]]], ['red', [[4, 10, undefined]]]]
             ]
           ]
         ]
@@ -423,11 +423,11 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['div', 1, 0, undefined]],
+            [['div', [[1, 0, undefined]]]],
             [[
-              ['background', 1, 4, undefined],
-              ['url(image.png)', 1, 15, undefined],
-              ['no-repeat', 1, 29, undefined]
+              ['background', [[1, 4, undefined]]],
+              ['url(image.png)', [[1, 15, undefined]]],
+              ['no-repeat', [[1, 29, undefined]]]
             ]]
           ]
         ]
@@ -437,11 +437,11 @@ vows.describe('source-maps/analyzer')
         [
           [
             'at-rule',
-            ['@charset __ESCAPED_FREE_TEXT_CLEAN_CSS0(1, 5)__;', 1, 0, undefined]
+            ['@charset __ESCAPED_FREE_TEXT_CLEAN_CSS0(1, 5)__;', [[1, 0, undefined]]]
           ],
           [
             'selector',
-            [['div', 2, 7, undefined]],
+            [['div', [[2, 7, undefined]]]],
             []
           ]
         ]
@@ -451,12 +451,12 @@ vows.describe('source-maps/analyzer')
         [
           [
             'block',
-            ['@media (__ESCAPED_COMMENT_CLEAN_CSS0(2, 1)__min-width:980px)', 1, 0, undefined],
+            ['@media (__ESCAPED_COMMENT_CLEAN_CSS0(2, 1)__min-width:980px)', [[1, 0, undefined]]],
             [
               [
                 'selector',
-                [['a', 3, 18, undefined]],
-                [[['color', 3, 20, undefined], ['red', 3, 26, undefined]]]
+                [['a', [[3, 18, undefined]]]],
+                [[['color', [[3, 20, undefined]]], ['red', [[3, 26, undefined]]]]]
               ]
             ]
           ]
@@ -479,7 +479,7 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, 'one.css']],
+            [['a', [[1, 0, 'one.css']]]],
             []
           ]
         ]
@@ -498,13 +498,13 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['a', 1, 0, 'one.css']],
+            [['a', [[1, 0, 'one.css']]]],
             []
           ],
           [
             'selector',
-            [['a', 2, 0, 'two.css']],
-            [[['color', 2, 2, 'two.css'], ['red', 2, 8, 'two.css']]]
+            [['a', [[2, 0, 'two.css']]]],
+            [[['color', [[2, 2, 'two.css']]], ['red', [[2, 8, 'two.css']]]]]
           ]
         ]
       ]
@@ -525,8 +525,8 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['div > a', 1, 4, 'styles.less']],
-            [[['color', 2, 2, 'styles.less'], ['red', 2, 2, 'styles.less']]]
+            [['div > a', [[1, 4, 'styles.less']]]],
+            [[['color', [[2, 2, 'styles.less']]], ['red', [[2, 2, 'styles.less']]]]]
           ]
         ]
       ],
@@ -543,8 +543,8 @@ vows.describe('source-maps/analyzer')
         [
           [
             'selector',
-            [['div > a', 1, 4, 'styles.less']],
-            [[['color', 2, 2, 'styles.less'], ['red', 2, 2, 'styles.less'], ['red', 2, 2, 'styles.less']]]
+            [['div > a', [[1, 4, 'styles.less']]]],
+            [[['color', [[2, 2, 'styles.less']]], ['red', [[2, 2, 'styles.less']]], ['red', [[2, 2, 'styles.less']]]]]
           ]
         ]
       ]
index abacf57..5dd5630 100644 (file)
@@ -1807,8 +1807,8 @@ vows.describe('source-map')
         'has right output': function (minified) {
           assert.equal(minified.styles, 'a{margin:10px 5px 4px}');
         },
-        'has 4 mappings': function (minified) {
-          assert.lengthOf(minified.sourceMap._mappings._array, 4);
+        'has 8 mappings': function (minified) {
+          assert.lengthOf(minified.sourceMap._mappings._array, 8);
         },
         'has a `a` mapping': function (minified) {
           var mapping = {
@@ -1821,6 +1821,50 @@ vows.describe('source-map')
           };
           assert.deepEqual(minified.sourceMap._mappings._array[0], mapping);
         },
+        'has a `margin` -> `margin-top mapping`': function (minified) {
+          var mapping = {
+            generatedLine: 1,
+            generatedColumn: 2,
+            originalLine: 1,
+            originalColumn: 2,
+            source: '$stdin',
+            name: null
+          };
+          assert.deepEqual(minified.sourceMap._mappings._array[1], mapping);
+        },
+        'has a `margin` -> `margin-bottom mapping`': function (minified) {
+          var mapping = {
+            generatedLine: 1,
+            generatedColumn: 2,
+            originalLine: 2,
+            originalColumn: 0,
+            source: '$stdin',
+            name: null
+          };
+          assert.deepEqual(minified.sourceMap._mappings._array[2], mapping);
+        },
+        'has a `margin` -> `margin-left mapping`': function (minified) {
+          var mapping = {
+            generatedLine: 1,
+            generatedColumn: 2,
+            originalLine: 3,
+            originalColumn: 0,
+            source: '$stdin',
+            name: null
+          };
+          assert.deepEqual(minified.sourceMap._mappings._array[3], mapping);
+        },
+        'has a `margin` -> `margin-right mapping`': function (minified) {
+          var mapping = {
+            generatedLine: 1,
+            generatedColumn: 2,
+            originalLine: 4,
+            originalColumn: 0,
+            source: '$stdin',
+            name: null
+          };
+          assert.deepEqual(minified.sourceMap._mappings._array[4], mapping);
+        },
         'has a `10px` mapping': function (minified) {
           var mapping = {
             generatedLine: 1,
@@ -1830,7 +1874,7 @@ vows.describe('source-map')
             source: '$stdin',
             name: null
           };
-          assert.deepEqual(minified.sourceMap._mappings._array[1], mapping);
+          assert.deepEqual(minified.sourceMap._mappings._array[5], mapping);
         },
         'has a `5px` mapping': function (minified) {
           var mapping = {
@@ -1841,7 +1885,7 @@ vows.describe('source-map')
             source: '$stdin',
             name: null
           };
-          assert.deepEqual(minified.sourceMap._mappings._array[2], mapping);
+          assert.deepEqual(minified.sourceMap._mappings._array[6], mapping);
         },
         'has a `4px` mapping': function (minified) {
           var mapping = {
@@ -1852,7 +1896,7 @@ vows.describe('source-map')
             source: '$stdin',
             name: null
           };
-          assert.deepEqual(minified.sourceMap._mappings._array[3], mapping);
+          assert.deepEqual(minified.sourceMap._mappings._array[7], mapping);
         }
       }
     }