37 lines
1.3 KiB
JavaScript
37 lines
1.3 KiB
JavaScript
import { readdir, readFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
|
|
async function findVueFiles(directory) {
|
|
const entries = await readdir(directory, { withFileTypes: true })
|
|
const files = await Promise.all(entries.map((entry) => {
|
|
const entryPath = path.join(directory, entry.name)
|
|
if (entry.isDirectory()) return findVueFiles(entryPath)
|
|
return entry.isFile() && entry.name.endsWith('.vue') ? [entryPath] : []
|
|
}))
|
|
return files.flat()
|
|
}
|
|
|
|
describe('form field identity', () => {
|
|
it('gives every native form field an id and name', async () => {
|
|
const vueFiles = await findVueFiles(path.join(projectRoot, 'src'))
|
|
const missing = []
|
|
|
|
for (const filePath of vueFiles) {
|
|
const source = await readFile(filePath, 'utf8')
|
|
for (const match of source.matchAll(/<(?:input|select|textarea)\b[^>]*>/gs)) {
|
|
const tag = match[0]
|
|
const line = source.slice(0, match.index).split('\n').length
|
|
if (!/\s(?::)?id=/.test(tag) || !/\s(?::)?name=/.test(tag)) {
|
|
missing.push(`${path.relative(projectRoot, filePath)}:${line} ${tag.replace(/\s+/g, ' ')}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
expect(missing).toEqual([])
|
|
})
|
|
})
|