All files / plugins no-override.js

97.37% Statements 37/38
88.89% Branches 16/18
100% Functions 8/8
97.3% Lines 36/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 752x 2x   2x 2x   2x 3x     2x 9x   9x 9x   9x 9x 9x 9x 1x   8x 8x 9360x 9360x 9232x             9x 9x 1x 1x   1x           9x       9x 3x             9x 11x 2x   9x 10x 1x                 9369x 9369x    
const stylelint = require('stylelint')
const {requirePrimerFile} = require('../src/primer')
 
const ruleName = 'primer/no-override'
const CLASS_PATTERN = /(\.[-\w]+)/g
 
const messages = stylelint.utils.ruleMessages(ruleName, {
  rejected: selector => `The selector "${selector}" should not be overridden.`
})
 
module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
  const {bundles = ['utilities']} = options
 
  const primerMeta = requirePrimerFile('dist/meta.json')
  const availableBundles = Object.keys(primerMeta.bundles)
 
  const immutableSelectors = new Set()
  const immutableClassSelectors = new Set()
  for (const bundle of bundles) {
    if (!availableBundles.includes(bundle)) {
      continue
    }
    const stats = require(`@primer/css/dist/stats/${bundle}.json`)
    for (const selector of stats.selectors.values) {
      immutableSelectors.add(selector)
      for (const classSelector of getClassSelectors(selector)) {
        immutableClassSelectors.add(classSelector)
      }
    }
  }
 
  // console.warn(`Got ${immutableSelectors.size} immutable selectors from: "${bundles.join('", "')}"`)
 
  return (root, result) => {
    if (!Array.isArray(bundles) || bundles.some(bundle => !availableBundles.includes(bundle))) {
      const invalidBundles = Array.isArray(bundles)
        ? `"${bundles.filter(bundle => !availableBundles.includes(bundle)).join('", "')}"`
        : '(not an array)'
      result.warn(`The "bundles" option must be an array of valid bundles; got: ${invalidBundles}`, {
        stylelintType: 'invalidOption',
        stylelintReference: 'https://github.com/primer/stylelint-config-primer#options'
      })
    }
 
    Iif (!enabled) {
      return
    }
 
    const report = (rule, selector) =>
      stylelint.utils.report({
        message: messages.rejected(selector),
        node: rule,
        result,
        ruleName
      })
 
    root.walkRules(rule => {
      if (immutableSelectors.has(rule.selector)) {
        report(rule, rule.selector)
      } else {
        for (const classSelector of getClassSelectors(rule.selector)) {
          if (immutableClassSelectors.has(classSelector)) {
            report(rule, classSelector)
          }
        }
      }
    })
  }
})
 
function getClassSelectors(selector) {
  const match = selector.match(CLASS_PATTERN)
  return match ? [...match] : []
}