tailwindcss/integrations/cli/index.test.ts
Philipp Spiess a1d56d8e24
Ensure content globs defined in @config files are relative to that file (#14314)
When you configure custom content globs inside an `@config` file, we
want to tread these globs as being relative to that config file and not
the CSS file that requires the content file. A config can be used by
multiple CSS configs.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-09-03 16:54:08 +02:00

186 lines
5.5 KiB
TypeScript

import os from 'node:os'
import path from 'node:path'
import { describe } from 'vitest'
import { candidate, css, html, js, json, test, yaml } from '../utils'
const STANDALONE_BINARY = (() => {
switch (os.platform()) {
case 'win32':
return 'tailwindcss-windows-x64.exe'
case 'darwin':
return os.arch() === 'x64' ? 'tailwindcss-macos-x64' : 'tailwindcss-macos-arm64'
case 'linux':
return os.arch() === 'x64' ? 'tailwindcss-linux-x64' : 'tailwindcss-linux-arm64'
default:
throw new Error(`Unsupported platform: ${os.platform()} ${os.arch()}`)
}
})()
describe.each([
['CLI', 'pnpm tailwindcss'],
[
'Standalone CLI',
path.resolve(__dirname, `../../packages/@tailwindcss-standalone/dist/${STANDALONE_BINARY}`),
],
])('%s', (_, command) => {
test(
'production build',
{
fs: {
'package.json': json`{}`,
'pnpm-workspace.yaml': yaml`
#
packages:
- project-a
`,
'project-a/package.json': json`
{
"dependencies": {
"tailwindcss": "workspace:^",
"@tailwindcss/cli": "workspace:^"
}
}
`,
'project-a/index.html': html`
<div
class="underline 2xl:font-bold hocus:underline inverted:flex"
></div>
`,
'project-a/plugin.js': js`
module.exports = function ({ addVariant }) {
addVariant('inverted', '@media (inverted-colors: inverted)')
addVariant('hocus', ['&:focus', '&:hover'])
}
`,
'project-a/tailwind.config.js': js`
module.exports = {
content: ['../project-b/src/**/*.js'],
}
`,
'project-a/src/index.css': css`
@import 'tailwindcss/utilities';
@config '../tailwind.config.js';
@source '../../project-b/src/**/*.html';
@plugin '../plugin.js';
`,
'project-a/src/index.js': js`
const className = "content-['project-a/src/index.js']"
module.exports = { className }
`,
'project-b/src/index.html': html`
<div class="flex" />
`,
'project-b/src/index.js': js`
const className = "content-['project-b/src/index.js']"
module.exports = { className }
`,
},
},
async ({ root, fs, exec }) => {
await exec(`${command} --input src/index.css --output dist/out.css`, {
cwd: path.join(root, 'project-a'),
})
await fs.expectFileToContain('project-a/dist/out.css', [
candidate`underline`,
candidate`flex`,
candidate`content-['project-a/src/index.js']`,
candidate`content-['project-b/src/index.js']`,
candidate`inverted:flex`,
candidate`hocus:underline`,
])
},
)
test(
'watch mode',
{
fs: {
'package.json': json`{}`,
'pnpm-workspace.yaml': yaml`
#
packages:
- project-a
`,
'project-a/package.json': json`
{
"dependencies": {
"tailwindcss": "workspace:^",
"@tailwindcss/cli": "workspace:^"
}
}
`,
'project-a/index.html': html`
<div
class="underline 2xl:font-bold hocus:underline inverted:flex"
></div>
`,
'project-a/plugin.js': js`
module.exports = function ({ addVariant }) {
addVariant('inverted', '@media (inverted-colors: inverted)')
addVariant('hocus', ['&:focus', '&:hover'])
}
`,
'project-a/tailwind.config.js': js`
module.exports = {
content: ['../project-b/src/**/*.js'],
}
`,
'project-a/src/index.css': css`
@import 'tailwindcss/utilities';
@config '../tailwind.config.js';
@source '../../project-b/src/**/*.html';
@plugin '../plugin.js';
`,
'project-a/src/index.js': js`
const className = "content-['project-a/src/index.js']"
module.exports = { className }
`,
'project-b/src/index.html': html`
<div class="flex" />
`,
'project-b/src/index.js': js`
const className = "content-['project-b/src/index.js']"
module.exports = { className }
`,
},
},
async ({ root, fs, spawn }) => {
await spawn(`${command} --input src/index.css --output dist/out.css --watch`, {
cwd: path.join(root, 'project-a'),
})
await fs.expectFileToContain('project-a/dist/out.css', [
candidate`underline`,
candidate`flex`,
candidate`content-['project-a/src/index.js']`,
candidate`content-['project-b/src/index.js']`,
candidate`inverted:flex`,
candidate`hocus:underline`,
])
await fs.write(
'project-a/src/index.js',
js`
const className = "[.changed_&]:content-['project-a/src/index.js']"
module.exports = { className }
`,
)
await fs.expectFileToContain('project-a/dist/out.css', [
candidate`[.changed_&]:content-['project-a/src/index.js']`,
])
await fs.write(
'project-b/src/index.js',
js`
const className = "[.changed_&]:content-['project-b/src/index.js']"
module.exports = { className }
`,
)
await fs.expectFileToContain('project-a/dist/out.css', [
candidate`[.changed_&]:content-['project-b/src/index.js']`,
])
},
)
})