Repository: sasstools/sass-lint (js)

Issue:
Class Name Format
Add support for pascal case to Class Name Format linter.
https://github.com/sasstools/sass-lint/blob/master/docs/rules/class-name-format.md

It would be nice to support a naming convention like [SUIT CSS](https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md).

Pull request:
Add pascal case to name format rules
Adds pascal case format to all name format rules

closes #678 

`<DCO 1.1 Signed-off-by: Dan Purdy dan@danpurdy.co.uk>`

Patch:
diff --git a/docs/rules/class-name-format.md b/docs/rules/class-name-format.md
index f63b5c5..45cf6b5 100644
--- a/docs/rules/class-name-format.md
+++ b/docs/rules/class-name-format.md
@@ -120,6 +120,35 @@ When enabled, the following are disallowed:
 
 ## Example 4
 
+Settings:
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+.PascalCase {
+  content: '';
+}
+
+.Foo {
+  @extend .AnotherPascalCase;
+}
+```
+
+When enabled, the following are disallowed:
+
+```scss
+.HYPHENATED-UPPERCASE {
+  content: '';
+}
+
+.foo {
+  @extend .snake_case;
+}
+```
+
+## Example 5
+
 Settings:
 - `convention: snakecase`
 
@@ -147,7 +176,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: strictbem`
@@ -176,7 +205,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 6
+## Example 7
 
 Settings:
 - `convention: hyphenatedbem`
@@ -211,7 +240,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 7
+## Example 8
 
 Settings:
 - `convention: ^[_A-Z]+$`
diff --git a/docs/rules/function-name-format.md b/docs/rules/function-name-format.md
index 054dfaa..3648c62 100644
--- a/docs/rules/function-name-format.md
+++ b/docs/rules/function-name-format.md
@@ -83,6 +83,40 @@ When enabled, the following are disallowed:
 
 ## Example 3
 
+Settings:
+- `allow-leading-underscore: false`
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+@function PascalCase() {
+  @return "foo";
+}
+
+.foo {
+  content: AnotherPascalCase();
+}
+```
+
+When enabled, the following are disallowed:
+
+```scss
+@function HYPHENATED-UPPERCASE() {
+  @return "foo";
+}
+
+@function _camelCaseWithLeadingUnderscore() {
+  @return "foo";
+}
+
+.foo {
+  content: snake_case();
+}
+```
+
+## Example 4
+
 Settings:
 - `allow-leading-underscore: false`
 - `convention: snakecase`
@@ -115,7 +149,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 4
+## Example 5
 
 Settings:
 - `convention: strictbem`
@@ -148,7 +182,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: hyphenatedbem`
@@ -181,7 +215,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 6
+## Example 7
 
 Settings:
 - `allow-leading-underscore: true`
diff --git a/docs/rules/id-name-format.md b/docs/rules/id-name-format.md
index 7b2517c..071a8c8 100644
--- a/docs/rules/id-name-format.md
+++ b/docs/rules/id-name-format.md
@@ -110,6 +110,23 @@ When enabled, the following are allowed:
 }
 ```
 
+## Example 4
+
+Settings:
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+#PascalCase {
+  content: '';
+}
+
+#Foo {
+  @extend #AnotherPascalCase;
+}
+```
+
 When enabled, the following are disallowed:
 
 ```scss
@@ -122,7 +139,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 4
+## Example 5
 
 Settings:
 - `convention: snakecase`
@@ -151,7 +168,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: ^[_A-Z]+$`
diff --git a/docs/rules/mixin-name-format.md b/docs/rules/mixin-name-format.md
index 2bbbbe3..82d59d6 100644
--- a/docs/rules/mixin-name-format.md
+++ b/docs/rules/mixin-name-format.md
@@ -84,6 +84,40 @@ When enabled, the following are disallowed:
 
 ## Example 3
 
