Repository: sasstools/sass-lint (js)

Issue:
New Rule: Border Zero
As per [Scsslint](https://github.com/brigade/scss-lint/blob/master/lib/scss_lint/linter/README.md#borderzero) - option to enforce either the use of `border: 0` or `border: none`

Pull request:
Add Border Zero rule
This PR adds a rule for Border Zero which enforces whether one should use `0` or `none` when specifying a zero `border` value

### Warning messages

When `convention: '0'` and value is `'none'`, the following message is displayed:
> A value of `none` is not allowed. `0` must be used.

When `convention: 'none'` and value is `'0'`, the following message is displayed:
> A value of `0` is not allowed. `none` must be used.

Closes #84 

DCO 1.1 Signed-off-by: Ben Griffith <gt11687@gmail.com>

Patch:
diff --git a/docs/rules/border-zero.md b/docs/rules/border-zero.md
new file mode 100644
index 0000000..a1377b7
--- /dev/null
+++ b/docs/rules/border-zero.md
@@ -0,0 +1,33 @@
+# Border Zero
+
+Rule `border-zero` will enforce whether one should use `0` or `none` when specifying a zero `border` value
+
+## Options
+
+* `convention`: `'0'`/`'none'` (defaults to `0`)
+
+## Examples
+
+When `convention: '0'`, the following are allowed. When `convention: 'none'`, the following are disallowed:
+
+```scss
+.foo {
+  border: 0;
+}
+
+.bar {
+  border-right: 0;
+}
+```
+
+When `convention: 'none'`, the following are allowed. When `convention: '0'`, the following are disallowed:
+
+```scss
+.foo {
+  border: none;
+}
+
+.bar {
+  border-left: none;
+}
+```
diff --git a/lib/config/sass-lint.yml b/lib/config/sass-lint.yml
index d106d16..7bf601f 100644
--- a/lib/config/sass-lint.yml
+++ b/lib/config/sass-lint.yml
@@ -25,6 +25,7 @@ rules:
   no-warn: 1
 
   # Style Guide
+  border-zero: 1
   clean-import-paths: 1
   comment: 1
   hex-length: 1
diff --git a/lib/rules/border-zero.js b/lib/rules/border-zero.js
new file mode 100644
index 0000000..9fdc9d7
--- /dev/null
+++ b/lib/rules/border-zero.js
@@ -0,0 +1,50 @@
+'use strict';
+
+var helpers = require('../helpers');
+
+var borders = ['border', 'border-top', 'border-right', 'border-bottom', 'border-left'];
+
+module.exports = {
+  'name': 'border-zero',
+  'defaults': {
+    'convention': '0'
+  },
+  'detect': function (ast, parser) {
+    var result = [];
+
+    ast.traverseByType('declaration', function (declaration) {
+      var isBorder = false;
+
+      declaration.traverse(function (item) {
+        if (item.type === 'property') {
+          item.traverse(function (child) {
+            if (borders.indexOf(child.content) !== -1) {
+              isBorder = true;
+            }
+          });
+        }
+
+        if (isBorder) {
+          if (item.type === 'value') {
+            var node = item.content[0];
+            if (node.type === 'number' || node.type === 'ident') {
+              if (node.content === '0' || node.content === 'none') {
+                if (parser.options.convention !== node.content) {
+                  result = helpers.addUnique(result, {
+                    'ruleId': parser.rule.name,
+                    'line': node.start.line,
+                    'column': node.start.column,
+                    'message': 'A value of `' + node.content + '` is not allowed. `' + parser.options.convention + '` must be used.',
+                    'severity': parser.severity
+                  });
+                }
+              }
+            }
+          }
+        }
+      });
+    });
+
+    return result;
+  }
+};


Test patch:
diff --git a/tests/main.js b/tests/main.js
index 070d509..7920294 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -499,6 +499,34 @@ describe('rule', function () {
     });
   });
 
+  //////////////////////////////
+  // Border Zero
+  //////////////////////////////
+
+  // Default
+  it('border zero - [convention: \'0\']', function (done) {
+    lintFile('border-zero.scss', {
+      'rules': {
+        'zero-unit': 0
+      }
+    }, function (data) {
+      assert.equal(2, data.warningCount);
+      done();
+    });
+  });
+
+  it('border zero - [convention: \'none\']', function (done) {
+    lintFile('border-zero.scss', {
+      'rules': {
+        'zero-unit': 0,
+        'border-zero': [1, { 'convention': 'none' }]
+      }
+    }, function (data) {
+      assert.equal(2, data.warningCount);
+      done();
+    });
+  });
+
   //////////////////////////////
   // Comment - no allowed
   //////////////////////////////
diff --git a/tests/sass/border-zero.scss b/tests/sass/border-zero.scss
new file mode 100644
index 0000000..7fcd5f6
--- /dev/null
+++ b/tests/sass/border-zero.scss
@@ -0,0 +1,19 @@
+.foo {
+  border: 0;
+}
+
+.bar {
+  border: none;
+}
+
+.baz {
+  border-right: 0;
+}
+
+.qux {
+  border-left: none;
+}
+
+.norf {
+  border: 1px;
+}