Skip to content
This repository was archived by the owner on Apr 6, 2021. It is now read-only.

Commit 4a95641

Browse files
Add error messages for nested at-rules & apply (#161)
* Add test for @apply of unknown utility classes * Add error for nested at rule + nested apply * Customize error message for nested @screen and nested @apply * Remove workaround by using current test name * Tweak error messages Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
1 parent eedc66e commit 4a95641

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

src/lib/expandApplyAtRules.js

+16
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,22 @@ function processApply(root, context) {
153153

154154
let [applyCandidates, important] = extractApplyCandidates(apply.params)
155155

156+
if (apply.parent.type === 'atrule') {
157+
if (apply.parent.name === 'screen') {
158+
const screenType = apply.parent.params
159+
160+
throw apply.error(
161+
`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates
162+
.map((c) => `${screenType}:${c}`)
163+
.join(' ')} instead.`
164+
)
165+
}
166+
167+
throw apply.error(
168+
`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`
169+
)
170+
}
171+
156172
for (let applyCandidate of applyCandidates) {
157173
if (!applyClassCache.has(applyCandidate)) {
158174
throw apply.error(

tests/10-apply.test.js

+78-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ const fs = require('fs')
44
const path = require('path')
55

66
function run(input, config = {}) {
7-
return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) })
7+
const { currentTestName } = expect.getState()
8+
9+
return postcss([tailwind(config)]).process(input, {
10+
from: `${path.resolve(__filename)}?test=${currentTestName}`,
11+
})
812
}
913

1014
test('@apply', () => {
@@ -139,4 +143,76 @@ test('@apply', () => {
139143
})
140144
})
141145

142-
// TODO: Test stuff that should throw
146+
test('@apply error with unknown utility', async () => {
147+
let config = {
148+
darkMode: 'class',
149+
purge: [path.resolve(__dirname, './10-apply.test.html')],
150+
corePlugins: { preflight: false },
151+
plugins: [],
152+
}
153+
154+
let css = `
155+
@tailwind components;
156+
@tailwind utilities;
157+
158+
@layer components {
159+
.foo {
160+
@apply a-utility-that-does-not-exist;
161+
}
162+
}
163+
`
164+
165+
await expect(run(css, config)).rejects.toThrowError('class does not exist')
166+
})
167+
168+
test('@apply error with nested @screen', async () => {
169+
let config = {
170+
darkMode: 'class',
171+
purge: [path.resolve(__dirname, './10-apply.test.html')],
172+
corePlugins: { preflight: false },
173+
plugins: [],
174+
}
175+
176+
let css = `
177+
@tailwind components;
178+
@tailwind utilities;
179+
180+
@layer components {
181+
.foo {
182+
@screen md {
183+
@apply text-black;
184+
}
185+
}
186+
}
187+
`
188+
189+
await expect(run(css, config)).rejects.toThrowError(
190+
'@apply is not supported within nested at-rules like @screen'
191+
)
192+
})
193+
194+
test('@apply error with nested @anyatrulehere', async () => {
195+
let config = {
196+
darkMode: 'class',
197+
purge: [path.resolve(__dirname, './10-apply.test.html')],
198+
corePlugins: { preflight: false },
199+
plugins: [],
200+
}
201+
202+
let css = `
203+
@tailwind components;
204+
@tailwind utilities;
205+
206+
@layer components {
207+
.foo {
208+
@genie {
209+
@apply text-black;
210+
}
211+
}
212+
}
213+
`
214+
215+
await expect(run(css, config)).rejects.toThrowError(
216+
'@apply is not supported within nested at-rules like @genie'
217+
)
218+
})

0 commit comments

Comments
 (0)