Repository: lesshint/lesshint (js)

Issue:
zeroUnit erroneously report zeros in color functions
In `2.0-rc` `zeroUnit` will report this:
```css
color: rgb(0, 0, 0);
```

I've been thinking and I don't think we can just exclude certain functions since there are a lot of them in Less, Math and Color for example (full reference: http://lesscss.org/functions/).

I suggest we just ignore all function calls in `zeroUnit`.

Pull request description:
Don't check function arguments in zeroUnit
Closes #184

Patch:
diff --git a/lib/linters/README.md b/lib/linters/README.md
index 6ec89c2..a957c8a 100644
--- a/lib/linters/README.md
+++ b/lib/linters/README.md
@@ -119,23 +119,18 @@ Option     | Description
 ### invalid
 ```less
 .foo {
-  font-size: 1.0em;  // leading
-  font-size:  .5em;  // leading, trailing, both
-  font-size: 0.5em;  // trailing, both, none
-  font-size: 1.5em;  // trailing, both
-  font-size: 0.50em; // leading, trailing, none
+  font-size: .5em;  // leading, both
+  font-size: 1em;   // trailing, both
+  font-size: 1.0em; // none
 }
 ```
 
 ### valid
 ```less
 .foo {
-  font-size: 0.5em;  // leading
-  font-size: 1.5em;  // leading, none
-  font-size:  .50em; // trailing
-  font-size: 1.0em;  // trailing, both
-  font-size: 0.50em; // both
-  font-size:  .5em;  // none
+  font-size: 0.5em; // leading, both
+  font-size: 1.0em; // trailing, both
+  font-size: .5em;  // none
 }
 ```
 ## depthLevel
diff --git a/lib/linters/decimal_zero.js b/lib/linters/decimal_zero.js
index 2e0323e..32359eb 100644
--- a/lib/linters/decimal_zero.js
+++ b/lib/linters/decimal_zero.js
@@ -23,12 +23,8 @@ module.exports = {
 
             number = child.value;
 
-            /*
-             * Bail if:
-             *  - Not a floating point number
-             *  - Float parsed as 0 (e.g. 0.0, .0, 0.)
-             */
-            if (!(/^-?(\d*\.\d*)/.test(number)) || parseFloat(number) === 0) {
+            // Bail if it's a float parsed as 0 (e.g. 0.0, .0, 0.)
+            if (parseFloat(number) === 0) {
                 return;
             }
 
@@ -39,25 +35,29 @@ module.exports = {
 
             switch (config.style) {
                 case 'leading':
-                    if (!/^-?(\d+)\.(\d*[1-9])$/.test(number)) {
+                    if (!/^-?(\d+)\.?(\d*)$/.test(number)) {
                         output.type = 'leading';
                     }
+
                     break;
                 case 'trailing':
-                    if (!/^-?([1-9]\d*)?\.(\d*0)$/.test(number)) {
+                    if (!/^-?(\d*)?\.(\d*)$/.test(number)) {
                         output.type = 'trailing';
                     }
+
                     break;
                 case 'both':
-                    if (!/^-?(\d+)\.(\d*0)$/.test(number)) {
+                    if (!/^-?(\d+)\.(\d+)$/.test(number)) {
                         output.type = 'leading and trailing';
                     }
+
                     break;
                 case 'none':
                     if (!/^-?([1-9]\d*)?\.(\d*[1-9])$/.test(number)) {
                         output.type = 'leading and trailing';
                         output.inclusion = 'without';
                     }
+
                     break;
                 default:
                     throw new Error('Invalid setting value for decimalZero: ' + config.style);
diff --git a/lib/linters/url_quotes.js b/lib/linters/url_quotes.js
index 459eecc..8d60fe3 100644
--- a/lib/linters/url_quotes.js
+++ b/lib/linters/url_quotes.js
@@ -1,19 +1,27 @@
 'use strict';
 
+var parser = require('postcss-values-parser');
+
 module.exports = {
     name: 'urlQuotes',
     nodeTypes: ['decl', 'atrule'],
     message: 'URLs should be enclosed in quotes.',
 
     lint: function urlQuotesLinter (config, node) {
-
-        var parser = require('postcss-values-parser');
-        var ast = parser(node.params || node.value).parse();
-        var uri = ast.first.first;
-        var column;
-        var value;
         var rSingle = /^\'(.+)\'$/;
         var rDouble = /^\"(.+)\"$/;
+        var column;
+        var value;
+        var ast;
+        var uri;
+
+        // Nothing to check, bail
+        if (!node.params && !node.value) {
+            return;
+        }
+
+        ast = parser(node.params || node.value).parse();
+        uri = ast.first.first;
 
         if (uri.type !== 'func' || uri.value !== 'url') {
             return;
diff --git a/lib/linters/zero_unit.js b/lib/linters/zero_unit.js
index 331f285..c89fd70 100644
--- a/lib/linters/zero_unit.js
+++ b/lib/linters/zero_unit.js
@@ -34,7 +34,7 @@ module.exports = {
 
         ast = parser(node.value).parse();
 
-        ast.walk(function (child) {
+        ast.first.each(function (child) {
             var unit = child.unit;
             var valid = true;
 


Test patch:
diff --git a/test/specs/linters/decimal_zero.js b/test/specs/linters/decimal_zero.js
index 5399359..165b7dd 100644
--- a/test/specs/linters/decimal_zero.js
+++ b/test/specs/linters/decimal_zero.js
@@ -110,16 +110,6 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should allow number without decimal', function () {
-                var source = 'font-size: 1em;';
-
-                return spec.parse(source, function (ast) {
-                    var result = spec.linter.lint(options, ast.root.first);
-
-                    expect(result).to.be.undefined;
-                });
-            });
-
             it('should allow number with trailing decimal zero', function () {
                 var source = 'font-size: 1.0em;';
 
@@ -131,26 +121,11 @@ describe('lesshint', function () {
             });
 
             it('should not allow number without trailing decimal zero', function () {
-                var source = 'font-size: 1.5em;';
+                var source = 'font-size: 1em;';
                 var expected = [{
                     column: 12,
                     line: 1,
-                    message: '1.5 should be written with trailing zero.'
-                }];
-
-                return spec.parse(source, function (ast) {
-                    var result = spec.linter.lint(options, ast.root.first);
-
-                    expect(result).to.deep.equal(expected);
-                });
-            });
-
-            it('should not allow number without trailing decimal zero in a function', function () {
-                var source = 'color: rgba(0, 0, 0, 0.1);';
-                var expected = [{
-                    column: 22,
-                    line: 1,
-                    message: '0.1 should be written with trailing zero.'
+                    message: '1 should be written with trailing zero.'
                 }];
 
                 return spec.parse(source, function (ast) {
@@ -178,8 +153,8 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should allow decimal number greater than 1 without leading zero', function () {
-                var source = 'font-size: 1.250em;';
+            it('should allow decimal number less than 1 without trailing zero', function () {
+                var source = 'font-size: 0.5em;';
 
                 return spec.parse(source, function (ast) {
                     var result = spec.linter.lint(options, ast.root.first);
@@ -188,42 +163,22 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should not allow number without trailing decimal zero', function () {
+            it('should allow decimal number greater than 1 without leading zero', function () {
                 var source = 'font-size: 1.5em;';
-                var expected = [{
-                    column: 12,
-                    line: 1,
-                    message: '1.5 should be written with leading and trailing zero.'
-                }];
 
                 return spec.parse(source, function (ast) {
                     var result = spec.linter.lint(options, ast.root.first);
 
-                    expect(result).to.deep.equal(expected);
-                });
-            });
-
-            it('should not allow number without trailing decimal zero in a function', function () {
-                var source = 'color: rgba(0, 0, 0, 1.5);';
-                var expected = [{
-                    column: 22,
-                    line: 1,
-                    message: '1.5 should be written with leading and trailing zero.'
-                }];
-
-                return spec.parse(source, function (ast) {
-                    var result = spec.linter.lint(options, ast.root.first);
-
-                    expect(result).to.deep.equal(expected);
+                    expect(result).to.be.undefined;
                 });
             });
 
             it('should not allow number without leading decimal zero', function () {
-                var source = 'font-size: .50em;';
+                var source = 'font-size: .5em;';
                 var expected = [{
                     column: 12,
                     line: 1,
-                    message: '.50 should be written with leading and trailing zero.'
+                    message: '.5 should be written with leading and trailing zero.'
                 }];
 
                 return spec.parse(source, function (ast) {
@@ -233,12 +188,12 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should not allow number without leading decimal zero in a function', function () {
-                var source = 'color: rgba(0, 0, 0, .50);';
+            it('should not allow number without trailing decimal zero', function () {
+                var source = 'font-size: 1em;';
                 var expected = [{
-                    column: 22,
+                    column: 12,
                     line: 1,
-                    message: '.50 should be written with leading and trailing zero.'
+                    message: '1 should be written with leading and trailing zero.'
                 }];
 
                 return spec.parse(source, function (ast) {
@@ -266,36 +221,6 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should not allow number with trailing decimal zero', function () {
-                var source = 'font-size: .50em;';
-                var expected = [{
-                    column: 12,
-                    line: 1,
-                    message: '.50 should be written without leading and trailing zero.'
-                }];
-
-                return spec.parse(source, function (ast) {
-                    var result = spec.linter.lint(options, ast.root.first);
-
-                    expect(result).to.deep.equal(expected);
-                });
-            });
-
-            it('should not allow number with trailing decimal zero in a function', function () {
-                var source = 'color: rgba(0, 0, 0, .50);';
-                var expected = [{
-                    column: 22,
-                    line: 1,
-                    message: '.50 should be written without leading and trailing zero.'
-                }];
-
-                return spec.parse(source, function (ast) {
-                    var result = spec.linter.lint(options, ast.root.first);
-
-                    expect(result).to.deep.equal(expected);
-                });
-            });
-
             it('should not allow number with leading decimal zero', function () {
                 var source = 'font-size: 0.5em;';
                 var expected = [{
@@ -311,12 +236,12 @@ describe('lesshint', function () {
                 });
             });
 
-            it('should not allow number with trailing decimal zero in a function', function () {
-                var source = 'color: rgba(0, 0, 0, 0.5);';
+            it('should not allow number with trailing decimal zero', function () {
+                var source = 'font-size: 1.0em;';
                 var expected = [{
-                    column: 22,
+                    column: 12,
                     line: 1,
-                    message: '0.5 should be written without leading and trailing zero.'
+                    message: '1.0 should be written without leading and trailing zero.'
                 }];
 
                 return spec.parse(source, function (ast) {
diff --git a/test/specs/linters/zero_unit.js b/test/specs/linters/zero_unit.js
index 3e76d51..8a9c594 100644
--- a/test/specs/linters/zero_unit.js
+++ b/test/specs/linters/zero_unit.js
@@ -144,6 +144,19 @@ describe('lesshint', function () {
             });
         });
 
+        it('should not check function arguments', function () {
+            var source = 'color: rgb(0, 0, 0);';
+            var options = {
+                style: 'no_unit'
+            };
+
+            return spec.parse(source, function (ast) {
+                var result = spec.linter.lint(options, ast.root.first);
+
+                expect(result).to.be.undefined;
+            });
+        });
+
         it('should throw on invalid "style" value', function () {
             var source = 'margin-right: 0;';
             var options = {