diff --git a/lib/rules/selector-max-attribute/index.js b/lib/rules/selector-max-attribute/index.js index d9d42f9d29..72e6cd0846 100644 --- a/lib/rules/selector-max-attribute/index.js +++ b/lib/rules/selector-max-attribute/index.js @@ -1,7 +1,6 @@ 'use strict'; const _ = require('lodash'); -const hasUnresolvedNestedSelector = require('../../utils/hasUnresolvedNestedSelector'); const isLogicalCombination = require('../../utils/isLogicalCombination'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector'); @@ -87,11 +86,6 @@ function rule(max, options) { return; } - if (hasUnresolvedNestedSelector(ruleNode)) { - // Skip unresolved nested selectors - return; - } - ruleNode.selectors.forEach((selector) => { resolvedNestedSelector(selector, ruleNode).forEach((resolvedSelector) => { parseSelector(resolvedSelector, result, ruleNode, (container) => diff --git a/lib/rules/selector-max-class/__tests__/index.js b/lib/rules/selector-max-class/__tests__/index.js index 7876ad1504..3a165b0b1c 100644 --- a/lib/rules/selector-max-class/__tests__/index.js +++ b/lib/rules/selector-max-class/__tests__/index.js @@ -162,13 +162,16 @@ testRule(rule, { code: '.foo.bar #{$test} {}', description: 'scss: ignore variable interpolation', }, + ], + + reject: [ { code: '.foo { margin: { left: 0; top: 0; }; }', description: 'scss: nested properties', + message: messages.expected('.foo', 0), + line: 1, + column: 1, }, - ], - - reject: [ { code: '@include test { .foo {} }', description: 'scss: mixin @include', @@ -194,9 +197,15 @@ testRule(rule, { code: '.setFont(@size) { font-size: @size; }', description: 'less: ignore mixins', }, + ], + + reject: [ { code: '.foo { .setFont(12px) }', description: 'less: ignore called mixins', + message: messages.expected('.foo', 0), + line: 1, + column: 1, }, ], }); diff --git a/lib/rules/selector-max-class/index.js b/lib/rules/selector-max-class/index.js index 4cd1ec5d18..c4a51785fa 100644 --- a/lib/rules/selector-max-class/index.js +++ b/lib/rules/selector-max-class/index.js @@ -61,11 +61,6 @@ function rule(max) { return; } - if (ruleNode.nodes.some((node) => ['rule', 'atrule'].indexOf(node.type) !== -1)) { - // Skip unresolved nested selectors - return; - } - ruleNode.selectors.forEach((selector) => { resolvedNestedSelector(selector, ruleNode).forEach((resolvedSelector) => { parseSelector(resolvedSelector, result, ruleNode, (container) => diff --git a/lib/rules/selector-max-combinators/index.js b/lib/rules/selector-max-combinators/index.js index ca283f18c9..e386521676 100644 --- a/lib/rules/selector-max-combinators/index.js +++ b/lib/rules/selector-max-combinators/index.js @@ -1,6 +1,5 @@ 'use strict'; -const hasUnresolvedNestedSelector = require('../../utils/hasUnresolvedNestedSelector'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector'); const parseSelector = require('../../utils/parseSelector'); @@ -63,11 +62,6 @@ function rule(max) { return; } - if (hasUnresolvedNestedSelector(ruleNode)) { - // Skip unresolved nested selectors - return; - } - ruleNode.selectors.forEach((selector) => { resolvedNestedSelector(selector, ruleNode).forEach((resolvedSelector) => { parseSelector(resolvedSelector, result, ruleNode, (container) => diff --git a/lib/rules/selector-max-type/__tests__/index.js b/lib/rules/selector-max-type/__tests__/index.js index 17ae9b9cb7..d8ddf6731a 100644 --- a/lib/rules/selector-max-type/__tests__/index.js +++ b/lib/rules/selector-max-type/__tests__/index.js @@ -211,6 +211,22 @@ testRule(rule, { line: 1, column: 7, }, + { + code: 'a { b { c { d { } } } }', + description: 'nested rule', + warnings: [ + { + message: messages.expected('a b c', 2), + line: 1, + column: 9, + }, + { + message: messages.expected('a b c d', 2), + line: 1, + column: 13, + }, + ], + }, ], }); @@ -558,6 +574,22 @@ testRule(rule, { line: 1, column: 1, }, + { + code: 'a { &:hover { } }', + description: 'nested rule', + warnings: [ + { + message: messages.expected('a', 0), + line: 1, + column: 1, + }, + { + message: messages.expected('a:hover', 0), + line: 1, + column: 5, + }, + ], + }, ], }); diff --git a/lib/rules/selector-max-type/index.js b/lib/rules/selector-max-type/index.js index 4f65c65177..0a4665e89d 100644 --- a/lib/rules/selector-max-type/index.js +++ b/lib/rules/selector-max-type/index.js @@ -1,7 +1,6 @@ 'use strict'; const _ = require('lodash'); -const hasUnresolvedNestedSelector = require('../../utils/hasUnresolvedNestedSelector'); const isKeyframeSelector = require('../../utils/isKeyframeSelector'); const isLogicalCombination = require('../../utils/isLogicalCombination'); const isOnlyWhitespace = require('../../utils/isOnlyWhitespace'); @@ -110,11 +109,6 @@ function rule(max, options) { return; } - if (hasUnresolvedNestedSelector(ruleNode)) { - // Skip unresolved nested selectors - return; - } - ruleNode.selectors.forEach((selector) => { resolvedNestedSelector(selector, ruleNode).forEach((resolvedSelector) => { if (!isStandardSyntaxSelector(resolvedSelector)) { diff --git a/lib/rules/selector-max-universal/index.js b/lib/rules/selector-max-universal/index.js index 2b44b9bfc5..bd2fa88db3 100644 --- a/lib/rules/selector-max-universal/index.js +++ b/lib/rules/selector-max-universal/index.js @@ -1,6 +1,5 @@ 'use strict'; -const hasUnresolvedNestedSelector = require('../../utils/hasUnresolvedNestedSelector'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector'); const parseSelector = require('../../utils/parseSelector'); @@ -65,11 +64,6 @@ function rule(max) { return; } - if (hasUnresolvedNestedSelector(ruleNode)) { - // Skip unresolved nested selectors - return; - } - const selectors = []; selectorParser() diff --git a/lib/utils/__tests__/hasUnresolvedNestedSelector.test.js b/lib/utils/__tests__/hasUnresolvedNestedSelector.test.js deleted file mode 100644 index e0fb4fe4ce..0000000000 --- a/lib/utils/__tests__/hasUnresolvedNestedSelector.test.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -const hasUnresolvedNestedSelector = require('../hasUnresolvedNestedSelector'); -const postcss = require('postcss'); -const scss = require('postcss-scss'); - -describe('hasUnresolvedNestedSelector', () => { - it('type', () => { - expect.assertions(1); - rules('a {}', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); - it('class', () => { - expect.assertions(1); - rules('.foo {}', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); - it('nested type', () => { - expect.assertions(1); - const parsed = postcss.parse('.foo { a {} }'); - - expect(hasUnresolvedNestedSelector(parsed.first)).toBeTruthy(); - }); - it('nested selector', () => { - expect.assertions(1); - const parsed = postcss.parse('.foo { .bar {} }'); - - expect(hasUnresolvedNestedSelector(parsed.first)).toBeTruthy(); - }); - it('SCSS mixin', () => { - expect.assertions(1); - scssRules('@include test-mixin {}', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); - it('SCSS nested mixin no children', () => { - expect.assertions(2); - scssRules('.foo { @include test-mixin; }', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); - it('SCSS nested mixin children', () => { - expect.assertions(2); - scssRules('.foo { @include test-mixin {} }', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); - it('SCSS multiple mixins', () => { - expect.assertions(2); - scssRules('@include test-mixin { @media (min-width: 10rem) {} }', (rule) => { - expect(hasUnresolvedNestedSelector(rule)).toBeFalsy(); - }); - }); -}); - -function rules(css, cb) { - postcss.parse(css).walk(cb); -} - -function scssRules(css, cb) { - scss.parse(css).walk(cb); -} diff --git a/lib/utils/hasUnresolvedNestedSelector.js b/lib/utils/hasUnresolvedNestedSelector.js deleted file mode 100644 index 9c88c2dc86..0000000000 --- a/lib/utils/hasUnresolvedNestedSelector.js +++ /dev/null @@ -1,9 +0,0 @@ -/* @flow */ -'use strict'; - -/** - * Check whether an array of nodes has some unresolved nested selector - */ -module.exports = function(rule /*: Object*/) /*: boolean*/ { - return (rule.nodes || []).some((node) => ['rule'].indexOf(node.type) !== -1); -}; diff --git a/system-tests/005/__snapshots__/005.test.js.snap b/system-tests/005/__snapshots__/005.test.js.snap index 477c5aef8b..fba562e3f5 100644 --- a/system-tests/005/__snapshots__/005.test.js.snap +++ b/system-tests/005/__snapshots__/005.test.js.snap @@ -16375,6 +16375,20 @@ Array [ "severity": "error", "text": "Expected \\"[type=\\"submit\\"]\\" to have no more than 0 attribute selectors (selector-max-attribute)", }, + Object { + "column": 3, + "line": 124, + "rule": "selector-max-combinators", + "severity": "error", + "text": "Expected \\"a .foo\\" to have no more than 0 combinators (selector-max-combinators)", + }, + Object { + "column": 5, + "line": 125, + "rule": "selector-max-combinators", + "severity": "error", + "text": "Expected \\"a .foo__foo\\" to have no more than 0 combinators (selector-max-combinators)", + }, Object { "column": 7, "line": 126, @@ -16972,6 +16986,27 @@ b\\" to have no more than 0 combinators (selector-max-combinators)", "severity": "error", "text": "Expected \\"a\\" to have no more than 0 type selectors (selector-max-type)", }, + Object { + "column": 1, + "line": 123, + "rule": "selector-max-type", + "severity": "error", + "text": "Expected \\"a\\" to have no more than 0 type selectors (selector-max-type)", + }, + Object { + "column": 3, + "line": 124, + "rule": "selector-max-type", + "severity": "error", + "text": "Expected \\"a .foo\\" to have no more than 0 type selectors (selector-max-type)", + }, + Object { + "column": 5, + "line": 125, + "rule": "selector-max-type", + "severity": "error", + "text": "Expected \\"a .foo__foo\\" to have no more than 0 type selectors (selector-max-type)", + }, Object { "column": 7, "line": 126, @@ -17191,6 +17226,13 @@ b\\" to have no more than 0 combinators (selector-max-combinators)", b\\" to have no more than 0 type selectors (selector-max-type)", }, + Object { + "column": 1, + "line": 194, + "rule": "selector-max-type", + "severity": "error", + "text": "Expected \\"a\\" to have no more than 0 type selectors (selector-max-type)", + }, Object { "column": 3, "line": 195,