Skip to content

Commit 7b73721

Browse files
authored
Merge pull request #11 from hrobertking/selector-name-pattern
Selector name pattern
2 parents 4030fb0 + 2d01d1a commit 7b73721

File tree

4 files changed

+76
-30
lines changed

4 files changed

+76
-30
lines changed

src/cli/common.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ function cli(api) {
1919
"ignore" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to ignore completely." },
2020
"exclude-list": { "format" : "<file|dir[,file|dir]+>", "description" : "Indicate which files/directories to exclude from being linted." },
2121
"config" : { "format" : "<file>", "description" : "Reads csslint options from specified file." },
22-
"version" : { "format" : "", "description" : "Outputs the current version number." }
22+
"version" : { "format" : "", "description" : "Outputs the current version number." },
23+
"name-pattern": { "format" : "<pattern>", "description" : "Indicate which pattern naming should follow." }
2324
};
2425

2526
//-------------------------------------------------------------------------
@@ -140,7 +141,7 @@ function cli(api) {
140141
function processFile(relativeFilePath, options) {
141142
var input = api.readFile(relativeFilePath),
142143
ruleset = filterRules(options),
143-
result = CSSLint.verify(input, gatherRules(options, ruleset)),
144+
result = CSSLint.verify(input, gatherRules(options, ruleset), options),
144145
formatter = CSSLint.getFormatter(options.format || "text"),
145146
messages = result.messages || [],
146147
output,

src/core/CSSLint.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,11 @@ var CSSLint = (function() {
169169
* @param {Object} ruleset (Optional) List of rules to apply. If null, then
170170
* all rules are used. If a rule has a value of 1 then it's a warning,
171171
* a value of 2 means it's an error.
172+
* @param {Object} options (Optional) options for processing
172173
* @return {Object} Results of the verification.
173174
* @method verify
174175
*/
175-
api.verify = function(text, ruleset) {
176+
api.verify = function(text, ruleset, options) {
176177

177178
var i = 0,
178179
reporter,
@@ -245,7 +246,7 @@ var CSSLint = (function() {
245246
for (i in ruleset) {
246247
if (ruleset.hasOwnProperty(i) && ruleset[i]) {
247248
if (rules[i]) {
248-
rules[i].init(parser, reporter);
249+
rules[i].init(parser, reporter, options);
249250
}
250251
}
251252
}

src/rules/selector-pattern.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,21 @@ CSSLint.addRule({
1111
browsers: "All",
1212

1313
// initialization
14-
init: function(parser, reporter) {
14+
init: function(parser, reporter, options) {
1515
"use strict";
1616
var rule = this,
17-
rxCamel = /^[a-z]+([0-9]+|[A-Z][a-z]+)?/,
18-
rxSnake = /^[a-z][a-z0-9\_]+$/,
19-
rxDashs = /^[a-z][a-z0-9\-]*$/,
20-
choice = "hyphen",
17+
rxCamel = { "accept": /^[a-z]+([0-9]+|[A-Z][a-z]+)?/, "reject": /[\-\_]+/ },
18+
rxSnake = { "accept": /^[a-z][a-z0-9\_]+$/, "reject": /\-/ },
19+
rxDashs = { "accept": /^[a-z][a-z0-9\-]*$/, "reject": /\_/ },
20+
choice = options ? options["name-pattern"] : "bem",
2121
pattern;
2222

23-
/**
24-
* use the hyphen pattern
25-
*/
23+
choice = (choice || "bem").toString().toLowerCase();
2624
switch (choice) {
27-
case "camel":
25+
case "camelcase":
2826
pattern = rxCamel;
2927
break;
30-
case "sname":
28+
case "snakecase":
3129
pattern = rxSnake;
3230
break;
3331
default:
@@ -46,8 +44,8 @@ CSSLint.addRule({
4644
if (event.selectors[sel].parts[pts].type === 8) {
4745
bites = event.selectors[sel].parts[pts].text.split(/\#|\./);
4846
for (cls = 0; cls < bites.length; cls += 1) {
49-
if (bites[cls] && !pattern.test(bites[cls])) {
50-
reporter.report("Selector naming convention not followed.", event.line, event.col, rule);
47+
if (bites[cls] && (!pattern.accept.test(bites[cls]) || pattern.reject.test(bites[cls]))) {
48+
reporter.report("Selector naming convention (" + choice + ") not followed.", event.line, event.col, rule);
5149
}
5250
}
5351
}

tests/rules/selector-pattern.js

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,91 @@
77

88
name: "selector naming convention errors",
99

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

1314
Assert.areEqual(1, result.messages.length);
1415
Assert.areEqual("warning", result.messages[0].type);
15-
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
16+
Assert.areEqual(msg.test(result.messages[0].message), true);
1617
},
1718

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

2123
Assert.areEqual(1, result.messages.length);
2224
Assert.areEqual("warning", result.messages[0].type);
23-
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
25+
Assert.areEqual(msg.test(result.messages[0].message), true);
2426
},
2527

26-
"Subselectors following the snakecase pattern should result in an error": function() {
27-
var result = CSSLint.verify("div .foo_bar { display: block; }", { "selector-pattern": 1 });
28+
"Subselectors following the camelcase pattern should not result in an error when camelcase is used": function() {
29+
var result = CSSLint.verify("div .fooBar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "camelcase"});
30+
31+
Assert.areEqual(0, result.messages.length);
32+
},
33+
34+
"Selectors following the camelcase pattern should not result in an error when camelcase is used": function() {
35+
var result = CSSLint.verify(".fooBar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "camelcase"});
36+
37+
Assert.areEqual(0, result.messages.length);
38+
},
39+
40+
"Subselectors following the snakecase pattern should result in an error when BEM is used": function() {
41+
var result = CSSLint.verify("div .foo_bar { display: block; }", { "selector-pattern": 1 }),
42+
msg = /Selector naming convention \(\w+\) not followed\./;
43+
44+
Assert.areEqual(1, result.messages.length);
45+
Assert.areEqual("warning", result.messages[0].type);
46+
Assert.areEqual(msg.test(result.messages[0].message), true);
47+
},
48+
49+
"Selectors following the snakecase pattern should result in an error when BEM is used": function() {
50+
var result = CSSLint.verify(".foo_bar { display: block; }", { "selector-pattern": 1 }),
51+
msg = /Selector naming convention \(\w+\) not followed\./;
52+
53+
Assert.areEqual(1, result.messages.length);
54+
Assert.areEqual("warning", result.messages[0].type);
55+
Assert.areEqual(msg.test(result.messages[0].message), true);
56+
},
57+
58+
"Subselectors following the snakecase pattern should not result in an error when snakecase is used": function() {
59+
var result = CSSLint.verify("div .foo_bar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "snakecase"});
60+
61+
Assert.areEqual(0, result.messages.length);
62+
},
63+
64+
"Selectors following the snakecase pattern should not result in an error when snakecase is used": function() {
65+
var result = CSSLint.verify(".foo_bar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "snakecase"});
66+
67+
Assert.areEqual(0, result.messages.length);
68+
},
69+
70+
"Subselectors following the BEM pattern should result in an error when BEM is not used": function() {
71+
var result = CSSLint.verify("div .foo-bar { display: block; }", { "selector-pattern": 1 }, { "name-pattern": "camelcase"}),
72+
msg = /Selector naming convention \(\w+\) not followed\./;
2873

2974
Assert.areEqual(1, result.messages.length);
3075
Assert.areEqual("warning", result.messages[0].type);
31-
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
76+
Assert.areEqual(msg.test(result.messages[0].message), true);
3277
},
3378

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

3783
Assert.areEqual(1, result.messages.length);
3884
Assert.areEqual("warning", result.messages[0].type);
39-
Assert.areEqual("Selector naming convention not followed.", result.messages[0].message);
85+
Assert.areEqual(msg.test(result.messages[0].message), true);
4086
},
4187

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

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

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

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

0 commit comments

Comments
 (0)