Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions src/rules/selector-pattern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Rule: warn when the selector naming convention is not followed
*/

CSSLint.addRule({

// rule information
id: "selector-pattern",
name: "Warn when the naming convention is not followed",
desc: "Will warn when the selector naming convention is not followed",
browsers: "All",

// initialization
init: function(parser, reporter) {
"use strict";
var rule = this,
rxCamel = /^[a-z]+([0-9]+|[A-Z][a-z]+)?/,
rxSnake = /^[a-z][a-z0-9\_]+$/,
rxDashs = /^[a-z][a-z0-9\-]*$/,
choice = "hyphen",
pattern;

/**
* use the hyphen pattern
*/
switch (choice) {
case "camel":
pattern = rxCamel;
break;
case "sname":
pattern = rxSnake;
break;
default:
pattern = rxDashs;
break;
}

parser.addListener("startrule", function(event) {
var sel,
pts,
cls,
bites;

for (sel = 0; sel < event.selectors.length; sel += 1) {
for (pts = 0; pts < event.selectors[sel].parts.length; pts += 1) {
if (event.selectors[sel].parts[pts].type === 8) {
bites = event.selectors[sel].parts[pts].text.split(/\#|\./);
for (cls = 0; cls < bites.length; cls += 1) {
if (bites[cls] && !pattern.test(bites[cls])) {
reporter.report("Selector naming convention not followed.", event.line, event.col, rule);
}
}
}
}
}
});
}

});
56 changes: 56 additions & 0 deletions tests/rules/selector-pattern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
(function() {
"use strict";

var Assert = YUITest.Assert;

YUITest.TestRunner.add(new YUITest.TestCase({

name: "selector naming convention errors",

"Subselectors following the camelcase pattern should result in an error": function() {
var result = CSSLint.verify("div .fooBar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
},

"Selectors following the camelcase pattern should result in an error": function() {
var result = CSSLint.verify(".fooBar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
},

"Subselectors following the snakecase pattern should result in an error": function() {
var result = CSSLint.verify("div .foo_bar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
},

"Selectors following the snakecase pattern should result in an error": function() {
var result = CSSLint.verify(".foo_bar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
},

"Subselectors following the hyphen pattern should not result in an error": function() {
var result = CSSLint.verify("div .foo-bar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(0, result.messages.length);
},

"Selectors following the hyphen pattern should not result in an error": function() {
var result = CSSLint.verify(".foo-bar { display: block; }", { "selector-pattern": 1 });

Assert.areEqual(0, result.messages.length);
}

}));

})();