SIGN IN SIGN UP

A utility-first CSS framework for rapid UI development.

0 0 25 TypeScript

Cleanup tests (#20053)

This PR does some cleanup work in the tests such that every test is
using the custom test helpers instead of creating the compiler itself
and using other test helpers such as `optimizeCss` or `pretty`.

For tests we have some helpers that introduce a small layer of
indirection. While you typically want to avoid indirection, this one
allows us to keep the tests the same whenever we make changes to the
internals.

It also allows us to run through the full core flow where we have to
setup a compiler, pass in the CSS, compile the candidates, optimize the
CSS and pretty print it for snapshot purposes.

Our tests often look like this when you are testing some candidates:
```ts
test('…', async () => {
  expect(await run(['flex', 'hover:flex'])).toMatchInlineSnapshot(`
    "
    .flex {
      display: flex;
    }

    @media (hover: hover) {
      .hover\\:flex:hover {
        display: flex;
      }
    }
    "
  `)
})
```

If you need to compile some CSS, we used the following:
```ts
test('…', async () => {
  expect(
    await compileCss(css`
      @tailwind utilities;
      .foo {
        @apply flex;
      }
    `),
  ).toMatchInlineSnapshot(`
    "
    .foo {
      display: flex;
    }
    "
  `)
})
```

With this PR, I normalized the tests by changing the signatures of those
tests slightly:
```ts
export async function run(
  // A list of candidates
  candidates: string[],

  // Optionally, custom CSS
  input = css`
    @tailwind utilities;
  `,

  // Optionally, custom compile options
  options: Parameters<typeof compile>[1] = {},
) {
  let { build } = await compile(input, options)
  return pretty(optimize(build(candidates)).code)
}

// Same as above, but without the candidates
export async function compileCss(css: string, options: Parameters<typeof compile>[1] = {}) {
  return run([], css, options)
}
```

They are very similar, but if we migrate _everything_ to `run`, then
there will be situations where you have to use:
```ts
test('…', async () => {
  expect(
    await run(
      [],
      css`
        @tailwind utilities;
        .foo {
          @apply flex;
        }
      `,
    ),
  ).toMatchInlineSnapshot(`
    "
    .foo {
      display: flex;
    }
    "
  `)
})
```

Which is a little bit confusing because what does `[]` even mean?

The next big change is that a lot of the tests were manually setting up
the compiler, passing in the CSS and compiler options, then building the
candidates, then manually optimizing the CSS and then manually pretty
printing the resulting CSS for snapshot purposes.

Other tests, didn't use all those steps and skipped the optimization
step for example. This means that not all tests were testing the
end-to-end core workflow.

This PR uses the tests helpers wherever we could. This now also means
that our tests look the same as much as possible.

The biggest goal of this was to get everything in a similar state.
Future PRs that add additional optimizations will now see those
optimizations reflected in the actual test output.

## Test plan

1. All tests still pass
- Some test _output_ has changed because the `optimizeCss` will now kick
in. But this reflects production better anyway.
2. No source code was changed
R
Robin Malfait committed
eefe64593af2a6a321354aa126e824f64524b6fd
Parent: ece4824
Committed by GitHub <noreply@github.com> on 5/14/2026, 9:43:34 AM