mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
* Update lockfile * Tweak formatting * Refactor content path parsing * Allow resolving content paths relative to the config file * Include resolved symlinks as additional content paths * Update changelog * Work on suite of tests for content resolution * reformat integration test list * Move content resolution tests to integration * Update future and experimental types
288 lines
8.0 KiB
JavaScript
288 lines
8.0 KiB
JavaScript
let fs = require('fs')
|
|
let path = require('path')
|
|
let { cwd } = require('./cwd.js')
|
|
let { writeConfigs, destroyConfigs } = require('./config.js')
|
|
|
|
let $ = require('../../execute')
|
|
let { css } = require('../../syntax')
|
|
|
|
let { readOutputFile } = require('../../io')({
|
|
output: 'dist',
|
|
input: '.',
|
|
})
|
|
|
|
// Write default configs before running tests and remove them afterwards
|
|
beforeAll(() => writeConfigs())
|
|
afterAll(() => destroyConfigs())
|
|
|
|
// Create a symlink at ./src/link that points to ./src/resolved and remove it afterwards
|
|
beforeAll(() =>
|
|
fs.promises.symlink(
|
|
path.resolve(__dirname, '../src/resolved'),
|
|
path.resolve(__dirname, '../src/link')
|
|
)
|
|
)
|
|
afterAll(async () => {
|
|
try {
|
|
await fs.promises.unlink(path.resolve(__dirname, '../src/link'))
|
|
} catch {}
|
|
})
|
|
|
|
// If we've changed directories reset the cwd back to what it was before running these tests
|
|
afterEach(() => cwd.unwind())
|
|
|
|
async function build({ cwd: cwdPath } = {}) {
|
|
let inputPath = path.resolve(__dirname, '../src/index.css')
|
|
let outputPath = path.resolve(__dirname, '../dist/main.css')
|
|
|
|
await cwd.switch(cwdPath)
|
|
|
|
// Note that ./tailwind.config.js is hardcoded on purpose here
|
|
// It represents a config but one that could be in different places
|
|
await $(`postcss ${inputPath} -o ${outputPath}`, {
|
|
env: { NODE_ENV: 'production' },
|
|
cwd: cwdPath,
|
|
})
|
|
|
|
return {
|
|
css: await readOutputFile('main.css'),
|
|
}
|
|
}
|
|
|
|
it('looks in the CWD by default', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
files: ['./src/real/yes.html'],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
})
|
|
|
|
it('looks in the CWD for non-config-relative paths', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
// Turn it on by default (eventual v4 behavior)
|
|
experimental: { relativeContentPathsByDefault: true },
|
|
|
|
// But then disable it anyway
|
|
content: {
|
|
relative: false,
|
|
files: ['./src/real/yes.html'],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
})
|
|
|
|
it('can look for content files relative to the config', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
relative: true,
|
|
files: ['./real/yes.html'],
|
|
},
|
|
},
|
|
})
|
|
|
|
// Here `./real` doesn't exist next to the config in the root directory
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(css``)
|
|
|
|
// But here it `./real` does exist next to the config in the `./src` directory!
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('it handles ignored globs correctly when not relative to the config', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
relative: false,
|
|
files: [
|
|
'./src/real/yes.html', // Scanned + static
|
|
'./src/real/*.js', // Scanned + dynamic
|
|
'!./src/real/no.js', // Ignored + static
|
|
'!./src/real/no-*.js', // Ignored + dynamic
|
|
],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[real-dynamic-positive\] {
|
|
--tw-content: real-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
|
|
// But here it `./real` does exist next to the config in the `./src` directory!
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
})
|
|
|
|
it('it handles ignored globs correctly when relative to the config', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
relative: true,
|
|
files: [
|
|
'./real/yes.html', // Scanned + static
|
|
'./real/*.js', // Scanned + dynamic
|
|
'!./real/no.js', // Ignored + static
|
|
'!./real/no-*.js', // Ignored + dynamic
|
|
],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
|
|
// But here it `./real` does exist next to the config in the `./src` directory!
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[real-dynamic-positive\] {
|
|
--tw-content: real-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('it can resolve symlinks for files when not relative to the config', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
relative: false,
|
|
files: [
|
|
'./src/real/yes.html', // Scanned + static
|
|
'./src/real/*.js', // Scanned + dynamic
|
|
'./src/link/yes.html', // Scanned + static + symlinked
|
|
'./src/link/*.js', // Scanned + dynamic + symlinked
|
|
'!./src/real/no.js', // Ignored + static
|
|
'!./src/real/no-*.js', // Ignored + dynamic
|
|
'!./src/link/no.js', // Ignored + static + symlinked
|
|
'!./src/link/no-*.js', // Ignored + dynamic + symlinked
|
|
],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[resolved-static-positive\] {
|
|
--tw-content: resolved-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[real-dynamic-positive\] {
|
|
--tw-content: real-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[resolved-dynamic-positive\] {
|
|
--tw-content: resolved-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
|
|
// But here it `./real` does exist next to the config in the `./src` directory!
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
})
|
|
|
|
it('it can resolve symlinks for files when relative to the config', async () => {
|
|
await writeConfigs({
|
|
both: {
|
|
content: {
|
|
relative: true,
|
|
files: [
|
|
'./real/yes.html', // Scanned + static
|
|
'./real/*.js', // Scanned + dynamic
|
|
'./link/yes.html', // Scanned + static + symlinked
|
|
'./link/*.js', // Scanned + dynamic + symlinked
|
|
'!./real/no.js', // Ignored + static
|
|
'!./real/no-*.js', // Ignored + dynamic
|
|
'!./link/no.js', // Ignored + static + symlinked
|
|
'!./link/no-*.js', // Ignored + dynamic + symlinked
|
|
],
|
|
},
|
|
},
|
|
})
|
|
|
|
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
|
|
|
expect(result.css).toMatchCss(``)
|
|
|
|
// But here it `./real` does exist next to the config in the `./src` directory!
|
|
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
|
|
|
expect(result.css).toMatchCss(css`
|
|
.content-\[real-static-positive\] {
|
|
--tw-content: real-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[resolved-static-positive\] {
|
|
--tw-content: resolved-static-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[real-dynamic-positive\] {
|
|
--tw-content: real-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
.content-\[resolved-dynamic-positive\] {
|
|
--tw-content: resolved-dynamic-positive;
|
|
content: var(--tw-content);
|
|
}
|
|
`)
|
|
})
|