Skip to content

Commit 35f799f

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
bound CVA conditions to flat literal arrays
1 parent 5259aeb commit 35f799f

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

‎scripts/check-design-conformance-command.test.ts‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ function commit(repo: string) {
5656
return git(repo, ['rev-parse', 'HEAD']).toString().trim()
5757
}
5858

59-
function run(args: string[], entry = cli, env: NodeJS.ProcessEnv = {}) {
59+
function run(args: string[], entry = cli, env: NodeJS.ProcessEnv = {}, timeout?: number) {
6060
return spawnSync('bun', ['--no-env-file', entry, ...args], {
6161
cwd: temp,
6262
encoding: 'utf8',
63+
timeout,
6364
env: { ...process.env, GITHUB_ACTIONS: 'false', ...env },
6465
})
6566
}
@@ -590,6 +591,45 @@ test.each([
590591
}
591592
)
592593

594+
test('nested CVA condition arrays finish within the real CLI timeout and remain unchecked', () => {
595+
const { repo } = fixture()
596+
const sourceFile = 'packages/emcn/src/components/recipe.ts'
597+
const write = (file: string, source: string) => {
598+
mkdirSync(path.dirname(path.join(repo, file)), { recursive: true })
599+
writeFileSync(path.join(repo, file), source)
600+
}
601+
write('packages/emcn/src/index.ts', "export {recipe} from './components/recipe'")
602+
const source = (leaf: string) => {
603+
let nested = JSON.stringify(leaf)
604+
for (let depth = 0; depth < 3; depth++) nested = `[${Array(32).fill(nested).join(',')}]`
605+
const compound = `{size:[${Array(64).fill('nested').join(',')}],class:'rounded-lg'}`
606+
return `import {cva} from 'class-variance-authority';const nested=${nested};export const recipe=cva('p-2',{variants:{size:{small:'',large:''}},compoundVariants:[${Array(24).fill(compound).join(',')}]});throw Error('Source must not execute')`
607+
}
608+
write(sourceFile, source('small'))
609+
const base = commit(repo)
610+
write(sourceFile, source('large'))
611+
const child = run(
612+
['--repo', repo, '--base', base, '--working-tree', '--format', 'json'],
613+
cli,
614+
{},
615+
15000
616+
)
617+
expect(
618+
child.error,
619+
`CLI must finish before its subprocess timeout: ${child.error?.message}`
620+
).toBeUndefined()
621+
expect(child.status, child.stderr).toBe(0)
622+
const report = JSON.parse(child.stdout) as Report
623+
expect(report.status).toBe('completed')
624+
expect(report.findings.filter((finding) => finding.file === sourceFile)).toHaveLength(0)
625+
expect(
626+
report.unchecked.some(
627+
(note) =>
628+
note.file === sourceFile && note.reason.startsWith('CVA compound condition is unchecked')
629+
)
630+
).toBe(true)
631+
}, 25_000)
632+
593633
test.each([
594634
['grid line integer', 'gridColumnStart', 'grid-column-start', '1', 1, ''],
595635
['grid row integer', 'gridRowEnd', 'grid-row-end', '3', 3, ''],

‎scripts/design-conformance/extract.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,8 @@ export function extract(
10551055
if (value.isNullLiteral()) return null
10561056
if (value.isUnaryExpression({ operator: '-' }) && value.get('argument').isNumericLiteral())
10571057
return -(value.node.argument as t.NumericLiteral).value
1058-
if (!value.isArrayExpression() || value.node.elements.length > 64) return undefined
1058+
if (depth > 0 || !value.isArrayExpression() || value.node.elements.length > 64)
1059+
return undefined
10591060
const values = value
10601061
.get('elements')
10611062
.map((element) =>

0 commit comments

Comments
 (0)