UNPKG

@yasanchezz/eslint-plugin-vue-data-testid

Version:

An `eslint` plugin for checking accessibility rules from within `.vue` files. Add `data-testid` to use better behavior testing

68 lines (67 loc) 3.23 kB
import * as path from 'node:path'; import { calculateAttributeNames, getAttributeValue } from "../utils/index.js"; const fileAttributeNames = new Map(); export default function createRule({ attributeName = 'data-testid', }) { return { meta: { docs: { description: 'data-testid attribute should be unique' }, type: 'suggestion', fixable: 'code', schema: [], // no options }, create(context) { const filename = path.basename(context.filename); const extname = path.extname(context.filename); if (extname !== '.vue') { return {}; } const attributeNames = fileAttributeNames.get(context.filename) ?? new Set(); fileAttributeNames.set(context.filename, attributeNames); attributeNames.clear(); return context.sourceCode.parserServices.defineTemplateBodyVisitor({ VAttribute(node) { const element = node.parent.parent; const isRoot = element.parent.type === 'VDocumentFragment'; const name = node.key.type === 'VDirectiveKey' ? node.key.name.name : node.key.name; const value = node.value?.type === 'VLiteral' ? node.value.value : undefined; const attributes = Iterator.from(fileAttributeNames) .reduce((result, [, set]) => result.union(set), new Set()); const option = { nodeName: element.rawName, filepath: context.filename, filename, isRoot, classNames: Array.from(getAttributeValue(element, 'class')) .flatMap(className => className.split(' ')) }; const userAttributeName = typeof attributeName === 'string' ? attributeName : attributeName(option); const searchedAttributeNames = calculateAttributeNames(userAttributeName); if (searchedAttributeNames.has(name) && value && attributes.has(value)) { const filename = Array.from(fileAttributeNames) .filter(([, set]) => set.has(value)) .map(([filepath]) => path.basename(filepath)) .at(0); context.report({ node: node, message: `should make ${userAttributeName} unique. {{attribute}} has already defined in the file {{filename}}`, data: { attribute: value, filename: filename ?? '' } }); } if (searchedAttributeNames.has(name) && value) { attributeNames.add(value); } return {}; } }); } }; }