Robin Malfait d94541cbf3
Handle old to new config when normalizing the config (#5658)
* immediately take the `safelist` values into account

Currently we had to manually add them in the `setupTrackingContext`,
`setupWatchingContext` and the `cli`.

This was a bit cumbersome, because the `safelist` function (to resolve
regex patterns) was implemented on the context. This means that we had
to do something like this:

```js
let changedContent = []
let context = createContext(config, changedContent)
for (let content of context.safelist()) {
  changedContent.push(content)
}
```

This just feels wrong in general, so now it is handled internally for
you which means that we can't mess it up anymore in those 3 spots.

* drop the dot from the extension

Our transformers and extractors are implemented for `html` for example.
However the `path.extname()` returns `.html`.

This isn't an issue by default, but it could be for with custom
extractors / transformers.

* normalize the configuration

* make shared cache local per extractor

* ensure we always have an `extension`

Defaults to `html`

* splitup custom-extractors test

* update old config structure to new structure

* ensure we validate the "old" structure, and warn if invalid

* add tests with "old" config, to ensure it keeps working

* add missing `content` object

* inline unnecessary function abstraction
2021-10-01 12:56:54 +02:00

319 lines
7.4 KiB
JavaScript

let $ = require('../../execute')
let { css, html, javascript } = require('../../syntax')
let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({
output: 'dist',
input: 'src',
})
function ready(message) {
return message.includes('Done in')
}
describe('static build', () => {
it('should be possible to generate tailwind output', async () => {
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
await $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css', {
env: { NODE_ENV: 'production' },
})
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
`
)
})
it('should safelist a list of classes to always include', async () => {
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
await writeInputFile(
'../tailwind.config.js',
javascript`
module.exports = {
content: {
files: ['./src/index.html'],
},
safelist: ['bg-red-500','bg-red-600'],
theme: {
extend: {
},
},
corePlugins: {
preflight: false,
},
plugins: [],
}
`
)
await $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css', {
env: { NODE_ENV: 'production' },
})
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}
.bg-red-600 {
--tw-bg-opacity: 1;
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
}
.font-bold {
font-weight: 700;
}
`
)
})
})
describe('watcher', () => {
test('classes are generated when the html file changes', async () => {
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
let runningProcess = $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css -w')
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
`
)
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
.font-normal {
font-weight: 400;
}
`
)
await appendToInputFile('index.html', html`<div class="bg-red-500"></div>`)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}
.font-bold {
font-weight: 700;
}
.font-normal {
font-weight: 400;
}
`
)
return runningProcess.stop()
})
test('@layers are replaced and cleaned when the html file changes', async () => {
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
await writeInputFile(
'index.css',
css`
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
scroll-behavior: smooth;
}
}
`
)
let runningProcess = $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css -w')
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
`
)
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).not.toIncludeCss(css`
@layer base {
html {
scroll-behavior: smooth;
}
}
`)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
.font-normal {
font-weight: 400;
}
`
)
return runningProcess.stop()
})
test('classes are generated when the tailwind.config.js file changes', async () => {
await writeInputFile('index.html', html`<div class="font-bold md:font-medium"></div>`)
let runningProcess = $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css -w')
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
font-weight: 500;
}
}
`
)
await writeInputFile(
'../tailwind.config.js',
javascript`
module.exports = {
content: ['./src/index.html'],
theme: {
extend: {
screens: {
md: '800px'
},
fontWeight: {
bold: 'bold'
}
},
},
corePlugins: {
preflight: false,
},
plugins: [],
}
`
)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
font-weight: 500;
}
}
`
)
return runningProcess.stop()
})
test('classes are generated when the index.css file changes', async () => {
await writeInputFile('index.html', html`<div class="font-bold btn"></div>`)
let runningProcess = $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css -w')
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.font-bold {
font-weight: 700;
}
`
)
await writeInputFile(
'index.css',
css`
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn {
@apply px-2 py-1 rounded;
}
}
`
)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.btn {
border-radius: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.font-bold {
font-weight: 700;
}
`
)
await writeInputFile(
'index.css',
css`
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn {
@apply px-2 py-1 rounded bg-red-500;
}
}
`
)
await runningProcess.onStderr(ready)
expect(await readOutputFile('main.css')).toIncludeCss(
css`
.btn {
border-radius: 0.25rem;
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
padding-left: 0.5rem;
padding-right: 0.5rem;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.font-bold {
font-weight: 700;
}
`
)
return runningProcess.stop()
})
})