lib/scss_lint/linter/name_format.rb in scss-lint-0.36.1 vs lib/scss_lint/linter/name_format.rb in scss-lint-0.37.0
- old
+ new
@@ -1,8 +1,8 @@
module SCSSLint
- # Checks that the declared names of functions, mixins, and variables are all
- # lowercase and use hyphens instead of underscores.
+ # Checks the format of declared names of functions, mixins, variables, and
+ # placeholders.
class Linter::NameFormat < Linter
include LinterRegistry
def visit_extend(node)
check_placeholder(node)
@@ -45,14 +45,14 @@
translateX translateY translateZ
].to_set
def check_name(node, node_type, node_text = node.name)
node_text = trim_underscore_prefix(node_text)
- return unless violation = violated_convention(node_text)
+ return unless violation = violated_convention(node_text, node_type)
- add_lint(node, "Name of #{node_type} `#{node_text}` should be " \
- "written #{violation[:explanation]}")
+ add_lint(node,
+ "Name of #{node_type} `#{node_text}` #{violation[:explanation]}")
end
# Removes underscore prefix from name if leading underscores are allowed.
def trim_underscore_prefix(name)
if config['allow_leading_underscore']
@@ -68,28 +68,50 @@
check_name(node, 'placeholder', selector_str.gsub('%', ''))
end
end
CONVENTIONS = {
+ 'camel_case' => {
+ explanation: 'should be written in camelCase format',
+ validator: ->(name) { name =~ /^[a-z][a-zA-Z0-9]*$/ },
+ },
+ 'snake_case' => {
+ explanation: 'should be written in snake_case',
+ validator: ->(name) { name !~ /[^_a-z0-9]/ },
+ },
'hyphenated_lowercase' => {
- explanation: 'in all lowercase letters with hyphens instead of underscores',
+ explanation: 'should be written in all lowercase letters with hyphens ' \
+ 'instead of underscores',
validator: ->(name) { name !~ /[_A-Z]/ },
},
- 'BEM' => {
- explanation: 'in BEM (Block Element Modifier) format',
- validator: ->(name) { name !~ /[A-Z]|-{3}|_{3}|[^_]_[^_]/ },
- },
}
- # Checks the given name and returns the violated convention if it failed.
- def violated_convention(name_string)
- convention_name = config['convention'] || 'hyphenated_lowercase'
+ def violated_convention(name_string, type)
+ convention_name = convention_name(type)
- convention = CONVENTIONS[convention_name] || {
- explanation: "must match regex /#{convention_name}/",
+ existing_convention = CONVENTIONS[convention_name]
+
+ convention = (existing_convention || {
validator: ->(name) { name =~ /#{convention_name}/ }
- }
+ }).merge(
+ explanation: convention_explanation(type), # Allow explanation to be customized
+ )
convention unless convention[:validator].call(name_string)
+ end
+
+ def convention_name(type)
+ config["#{type}_convention"] ||
+ config['convention'] ||
+ 'hyphenated_lowercase'
+ end
+
+ def convention_explanation(type)
+ existing_convention = CONVENTIONS[convention_name(type)]
+
+ config["#{type}_convention_explanation"] ||
+ config['convention_explanation'] ||
+ (existing_convention && existing_convention[:explanation]) ||
+ "should match regex /#{convention_name(type)}/"
end
end
end