diff --git a/integrations/postcss/index.test.ts b/integrations/postcss/index.test.ts new file mode 100644 index 000000000000..a6b3e0353381 --- /dev/null +++ b/integrations/postcss/index.test.ts @@ -0,0 +1,164 @@ +import path from 'node:path' +import { candidate, css, html, js, json, test, yaml } from '../utils' + +test( + 'production build', + { + fs: { + 'package.json': json`{}`, + 'pnpm-workspace.yaml': yaml` + # + packages: + - project-a + `, + 'project-a/package.json': json` + { + "dependencies": { + "postcss": "^8", + "postcss-cli": "^10", + "tailwindcss": "workspace:^", + "@tailwindcss/postcss": "workspace:^" + } + } + `, + 'project-a/postcss.config.js': js` + module.exports = { + plugins: { + '@tailwindcss/postcss': {}, + }, + } + `, + 'project-a/index.html': html` +
+ `, + 'project-a/plugin.js': js` + module.exports = function ({ addVariant }) { + addVariant('inverted', '@media (inverted-colors: inverted)') + addVariant('hocus', ['&:focus', '&:hover']) + } + `, + 'project-a/src/index.css': css` + @import 'tailwindcss/utilities'; + @content '../../project-b/src/**/*.js'; + @plugin '../plugin.js'; + `, + 'project-a/src/index.js': js` + const className = "content-['a/src/index.js']" + module.exports = { className } + `, + 'project-b/src/index.js': js` + const className = "content-['b/src/index.js']" + module.exports = { className } + `, + }, + }, + async ({ root, fs, exec }) => { + await exec('pnpm postcss src/index.css --output dist/out.css', { + cwd: path.join(root, 'project-a'), + }) + + await fs.expectFileToContain('project-a/dist/out.css', [ + candidate`underline`, + candidate`content-['a/src/index.js']`, + candidate`content-['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": { + "postcss": "^8", + "postcss-cli": "^10", + "tailwindcss": "workspace:^", + "@tailwindcss/postcss": "workspace:^" + } + } + `, + 'project-a/postcss.config.js': js` + module.exports = { + plugins: { + '@tailwindcss/postcss': {}, + }, + } + `, + 'project-a/index.html': html` + + `, + 'project-a/plugin.js': js` + module.exports = function ({ addVariant }) { + addVariant('inverted', '@media (inverted-colors: inverted)') + addVariant('hocus', ['&:focus', '&:hover']) + } + `, + 'project-a/src/index.css': css` + @import 'tailwindcss/utilities'; + @content '../../project-b/src/**/*.js'; + @plugin '../plugin.js'; + `, + 'project-a/src/index.js': js` + const className = "content-['a/src/index.js']" + module.exports = { className } + `, + 'project-b/src/index.js': js` + const className = "content-['b/src/index.js']" + module.exports = { className } + `, + }, + }, + async ({ root, fs, spawn }) => { + let process = await spawn( + 'pnpm postcss src/index.css --output dist/out.css --watch --verbose', + { cwd: path.join(root, 'project-a') }, + ) + await process.onStderr((message) => message.includes('Waiting for file changes...')) + + await fs.expectFileToContain('project-a/dist/out.css', [ + candidate`underline`, + candidate`content-['a/src/index.js']`, + candidate`content-['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']`, + ]) + }, +) diff --git a/integrations/utils.ts b/integrations/utils.ts index b4bd0f1d56f6..52ae3572ab57 100644 --- a/integrations/utils.ts +++ b/integrations/utils.ts @@ -96,10 +96,18 @@ export function test( } let disposables: (() => Promise