+Settings:
+- `allow-leading-underscore: false`
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+@mixin PascalCase() {
+  content: '';
+}
+
+.foo {
+  @include AnotherPascalCase();
+}
+```
+
+When enabled, the following are disallowed:
+
+```scss
+@mixin HYPHENATED-UPPERCASE() {
+  content: '';
+}
+
+@mixin _camelCaseWithLeadingUnderscore() {
+  content: '';
+}
+
+.foo {
+  @include snake_case();
+}
+```
+
+## Example 4
+
 Settings:
 - `allow-leading-underscore: false`
 - `convention: snakecase`
@@ -116,7 +150,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 4
+## Example 5
 
 Settings:
 - `convention: strictbem`
@@ -149,7 +183,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: hyphenatedbem`
@@ -183,7 +217,7 @@ When enabled, the following are disallowed:
 ```
 
 
-## Example 6
+## Example 7
 
 Settings:
 - `allow-leading-underscore: true`
diff --git a/docs/rules/placeholder-name-format.md b/docs/rules/placeholder-name-format.md
index 9cb3a68..a9f9866 100644
--- a/docs/rules/placeholder-name-format.md
+++ b/docs/rules/placeholder-name-format.md
@@ -84,6 +84,40 @@ When enabled, the following are disallowed:
 
 ## Example 3
 
+Settings:
+- `allow-leading-underscore: false`
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+%PascalCase {
+  content: '';
+}
+
+.foo {
+  @extend %AnotherPascalCase;
+}
+```
+
+When enabled, the following are disallowed:
+
+```scss
+%HYPHENATED-UPPERCASE {
+  content: '';
+}
+
+%_camelCaseWithLeadingUnderscore {
+  content: '';
+}
+
+.foo {
+  @extend %snake_case;
+}
+```
+
+## Example 4
+
 Settings:
 - `allow-leading-underscore: false`
 - `convention: snakecase`
@@ -116,7 +150,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 4
+## Example 5
 
 Settings:
 - `convention: strictbem`
@@ -149,7 +183,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: hyphenatedbem`
@@ -182,7 +216,7 @@ When enabled, the following are disallowed:
 }
 ```
 
-## Example 6
+## Example 7
 
 Settings:
 - `allow-leading-underscore: true`
diff --git a/docs/rules/variable-name-format.md b/docs/rules/variable-name-format.md
index df819ef..5d6e1f5 100644
--- a/docs/rules/variable-name-format.md
+++ b/docs/rules/variable-name-format.md
@@ -67,6 +67,33 @@ $_camelCaseWithLeadingUnderscore: 1px;
 
 ## Example 3
 
+Settings:
+- `allow-leading-underscore: false`
+- `convention: pascalcase`
+
+When enabled, the following are allowed:
+
+```scss
+$PascalCase: 1px;
+
+.foo {
+  width: $AnotherPascalCase;
+}
+```
+
+When enabled, the following are disallowed:
+
+```scss
+$HYPHENATED-UPPERCASE: 1px;
+$_camelCaseWithLeadingUnderscore: 1px;
+
+.foo {
+  width: $snake_case;
+}
+```
+
+## Example 4
+
 Settings:
 - `allow-leading-underscore: false`
 - `convention: snakecase`
@@ -92,7 +119,7 @@ $_snake_case_with_leading_underscore: 1px;
 }
 ```
 
-## Example 4
+## Example 5
 
 Settings:
 - `convention: strictbem`
@@ -119,7 +146,7 @@ $HYPHENATED-UPPERCASE: 1px;
 }
 ```
 
-## Example 5
+## Example 6
 
 Settings:
 - `convention: hyphenatedbem`
