Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ignore map property name in unit-no-unknown (#4450)
* Ignore map property name (#4375) * Update isMap, add comments * Update types * Update lib/utils/isMap.js Co-Authored-By: Aleks Hudochenkov <aleks@hudochenkov.com> * Update lib/utils/isMap.js Co-Authored-By: Aleks Hudochenkov <aleks@hudochenkov.com> * Clarify const purpose
- Loading branch information
1 parent
cbfb82d
commit a3a74a3
Showing
4 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
'use strict'; | ||
|
||
const isMap = require('../isMap'); | ||
const sass = require('postcss-sass'); | ||
const scss = require('postcss-scss'); | ||
const valueParser = require('postcss-value-parser'); | ||
|
||
describe('isMap', () => { | ||
const simpleMaps = [ | ||
['$map: (prop: "flex");', true], | ||
['$font: (italic bold 10px/8pix)', false], | ||
['$map: (prop: /* comment */ 0);', true], | ||
['$calc: calc(100% / 2px);', false], | ||
['$url: url();', false], | ||
]; | ||
const nestedMaps = [ | ||
['$map: (prop: 0, prop2: (prop3: "normal"), prop4: 2px);', [0, 17]], | ||
['$map: (prop: 0, prop2: (prop3: "normal", prop4: (prop5: "grid")), prop6: 2px);', [0, 17, 42]], | ||
]; | ||
|
||
test.each(simpleMaps)('simple maps', (css, expected) => { | ||
runTests(css, (decl) => { | ||
const parsedValue = valueParser(decl.value).nodes[0]; | ||
|
||
expect(isMap(parsedValue)).toBe(expected); | ||
}); | ||
}); | ||
|
||
test.each(nestedMaps)('nested maps', (css, expected) => { | ||
runTests(css, (decl) => { | ||
const parsedValue = valueParser(decl.value); | ||
|
||
parsedValue.walk(function(valueNode) { | ||
if (expected.includes(valueNode.sourceIndex)) { | ||
expect(isMap(valueNode)).toBeTruthy(); | ||
} else { | ||
expect(isMap(valueNode)).toBeFalsy(); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
it('empty map returns `false`', () => { | ||
const emptyMap = '$map: ();'; | ||
|
||
runTests(emptyMap, (decl) => { | ||
const parsedValue = valueParser(decl.value); | ||
|
||
expect(isMap(parsedValue)).toBeFalsy(); | ||
}); | ||
}); | ||
}); | ||
|
||
function sassDecls(css, cb) { | ||
sass.parse(css).walkDecls(cb); | ||
} | ||
|
||
function scssDecls(css, cb) { | ||
scss.parse(css).walkDecls(cb); | ||
} | ||
|
||
function runTests(css, cb) { | ||
[sassDecls, scssDecls].forEach((fn) => { | ||
fn(css, cb); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
'use strict'; | ||
|
||
/** @typedef {import('postcss-value-parser').Node} ValueNode */ | ||
|
||
/** | ||
* @param {ValueNode | undefined} valueNode | ||
* @returns {boolean} | ||
*/ | ||
module.exports = function(valueNode) { | ||
if (!valueNode) { | ||
return false; | ||
} | ||
|
||
if (valueNode.type !== 'function' || !valueNode.nodes || valueNode.value) { | ||
return false; | ||
} | ||
|
||
// It's necessary to remove comments and spaces if they are present | ||
const cleanNodes = valueNode.nodes.filter( | ||
(node) => node.type !== 'comment' && node.type !== 'space', | ||
); | ||
|
||
// Map without comments and spaces will have the structure like $map (prop: value, prop2: value) | ||
// ↑ ↑ ↑ ↑ | ||
// 0 1 2 3 | ||
if (cleanNodes[0] && cleanNodes[0].type !== 'word' && cleanNodes[0].type !== 'string') { | ||
return false; | ||
} | ||
|
||
if (cleanNodes[1] && cleanNodes[1].value !== ':') { | ||
return false; | ||
} | ||
|
||
// There is no need to check type or value of this node since it could be anything | ||
if (!cleanNodes[2]) { | ||
return false; | ||
} | ||
|
||
if (cleanNodes[3] && cleanNodes[3].value !== ',') { | ||
return false; | ||
} | ||
|
||
return true; | ||
}; |