8000 Selector name pattern by hrobertking · Pull Request #11 · hrobertking/csslint · GitHub
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
5 changes: 3 additions & 2 deletions src/cli/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ function cli(api) {
"ignore" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to ignore completely." },
"exclude-list": { "format" : "<file|dir[,file|dir]+>", "description" : "Indicate which files/directories to exclude from being linted." },
"config" : { "format" : "<file>", "description" : "Reads csslint options from specified file." },
"version" : { "format" : "", "description" : "Outputs the current version number." }
"version" : { "format" : "", "description" : "Outputs the current version number." },
"name-pattern": { "format" : "<pattern>", "description" : "Indicate which pattern naming should follow." }
};

//-------------------------------------------------------------------------
Expand Down Expand Up @@ -140,7 +141,7 @@ function cli(api) {
function processFile(relativeFilePath, options) {
var input = api.readFile(relativeFilePath),
ruleset = filterRules(options),
result = CSSLint.verify(input, gatherRules(options, ruleset)),
result = CSSLint.verify(input, gatherRules(options, ruleset), options),
formatter = CSSLint.getFormatter(options.format || "text"),
messages = result.messages || [],
output,
Expand Down
5 changes: 3 additions & 2 deletions src/core/CSSLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,11 @@ var CSSLint = (function() {
* @param {Object} ruleset (Optional) List of rules to apply. If null, then
* all rules are used. If a rule has a value of 1 then it's a warning,
* a value of 2 means it's an error.
* @param {Object} options (Optional) options for processing
* @return {Object} Results of the verification.
* @method verify
*/
api.verify = function(text, ruleset) {
api.verify = function(text, ruleset, options) {

var i = 0,
reporter,
Expand Down Expand Up @@ -245,7 +246,7 @@ var CSSLint = (function() {
for (i in ruleset) {
if (ruleset.hasOwnProperty(i) && ruleset[i]) {
if (rules[i]) {
rules[i].init(parser, reporter);
rules[i].init(parser, reporter, options);
}
}
}
Expand Down
22 changes: 10 additions & 12 deletions src/rules/selector-pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,21 @@ CSSLint.addRule({
browsers: "All",

// initialization
init: function(parser, reporter) {
init: function(parser, reporter, options) {
"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",
rxCamel = { "accept": /^[a-z]+([0-9]+|[A-Z][a-z]+)?/, "reject": /[\-\_]+/ },
rxSnake = { "accept": /^[a-z][a-z0-9\_]+$/, "reject": /\-/ },
rxDashs = { "accept": /^[a-z][a-z0-9\-]*$/, "reject": /\_/ },
choice = options ? options["name-pattern"] : "bem",
pattern;

/**
* use the hyphen pattern
*/
choice = (choice || "bem").toString().toLowerCase();
switch (choice) {
case "camel":
case "camelcase":
pattern = rxCamel;
break;
case "sname":
case "snakecase":
pattern = rxSnake;
break;
default:
Expand All @@ -46,8 +44,8 @@ CSSLint.addRule({
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);
if (bites[cls] && (!pattern.accept.test(bites[cls]) || pattern.reject.test(bites[cls]))) {
reporter.report("Selector naming convention (" + choice + ") not followed.", event.line, event.col, rule);
}
}
}
Expand Down
74 changes: 60 additions & 14 deletions tests/rules/selector-pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,91 @@

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 });
"Subselectors following the camelcase pattern should result in an error when BEM is used": function() {
var result = CSSLint.verify("div .fooBar { display: block; }", { "selector-pattern": 1 }),
msg = /Selector naming convention \(\w+\) not followed\./;

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

"Selectors following the camelcase pattern should result in an error": function() {
var result = CSSLint.verify(".fooBar { display: block; }", { "selector-pattern": 1 });
"Selectors following the camelcase pattern should result in an error when BEM is used": function() {
var result = CSSLint.verify(".fooBar { display: block; }", { "selector-pattern": 1 }),
msg = /Selector naming convention \(\w+\) not followed\./;

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

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

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

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

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

"Subselectors following the snakecase pattern should result in an error when BEM is used": function() {
var result = CSSLint.verify("div .foo_bar { display: block; }", { "selector-pattern": 1 }),
msg = /Selector naming convention \(\w+\) not followed\./;

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual(msg.test(result.messages[0].message), true);
},

"Selectors following the snakecase pattern should result in an error when BEM is used": function() {
var result = CSSLint.verify(".foo_bar { display: block; }", { "selector-pattern": 1 }),
msg = /Selector naming convention \(\w+\) not followed\./;

Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual(msg.test(result.messages[0].message), true);
},

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

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

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

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

"Subselectors following the BEM pattern should result in an error when BEM is not used": function() {
var result = CSSLint.verify("div .foo-bar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "camelcase"}),
msg = /Selector naming convention \(\w+\) not followed\./;

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

"Selectors following the snakecase pattern should result in an error": function() {
var result = CSSLint.verify(".foo_bar { display: block; }", { "selector-pattern": 1 });
"Selectors following the BEM pattern should result in an error when BEM is not used": function() {
var result = CSSLint.verify(".foo-bar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "snakecase"}),
msg = /Selector naming convention \(\w+\) not followed\./;

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

"Subselectors following the hyphen pattern should not result in an error": function() {
"Subselectors following the BEM 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() {
"Selectors following the BEM 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);
Expand Down