53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { readFileSync, readdirSync } from 'node:fs'
|
||||
|
|
import { extname, join, relative } from 'node:path'
|
|||
|
|
import { describe, expect, it } from 'vitest'
|
|||
|
|
|
|||
|
|
const modulesRoot = join(process.cwd(), 'src/modules')
|
|||
|
|
|
|||
|
|
function vueFiles(directory: string): string[] {
|
|||
|
|
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|||
|
|
const path = join(directory, entry.name)
|
|||
|
|
if (entry.isDirectory()) return vueFiles(path)
|
|||
|
|
return extname(entry.name) === '.vue' ? [path] : []
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isPermanentlyReadOnly(tag: string): boolean {
|
|||
|
|
return (
|
|||
|
|
/\s(?:disabled|readonly)(?=\s|\/>|>)/.test(tag) ||
|
|||
|
|
/\s(?:disabled|readonly)=(?:""|'')/.test(tag) ||
|
|||
|
|
/\s(?::|v-bind:)(?:disabled|readonly)=(?:"true"|'true')/.test(tag)
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasMeaningfulPlaceholder(tag: string): boolean {
|
|||
|
|
const value = tag.match(/\s(?::|v-bind:)?placeholder\s*=\s*(["'])(.*?)\1/)?.[2]
|
|||
|
|
return Boolean(value?.trim())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
describe('正式业务模块输入提示合同', () => {
|
|||
|
|
it('所有可编辑 el-input 与 el-input-number 都提供 placeholder', () => {
|
|||
|
|
const violations: string[] = []
|
|||
|
|
|
|||
|
|
for (const file of vueFiles(modulesRoot)) {
|
|||
|
|
const source = readFileSync(file, 'utf8').replace(/<!--[\s\S]*?-->/g, (comment) =>
|
|||
|
|
comment.replace(/[^\n]/g, ' '),
|
|||
|
|
)
|
|||
|
|
const openingTag = /<el-input(?:-number)?\b(?:"[^"]*"|'[^']*'|[^'">])*>/g
|
|||
|
|
|
|||
|
|
for (const match of source.matchAll(openingTag)) {
|
|||
|
|
const tag = match[0]
|
|||
|
|
if (isPermanentlyReadOnly(tag)) continue
|
|||
|
|
if (hasMeaningfulPlaceholder(tag)) continue
|
|||
|
|
|
|||
|
|
const line = source.slice(0, match.index).split('\n').length
|
|||
|
|
violations.push(
|
|||
|
|
`${relative(modulesRoot, file).replaceAll('\\', '/')}:${line} ${tag.replace(/\s+/g, ' ')}`,
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
expect(violations, `缺少 placeholder:\n${violations.join('\n')}`).toEqual([])
|
|||
|
|
})
|
|||
|
|
})
|