Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix false positives for maps in property-no-unknown #5690

Merged
merged 9 commits into from Nov 13, 2021
36 changes: 28 additions & 8 deletions lib/rules/color-no-invalid-hex/__tests__/index.js
Expand Up @@ -30,14 +30,6 @@ testRule({
{
code: 'a::before { content: "#ababa"; }',
},
{
code: 'a { border-#$side: 0; }',
description: 'ignore sass-like interpolation',
},
{
code: 'a { box-sizing: #$type-box; }',
description: 'ignore sass-like interpolation',
},
{
code: "a { background-image: svg-load('x.svg', fill=url(#a)); }",
description: 'svg-load url with fill',
Expand Down Expand Up @@ -91,6 +83,34 @@ testRule({
],
});

testRule({
ruleName,
config: [true],
customSyntax: 'postcss-less',
accept: [
{
code: 'a { color: #colors[somecolor]; }',
description: 'Less map usage',
},
],
});

testRule({
ruleName,
config: [true],
customSyntax: 'postcss-scss',
accept: [
{
code: 'a { border-#$side: 0; }',
description: 'ignore sass-like interpolation',
},
{
code: 'a { box-sizing: #$type-box; }',
description: 'ignore sass-like interpolation',
},
],
});

testRule({
skip: true,
ruleName,
Expand Down
5 changes: 5 additions & 0 deletions lib/rules/color-no-invalid-hex/index.js
@@ -1,6 +1,7 @@
'use strict';

const declarationValueIndex = require('../../utils/declarationValueIndex');
const isStandardSyntaxHexColor = require('../../utils/isStandardSyntaxHexColor');
const isValidHex = require('../../utils/isValidHex');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
Expand All @@ -23,6 +24,10 @@ const rule = (primary) => {
}

root.walkDecls((decl) => {
if (!isStandardSyntaxHexColor(decl.value)) {
return;
}

valueParser(decl.value).walk(({ value, type, sourceIndex }) => {
if (type === 'function' && value.endsWith('url')) return false;

Expand Down
4 changes: 4 additions & 0 deletions lib/utils/__tests__/isStandardSyntaxDeclaration.test.js
Expand Up @@ -139,6 +139,10 @@ describe('isStandardSyntaxDeclaration', () => {
expect(isStandardSyntaxDeclaration(lessDecl('@map: { key: value; }'))).toBe(false);
});

it('less another map', () => {
expect(isStandardSyntaxDeclaration(lessDecl('#my-map() { key: value; }'))).toBe(false);
});

it('scss map declaration', () => {
expect(isStandardSyntaxDeclaration(scssDecl('$foo: (key: value, key2: value2)'))).toBe(false);
});
Expand Down
12 changes: 12 additions & 0 deletions lib/utils/__tests__/isStandardSyntaxHexColor.test.js
@@ -0,0 +1,12 @@
'use strict';

const isStandardSyntaxHexColor = require('../isStandardSyntaxHexColor');

describe('isStandardSyntaxHexColor', () => {
it('default hex', () => {
expect(isStandardSyntaxHexColor('#000000')).toBe(true);
});
it('less map usage', () => {
expect(isStandardSyntaxHexColor('#prop[someprop]')).toBe(false);
});
});
11 changes: 11 additions & 0 deletions lib/utils/isStandardSyntaxDeclaration.js
Expand Up @@ -46,6 +46,17 @@ module.exports = function (decl) {
return false;
}

// Less map (e.g. #my-map() { myprop: red; })
if (
parent &&
isRule(parent) &&
parent.selector &&
parent.selector.startsWith('#') &&
parent.selector.endsWith('()')
) {
return false;
}

// Sass nested properties (e.g. border: { style: solid; color: red; })
if (
parent &&
Expand Down
16 changes: 16 additions & 0 deletions lib/utils/isStandardSyntaxHexColor.js
@@ -0,0 +1,16 @@
'use strict';

/**
* Check whether a hex color is standard
*
* @param {string} hex
* @returns {boolean}
*/
module.exports = function isStandardSyntaxHexColor(hex) {
// Less map usage (e.g. .myclass { color: #colors[somecolor]; })
if (hex.includes('[')) {
return false;
}

return true;
};