Skip to content

Commit

Permalink
Add classic_BEM convention for SelectorFormat
Browse files Browse the repository at this point in the history
Currently the `strict_BEM` convention does not follow the official BEM
style a.k.a. `classic`. For example, in classic, `.block_modifier` is
valid, but the strict convention reports an error.
`.block__element_modifier` is also reported as an error, but with
classic, it's valid.

Fixes: sds#859
  • Loading branch information
aar0nr authored and sds committed Sep 25, 2017
1 parent 5c04a4f commit f9cb439
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## master (unreleased)

* Add `ng-deep` to the list recognized by the `PseudoElement` linter
* Add `classic_BEM` convention for `SelectorFormat`

## 0.54.0

Expand Down
2 changes: 1 addition & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ linters:

SelectorFormat:
enabled: true
convention: hyphenated_lowercase # or 'strict_BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern
convention: hyphenated_lowercase # or 'classic_BEM', or 'strict_BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern

Shorthand:
enabled: true
Expand Down
10 changes: 10 additions & 0 deletions lib/scss_lint/linter/selector_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ def check(node, type)
explanation: 'should be written in camelCase format',
validator: ->(name) { name =~ /^[a-z][a-zA-Z0-9]*$/ },
},
'classic_BEM' => {
explanation: 'should be written in classic BEM (Block Element Modifier) format',
validator: lambda do |name|
name =~ /
^[a-z]([-]?[a-z0-9]+)*
(__[a-z0-9]([-]?[a-z0-9]+)*)?
((_[a-z0-9]([-]?[a-z0-9]+)*){1,2})?$
/x
end
},
'hyphenated_BEM' => {
explanation: 'should be written in hyphenated BEM (Block Element Modifier) format',
validator: ->(name) { name !~ /[A-Z]|-{3}|_{3}|[^_]_[^_]/ },
Expand Down
82 changes: 82 additions & 0 deletions spec/scss_lint/linter/selector_format_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,88 @@
end
end

context 'when the classic_BEM convention is specified' do
let(:linter_config) { { 'convention' => 'classic_BEM' } }

context 'when a name contains no underscores or hyphens' do
let(:scss) { '.block {}' }

it { should_not report_lint }
end

context 'when a name contains single hyphen' do
let(:scss) { '.b-block {}' }

it { should_not report_lint }
end

context 'when a name contains multiple hyphens' do
let(:scss) { '.b-block-name {}' }

it { should_not report_lint }
end

context 'when a name contains multiple hyphens in a row' do
let(:scss) { '.b-block--modifier {}' }

it { should report_lint }
end

context 'when a name contains a single underscore' do
let(:scss) { '.block_modifier {}' }

it { should_not report_lint }
end

context 'when a block has name-value modifier' do
let(:scss) { '.block_modifier_value {}' }

it { should_not report_lint }
end

context 'when a block has name-value modifier with lots of hyphens' do
let(:scss) { '.b-block-name_modifier-name-here_value-name-here {}' }

it { should_not report_lint }
end

context 'when a name has double underscores' do
let(:scss) { '.b-block__element {}' }

it { should_not report_lint }
end

context 'when element goes after block with modifier' do
let(:scss) { '.block_modifier_value__element {}' }

it { should report_lint }
end

context 'when element has modifier' do
let(:scss) { '.block__element_modifier_value {}' }

it { should_not report_lint }
end

context 'when element has not paired modifier' do
let(:scss) { '.block__element_modifier {}' }

it { should_not report_lint }
end

context 'when element has hypenated modifier' do
let(:scss) { '.block__element--modifier {}' }

it { should report_lint }
end

context 'when element has hypenated paired modifier' do
let(:scss) { '.block__element--modifier_value {}' }

it { should report_lint }
end
end

context 'when the strict_BEM convention is specified' do
let(:linter_config) { { 'convention' => 'strict_BEM' } }

Expand Down

0 comments on commit f9cb439

Please sign in to comment.