Repository: tailwindlabs/tailwindcss
File: packages/@tailwindcss-upgrade/src/template/codemods/automatic-var-injection.test.ts (TypeScript)

Code before:
test.each([
  // Arbitrary candidates
  ['[color:--my-color]', '[color:var(--my-color)]'],

  // Arbitrary values for functional candidates
  ['bg-[--my-color]', 'bg-[var(--my-color)]'],
  ['bg-[color:--my-color]', 'bg-[color:var(--my-color)]'],
  ['border-[length:--my-length]', 'border-[length:var(--my-length)]'],
  ['border-[line-width:--my-width]', 'border-[line-width:var(--my-width)]'],

  // Does not add var() if there is a _ before the variable name
  ['bg-[_--my-color]', null],
  ['bg-[color:_--my-color]', null],
  ['border-[length:_--my-length]', null],
  ['border-[line-width:_--my-width]', null],

  // Modifiers
  ['[color:--my-color]/[--my-opacity]', '[color:var(--my-color)]/[var(--my-opacity)]'],
  ['bg-red-500/[--my-opacity]', 'bg-red-500/[var(--my-opacity)]'],
  ['bg-[--my-color]/[--my-opacity]', 'bg-[var(--my-color)]/[var(--my-opacity)]'],
  ['bg-[color:--my-color]/[--my-opacity]', 'bg-[color:var(--my-color)]/[var(--my-opacity)]'],

  ['[color:--my-color]/[_--my-opacity]', '[color:var(--my-color)]/[_--my-opacity]'],
  ['bg-red-500/[_--my-opacity]', null],
  ['bg-[--my-color]/[_--my-opacity]', 'bg-[var(--my-color)]/[_--my-opacity]'],
  ['bg-[color:--my-color]/[_--my-opacity]', 'bg-[color:var(--my-color)]/[_--my-opacity]'],

  // Variants
  ['supports-[--test]:flex', 'supports-[var(--test)]:flex'],
  ['supports-[_--test]:flex', null],
])('%s => %s', async (candidate, result) => {
  let designSystem = await __unstable__loadDesignSystem('@import "tailwindcss";', {
    base: __dirname,
  })

  let migrated = automaticVarInjection(designSystem.parseCandidate(candidate)[0]!)
  expect(migrated ? printCandidate(migrated) : migrated).toEqual(result)
})


Review comment (suggestion):
Since the `_--` was a workaround, I think we can safely map this to `--` _without_ the `var(…)`

```suggestion
  ['bg-[color:--my-color]/[_--my-opacity]', 'bg-[color:var(--my-color)]/[--my-opacity]'],
```

(I think that applies everywhere, so values and modifiers)

Code after:
  // Arbitrary candidates
  ['[color:--my-color]', '[color:var(--my-color)]'],
  ['[--my-color:red]', '[--my-color:red]'],
  ['[--my-color:--my-other-color]', '[--my-color:var(--my-other-color)]'],

  // Arbitrary values for functional candidates
  ['bg-[--my-color]', 'bg-[var(--my-color)]'],
  ['bg-[color:--my-color]', 'bg-[color:var(--my-color)]'],
  ['border-[length:--my-length]', 'border-[length:var(--my-length)]'],
  ['border-[line-width:--my-width]', 'border-[line-width:var(--my-width)]'],

  // Can clean up the workaround for opting out of automatic var injection
  ['bg-[_--my-color]', 'bg-[--my-color]'],
  ['bg-[color:_--my-color]', 'bg-[color:--my-color]'],
  ['border-[length:_--my-length]', 'border-[length:--my-length]'],
  ['border-[line-width:_--my-width]', 'border-[line-width:--my-width]'],

  // Modifiers
  ['[color:--my-color]/[--my-opacity]', '[color:var(--my-color)]/[var(--my-opacity)]'],
  ['bg-red-500/[--my-opacity]', 'bg-red-500/[var(--my-opacity)]'],
  ['bg-[--my-color]/[--my-opacity]', 'bg-[var(--my-color)]/[var(--my-opacity)]'],
  ['bg-[color:--my-color]/[--my-opacity]', 'bg-[color:var(--my-color)]/[var(--my-opacity)]'],

  // Can clean up the workaround for opting out of automatic var injection
  ['[color:--my-color]/[_--my-opacity]', '[color:var(--my-color)]/[--my-opacity]'],
  ['bg-red-500/[_--my-opacity]', 'bg-red-500/[--my-opacity]'],
  ['bg-[--my-color]/[_--my-opacity]', 'bg-[var(--my-color)]/[--my-opacity]'],
  ['bg-[color:--my-color]/[_--my-opacity]', 'bg-[color:var(--my-color)]/[--my-opacity]'],

  // Variants
  ['supports-[--test]:flex', 'supports-[var(--test)]:flex'],
  ['supports-[_--test]:flex', 'supports-[--test]:flex'],

  // Some properties never had var() injection in v3.
  ['[scroll-timeline-name:--myTimeline]', '[scroll-timeline-name:--myTimeline]'],
  ['[timeline-scope:--myScope]', '[timeline-scope:--myScope]'],
  ['[view-timeline-name:--myTimeline]', '[view-timeline-name:--myTimeline]'],
  ['[font-palette:--myPalette]', '[font-palette:--myPalette]'],
  ['[anchor-name:--myAnchor]', '[anchor-name:--myAnchor]'],
  ['[anchor-scope:--myScope]', '[anchor-scope:--myScope]'],
  ['[position-anchor:--myAnchor]', '[position-anchor:--myAnchor]'],
  ['[position-try-options:--myAnchor]', '[position-try-options:--myAnchor]'],
  ['[scroll-timeline:--myTimeline]', '[scroll-timeline:--myTimeline]'],
  ['[animation-timeline:--myAnimation]', '[animation-timeline:--myAnimation]'],
  ['[view-timeline:--myTimeline]', '[view-timeline:--myTimeline]'],
  ['[position-try:--myAnchor]', '[position-try:--myAnchor]'],
])('%s => %s', async (candidate, result) => {
  let designSystem = await __unstable__loadDesignSystem('@import "tailwindcss";', {
    base: __dirname,
  })