From 8e033ddfc3024bc12353bdf100cf5ce67fb714bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Heidk=C3=A4mper?= Date: Mon, 27 Jan 2025 20:04:33 +0100 Subject: [PATCH] add legacy tailwind tests --- .../{npm-publish.yml => publish.yml} | 3 +- .github/workflows/{ci.yml => tests.yml} | 14 +- jest/index.test.js | 144 +++++++++--------- jest/legacy/index.test.js | 94 ++++++++++++ jest/legacy/package.json | 11 ++ 5 files changed, 186 insertions(+), 80 deletions(-) rename .github/workflows/{npm-publish.yml => publish.yml} (91%) rename .github/workflows/{ci.yml => tests.yml} (63%) create mode 100644 jest/legacy/index.test.js create mode 100644 jest/legacy/package.json diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/publish.yml similarity index 91% rename from .github/workflows/npm-publish.yml rename to .github/workflows/publish.yml index cf3362c..e3ff791 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,4 @@ -name: NPM Publish +name: Publish on: release: @@ -13,6 +13,7 @@ jobs: with: node-version: '20.x' - run: npm install + - run: npm install --prefix jest/legacy - run: npm test publish: diff --git a/.github/workflows/ci.yml b/.github/workflows/tests.yml similarity index 63% rename from .github/workflows/ci.yml rename to .github/workflows/tests.yml index b784dd1..da3f2be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/tests.yml @@ -1,22 +1,20 @@ -name: CI +name: Tests on: [push, pull_request] jobs: test: - runs-on: ubuntu-latest - strategy: matrix: - node-version: [20.x, 21.x] - + node-version: [20.x, 22.x] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - run: yarn - - run: yarn lint - - run: yarn test + - run: npm install + - run: npm install --prefix jest/legacy + - run: npm run lint + - run: npm run test diff --git a/jest/index.test.js b/jest/index.test.js index 0c3b864..cc443f2 100644 --- a/jest/index.test.js +++ b/jest/index.test.js @@ -22,84 +22,86 @@ async function run(file, options = {}) { return result.css } -it('generates `delay` utilities', async () => { - expect(await run('content/delay.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-delay-75 { animation-delay: 75ms; }', - '.animate-delay-333 { animation-delay: 333ms; }', - '.animate-delay-\\[666ms\\] { animation-delay: 666ms; }', - ]) -}) +describe('modern tailwind', () => { + it('generates `composition` utilities', async () => { + expect(await run('content/composition.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-add { animation-composition: add; }', + '.animate-replace { animation-composition: replace; }', + '.animate-accumulate { animation-composition: accumulate; }', + ]) + }) -it('generates `duration` utilities', async () => { - expect(await run('content/duration.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-duration-75 { animation-duration: 75ms; }', - '.animate-duration-333 { animation-duration: 333ms; }', - '.animate-duration-\\[666ms\\] { animation-duration: 666ms; }', - ]) -}) + it('generates `delay` utilities', async () => { + expect(await run('content/delay.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-delay-75 { animation-delay: 75ms; }', + '.animate-delay-333 { animation-delay: 333ms; }', + '.animate-delay-\\[666ms\\] { animation-delay: 666ms; }', + ]) + }) -it('generates `direction` utilities', async () => { - expect(await run('content/direction.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-normal { animation-direction: normal; }', - '.animate-reverse { animation-direction: reverse; }', - ]) -}) + it('generates `direction` utilities', async () => { + expect(await run('content/direction.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-normal { animation-direction: normal; }', + '.animate-reverse { animation-direction: reverse; }', + ]) + }) -it('generates `fill-mode` utilities', async () => { - expect(await run('content/fill-mode.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-fill-both { animation-fill-mode: both; }', - '.animate-fill-none { animation-fill-mode: normal; }', - ]) -}) + it('generates `duration` utilities', async () => { + expect(await run('content/duration.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-duration-75 { animation-duration: 75ms; }', + '.animate-duration-333 { animation-duration: 333ms; }', + '.animate-duration-\\[666ms\\] { animation-duration: 666ms; }', + ]) + }) -it('generates `iteration-count` utilities', async () => { - expect(await run('content/iteration-count.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-infinite { animation-iteration-count: infinite; }', - '.animate-once { animation-iteration-count: 1; }', - '.animate-iteration-7 { animation-iteration-count: 7; }', - '.animate-iteration-\\[14\\] { animation-iteration-count: 14; }', - ]) -}) + it('generates `fill-mode` utilities', async () => { + expect(await run('content/fill-mode.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-fill-both { animation-fill-mode: both; }', + '.animate-fill-none { animation-fill-mode: normal; }', + ]) + }) -it('generates `play-state` utilities', async () => { - expect(await run('content/play-state.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-play { animation-play-state: running; }', - '.animate-stop { animation-play-state: paused; }', - ]) -}) + it('generates `iteration-count` utilities', async () => { + expect(await run('content/iteration-count.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-infinite { animation-iteration-count: infinite; }', + '.animate-once { animation-iteration-count: 1; }', + '.animate-iteration-7 { animation-iteration-count: 7; }', + '.animate-iteration-\\[14\\] { animation-iteration-count: 14; }', + ]) + }) -it('generates `timing-function` utilities', async () => { - expect(await run('content/timing-function.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-ease { animation-timing-function: ease; }', - '.animate-ease-linear { animation-timing-function: linear; }', - '.animate-ease-\\[cubic-bezier\\(1\\,0\\.66\\,0\\.33\\,0\\)\\] { animation-timing-function: cubic-bezier(1,0.66,0.33,0); }', - ]) -}) + it('generates `play-state` utilities', async () => { + expect(await run('content/play-state.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-play { animation-play-state: running; }', + '.animate-stop { animation-play-state: paused; }', + ]) + }) -it('generates `composition` utilities', async () => { - expect(await run('content/composition.html', { scope: 'utilities' })).toIncludeAll([ - '.animate-add { animation-composition: add; }', - '.animate-replace { animation-composition: replace; }', - '.animate-accumulate { animation-composition: accumulate; }', - ]) -}) + it('generates predefined animations for modern import', async () => { + expect(await run('content/predefined-animations.html', { importType: 'modern' })).toIncludeAll([ + '.animate-fade { animation: var(--animate-fade); }', + '--animate-fade: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both;', + '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', + '.animate-spin { animation: var(--animate-spin); }', + '--animate-spin: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite;', + '@keyframes spin { to { transform: rotate(360deg); }}', + ]) + }) -it('generates predefined animations for modern import', async () => { - expect(await run('content/predefined-animations.html', { importType: 'modern' })).toIncludeAll([ - '.animate-fade { animation: var(--animate-fade); }', - '--animate-fade: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both;', - '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', - '.animate-spin { animation: var(--animate-spin); }', - '--animate-spin: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite;', - '@keyframes spin { to { transform: rotate(360deg); }}', - ]) -}) + it('generates predefined animations for legacy import', async () => { + expect(await run('content/predefined-animations.html', { importType: 'legacy' })).toIncludeAll([ + '.animate-fade { animation: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; }', + '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', + '.animate-spin { animation: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite; }', + '@keyframes spin { to { transform: rotate(360deg); }}', + ]) + }) -it('generates predefined animations for legacy import', async () => { - expect(await run('content/predefined-animations.html', { importType: 'legacy' })).toIncludeAll([ - '.animate-fade { animation: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; }', - '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', - '.animate-spin { animation: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite; }', - '@keyframes spin { to { transform: rotate(360deg); }}', - ]) + it('generates `timing-function` utilities', async () => { + expect(await run('content/timing-function.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-ease { animation-timing-function: ease; }', + '.animate-ease-linear { animation-timing-function: linear; }', + '.animate-ease-\\[cubic-bezier\\(1\\,0\\.66\\,0\\.33\\,0\\)\\] { animation-timing-function: cubic-bezier(1,0.66,0.33,0); }', + ]) + }) }) diff --git a/jest/legacy/index.test.js b/jest/legacy/index.test.js new file mode 100644 index 0000000..92935da --- /dev/null +++ b/jest/legacy/index.test.js @@ -0,0 +1,94 @@ +const fs = require('fs') +const path = require('path') +const postcss = require('postcss') +const tailwindcss = require('tailwindcss') + +async function run(file) { + const { currentTestName } = expect.getState() + + const config = { + content: [file], + corePlugins: { preflight: false }, + plugins: [require('../../src')], + } + + const result = await postcss(tailwindcss(config)).process('@tailwind utilities', { + from: `${path.resolve(__filename)}?test=${currentTestName}`, + }) + + return result.css +} + +describe('legacy tailwind', () => { + if (! fs.existsSync(`${__dirname}/node_modules`)) { + throw new Error(`Dependencies in ${__dirname} are missing`) + } + + it('generates `composition` utilities', async () => { + expect(await run('jest/content/composition.html')).toIncludeAll([ + '.animate-add { animation-composition: add; }', + '.animate-replace { animation-composition: replace; }', + '.animate-accumulate { animation-composition: accumulate; }', + ]) + }) + + it('should add `delay` utilities', async () => { + expect(await run('jest/content/delay.html')).toIncludeAll([ + '.animate-delay-75 { animation-delay: 75ms; }', + '.animate-delay-\\[666ms\\] { animation-delay: 666ms; }', + ]) + }) + + it('generates `direction` utilities', async () => { + expect(await run('jest/content/direction.html')).toIncludeAll([ + '.animate-normal { animation-direction: normal; }', + '.animate-reverse { animation-direction: reverse; }', + ]) + }) + + it('generates `duration` utilities', async () => { + expect(await run('jest/content/duration.html')).toIncludeAll([ + '.animate-duration-75 { animation-duration: 75ms; }', + '.animate-duration-\\[666ms\\] { animation-duration: 666ms; }', + ]) + }) + + it('generates `fill-mode` utilities', async () => { + expect(await run('jest/content/fill-mode.html')).toIncludeAll([ + '.animate-fill-both { animation-fill-mode: both; }', + '.animate-fill-none { animation-fill-mode: normal; }', + ]) + }) + + it('generates `iteration-count` utilities', async () => { + expect(await run('jest/content/iteration-count.html')).toIncludeAll([ + '.animate-infinite { animation-iteration-count: infinite; }', + '.animate-once { animation-iteration-count: 1; }', + '.animate-iteration-\\[14\\] { animation-iteration-count: 14; }', + ]) + }) + + it('generates `play-state` utilities', async () => { + expect(await run('jest/content/play-state.html')).toIncludeAll([ + '.animate-play { animation-play-state: running; }', + '.animate-stop { animation-play-state: paused; }', + ]) + }) + + it('generates predefined animations', async () => { + expect(await run('jest/content/predefined-animations.html')).toIncludeAll([ + '.animate-fade { animation: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; }', + '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', + '.animate-spin { animation: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite; }', + '@keyframes spin { to { transform: rotate(360deg); }}', + ]) + }) + + it('generates `timing-function` utilities', async () => { + expect(await run('jest/content/timing-function.html')).toIncludeAll([ + '.animate-ease { animation-timing-function: ease; }', + '.animate-ease-linear { animation-timing-function: linear; }', + '.animate-ease-\\[cubic-bezier\\(1\\2c 0\\.66\\2c 0\\.33\\2c 0\\)\\] { animation-timing-function: cubic-bezier(1,0.66,0.33,0); }', + ]) + }) +}) diff --git a/jest/legacy/package.json b/jest/legacy/package.json new file mode 100644 index 0000000..fb7021d --- /dev/null +++ b/jest/legacy/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "devDependencies": { + "tailwindcss": "3.1.0" + }, + "browserslist": { + "defaults": [ + "> 2%" + ] + } +}