@@ -146,7 +173,7 @@ $HYPHENATED-UPPERCASE: 1px;
 }
 ```
 
-## Example 6
+## Example 7
 
 Settings:
 - `allow-leading-underscore: true`
diff --git a/lib/helpers.js b/lib/helpers.js
index 8183ba0..eb31192 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -136,6 +136,15 @@ helpers.isCamelCase = function (str) {
   return /^[a-z][a-zA-Z0-9]*$/.test(str);
 };
 
+/**
+ * Determines if a given string adheres to pascal-case format
+ * @param   {string}  str String to test
+ * @returns {boolean}     Whether str adheres to pascal-case format
+ */
+helpers.isPascalCase = function (str) {
+  return /^[A-Z][a-zA-Z0-9]*$/.test(str);
+};
+
 /**
  * Determines if a given string adheres to hyphenated-lowercase format
  * @param   {string}  str String to test
diff --git a/lib/rules/class-name-format.js b/lib/rules/class-name-format.js
index 8ecfe2f..983998d 100644
--- a/lib/rules/class-name-format.js
+++ b/lib/rules/class-name-format.js
@@ -42,6 +42,11 @@ module.exports = {
             violationMessage = 'Class \'.' + name + '\' should be written in camelCase';
           }
           break;
+        case 'pascalcase':
+          if (!helpers.isPascalCase(strippedName)) {
+            violationMessage = 'Class \'.' + name + '\' should be written in PascalCase';
+          }
+          break;
         case 'snakecase':
           if (!helpers.isSnakeCase(strippedName)) {
             violationMessage = 'Class \'.' + name + '\' should be written in snake_case';
diff --git a/lib/rules/function-name-format.js b/lib/rules/function-name-format.js
index 2bdccb9..8c2ea35 100644
--- a/lib/rules/function-name-format.js
+++ b/lib/rules/function-name-format.js
@@ -45,6 +45,11 @@ module.exports = {
           violationMessage = 'Function \'' + name + '\' should be written in camelCase';
         }
         break;
+      case 'pascalcase':
+        if (!helpers.isPascalCase(strippedName)) {
+          violationMessage = 'Function \'' + name + '\' should be written in PascalCase';
+        }
+        break;
       case 'snakecase':
         if (!helpers.isSnakeCase(strippedName)) {
           violationMessage = 'Function \'' + name + '\' should be written in snake_case';
@@ -52,12 +57,12 @@ module.exports = {
         break;
       case 'strictbem':
         if (!helpers.isStrictBEM(strippedName)) {
-          violationMessage = 'Function \'.' + name + '\' should be written in BEM (Block Element Modifier) format';
+          violationMessage = 'Function \'' + name + '\' should be written in BEM (Block Element Modifier) format';
         }
         break;
       case 'hyphenatedbem':
         if (!helpers.isHyphenatedBEM(strippedName)) {
-          violationMessage = 'Function \'.' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
+          violationMessage = 'Function \'' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
         }
         break;
       default:
diff --git a/lib/rules/id-name-format.js b/lib/rules/id-name-format.js
index 6a7801f..4186212 100644
--- a/lib/rules/id-name-format.js
+++ b/lib/rules/id-name-format.js
@@ -42,6 +42,11 @@ module.exports = {
             violationMessage = 'ID \'#' + name + '\' should be written in camelCase';
           }
           break;
+        case 'pascalcase':
+          if (!helpers.isPascalCase(strippedName)) {
+            violationMessage = 'ID \'#' + name + '\' should be written in PascalCase';
+          }
+          break;
         case 'snakecase':
           if (!helpers.isSnakeCase(strippedName)) {
             violationMessage = 'ID \'#' + name + '\' should be written in snake_case';
diff --git a/lib/rules/mixin-name-format.js b/lib/rules/mixin-name-format.js
index 3f10ef5..441badb 100644
--- a/lib/rules/mixin-name-format.js
+++ b/lib/rules/mixin-name-format.js
@@ -55,6 +55,11 @@ module.exports = {
             violationMessage = 'Mixin \'' + name + '\' should be written in camelCase';
           }
           break;
+        case 'pascalcase':
+          if (!helpers.isPascalCase(strippedName)) {
+            violationMessage = 'Mixin \'' + name + '\' should be written in PascalCase';
+          }
+          break;
         case 'snakecase':
           if (!helpers.isSnakeCase(strippedName)) {
             violationMessage = 'Mixin \'' + name + '\' should be written in snake_case';
@@ -62,12 +67,12 @@ module.exports = {
           break;
         case 'strictbem':
           if (!helpers.isStrictBEM(strippedName)) {
-            violationMessage = 'Mixin \'.' + name + '\' should be written in BEM (Block Element Modifier) format';
+            violationMessage = 'Mixin \'' + name + '\' should be written in BEM (Block Element Modifier) format';
           }
           break;
         case 'hyphenatedbem':
           if (!helpers.isHyphenatedBEM(strippedName)) {
-            violationMessage = 'Mixin \'.' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
+            violationMessage = 'Mixin \'' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
           }
           break;
         default:
diff --git a/lib/rules/placeholder-name-format.js b/lib/rules/placeholder-name-format.js
index 9b5e372..5024488 100644
--- a/lib/rules/placeholder-name-format.js
+++ b/lib/rules/placeholder-name-format.js
@@ -35,6 +35,11 @@ module.exports = {
             violationMessage = 'Placeholder \'%' + name + '\' should be written in camelCase';
           }
           break;
+        case 'pascalcase':
+          if (!helpers.isPascalCase(strippedName)) {
+            violationMessage = 'Placeholder \'%' + name + '\' should be written in PascalCase';
+          }
+          break;
         case 'snakecase':
           if (!helpers.isSnakeCase(strippedName)) {
             violationMessage = 'Placeholder \'%' + name + '\' should be written in snake_case';
@@ -42,12 +47,12 @@ module.exports = {
           break;
         case 'strictbem':
           if (!helpers.isStrictBEM(strippedName)) {
-            violationMessage = 'Placeholder \'.' + name + '\' should be written in BEM (Block Element Modifier) format';
+            violationMessage = 'Placeholder \'%' + name + '\' should be written in BEM (Block Element Modifier) format';
           }
           break;
         case 'hyphenatedbem':
           if (!helpers.isHyphenatedBEM(strippedName)) {
-            violationMessage = 'Placeholder \'.' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
+            violationMessage = 'Placeholder \'%' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
           }
           break;
         default:
diff --git a/lib/rules/variable-name-format.js b/lib/rules/variable-name-format.js
index 9ab4d6c..71e1723 100644
--- a/lib/rules/variable-name-format.js
+++ b/lib/rules/variable-name-format.js
@@ -35,6 +35,11 @@ module.exports = {
           violationMessage = 'Variable \'' + name + '\' should be written in camelCase';
         }
         break;
+      case 'pascalcase':
+        if (!helpers.isPascalCase(strippedName)) {
+          violationMessage = 'Variable \'' + name + '\' should be written in PascalCase';
+        }
+        break;
       case 'snakecase':
         if (!helpers.isSnakeCase(strippedName)) {
           violationMessage = 'Variable \'' + name + '\' should be written in snake_case';
@@ -42,12 +47,12 @@ module.exports = {
         break;
       case 'strictbem':
         if (!helpers.isStrictBEM(strippedName)) {
-          violationMessage = 'Variable \'.' + name + '\' should be written in BEM (Block Element Modifier) format';
+          violationMessage = 'Variable \'' + name + '\' should be written in BEM (Block Element Modifier) format';
         }
         break;
       case 'hyphenatedbem':
         if (!helpers.isHyphenatedBEM(strippedName)) {
-          violationMessage = 'Variable \'.' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
+          violationMessage = 'Variable \'' + name + '\' should be written in hyphenated BEM (Block Element Modifier) format';
         }
         break;
       default:


Test patch:
diff --git a/tests/helpers.js b/tests/helpers.js
index 126d10c..639bb02 100644
--- a/tests/helpers.js
+++ b/tests/helpers.js
@@ -458,6 +458,50 @@ describe('helpers', function () {
     done();
   });
 
+  //////////////////////////////
+  // isPascalCase
+  //////////////////////////////
+
+  it('isPascalCase - [\'TEST\' - true]', function (done) {
+
+    var result = helpers.isPascalCase('TEST');
+
+    assert.equal(true, result);
+    done();
+  });
+
+  it('isPascalCase - [\'test\' - false]', function (done) {
+
+    var result = helpers.isPascalCase('test');
+
+    assert.equal(false, result);
+    done();
+  });
+
+  it('isPascalCase - [AbcDEF - true]', function (done) {
+
+    var result = helpers.isPascalCase('AbcDEF');
+
+    assert.equal(true, result);
+    done();
+  });
+
+  it('isPascalCase - [\'123\' - false]', function (done) {
+
+    var result = helpers.isPascalCase('123');
+
+    assert.equal(false, result);
+    done();
+  });
+
+  it('isPascalCase - [\'ABcDeF\' - true]', function (done) {
+
+    var result = helpers.isPascalCase('ABcDeF');
+
+    assert.equal(true, result);
+    done();
+  });
+
   //////////////////////////////
   // isHyphenatedLowercase
   //////////////////////////////
diff --git a/tests/rules/class-name-format.js b/tests/rules/class-name-format.js
index c7bd7c9..220f382 100644
--- a/tests/rules/class-name-format.js
+++ b/tests/rules/class-name-format.js
@@ -12,7 +12,7 @@ describe('class name format - scss', function () {
     lint.test(file, {
       'class-name-format': 1
     }, function (data) {
-      lint.assert.equal(24, data.warningCount);
+      lint.assert.equal(27, data.warningCount);
       done();
     });
   });
@@ -26,7 +26,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(23, data.warningCount);
+      lint.assert.equal(26, data.warningCount);
       done();
     });
   });
@@ -40,7 +40,21 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(34, data.warningCount);
+      lint.assert.equal(36, data.warningCount);
+      done();
+    });
+  });
+
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'class-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(36, data.warningCount);
       done();
     });
   });
@@ -54,7 +68,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(29, data.warningCount);
+      lint.assert.equal(32, data.warningCount);
       done();
     });
   });
@@ -68,7 +82,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(19, data.warningCount);
+      lint.assert.equal(22, data.warningCount);
       done();
     });
   });
@@ -82,7 +96,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(17, data.warningCount);
+      lint.assert.equal(20, data.warningCount);
       done();
     });
   });
@@ -96,7 +110,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(35, data.warningCount);
+      lint.assert.equal(38, data.warningCount);
       done();
     });
   });
@@ -112,7 +126,7 @@ describe('class name format - scss', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(31, data.warningCount);
+      lint.assert.equal(34, data.warningCount);
       lint.assert.equal(data.messages[0].message, message);
       done();
     });
@@ -129,7 +143,7 @@ describe('class name format - sass', function () {
     lint.test(file, {
       'class-name-format': 1
     }, function (data) {
-      lint.assert.equal(24, data.warningCount);
+      lint.assert.equal(27, data.warningCount);
       done();
     });
   });
@@ -143,7 +157,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(23, data.warningCount);
+      lint.assert.equal(26, data.warningCount);
       done();
     });
   });
@@ -157,7 +171,21 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(34, data.warningCount);
+      lint.assert.equal(36, data.warningCount);
+      done();
+    });
+  });
+
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'class-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(36, data.warningCount);
       done();
     });
   });
@@ -171,7 +199,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(29, data.warningCount);
+      lint.assert.equal(32, data.warningCount);
       done();
     });
   });
@@ -185,7 +213,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(19, data.warningCount);
+      lint.assert.equal(22, data.warningCount);
       done();
     });
   });
@@ -199,7 +227,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(17, data.warningCount);
+      lint.assert.equal(20, data.warningCount);
       done();
     });
   });
@@ -213,7 +241,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(35, data.warningCount);
+      lint.assert.equal(38, data.warningCount);
       done();
     });
   });
@@ -229,7 +257,7 @@ describe('class name format - sass', function () {
         }
       ]
     }, function (data) {
-      lint.assert.equal(31, data.warningCount);
+      lint.assert.equal(34, data.warningCount);
       lint.assert.equal(data.messages[0].message, message);
       done();
     });
diff --git a/tests/rules/function-name-format.js b/tests/rules/function-name-format.js
index e797f6a..ba2bb02 100644
--- a/tests/rules/function-name-format.js
+++ b/tests/rules/function-name-format.js
@@ -28,6 +28,20 @@ describe('function name format - scss', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'function-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'function-name-format': [
@@ -126,6 +140,20 @@ describe('function name format - sass', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'function-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'function-name-format': [
diff --git a/tests/rules/id-name-format.js b/tests/rules/id-name-format.js
index 0518279..93ab922 100644
--- a/tests/rules/id-name-format.js
+++ b/tests/rules/id-name-format.js
@@ -59,6 +59,20 @@ describe('id name format - scss', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'id-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(20, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: RegExp ^[_A-Z]+$]', function (done) {
     lint.test(file, {
       'id-name-format': [
@@ -134,6 +148,20 @@ describe('id name format - sass', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'id-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(20, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'id-name-format': [
diff --git a/tests/rules/mixin-name-format.js b/tests/rules/mixin-name-format.js
index f56bb14..3b57f45 100644
--- a/tests/rules/mixin-name-format.js
+++ b/tests/rules/mixin-name-format.js
@@ -28,6 +28,20 @@ describe('mixin name format - scss', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'mixin-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'mixin-name-format': [
@@ -140,6 +154,20 @@ describe('mixin name format - sass', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'mixin-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: strictbem]', function (done) {
     lint.test(file, {
       'mixin-name-format': [
diff --git a/tests/rules/placeholder-name-format.js b/tests/rules/placeholder-name-format.js
index f0f2035..a5f8e40 100644
--- a/tests/rules/placeholder-name-format.js
+++ b/tests/rules/placeholder-name-format.js
@@ -2,6 +2,10 @@
 
 var lint = require('./_lint');
 
+// ==============================================================================
+//  SCSS
+// ==============================================================================
+
 describe('placeholder name format - scss', function () {
   var file = lint.file('placeholder-name-format.scss');
 
@@ -28,6 +32,20 @@ describe('placeholder name format - scss', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'placeholder-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'placeholder-name-format': [
@@ -100,6 +118,10 @@ describe('placeholder name format - scss', function () {
   });
 });
 
+// ==============================================================================
+//  Sass
+// ==============================================================================
+
 describe('placeholder name format - sass', function () {
   var file = lint.file('placeholder-name-format.sass');
 
@@ -140,6 +162,20 @@ describe('placeholder name format - sass', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'placeholder-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(17, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: strictbem]', function (done) {
     lint.test(file, {
       'placeholder-name-format': [
diff --git a/tests/rules/variable-name-format.js b/tests/rules/variable-name-format.js
index 6716890..9d3cf40 100644
--- a/tests/rules/variable-name-format.js
+++ b/tests/rules/variable-name-format.js
@@ -2,6 +2,10 @@
 
 var lint = require('./_lint');
 
+// ==============================================================================
+//  SCSS
+// ==============================================================================
+
 describe('variable name format - scss', function () {
   var file = lint.file('variable-name-format.scss');
 
@@ -28,6 +32,20 @@ describe('variable name format - scss', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'variable-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(16, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: snakecase]', function (done) {
     lint.test(file, {
       'variable-name-format': [
@@ -100,6 +118,10 @@ describe('variable name format - scss', function () {
   });
 });
 
+// ==============================================================================
+//  Sass
+// ==============================================================================
+
 describe('variable name format - sass', function () {
   var file = lint.file('variable-name-format.sass');
 
@@ -140,6 +162,20 @@ describe('variable name format - sass', function () {
     });
   });
 
+  it('[convention: pascalcase]', function (done) {
+    lint.test(file, {
+      'variable-name-format': [
+        1,
+        {
+          'convention': 'pascalcase'
+        }
+      ]
+    }, function (data) {
+      lint.assert.equal(16, data.warningCount);
+      done();
+    });
+  });
+
   it('[convention: strictbem]', function (done) {
     lint.test(file, {
       'variable-name-format': [
diff --git a/tests/sass/class-name-format.sass b/tests/sass/class-name-format.sass
index ecc6fb8..07a34e9 100644
--- a/tests/sass/class-name-format.sass
+++ b/tests/sass/class-name-format.sass
@@ -76,3 +76,8 @@
   &_valid_child,
   &-invalid-child
     height: 10px
+
+.Pascal
+  .APascalCase
+    .camelCase
+      color: red
diff --git a/tests/sass/class-name-format.scss b/tests/sass/class-name-format.scss
index 019e00a..3a3af0c 100644
--- a/tests/sass/class-name-format.scss
+++ b/tests/sass/class-name-format.scss
@@ -108,3 +108,11 @@
     height: 10px;
   }
 }
+
+.Pascal {
+  .APascalCase {
+    .camelCase {
+      color: red;
+    }
+  }
+}