|
1 | 1 | import fs from 'node:fs'
|
2 | 2 | import path from 'node:path'
|
3 | 3 | import { describe, expect, it, test } from 'vitest'
|
4 |
| -import { compile, Polyfills } from '.' |
| 4 | +import { compile, Features, Polyfills } from '.' |
5 | 5 | import type { PluginAPI } from './compat/plugin-api'
|
6 | 6 | import plugin from './plugin'
|
7 | 7 | import { compileCss, optimizeCss, run } from './test-utils/run'
|
@@ -5373,3 +5373,130 @@ describe('`@property` polyfill', async () => {
|
5373 | 5373 | `)
|
5374 | 5374 | })
|
5375 | 5375 | })
|
| 5376 | + |
| 5377 | +describe('feature detection', () => { |
| 5378 | + test('using `@tailwind utilities`', async () => { |
| 5379 | + let compiler = await compile(css` |
| 5380 | + @tailwind utilities; |
| 5381 | + `) |
| 5382 | + |
| 5383 | + expect(compiler.features & Features.Utilities).toBeTruthy() |
| 5384 | + }) |
| 5385 | + |
| 5386 | + test('using `@apply`', async () => { |
| 5387 | + let compiler = await compile(css` |
| 5388 | + .foo { |
| 5389 | + @apply underline; |
| 5390 | + } |
| 5391 | + `) |
| 5392 | + |
| 5393 | + expect(compiler.features & Features.AtApply).toBeTruthy() |
| 5394 | + }) |
| 5395 | + |
| 5396 | + test('using `@import`', async () => { |
| 5397 | + let compiler = await compile( |
| 5398 | + css` |
| 5399 | + @import 'tailwindcss/preflight'; |
| 5400 | + `, |
| 5401 | + { loadStylesheet: async (_, base) => ({ base, content: '' }) }, |
| 5402 | + ) |
| 5403 | + |
| 5404 | + expect(compiler.features & Features.AtImport).toBeTruthy() |
| 5405 | + }) |
| 5406 | + |
| 5407 | + test('using `@reference`', async () => { |
| 5408 | + let compiler = await compile( |
| 5409 | + css` |
| 5410 | + @import 'tailwindcss/preflight'; |
| 5411 | + `, |
| 5412 | + { loadStylesheet: async (_, base) => ({ base, content: '' }) }, |
| 5413 | + ) |
| 5414 | + |
| 5415 | + // There's little difference between `@reference` and `@import` on a feature |
| 5416 | + // level as it's just like an import but with side-effect behavior. |
| 5417 | + // |
| 5418 | + // It's really just shorthand for `@import "…" reference;` |
| 5419 | + expect(compiler.features & Features.AtImport).toBeTruthy() |
| 5420 | + }) |
| 5421 | + |
| 5422 | + test('using `theme(…)`', async () => { |
| 5423 | + let compiler = await compile( |
| 5424 | + css` |
| 5425 | + @theme { |
| 5426 | + --color-red: #f00; |
| 5427 | + } |
| 5428 | +
|
| 5429 | + .foo { |
| 5430 | + color: theme(--color-red); |
| 5431 | + } |
| 5432 | + `, |
| 5433 | + { loadStylesheet: async (_, base) => ({ base, content: '' }) }, |
| 5434 | + ) |
| 5435 | + |
| 5436 | + expect(compiler.features & Features.ThemeFunction).toBeTruthy() |
| 5437 | + }) |
| 5438 | + |
| 5439 | + test('using `@plugin`', async () => { |
| 5440 | + let compiler = await compile( |
| 5441 | + css` |
| 5442 | + @plugin "./some-plugin.js"; |
| 5443 | + `, |
| 5444 | + { loadModule: async (_, base) => ({ base, module: () => {} }) }, |
| 5445 | + ) |
| 5446 | + |
| 5447 | + expect(compiler.features & Features.JsPluginCompat).toBeTruthy() |
| 5448 | + }) |
| 5449 | + |
| 5450 | + test('using `@config`', async () => { |
| 5451 | + let compiler = await compile( |
| 5452 | + css` |
| 5453 | + @config "./some-config.js"; |
| 5454 | + `, |
| 5455 | + { loadModule: async (_, base) => ({ base, module: {} }) }, |
| 5456 | + ) |
| 5457 | + |
| 5458 | + expect(compiler.features & Features.JsPluginCompat).toBeTruthy() |
| 5459 | + }) |
| 5460 | + |
| 5461 | + test('using `@variant`', async () => { |
| 5462 | + let compiler = await compile(css` |
| 5463 | + .foo { |
| 5464 | + @variant dark { |
| 5465 | + color: red; |
| 5466 | + } |
| 5467 | + } |
| 5468 | + `) |
| 5469 | + |
| 5470 | + expect(compiler.features & Features.Variants).toBeTruthy() |
| 5471 | + }) |
| 5472 | + |
| 5473 | + test('legacy `@variant` syntax does not trigger the variant feature', async () => { |
| 5474 | + let compiler = await compile(css` |
| 5475 | + @variant dark (&:is(.dark, .dark *)); |
| 5476 | + `) |
| 5477 | + |
| 5478 | + expect(compiler.features & Features.Variants).toBeFalsy() |
| 5479 | + }) |
| 5480 | + |
| 5481 | + test('`@tailwind utilities` is ignored inside `@reference`', async () => { |
| 5482 | + let compiler = await compile( |
| 5483 | + css` |
| 5484 | + @reference "tailwindcss/utilities"; |
| 5485 | + `, |
| 5486 | + { |
| 5487 | + async loadStylesheet(id, base) { |
| 5488 | + return { |
| 5489 | + base, |
| 5490 | + content: css` |
| 5491 | + @tailwind utilities; |
| 5492 | + `, |
| 5493 | + } |
| 5494 | + }, |
| 5495 | + }, |
| 5496 | + ) |
| 5497 | + |
| 5498 | + // We see @tailwind utilities but because of @reference it is ignored |
| 5499 | + expect(compiler.features & Features.AtImport).toBeTruthy() |
| 5500 | + expect(compiler.features & Features.Utilities).toBeFalsy() |
| 5501 | + }) |
| 5502 | +}) |
0 commit comments