From b15603cc5acf4e913aece94d26563974d7f507ba Mon Sep 17 00:00:00 2001 From: Romain Menke <11521496+romainmenke@users.noreply.github.com> Date: Tue, 26 Dec 2023 19:30:49 +0100 Subject: [PATCH] use `node:test` in `postcss-tape` (#1224) --- .github/bin/new-plugin.mjs | 2 +- .github/workflows/test.yml | 12 +- experimental/css-has-pseudo/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 4 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 6 +- experimental/postcss-nesting/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 20 +- knip.json | 33 +- package-lock.json | 117 +--- package.json | 1 - packages/base-cli/package.json | 2 +- packages/base-cli/test/test.mjs | 15 +- .../cascade-layer-name-parser/package.json | 4 +- packages/color-helpers/package.json | 2 +- packages/css-calc/package.json | 2 +- packages/css-color-parser/package.json | 2 +- packages/css-parser-algorithms/package.json | 4 +- packages/css-tokenizer/package.json | 2 +- packages/generate-test-cases/package.json | 3 +- packages/media-query-list-parser/package.json | 4 +- packages/postcss-tape/CHANGELOG.md | 4 + packages/postcss-tape/README.md | 68 ++- packages/postcss-tape/dist/index.cjs | 4 +- packages/postcss-tape/dist/index.d.ts | 69 ++- packages/postcss-tape/dist/index.mjs | 4 +- packages/postcss-tape/package.json | 3 +- .../src/file-contents-or-empty-string.ts | 9 + packages/postcss-tape/src/format-asserts.ts | 72 --- .../postcss-tape/src/github-annotations.ts | 33 - packages/postcss-tape/src/index.ts | 574 +++++++----------- .../postcss-tape/src/test-case-options.ts | 6 +- .../test-self/basic.before-after.expect.log | 2 +- .../test-self/basic.break-css.expect.log | 10 +- .../basic.broken-sourcemap.expect.log | 15 +- .../postcss-tape/test-self/basic.expect.log | 2 +- .../basic.with-diff-in-expect.expect.log | 18 +- .../test-self/basic.with-warnings.expect.log | 46 +- .../test-self/basic.without-expect.expect.log | 10 +- .../test-self/document.expect.code | 1 - .../test-self/document.expect.log | 1 - packages/postcss-tape/test-self/test.sh | 33 +- .../postcss-tape/test/document.expect.html | 17 - packages/postcss-tape/test/document.html | 17 - packages/postcss-tape/test/document.mjs | 9 - .../postcss-tape/test/document.result.html | 17 - packages/selector-specificity/package.json | 2 +- plugin-packs/postcss-bundler/package.json | 4 +- .../postcss-bundler/stryker.conf.json | 2 +- .../{.tape.mjs => test/_tape.mjs} | 20 +- plugin-packs/postcss-preset-env/package.json | 4 +- .../postcss-preset-env/src/test/test.mjs | 8 - plugin-packs/postcss-preset-env/test/_lib.mjs | 8 + .../{.tape.mjs => test/_tape.mjs} | 226 +++---- plugins/css-blank-pseudo/package.json | 5 +- plugins/css-blank-pseudo/test/_browser.mjs | 107 ++-- .../{.tape.mjs => test/_tape.mjs} | 42 +- plugins/css-has-pseudo/package.json | 5 +- plugins/css-has-pseudo/test/_browser.mjs | 102 ++-- .../test.mjs => test/_encode-decode.mjs} | 6 +- .../{.tape.mjs => test/_tape.mjs} | 22 +- plugins/css-has-pseudo/tsconfig.json | 2 +- plugins/css-prefers-color-scheme/package.json | 5 +- .../test/_browser.mjs | 110 ++-- .../{.tape.mjs => test/_tape.mjs} | 22 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-base-plugin/package.json | 4 +- plugins/postcss-base-plugin/test/_import.mjs | 12 +- plugins/postcss-base-plugin/test/_require.cjs | 11 +- .../{.tape.mjs => test/_tape.mjs} | 16 +- .../test/document.expect.html | 21 - .../postcss-base-plugin/test/document.html | 21 - plugins/postcss-cascade-layers/package.json | 5 +- .../postcss-cascade-layers/test/_browser.mjs | 130 ++-- .../{.tape.mjs => test/_tape.mjs} | 38 +- plugins/postcss-color-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 28 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 22 +- plugins/postcss-color-hex-alpha/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- .../postcss-color-mix-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- .../postcss-color-rebeccapurple/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 20 +- .../postcss-conditional-values/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 12 +- plugins/postcss-custom-media/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 44 +- .../postcss-custom-properties/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 24 +- plugins/postcss-custom-selectors/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 24 +- plugins/postcss-debug-logger/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 8 +- .../test/document.expect.html | 21 - .../postcss-debug-logger/test/document.html | 21 - plugins/postcss-design-tokens/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 103 ++-- plugins/postcss-dir-pseudo-class/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 50 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-env-function/package.json | 4 +- .../{.tape.cjs => test/_tape.cjs} | 52 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 12 +- plugins/postcss-extract/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 136 ++--- plugins/postcss-focus-visible/package.json | 5 +- .../postcss-focus-visible/test/_browser.mjs | 77 ++- .../{.tape.mjs => test/_tape.mjs} | 36 +- plugins/postcss-focus-within/package.json | 5 +- .../postcss-focus-within/test/_browser.mjs | 107 ++-- .../{.tape.mjs => test/_tape.mjs} | 14 +- .../postcss-font-format-keywords/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 10 +- plugins/postcss-gamut-mapping/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 2 +- plugins/postcss-gap-properties/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- plugins/postcss-global-data/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 8 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 26 +- plugins/postcss-hwb-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- plugins/postcss-ic-unit/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- .../postcss-image-set-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 28 +- plugins/postcss-initial/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 28 +- plugins/postcss-is-pseudo-class/.tape.mjs | 77 --- plugins/postcss-is-pseudo-class/package.json | 5 +- .../postcss-is-pseudo-class/test/_browser.mjs | 74 ++- .../postcss-is-pseudo-class/test/_tape.mjs | 77 +++ plugins/postcss-lab-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 40 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-logical-overflow/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 10 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 10 +- plugins/postcss-logical-resize/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 12 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 28 +- plugins/postcss-logical/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 32 +- plugins/postcss-media-minmax/package.json | 5 +- .../postcss-media-minmax/test/_browser.mjs | 116 ++-- .../{.tape.mjs => test/_tape.mjs} | 30 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- plugins/postcss-minify/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 6 +- plugins/postcss-nested-calc/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-nesting/package.json | 5 +- plugins/postcss-nesting/test/_browser.mjs | 122 ++-- .../{.tape.mjs => test/_tape.mjs} | 22 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 4 +- plugins/postcss-oklab-function/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 22 +- .../postcss-overflow-shorthand/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-place/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 16 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 2 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 40 +- plugins/postcss-rebase-url/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 12 +- .../postcss-scope-pseudo-class/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 18 +- plugins/postcss-selector-not/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 2 +- plugins/postcss-slow-plugins/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 8 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 10 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 24 +- plugins/postcss-todo-or-die/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 30 +- .../package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 10 +- plugins/postcss-unset-value/package.json | 4 +- .../{.tape.mjs => test/_tape.mjs} | 14 +- rollup/configs/externals.mjs | 4 + rollup/default.mjs | 7 +- rollup/presets/package-typescript.mjs | 6 +- rollup/transforms/node-coverage-disable.mjs | 8 + 200 files changed, 2051 insertions(+), 2435 deletions(-) rename experimental/css-has-pseudo/{.tape.mjs => test/_tape.mjs} (71%) rename experimental/postcss-gradient-stop-increments/{.tape.mjs => test/_tape.mjs} (84%) rename experimental/postcss-nesting/{.tape.mjs => test/_tape.mjs} (91%) create mode 100644 packages/postcss-tape/src/file-contents-or-empty-string.ts delete mode 100644 packages/postcss-tape/src/format-asserts.ts delete mode 100644 packages/postcss-tape/src/github-annotations.ts delete mode 100644 packages/postcss-tape/test-self/document.expect.code delete mode 100644 packages/postcss-tape/test-self/document.expect.log delete mode 100644 packages/postcss-tape/test/document.expect.html delete mode 100644 packages/postcss-tape/test/document.html delete mode 100644 packages/postcss-tape/test/document.mjs delete mode 100644 packages/postcss-tape/test/document.result.html rename plugin-packs/postcss-bundler/{.tape.mjs => test/_tape.mjs} (85%) delete mode 100644 plugin-packs/postcss-preset-env/src/test/test.mjs create mode 100644 plugin-packs/postcss-preset-env/test/_lib.mjs rename plugin-packs/postcss-preset-env/{.tape.mjs => test/_tape.mjs} (86%) rename plugins/css-blank-pseudo/{.tape.mjs => test/_tape.mjs} (77%) rename plugins/css-has-pseudo/{src/encode/test.mjs => test/_encode-decode.mjs} (96%) rename plugins/css-has-pseudo/{.tape.mjs => test/_tape.mjs} (91%) rename plugins/css-prefers-color-scheme/{.tape.mjs => test/_tape.mjs} (77%) rename plugins/postcss-attribute-case-insensitive/{.tape.mjs => test/_tape.mjs} (82%) rename plugins/postcss-base-plugin/{.tape.mjs => test/_tape.mjs} (60%) delete mode 100644 plugins/postcss-base-plugin/test/document.expect.html delete mode 100644 plugins/postcss-base-plugin/test/document.html rename plugins/postcss-cascade-layers/{.tape.mjs => test/_tape.mjs} (58%) rename plugins/postcss-color-function/{.tape.mjs => test/_tape.mjs} (92%) rename plugins/postcss-color-functional-notation/{.tape.mjs => test/_tape.mjs} (85%) rename plugins/postcss-color-hex-alpha/{.tape.mjs => test/_tape.mjs} (76%) rename plugins/postcss-color-mix-function/{.tape.mjs => test/_tape.mjs} (88%) rename plugins/postcss-color-rebeccapurple/{.tape.mjs => test/_tape.mjs} (69%) rename plugins/postcss-conditional-values/{.tape.mjs => test/_tape.mjs} (67%) rename plugins/postcss-custom-media/{.tape.mjs => test/_tape.mjs} (67%) rename plugins/postcss-custom-properties/{.tape.mjs => test/_tape.mjs} (75%) rename plugins/postcss-custom-selectors/{.tape.mjs => test/_tape.mjs} (77%) rename plugins/postcss-debug-logger/{.tape.mjs => test/_tape.mjs} (53%) delete mode 100644 plugins/postcss-debug-logger/test/document.expect.html delete mode 100644 plugins/postcss-debug-logger/test/document.html rename plugins/postcss-design-tokens/{.tape.mjs => test/_tape.mjs} (53%) rename plugins/postcss-dir-pseudo-class/{.tape.mjs => test/_tape.mjs} (56%) rename plugins/postcss-double-position-gradients/{.tape.mjs => test/_tape.mjs} (79%) rename plugins/postcss-env-function/{.tape.cjs => test/_tape.cjs} (75%) rename plugins/postcss-exponential-functions/{.tape.mjs => test/_tape.mjs} (74%) rename plugins/postcss-extract/{.tape.mjs => test/_tape.mjs} (72%) rename plugins/postcss-focus-visible/{.tape.mjs => test/_tape.mjs} (77%) rename plugins/postcss-focus-within/{.tape.mjs => test/_tape.mjs} (92%) rename plugins/postcss-font-format-keywords/{.tape.mjs => test/_tape.mjs} (88%) rename plugins/postcss-gamut-mapping/{.tape.mjs => test/_tape.mjs} (85%) rename plugins/postcss-gap-properties/{.tape.mjs => test/_tape.mjs} (71%) rename plugins/postcss-global-data/{.tape.mjs => test/_tape.mjs} (87%) rename plugins/postcss-gradients-interpolation-method/{.tape.mjs => test/_tape.mjs} (88%) rename plugins/postcss-hwb-function/{.tape.mjs => test/_tape.mjs} (88%) rename plugins/postcss-ic-unit/{.tape.mjs => test/_tape.mjs} (86%) rename plugins/postcss-image-set-function/{.tape.mjs => test/_tape.mjs} (81%) rename plugins/postcss-initial/{.tape.mjs => test/_tape.mjs} (66%) delete mode 100644 plugins/postcss-is-pseudo-class/.tape.mjs create mode 100644 plugins/postcss-is-pseudo-class/test/_tape.mjs rename plugins/postcss-lab-function/{.tape.mjs => test/_tape.mjs} (83%) rename plugins/postcss-logical-float-and-clear/{.tape.mjs => test/_tape.mjs} (56%) rename plugins/postcss-logical-overflow/{.tape.mjs => test/_tape.mjs} (74%) rename plugins/postcss-logical-overscroll-behavior/{.tape.mjs => test/_tape.mjs} (75%) rename plugins/postcss-logical-resize/{.tape.mjs => test/_tape.mjs} (79%) rename plugins/postcss-logical-viewport-units/{.tape.mjs => test/_tape.mjs} (63%) rename plugins/postcss-logical/{.tape.mjs => test/_tape.mjs} (87%) rename plugins/postcss-media-minmax/{.tape.mjs => test/_tape.mjs} (67%) rename plugins/postcss-media-queries-aspect-ratio-number-values/{.tape.mjs => test/_tape.mjs} (70%) rename plugins/postcss-minify/{.tape.mjs => test/_tape.mjs} (68%) rename plugins/postcss-nested-calc/{.tape.mjs => test/_tape.mjs} (72%) rename plugins/postcss-nesting/{.tape.mjs => test/_tape.mjs} (95%) rename plugins/postcss-normalize-display-values/{.tape.mjs => test/_tape.mjs} (92%) rename plugins/postcss-oklab-function/{.tape.mjs => test/_tape.mjs} (87%) rename plugins/postcss-overflow-shorthand/{.tape.mjs => test/_tape.mjs} (81%) rename plugins/postcss-place/{.tape.mjs => test/_tape.mjs} (86%) rename plugins/postcss-progressive-custom-properties/{.tape.mjs => test/_tape.mjs} (82%) rename plugins/postcss-pseudo-class-any-link/{.tape.mjs => test/_tape.mjs} (79%) rename plugins/postcss-rebase-url/{.tape.mjs => test/_tape.mjs} (75%) rename plugins/postcss-relative-color-syntax/{.tape.mjs => test/_tape.mjs} (74%) rename plugins/postcss-scope-pseudo-class/{.tape.mjs => test/_tape.mjs} (80%) rename plugins/postcss-selector-not/{.tape.mjs => test/_tape.mjs} (84%) rename plugins/postcss-slow-plugins/{.tape.mjs => test/_tape.mjs} (92%) rename plugins/postcss-stepped-value-functions/{.tape.mjs => test/_tape.mjs} (82%) rename plugins/postcss-text-decoration-shorthand/{.tape.mjs => test/_tape.mjs} (77%) rename plugins/postcss-todo-or-die/{.tape.mjs => test/_tape.mjs} (70%) rename plugins/postcss-trigonometric-functions/{.tape.mjs => test/_tape.mjs} (78%) rename plugins/postcss-unset-value/{.tape.mjs => test/_tape.mjs} (60%) create mode 100644 rollup/transforms/node-coverage-disable.mjs diff --git a/.github/bin/new-plugin.mjs b/.github/bin/new-plugin.mjs index 59303a563..ee5fee3e7 100644 --- a/.github/bin/new-plugin.mjs +++ b/.github/bin/new-plugin.mjs @@ -52,7 +52,7 @@ console.log(`- Creating new plugin ${pluginName}`); await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'src', 'index.ts')); await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'test', '_import.mjs')); await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'test', '_require.cjs')); - await replaceBasePluginReferencesForFilePath(path.join(pluginDir, '.tape.mjs')); + await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'test', '_tape.mjs')); await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'README.md')); await replaceBasePluginReferencesForFilePath(path.join(pluginDir, 'INSTALL.md')); await fsp.writeFile( diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e3fa7bd88..15dc512f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,9 @@ jobs: - name: npm ci run: | - npm ci --ignore-scripts + npm ci + env: + BROWSER_TESTS: true if: ${{ (matrix.is_base_node_version && matrix.is_base_os_version) }} - name: npm ci @@ -85,14 +87,6 @@ jobs: NPM_CONFIG_ENGINE_STRICT=false npm install --ignore-scripts npm run test:cli --if-present $MODIFIED_WORKSPACES - # Browser Tests - # running "npm ci" again, but allowing scripts so that Chrome is installed - - name: test:browser - run: | - npm ci - npm run test:browser --if-present $MODIFIED_WORKSPACES - if: matrix.is_base_node_version && matrix.is_base_os_version - # E2E Tests - name: test:e2e run: | diff --git a/experimental/css-has-pseudo/package.json b/experimental/css-has-pseudo/package.json index 0e70501fa..b28d002ea 100644 --- a/experimental/css-has-pseudo/package.json +++ b/experimental/css-has-pseudo/package.json @@ -56,8 +56,8 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/experimental/css-has-pseudo#readme", "repository": { diff --git a/experimental/css-has-pseudo/.tape.mjs b/experimental/css-has-pseudo/test/_tape.mjs similarity index 71% rename from experimental/css-has-pseudo/.tape.mjs rename to experimental/css-has-pseudo/test/_tape.mjs index edbad92ae..cf01f1fb7 100644 --- a/experimental/css-has-pseudo/.tape.mjs +++ b/experimental/css-has-pseudo/test/_tape.mjs @@ -1,9 +1,9 @@ import { postcssTape } from '@csstools/postcss-tape'; import plugin from '@csstools/css-has-pseudo-experimental'; -postcssTape(plugin)({ +postcssTape(plugin, { skipPackageNameCheck: true })({ 'basic': { message: 'supports basic usage', - warnings: 1 + warnings: 1, }, }); diff --git a/experimental/postcss-gradient-stop-increments/package.json b/experimental/postcss-gradient-stop-increments/package.json index e08f8caf1..77315c821 100644 --- a/experimental/postcss-gradient-stop-increments/package.json +++ b/experimental/postcss-gradient-stop-increments/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradient-stop-increments#readme", "repository": { diff --git a/experimental/postcss-gradient-stop-increments/.tape.mjs b/experimental/postcss-gradient-stop-increments/test/_tape.mjs similarity index 84% rename from experimental/postcss-gradient-stop-increments/.tape.mjs rename to experimental/postcss-gradient-stop-increments/test/_tape.mjs index fa441888d..f5eccf52d 100644 --- a/experimental/postcss-gradient-stop-increments/.tape.mjs +++ b/experimental/postcss-gradient-stop-increments/test/_tape.mjs @@ -3,7 +3,7 @@ import plugin from '@csstools/postcss-gradient-stop-increments-experimental'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'examples/example': { message: 'minimal example', @@ -11,7 +11,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/experimental/postcss-nesting/package.json b/experimental/postcss-nesting/package.json index 70c32fb95..bdb7a3622 100644 --- a/experimental/postcss-nesting/package.json +++ b/experimental/postcss-nesting/package.json @@ -49,8 +49,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting#readme", "repository": { diff --git a/experimental/postcss-nesting/.tape.mjs b/experimental/postcss-nesting/test/_tape.mjs similarity index 91% rename from experimental/postcss-nesting/.tape.mjs rename to experimental/postcss-nesting/test/_tape.mjs index e9cd5b14a..2aae0cce7 100644 --- a/experimental/postcss-nesting/.tape.mjs +++ b/experimental/postcss-nesting/test/_tape.mjs @@ -9,10 +9,10 @@ const mixinPluginRule = () => { node.replaceWith(postcss.parse('& .in{ &.deep { color: blue; }}', {from : 'mixin.css'})); }, }, - } -} + }; +}; -mixinPluginRule.postcss = true +mixinPluginRule.postcss = true; const mixinPluginDeclaration = () => { return { @@ -22,10 +22,10 @@ const mixinPluginDeclaration = () => { node.replaceWith(postcss.parse('color: blue;', {from : 'mixin.css'})); }, }, - } -} + }; +}; -mixinPluginDeclaration.postcss = true +mixinPluginDeclaration.postcss = true; postcssTape(plugin)({ 'basic': { @@ -54,7 +54,7 @@ postcssTape(plugin)({ }, 'invalid-selector': { message: 'warns on invalid selectors', - warnings: 2 + warnings: 2, }, 'media': { message: 'supports nested @media', @@ -80,11 +80,11 @@ postcssTape(plugin)({ }, 'mixin-declaration': { message: 'supports other visitors (mixin declaration)', - plugins: [mixinPluginDeclaration(), plugin()] + plugins: [mixinPluginDeclaration(), plugin()], }, 'mixin-rule': { message: 'supports other visitors (mixin rule)', - plugins: [mixinPluginRule(), plugin()] + plugins: [mixinPluginRule(), plugin()], }, 'spec-examples': { message: 'supports all spec examples', @@ -98,5 +98,5 @@ postcssTape(plugin)({ }, 'ampersand-everywhere': { message: 'allow & to be used everywhere', - } + }, }); diff --git a/knip.json b/knip.json index fa84f1b8f..a6259a739 100644 --- a/knip.json +++ b/knip.json @@ -9,12 +9,9 @@ }, "packages/*": { "entry": [ - ".tape.{cjs,mjs}", "scripts/**/*.mjs", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs", - "test/test.mjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.{ts,js,mjs}", @@ -23,10 +20,8 @@ }, "plugins/postcss-design-tokens": { "entry": [ - ".tape.{cjs,mjs}", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.ts", @@ -38,10 +33,8 @@ }, "plugins/postcss-global-data": { "entry": [ - ".tape.{cjs,mjs}", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.ts", @@ -53,15 +46,12 @@ }, "plugins/*": { "entry": [ - ".tape.{cjs,mjs}", "scripts/**/*.mjs", "src/browser-global.js", "src/browser.js", "src/index.js", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs", - "test/test.mjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.{ts,js,mjs}", @@ -70,15 +60,12 @@ }, "experimental/*": { "entry": [ - ".tape.{cjs,mjs}", "scripts/**/*.mjs", "src/browser-global.js", "src/browser.js", "src/index.js", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs", - "test/test.mjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.{ts,js,mjs}", @@ -87,11 +74,8 @@ }, "plugin-packs/postcss-bundler": { "entry": [ - ".tape.{cjs,mjs}", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs", - "test/test.mjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.ts", @@ -105,12 +89,9 @@ }, "plugin-packs/*": { "entry": [ - ".tape.{cjs,mjs}", "scripts/**/*.mjs", "src/index.ts", - "test/_import.mjs", - "test/_require.cjs", - "test/test.mjs" + "test/**/*.{cjs,mjs}" ], "project": [ "**/*.{ts,js,mjs}", diff --git a/package-lock.json b/package-lock.json index bc9626fad..ae7107a49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5382,57 +5382,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5483,17 +5432,6 @@ "once": "^1.4.0" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -6536,24 +6474,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/http-proxy-agent": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", @@ -8543,25 +8463,6 @@ "resolved": "plugins/postcss-gap-properties", "link": true }, - "node_modules/postcss-html": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.5.0.tgz", - "integrity": "sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==", - "dependencies": { - "htmlparser2": "^8.0.0", - "js-tokens": "^8.0.0", - "postcss": "^8.4.0", - "postcss-safe-parser": "^6.0.0" - }, - "engines": { - "node": "^12 || >=14" - } - }, - "node_modules/postcss-html/node_modules/js-tokens": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.2.tgz", - "integrity": "sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==" - }, "node_modules/postcss-image-set-function": { "resolved": "plugins/postcss-image-set-function", "link": true @@ -8673,21 +8574,6 @@ "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", "dev": true }, - "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, "node_modules/postcss-selector-not": { "resolved": "plugins/postcss-selector-not", "link": true @@ -11057,8 +10943,7 @@ "license": "MIT-0", "dependencies": { "postcss": "~8.4", - "postcss-8.4": "npm:postcss@~8.4", - "postcss-html": "^1.5.0" + "postcss-8.4": "npm:postcss@~8.4" }, "engines": { "node": "^14 || ^16 || >=18" diff --git a/package.json b/package.json index 296c5c359..ef5ee5933 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "release-plan": "node .github/bin/release-plan/release-plan.mjs", "release-plan:dry-run": "node .github/bin/release-plan/release-plan.mjs --dry-run", "test": "npm run test --workspaces --if-present", - "test:browser": "npm run test:browser --workspaces --if-present", "knip": "knip" }, "volta": { diff --git a/packages/base-cli/package.json b/packages/base-cli/package.json index 4749c90a3..e2be88e1c 100644 --- a/packages/base-cli/package.json +++ b/packages/base-cli/package.json @@ -41,7 +41,7 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs" + "test": "node --test" }, "repository": { "type": "git", diff --git a/packages/base-cli/test/test.mjs b/packages/base-cli/test/test.mjs index 2a7e6f735..081edee29 100644 --- a/packages/base-cli/test/test.mjs +++ b/packages/base-cli/test/test.mjs @@ -1,4 +1,5 @@ -import assert from 'assert'; +import assert from 'node:assert/strict'; +import test from 'node:test'; import { parseArguments } from '@csstools/base-cli'; const argumentParsingCases = [ @@ -408,9 +409,9 @@ const argumentParsingCases = [ }, ]; -argumentParsingCases.forEach((testCase) => { - const result = parseArguments(testCase.args, testCase.allowedPluginOpts, () => { }); - assert.strict.deepEqual(result, testCase.expected, testCase.message); -}); - -console.log('pass base-cli'); +for (const testCase of argumentParsingCases) { + test(testCase.message, () => { + const result = parseArguments(testCase.args, testCase.allowedPluginOpts, () => { }); + assert.deepEqual(result, testCase.expected); + }); +} diff --git a/packages/cascade-layer-name-parser/package.json b/packages/cascade-layer-name-parser/package.json index 53aeda590..f68d4750d 100644 --- a/packages/cascade-layer-name-parser/package.json +++ b/packages/cascade-layer-name-parser/package.json @@ -56,8 +56,8 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node ./test/test.mjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test ./test/test.mjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/cascade-layer-name-parser#readme", "repository": { diff --git a/packages/color-helpers/package.json b/packages/color-helpers/package.json index 95c496107..21e29e11a 100644 --- a/packages/color-helpers/package.json +++ b/packages/color-helpers/package.json @@ -53,7 +53,7 @@ "check-sources-integrity:rewrite": "REWRITE_HASHES=true node ./scripts/check-changes.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node ./test/_import.mjs && node ./test/_require.cjs" + "test": "node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers#readme", "repository": { diff --git a/packages/css-calc/package.json b/packages/css-calc/package.json index 13090272e..82be51099 100644 --- a/packages/css-calc/package.json +++ b/packages/css-calc/package.json @@ -56,7 +56,7 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc#readme", "repository": { diff --git a/packages/css-color-parser/package.json b/packages/css-color-parser/package.json index 25e690497..6cd99a457 100644 --- a/packages/css-color-parser/package.json +++ b/packages/css-color-parser/package.json @@ -60,7 +60,7 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser#readme", "repository": { diff --git a/packages/css-parser-algorithms/package.json b/packages/css-parser-algorithms/package.json index d42f57fb8..dc7976123 100644 --- a/packages/css-parser-algorithms/package.json +++ b/packages/css-parser-algorithms/package.json @@ -55,8 +55,8 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node ./test/test.mjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test ./test/test.mjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms#readme", "repository": { diff --git a/packages/css-tokenizer/package.json b/packages/css-tokenizer/package.json index 4cb7fa896..e41a01cdb 100644 --- a/packages/css-tokenizer/package.json +++ b/packages/css-tokenizer/package.json @@ -58,7 +58,7 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer#readme", "repository": { diff --git a/packages/generate-test-cases/package.json b/packages/generate-test-cases/package.json index 82069aa4a..c188fb5aa 100644 --- a/packages/generate-test-cases/package.json +++ b/packages/generate-test-cases/package.json @@ -26,8 +26,7 @@ "scripts": { "build": "exit 0;", "generate": "node ./src/index.mjs", - "lint": "node ../../.github/bin/format-package-json.mjs", - "test": "exit 0;" + "lint": "node ../../.github/bin/format-package-json.mjs" }, "repository": { "type": "git", diff --git a/packages/media-query-list-parser/package.json b/packages/media-query-list-parser/package.json index 525b78ffc..4d99d5c0c 100644 --- a/packages/media-query-list-parser/package.json +++ b/packages/media-query-list-parser/package.json @@ -56,8 +56,8 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node ./test/test.mjs" + "test": "node --test ./test/test.mjs ./test/_import.mjs ./test/_require.cjs", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test ./test/test.mjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/media-query-list-parser#readme", "repository": { diff --git a/packages/postcss-tape/CHANGELOG.md b/packages/postcss-tape/CHANGELOG.md index 4175907b7..f051fe8b9 100644 --- a/packages/postcss-tape/CHANGELOG.md +++ b/packages/postcss-tape/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Tape +## Unreleased (major) + +- Use `node:test` instead of custom logic. + ### 3.0.2 _December 15, 2023_ diff --git a/packages/postcss-tape/README.md b/packages/postcss-tape/README.md index cb6e59f10..b5777d3f6 100644 --- a/packages/postcss-tape/README.md +++ b/packages/postcss-tape/README.md @@ -1,10 +1,24 @@ # PostCSS Tape for csstools/postcss-plugins -See [.tape.mjs](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-base-plugin/.tape.mjs) in the base plugin for a minimal example. +- compare the output of your PostCSS plugin with the expected output +- test that the output can be re-parsed by PostCSS +- test Sourcemap validity +- test interop with other PostCSS plugins +- enforce [guidelines for PostCSS plugins](https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md) +- test both latest `PostCSS` and an older minor version to ensure compatibility +- uses [`node:test`](https://nodejs.org/docs/latest/api/test.html) under the hood + +See [`test/_tape.mjs`](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-base-plugin/test/_tape.mjs) in the base plugin for a minimal example. + +```sh +# See https://nodejs.org/docs/latest/api/test.html for more usage details. +node --test +``` ```js +/* test/_tape.mjs */ import { postcssTape } from '@csstools/postcss-tape'; -import plugin from '@csstools/postcss-base-plugin'; +import plugin from ''; postcssTape(plugin)({ basic: { @@ -16,23 +30,61 @@ postcssTape(plugin)({ color: 'purple' } }, - example: { - message: "minimal example", - }, }); ``` Browse the [source code and tests here](https://github.com/csstools/postcss-plugins/tree/main/packages/postcss-tape) or see [tests in plugins](https://github.com/csstools/postcss-plugins/tree/main/plugins) for more usage details. +> [!NOTE] +> We use `test/_tape.mjs` for our tests, but you can use any file name you want. +> We like to group things in a `test` directory and we use a leading underscore to sort it before the css files. + +## File name format and test case naming + +Test source files and test case names are related. +The test case name is expected to be the relative file path with the `.css` extension removed. + +Test variants (with different plugin options) are separated by a colon `:`. + +All test files are expected to be in a `test` directory in the current working directory. + +| test case name | file name | result file name | notes | +| --- | --- | --- | --- | +| `basic` | `test/basic.css` | `test/basic.result.css` | | +| `basic:color` | `test/basic.css` | `test/basic.color.result.css` | A variant test for `basic`. Everything after `:` is ignored. | +| `foo/bar` | `test/foo/bar.css` | `test/foo/bar.result.css` | A test file in a directory | + +## `.gitignore` + +We recommend adding `*.result.css` to your `.gitignore` file. +This is not functionally required, but it will reduce noise in your git history. + ## Quickly update all `expect.css` files. -Set an env variable `REWRITE_EXPECTS` to `true` to update all `expect` files. +Set env variable `REWRITE_EXPECTS` to `true` to update all `.expect` files. example : ```json "scripts": { - "test": "node .tape.mjs ", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, ``` + +## Options + +### `skipPackageNameCheck` + +When your plugin name does not start with `postcss-`: + +```js +import { postcssTape } from '@csstools/postcss-tape'; +import plugin from ''; + +postcssTape(plugin, { skipPackageNameCheck: true })({ + basic: { + message: "supports basic usage", + }, +}); +``` diff --git a/packages/postcss-tape/dist/index.cjs b/packages/postcss-tape/dist/index.cjs index f576142c9..b3885e354 100644 --- a/packages/postcss-tape/dist/index.cjs +++ b/packages/postcss-tape/dist/index.cjs @@ -1 +1,3 @@ -"use strict";var e=require("fs"),n=require("path"),o=require("postcss"),s=require("postcss-8.4"),t=require("postcss-html"),r=require("assert");const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});noopPlugin.postcss=!0;const c="----------------------------------------";function formatCSSAssertError(e,n,o,s=!1){let t="";if(t+=`\n${e}\n\n`,n.message&&(t+=`message :\n ${n.message}\n\n`),n.options)try{t+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(e){}return t+=`output changed :\n${prettyDiff(o.message)}\n`,s||(t+="\n"+c),t}function formatWarningsAssertError(e,n,o,s,t=!1){let r="";if(r+=`\n${e}\n\n`,n.message&&(r+=`message :\n ${n.message}\n\n`),n.options)try{r+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(e){}return r+=`unexpected or missing warnings :\n+ actual ${o.length}\n- expected ${s}\n`,t||(o.forEach((e=>{r+=`\n[${e.plugin}]: ${e.text}`})),o.length&&(r+="\n"),r+="\n"+c),r}function prettyDiff(e){return e.replace(/[^\\](\\n)/gm,((e,n)=>e.replace(n," "))).replace(/(\\t)/gm,((e,n)=>e.replace(n," "))).replace(/\+$/gm,"").replace(/^Expected values to be strictly equal:\n/,"")}function formatGitHubActionAnnotation(e,o="error",s={}){let t="::"+o;const r=Object.keys(s).map((e=>{let o=String(s[e]);return"file"===e&&process.env.GITHUB_WORKSPACE&&(o=n.relative(process.env.GITHUB_WORKSPACE,n.resolve(o))),`${e}=${t=o,t.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}`;var t})).join(",");return r&&(t+=` ${r}`),`${t}::${c=e||"",c.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}`;var c}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}const i=process.env.GITHUB_ACTIONS&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_NODE&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_OS;function postcssSyntax(e){if(e.postcssSyntaxHTML)return t()}function postcssSyntaxSupportsSourceMaps(e){return!e.postcssSyntaxHTML}const a={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},l={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{RuleExit(n){e.has(n)||"to-clone"===n.selector&&(e.add(n),n.cloneBefore({selector:"cloned"}))}}}},p={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{AtRuleExit(n){if(!e.has(n))return"to-clone"===n.params?(e.add(n),void n.cloneBefore({params:"cloned"})):"to-clone"===n.name?(e.add(n),void n.cloneBefore({name:"cloned"})):void 0}}}};exports.atRuleClonerPlugin=p,exports.declarationClonerPlugin=a,exports.postcssTape=function postcssTape(t){let a=!1;{!0!==t.postcss&&(a=!0,i?console.log(formatGitHubActionAnnotation('postcss flag not set to "true" on exported plugin object',"error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss flag not set to "true"\n\n${c}`));const n=t();n.postcssPlugin&&"string"==typeof n.postcssPlugin||(a=!0,i?console.log(formatGitHubActionAnnotation('plugin name not set via "postcssPlugin"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name not set via "postcssPlugin"\n\n${c}`));const o=JSON.parse(e.readFileSync("./package.json","utf-8").toString());o.keywords&&o.keywords.includes("postcss-plugin")||(a=!0,i?console.log(formatGitHubActionAnnotation('package.json does not include "postcss-plugin" keyword',"error",{file:"./package.json",line:1,col:1})):console.error(`\npackage.json does not include "postcss-plugin" keyword\n\n${c}`));const s=["css-has-pseudo","css-blank-pseudo","css-prefers-color-scheme","@csstools/css-has-pseudo-experimental"].includes(o.name);let r=o.name;if(r.startsWith("@")){r=o.name.split("/").slice(1).join("/")}r.startsWith("postcss-")||s||(a=!0,i?console.log(formatGitHubActionAnnotation('plugin name in package.json does not start with "postcss-"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name in package.json does not start with "postcss-"\n\n${c}`)),Object.keys(Object(o.dependencies)).includes("postcss")&&!("postcssTapeSelfTest"in t)&&(a=!0,i?console.log(formatGitHubActionAnnotation("postcss should only be a peer and/or dev dependency","error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss should only be a peer and/or dev dependency\n\n${c}`))}return async l=>{const p=new Set;for(const u in l){const g=l[u];g.before&&await g.before();const f=n.join(".","test",u.split(":")[0]),d=n.join(".","test",u.replace(/:/g,"."));let S="css";g.postcssSyntaxHTML&&(S="html");const m=`${f}.${S}`;let y=`${d}.expect.${S}`,A=`${d}.result.${S}`;g.expect&&(y=n.join(".","test",g.expect)),g.result&&(A=n.join(".","test",g.result));const $=g.plugins??[t(g.options)],x=e.readFileSync(m,"utf8");let h,w="";try{w=e.readFileSync(y,"utf8")}catch(e){a=!0,w=!1,i?console.log(formatGitHubActionAnnotation(`${u}\n\nmissing or broken "expect" file: "${n.parse(y).base}"`,"error",{file:m,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nmissing or broken "expect" file: "${n.parse(y).base}"\n\n${c}`))}let b=!1;try{h=await o($).process(x,{from:m,to:A,map:!!postcssSyntaxSupportsSourceMaps(g)&&{inline:!1,annotation:!1},syntax:postcssSyntax(g)})}catch(e){if(reduceInformationInCssSyntaxError(e),b=!0,g.exception&&g.exception.test(e.message))continue;throw e}!b&&g.exception&&(a=!0,i?console.log(formatGitHubActionAnnotation(`${u}\n\nexpected an exception but got none`,"error",{file:m,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nexpected an exception but got none\n\n${c}`)));const E=h.css.toString();if(e.writeFileSync(A,E,"utf8"),process.env.REWRITE_EXPECTS&&e.writeFileSync(y,E,"utf8"),!1!==w){try{r.strict.strictEqual(E,w)}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(formatCSSAssertError(u,g,e,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error(formatCSSAssertError(u,g,e)))}try{if(!g.postcssSyntaxHTML&&h.map.toJSON().sources.includes(""))throw new Error("Sourcemap is broken")}catch(e){a=!0;const n='\nThis is most likely a newly created PostCSS AST Node without a value for "source".\nsee :\n- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes\n- https://postcss.org/api/#node-source';i?console.log(formatGitHubActionAnnotation(`${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${n}`,"error",{file:m,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${n}\n\n${c}`))}g.after&&await g.after();try{const n=e.readFileSync(A,"utf8");if((await o([noopPlugin()]).process(n,{from:A,to:A,map:!!postcssSyntaxSupportsSourceMaps(g)&&{inline:!1,annotation:!1},syntax:postcssSyntax(g)})).warnings().length)throw new Error("Unexpected warnings on second pass")}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(`${u}\n\nresult was not parsable with PostCSS.`,"error",{file:y,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nresult was not parsable with PostCSS.\n\n${c}`))}if(o([noopPlugin()]).version!==s([noopPlugin()]).version){const e=await s($).process(x,{from:m,to:A,map:!!postcssSyntaxSupportsSourceMaps(g)&&{inline:!1,annotation:!1}});try{r.strict.strictEqual(e.css.toString(),E)}catch(e){reduceInformationInCssSyntaxError(e),a=!0,i?console.log(formatGitHubActionAnnotation("testing older PostCSS:\n"+formatCSSAssertError(u,g,e,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error("testing older PostCSS:\n"+formatCSSAssertError(u,g,e)))}}try{(h.warnings().length||g.warnings)&&r.strict.strictEqual(h.warnings().length,g.warnings)}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(formatWarningsAssertError(u,g,h.warnings(),g.warnings??0,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error(formatWarningsAssertError(u,g,h.warnings(),g.warnings??0)))}}}if(p.size){console.error("\nunexpected failures:");for(const e of p.values())console.error(" - "+e)}a&&process.exit(1),console.warn("pass "+t().postcssPlugin)}},exports.ruleClonerPlugin=l; +/* node:coverage disable */ +"use strict";var e=require("node:assert/strict"),t=require("fs/promises"),s=require("path"),n=require("postcss"),o=require("postcss-8.4"),i=require("node:test");const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});async function fileContentsOrEmptyString(e){try{return await t.readFile(e,"utf8")}catch(e){return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}noopPlugin.postcss=!0;const r={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},a={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{RuleExit(t){e.has(t)||"to-clone"===t.selector&&(e.add(t),t.cloneBefore({selector:"cloned"}))}}}},c={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{AtRuleExit(t){if(!e.has(t))return"to-clone"===t.params?(e.add(t),void t.cloneBefore({params:"cloned"})):"to-clone"===t.name?(e.add(t),void t.cloneBefore({name:"cloned"})):void 0}}}};exports.atRuleClonerPlugin=c,exports.declarationClonerPlugin=r,exports.postcssTape=function postcssTape(r,a){a=a??{},i("`postcss` flag is set on exported plugin creator",(()=>{e.strictEqual(r.postcss,!0)})),i("exported plugin creator is a function",(()=>{e.strictEqual(typeof r,"function")})),i("`postcssPlugin` is set on a plugin instance",(()=>{const t=r();e.ok(t.postcssPlugin),e.strictEqual(typeof t.postcssPlugin,"string")})),i("package.json",(async s=>{const n=await t.readFile("./package.json","utf-8"),o=JSON.parse(n);await s.test('includes "postcss-plugin" keyword',(()=>{e.ok(o.keywords),e.ok(o.keywords.includes("postcss-plugin"))})),await s.test('name starts with "postcss-"',{skip:a?.skipPackageNameCheck},(()=>{let t=o.name;if(t.startsWith("@")){t=o.name.split("/").slice(1).join("/")}e.ok(t.startsWith("postcss-"),`package name "${t}" does not start with "postcss-"`)})),await s.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in r},(()=>{e.ok(o.peerDependencies),e.ok(Object.keys(Object(o.peerDependencies)).includes("postcss")),e.ok(!Object.keys(Object(o.dependencies)).includes("postcss"))}))}));const c=r().postcssPlugin;return async a=>{await i(c,(async i=>{for(const c in a)await i.test(c,(async i=>{const p=a[c];p.before&&await p.before();const l=s.join(".","test",c.split(":")[0]),u=s.join(".","test",c.replace(/:/g,".")),d="css",g=`${l}.${d}`;let f=`${u}.expect.${d}`,w=`${u}.result.${d}`;p.expect&&(f=s.join(".","test",p.expect)),p.result&&(w=s.join(".","test",p.result));const m=p.plugins??[r(p.options)],k=await fileContentsOrEmptyString(g),y=await fileContentsOrEmptyString(f);let S,x=!1;try{S=await n(m).process(k,{from:g,to:w,map:{inline:!1,annotation:!1}})}catch(t){if(reduceInformationInCssSyntaxError(t),x=!0,p.exception&&p.exception.test(t.message))return;e.ifError(t)}e.notEqual(!x,p.exception,"expected an exception but got none");const E=S.css.toString();{const e=[t.writeFile(w,E,"utf8")];process.env.REWRITE_EXPECTS&&e.push(t.writeFile(f,E,"utf8")),await Promise.all(e)}e.ok(y,"Missing expected result file"),await i.test("has expected output",(()=>{e.strictEqual(E,y),e.deepStrictEqual(S.warnings().length,p.warnings??0,"Unexpected number warnings")})),await i.test("sourcemaps",(async()=>{e.ok(!S.map.toJSON().sources.includes(""),'Sourcemap is broken. This is most likely a newly created PostCSS AST Node without a value for "source". See: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes')})),p.after&&await p.after(),await i.test("output is parsable with PostCSS",(async()=>{const t=await fileContentsOrEmptyString(w),s=await n([noopPlugin()]).process(t,{from:w,to:w,map:{inline:!1,annotation:!1}});e.deepStrictEqual(s.warnings(),[],"Unexpected warnings on second pass")})),await i.test("The oldest and current PostCSS version produce the same result",{skip:n([noopPlugin()]).version===o([noopPlugin()]).version},(async()=>{const t=await o(m).process(k,{from:g,to:w,map:{inline:!1,annotation:!1}});e.strictEqual(t.css.toString(),E)}))}))}))}},exports.ruleClonerPlugin=a; +/* node:coverage enable */ diff --git a/packages/postcss-tape/dist/index.d.ts b/packages/postcss-tape/dist/index.d.ts index 2e4ad86eb..e0af67192 100644 --- a/packages/postcss-tape/dist/index.d.ts +++ b/packages/postcss-tape/dist/index.d.ts @@ -1,9 +1,41 @@ +/** + * A test suite for PostCSS plugins. + * + * @example + * ```sh + * node --test + * ``` + * + * ```js + * // test/_tape.mjs + * import { postcssTape } from '@csstools/postcss-tape'; + * import plugin from ''; + * + * postcssTape(plugin)({ + * basic: { + * message: "supports basic usage", + * }, + * 'basic:color': { + * message: "supports { color: '' }", + * options: { + * color: 'purple' + * } + * }, + * }); + * ``` + * + * @packageDocumentation + */ + import type { AtRule } from 'postcss'; import type { Declaration } from 'postcss'; import type { Plugin } from 'postcss'; import type { PluginCreator } from 'postcss'; import type { Rule } from 'postcss'; +/** + * A dummy PostCSS plugin that clones any at rule with params `to-clone` to a new at rule with params `cloned`. + */ export declare const atRuleClonerPlugin: { postcssPlugin: string; prepare(): { @@ -11,13 +43,43 @@ export declare const atRuleClonerPlugin: { }; }; +/** + * A dummy PostCSS plugin that clones any declaration with the property `to-clone` to a new declaration with the property `cloned`. + */ export declare const declarationClonerPlugin: { postcssPlugin: string; Declaration(decl: Declaration): void; }; -export declare function postcssTape(currentPlugin: PluginCreator): (options: Record) => Promise; +/** + * General options for `@csstools/postcss-tape`. + * These affect the entire test run, not individual test cases. + * + * @example + * ```js + * import { postcssTape } from '@csstools/postcss-tape'; + * import plugin from 'your-postcss-plugin'; + * + * postcssTape(plugin, { + * skipPackageNameCheck: true, + * })(...); + */ +export declare type Options = { + /** + * PostCSS plugins should start their name with `postcss-`. + * If this is something you do not want to do, you can set this to `true` to skip this check. + */ + skipPackageNameCheck?: boolean; +}; + +/** + * Create a test suite for a PostCSS plugin. + */ +export declare function postcssTape(currentPlugin: PluginCreator, runOptions?: Options): (options: Record) => Promise; +/** + * A dummy PostCSS plugin that clones any rule with the selector `to-clone` to a new rule with the selector `cloned`. + */ export declare const ruleClonerPlugin: { postcssPlugin: string; prepare(): { @@ -35,18 +97,15 @@ export declare type TestCaseOptions = { /** The expected number of warnings. */ warnings?: number; /** Expected exception */ - /** NOTE: plugins should not throw exceptions, this goes against best practices. Use `errors` instead. */ exception?: RegExp; /** Override the file name of the "expect" file. */ expect?: string; /** Override the file name of the "result" file. */ result?: string; /** Do something before the test is run. */ - before?: () => void; + before?: () => void | Promise; /** Do something after the test is run. */ after?: () => void | Promise; - /** Process the test cases with "postcss-html" as the syntax */ - postcssSyntaxHTML?: boolean; }; export { } diff --git a/packages/postcss-tape/dist/index.mjs b/packages/postcss-tape/dist/index.mjs index 092cd8e73..72a7ad800 100644 --- a/packages/postcss-tape/dist/index.mjs +++ b/packages/postcss-tape/dist/index.mjs @@ -1 +1,3 @@ -import o from"fs";import n from"path";import e from"postcss";import t from"postcss-8.4";import s from"postcss-html";import{strict as r}from"assert";const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});noopPlugin.postcss=!0;const c="----------------------------------------";function formatCSSAssertError(o,n,e,t=!1){let s="";if(s+=`\n${o}\n\n`,n.message&&(s+=`message :\n ${n.message}\n\n`),n.options)try{s+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(o){}return s+=`output changed :\n${prettyDiff(e.message)}\n`,t||(s+="\n"+c),s}function formatWarningsAssertError(o,n,e,t,s=!1){let r="";if(r+=`\n${o}\n\n`,n.message&&(r+=`message :\n ${n.message}\n\n`),n.options)try{r+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(o){}return r+=`unexpected or missing warnings :\n+ actual ${e.length}\n- expected ${t}\n`,s||(e.forEach((o=>{r+=`\n[${o.plugin}]: ${o.text}`})),e.length&&(r+="\n"),r+="\n"+c),r}function prettyDiff(o){return o.replace(/[^\\](\\n)/gm,((o,n)=>o.replace(n," "))).replace(/(\\t)/gm,((o,n)=>o.replace(n," "))).replace(/\+$/gm,"").replace(/^Expected values to be strictly equal:\n/,"")}function formatGitHubActionAnnotation(o,e="error",t={}){let s="::"+e;const r=Object.keys(t).map((o=>{let e=String(t[o]);return"file"===o&&process.env.GITHUB_WORKSPACE&&(e=n.relative(process.env.GITHUB_WORKSPACE,n.resolve(e))),`${o}=${s=e,s.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}`;var s})).join(",");return r&&(s+=` ${r}`),`${s}::${c=o||"",c.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}`;var c}function reduceInformationInCssSyntaxError(o){process.env.DEBUG||(delete o.source,o.input&&delete o.input.source,delete o.postcssNode)}const a=process.env.GITHUB_ACTIONS&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_NODE&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_OS;function postcssSyntax(o){if(o.postcssSyntaxHTML)return s()}function postcssSyntaxSupportsSourceMaps(o){return!o.postcssSyntaxHTML}function postcssTape(s){let i=!1;{!0!==s.postcss&&(i=!0,a?console.log(formatGitHubActionAnnotation('postcss flag not set to "true" on exported plugin object',"error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss flag not set to "true"\n\n${c}`));const n=s();n.postcssPlugin&&"string"==typeof n.postcssPlugin||(i=!0,a?console.log(formatGitHubActionAnnotation('plugin name not set via "postcssPlugin"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name not set via "postcssPlugin"\n\n${c}`));const e=JSON.parse(o.readFileSync("./package.json","utf-8").toString());e.keywords&&e.keywords.includes("postcss-plugin")||(i=!0,a?console.log(formatGitHubActionAnnotation('package.json does not include "postcss-plugin" keyword',"error",{file:"./package.json",line:1,col:1})):console.error(`\npackage.json does not include "postcss-plugin" keyword\n\n${c}`));const t=["css-has-pseudo","css-blank-pseudo","css-prefers-color-scheme","@csstools/css-has-pseudo-experimental"].includes(e.name);let r=e.name;if(r.startsWith("@")){r=e.name.split("/").slice(1).join("/")}r.startsWith("postcss-")||t||(i=!0,a?console.log(formatGitHubActionAnnotation('plugin name in package.json does not start with "postcss-"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name in package.json does not start with "postcss-"\n\n${c}`)),Object.keys(Object(e.dependencies)).includes("postcss")&&!("postcssTapeSelfTest"in s)&&(i=!0,a?console.log(formatGitHubActionAnnotation("postcss should only be a peer and/or dev dependency","error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss should only be a peer and/or dev dependency\n\n${c}`))}return async l=>{const p=new Set;for(const u in l){const f=l[u];f.before&&await f.before();const g=n.join(".","test",u.split(":")[0]),d=n.join(".","test",u.replace(/:/g,"."));let m="css";f.postcssSyntaxHTML&&(m="html");const S=`${g}.${m}`;let y=`${d}.expect.${m}`,A=`${d}.result.${m}`;f.expect&&(y=n.join(".","test",f.expect)),f.result&&(A=n.join(".","test",f.result));const $=f.plugins??[s(f.options)],h=o.readFileSync(S,"utf8");let w,x="";try{x=o.readFileSync(y,"utf8")}catch(o){i=!0,x=!1,a?console.log(formatGitHubActionAnnotation(`${u}\n\nmissing or broken "expect" file: "${n.parse(y).base}"`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nmissing or broken "expect" file: "${n.parse(y).base}"\n\n${c}`))}let b=!1;try{w=await e($).process(h,{from:S,to:A,map:!!postcssSyntaxSupportsSourceMaps(f)&&{inline:!1,annotation:!1},syntax:postcssSyntax(f)})}catch(o){if(reduceInformationInCssSyntaxError(o),b=!0,f.exception&&f.exception.test(o.message))continue;throw o}!b&&f.exception&&(i=!0,a?console.log(formatGitHubActionAnnotation(`${u}\n\nexpected an exception but got none`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nexpected an exception but got none\n\n${c}`)));const E=w.css.toString();if(o.writeFileSync(A,E,"utf8"),process.env.REWRITE_EXPECTS&&o.writeFileSync(y,E,"utf8"),!1!==x){try{r.strictEqual(E,x)}catch(o){i=!0,a?console.log(formatGitHubActionAnnotation(formatCSSAssertError(u,f,o,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error(formatCSSAssertError(u,f,o)))}try{if(!f.postcssSyntaxHTML&&w.map.toJSON().sources.includes(""))throw new Error("Sourcemap is broken")}catch(o){i=!0;const n='\nThis is most likely a newly created PostCSS AST Node without a value for "source".\nsee :\n- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes\n- https://postcss.org/api/#node-source';a?console.log(formatGitHubActionAnnotation(`${u}\n\nbroken source map: ${JSON.stringify(w.map.toJSON().sources)}\n${n}`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nbroken source map: ${JSON.stringify(w.map.toJSON().sources)}\n${n}\n\n${c}`))}f.after&&await f.after();try{const n=o.readFileSync(A,"utf8");if((await e([noopPlugin()]).process(n,{from:A,to:A,map:!!postcssSyntaxSupportsSourceMaps(f)&&{inline:!1,annotation:!1},syntax:postcssSyntax(f)})).warnings().length)throw new Error("Unexpected warnings on second pass")}catch(o){i=!0,a?console.log(formatGitHubActionAnnotation(`${u}\n\nresult was not parsable with PostCSS.`,"error",{file:y,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nresult was not parsable with PostCSS.\n\n${c}`))}if(e([noopPlugin()]).version!==t([noopPlugin()]).version){const o=await t($).process(h,{from:S,to:A,map:!!postcssSyntaxSupportsSourceMaps(f)&&{inline:!1,annotation:!1}});try{r.strictEqual(o.css.toString(),E)}catch(o){reduceInformationInCssSyntaxError(o),i=!0,a?console.log(formatGitHubActionAnnotation("testing older PostCSS:\n"+formatCSSAssertError(u,f,o,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error("testing older PostCSS:\n"+formatCSSAssertError(u,f,o)))}}try{(w.warnings().length||f.warnings)&&r.strictEqual(w.warnings().length,f.warnings)}catch(o){i=!0,a?console.log(formatGitHubActionAnnotation(formatWarningsAssertError(u,f,w.warnings(),f.warnings??0,!0),"error",{file:y,line:1,col:1})):(p.add(u),console.error(formatWarningsAssertError(u,f,w.warnings(),f.warnings??0)))}}}if(p.size){console.error("\nunexpected failures:");for(const o of p.values())console.error(" - "+o)}i&&process.exit(1),console.warn("pass "+s().postcssPlugin)}}const i={postcssPlugin:"declaration-cloner",Declaration(o){"to-clone"===o.prop&&o.cloneBefore({prop:"cloned"})}},l={postcssPlugin:"rule-cloner",prepare(){const o=new WeakSet;return{RuleExit(n){o.has(n)||"to-clone"===n.selector&&(o.add(n),n.cloneBefore({selector:"cloned"}))}}}},p={postcssPlugin:"at-rule-cloner",prepare(){const o=new WeakSet;return{AtRuleExit(n){if(!o.has(n))return"to-clone"===n.params?(o.add(n),void n.cloneBefore({params:"cloned"})):"to-clone"===n.name?(o.add(n),void n.cloneBefore({name:"cloned"})):void 0}}}};export{p as atRuleClonerPlugin,i as declarationClonerPlugin,postcssTape,l as ruleClonerPlugin}; +/* node:coverage disable */ +import e from"node:assert/strict";import t from"fs/promises";import s from"path";import o from"postcss";import n from"postcss-8.4";import i from"node:test";const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});async function fileContentsOrEmptyString(e){try{return await t.readFile(e,"utf8")}catch(e){return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}function postcssTape(r,a){a=a??{},i("`postcss` flag is set on exported plugin creator",(()=>{e.strictEqual(r.postcss,!0)})),i("exported plugin creator is a function",(()=>{e.strictEqual(typeof r,"function")})),i("`postcssPlugin` is set on a plugin instance",(()=>{const t=r();e.ok(t.postcssPlugin),e.strictEqual(typeof t.postcssPlugin,"string")})),i("package.json",(async s=>{const o=await t.readFile("./package.json","utf-8"),n=JSON.parse(o);await s.test('includes "postcss-plugin" keyword',(()=>{e.ok(n.keywords),e.ok(n.keywords.includes("postcss-plugin"))})),await s.test('name starts with "postcss-"',{skip:a?.skipPackageNameCheck},(()=>{let t=n.name;if(t.startsWith("@")){t=n.name.split("/").slice(1).join("/")}e.ok(t.startsWith("postcss-"),`package name "${t}" does not start with "postcss-"`)})),await s.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in r},(()=>{e.ok(n.peerDependencies),e.ok(Object.keys(Object(n.peerDependencies)).includes("postcss")),e.ok(!Object.keys(Object(n.dependencies)).includes("postcss"))}))}));const c=r().postcssPlugin;return async a=>{await i(c,(async i=>{for(const c in a)await i.test(c,(async i=>{const p=a[c];p.before&&await p.before();const l=s.join(".","test",c.split(":")[0]),u=s.join(".","test",c.replace(/:/g,".")),d="css",f=`${l}.${d}`;let m=`${u}.expect.${d}`,g=`${u}.result.${d}`;p.expect&&(m=s.join(".","test",p.expect)),p.result&&(g=s.join(".","test",p.result));const w=p.plugins??[r(p.options)],k=await fileContentsOrEmptyString(f),y=await fileContentsOrEmptyString(m);let S,E=!1;try{S=await o(w).process(k,{from:f,to:g,map:{inline:!1,annotation:!1}})}catch(t){if(reduceInformationInCssSyntaxError(t),E=!0,p.exception&&p.exception.test(t.message))return;e.ifError(t)}e.notEqual(!E,p.exception,"expected an exception but got none");const h=S.css.toString();{const e=[t.writeFile(g,h,"utf8")];process.env.REWRITE_EXPECTS&&e.push(t.writeFile(m,h,"utf8")),await Promise.all(e)}e.ok(y,"Missing expected result file"),await i.test("has expected output",(()=>{e.strictEqual(h,y),e.deepStrictEqual(S.warnings().length,p.warnings??0,"Unexpected number warnings")})),await i.test("sourcemaps",(async()=>{e.ok(!S.map.toJSON().sources.includes(""),'Sourcemap is broken. This is most likely a newly created PostCSS AST Node without a value for "source". See: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes')})),p.after&&await p.after(),await i.test("output is parsable with PostCSS",(async()=>{const t=await fileContentsOrEmptyString(g),s=await o([noopPlugin()]).process(t,{from:g,to:g,map:{inline:!1,annotation:!1}});e.deepStrictEqual(s.warnings(),[],"Unexpected warnings on second pass")})),await i.test("The oldest and current PostCSS version produce the same result",{skip:o([noopPlugin()]).version===n([noopPlugin()]).version},(async()=>{const t=await n(w).process(k,{from:f,to:g,map:{inline:!1,annotation:!1}});e.strictEqual(t.css.toString(),h)}))}))}))}}noopPlugin.postcss=!0;const r={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},a={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{RuleExit(t){e.has(t)||"to-clone"===t.selector&&(e.add(t),t.cloneBefore({selector:"cloned"}))}}}},c={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{AtRuleExit(t){if(!e.has(t))return"to-clone"===t.params?(e.add(t),void t.cloneBefore({params:"cloned"})):"to-clone"===t.name?(e.add(t),void t.cloneBefore({name:"cloned"})):void 0}}}};export{c as atRuleClonerPlugin,r as declarationClonerPlugin,postcssTape,a as ruleClonerPlugin}; +/* node:coverage enable */ diff --git a/packages/postcss-tape/package.json b/packages/postcss-tape/package.json index 2d4920600..e6eab7737 100644 --- a/packages/postcss-tape/package.json +++ b/packages/postcss-tape/package.json @@ -50,8 +50,7 @@ ], "dependencies": { "postcss": "~8.4", - "postcss-8.4": "npm:postcss@~8.4", - "postcss-html": "^1.5.0" + "postcss-8.4": "npm:postcss@~8.4" }, "scripts": { "build": "rollup -c ../../rollup/default.mjs", diff --git a/packages/postcss-tape/src/file-contents-or-empty-string.ts b/packages/postcss-tape/src/file-contents-or-empty-string.ts new file mode 100644 index 000000000..0183a57d2 --- /dev/null +++ b/packages/postcss-tape/src/file-contents-or-empty-string.ts @@ -0,0 +1,9 @@ +import fs from 'fs/promises'; + +export async function fileContentsOrEmptyString(path: string): Promise { + try { + return await fs.readFile(path, 'utf8'); + } catch (error) { + return ''; + } +} diff --git a/packages/postcss-tape/src/format-asserts.ts b/packages/postcss-tape/src/format-asserts.ts deleted file mode 100644 index 9eeb4053f..000000000 --- a/packages/postcss-tape/src/format-asserts.ts +++ /dev/null @@ -1,72 +0,0 @@ -import type { Warning } from 'postcss'; -import type { TestCaseOptions } from './test-case-options'; - -export const dashesSeparator = '----------------------------------------'; - -export function formatCSSAssertError(testCaseLabel: string, testCaseOptions: TestCaseOptions, err: Error, forGithubAnnotation = false) { - let formatted = ''; - formatted += `\n${testCaseLabel}\n\n`; - - if (testCaseOptions.message) { - formatted += `message :\n ${testCaseOptions.message}\n\n`; - } - - if (testCaseOptions.options) { - try { - formatted += `options :\n${JSON.stringify(testCaseOptions.options, null, 2)}\n\n`; - } catch (_) { - // ignore - } - } - - formatted += `output changed :\n${prettyDiff(err.message)}\n`; - - if (!forGithubAnnotation) { - formatted += '\n' + dashesSeparator; - } - - return formatted; -} - -export function formatWarningsAssertError(testCaseLabel: string, testCaseOptions: TestCaseOptions, actual: Array, expected: number, forGithubAnnotation = false) { - let formatted = ''; - formatted += `\n${testCaseLabel}\n\n`; - - if (testCaseOptions.message) { - formatted += `message :\n ${testCaseOptions.message}\n\n`; - } - - if (testCaseOptions.options) { - try { - formatted += `options :\n${JSON.stringify(testCaseOptions.options, null, 2)}\n\n`; - } catch (_) { - // ignore - } - } - - formatted += `unexpected or missing warnings :\n+ actual ${actual.length}\n- expected ${expected}\n`; - - if (!forGithubAnnotation) { - actual.forEach((warning) => { - formatted += `\n[${warning.plugin}]: ${warning.text}`; - }); - - if (actual.length) { - formatted += '\n'; - } - - formatted += '\n' + dashesSeparator; - } - - return formatted; -} - -function prettyDiff(assertMessage: string) { - const newLineRegex = /[^\\](\\n)/gm; - const tabRegex = /(\\t)/gm; - return assertMessage.replace(newLineRegex, (match, p1) => { // decode new lines in CSS - return match.replace(p1, ' '); - }).replace(tabRegex, (match, p1) => { // decode tabs in CSS - return match.replace(p1, ' '); - }).replace(/\+$/gm, '').replace(/^Expected values to be strictly equal:\n/, ''); // remove trailing + outputted by `assert` -} diff --git a/packages/postcss-tape/src/github-annotations.ts b/packages/postcss-tape/src/github-annotations.ts deleted file mode 100644 index e11940032..000000000 --- a/packages/postcss-tape/src/github-annotations.ts +++ /dev/null @@ -1,33 +0,0 @@ -import path from 'path'; - -export function formatGitHubActionAnnotation(message: string, level = 'error', options: Record = {}) { - let output = '::' + level; - - const outputOptions = Object.keys(options).map((key) => { - let value = String(options[key]); - - if (key === 'file' && process.env.GITHUB_WORKSPACE) { - // make file paths relative to the workspace root. - value = path.relative(process.env.GITHUB_WORKSPACE, path.resolve(value)); - } - - return `${key}=${escapeValue(value)}`; - }).join(','); - - if (outputOptions) { - output += ` ${outputOptions}`; - } - - return `${output}::${escapeData(message || '')}`; -} - -function escapeData(s: string) { - return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A'); -} - -function escapeValue(s: string) { - return s.replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/]/g, '%5D') - .replace(/;/g, '%3B'); -} diff --git a/packages/postcss-tape/src/index.ts b/packages/postcss-tape/src/index.ts index 2fcf7a056..cc62fb633 100644 --- a/packages/postcss-tape/src/index.ts +++ b/packages/postcss-tape/src/index.ts @@ -1,408 +1,264 @@ -import fs from 'fs'; +/** + * A test suite for PostCSS plugins. + * + * @example + * ```sh + * node --test + * ``` + * + * ```js + * // test/_tape.mjs + * import { postcssTape } from '@csstools/postcss-tape'; + * import plugin from ''; + * + * postcssTape(plugin)({ + * basic: { + * message: "supports basic usage", + * }, + * 'basic:color': { + * message: "supports { color: '' }", + * options: { + * color: 'purple' + * } + * }, + * }); + * ``` + * + * @packageDocumentation + */ + +import assert from 'node:assert/strict'; +import fs from 'fs/promises'; import noopPlugin from './noop-plugin'; import path from 'path'; import postcss from 'postcss'; -import postcssOldestSupported, { AcceptedPlugin } from 'postcss-8.4'; -import syntaxHTML from 'postcss-html'; +import postcssOldestSupported from 'postcss-8.4'; +import test from 'node:test'; +import { fileContentsOrEmptyString } from './file-contents-or-empty-string'; +import { reduceInformationInCssSyntaxError } from './reduce-css-syntax-error'; + +import type { AcceptedPlugin } from 'postcss-8.4'; import type { AtRule, Declaration, Rule } from 'postcss'; import type { PluginCreator, Plugin, Result } from 'postcss'; import type { TestCaseOptions } from './test-case-options'; -import { dashesSeparator, formatCSSAssertError, formatWarningsAssertError } from './format-asserts'; -import { formatGitHubActionAnnotation } from './github-annotations'; -import { reduceInformationInCssSyntaxError } from './reduce-css-syntax-error'; -import { strict as assert } from 'assert'; -export type { TestCaseOptions } from './test-case-options'; - -const emitGitHubAnnotations = process.env.GITHUB_ACTIONS && process.env.ENABLE_ANNOTATIONS_FOR_NODE === 'true' && process.env.ENABLE_ANNOTATIONS_FOR_OS === 'true'; -function postcssSyntax(options: TestCaseOptions) { - if (options.postcssSyntaxHTML) { - return syntaxHTML(); - } - - return undefined; -} - -function postcssSyntaxSupportsSourceMaps(options: TestCaseOptions) { - if (options.postcssSyntaxHTML) { - return false; - } +export type { TestCaseOptions } from './test-case-options'; - return true; +/** + * General options for `@csstools/postcss-tape`. + * These affect the entire test run, not individual test cases. + * + * @example + * ```js + * import { postcssTape } from '@csstools/postcss-tape'; + * import plugin from 'your-postcss-plugin'; + * + * postcssTape(plugin, { + * skipPackageNameCheck: true, + * })(...); + */ +export type Options = { + /** + * PostCSS plugins should start their name with `postcss-`. + * If this is something you do not want to do, you can set this to `true` to skip this check. + */ + skipPackageNameCheck?: boolean, } -export function postcssTape(currentPlugin: PluginCreator) { - let hasErrors = false; +/** + * Create a test suite for a PostCSS plugin. + */ +export function postcssTape(currentPlugin: PluginCreator, runOptions?: Options) { + runOptions = runOptions ?? {}; // Plugin conforms to https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md - { - if (currentPlugin.postcss !== true) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'postcss flag not set to "true" on exported plugin object', - 'error', - { file: './package.json', line: 1, col: 1 }, /* attributed to package.json because we don't know the source file of "currentPlugin" */ - )); - } else { - console.error(`\npostcss flag not set to "true"\n\n${dashesSeparator}`); - } - } + test('`postcss` flag is set on exported plugin creator', () => { + assert.strictEqual(currentPlugin.postcss, true); + }); + + test('exported plugin creator is a function', () => { + assert.strictEqual(typeof currentPlugin, 'function'); + }); + test('`postcssPlugin` is set on a plugin instance', () => { // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#15-set-pluginpostcssplugin-with-plugin-name // Set plugin.postcssPlugin with plugin name - const plugin = currentPlugin() as Plugin; - if (!plugin.postcssPlugin || typeof plugin.postcssPlugin !== 'string') { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'plugin name not set via "postcssPlugin"', - 'error', - { file: './package.json', line: 1, col: 1 }, /* attributed to package.json because we don't know the source file of "currentPlugin" */ - )); - } else { - console.error(`\nplugin name not set via "postcssPlugin"\n\n${dashesSeparator}`); - } - } - // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#54-include-postcss-plugin-keyword-in-packagejson - // Include postcss-plugin keyword in package.json - const packageInfo = JSON.parse(fs.readFileSync('./package.json', 'utf-8').toString()); - if (!packageInfo.keywords || !packageInfo.keywords.includes('postcss-plugin')) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'package.json does not include "postcss-plugin" keyword', - 'error', - { file: './package.json', line: 1, col: 1 }, /* attributed to package.json because we don't know the source file of "currentPlugin" */ - )); - } else { - console.error(`\npackage.json does not include "postcss-plugin" keyword\n\n${dashesSeparator}`); - } - } + const plugin = currentPlugin() as Plugin; - // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#11-clear-name-with-postcss--prefix - // Clear name with postcss- prefix - const isOlderPackageName = [ - 'css-has-pseudo', - 'css-blank-pseudo', - 'css-prefers-color-scheme', - '@csstools/css-has-pseudo-experimental', - ].includes(packageInfo.name); - - let packageName = packageInfo.name; - if (packageName.startsWith('@')) { - const parts = packageInfo.name.split('/'); - packageName = parts.slice(1).join('/'); - } + assert.ok(plugin.postcssPlugin); + assert.strictEqual(typeof plugin.postcssPlugin, 'string'); + }); - if (!packageName.startsWith('postcss-') && !isOlderPackageName) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'plugin name in package.json does not start with "postcss-"', - 'error', - { file: './package.json', line: 1, col: 1 }, - )); - } else { - console.error(`\nplugin name in package.json does not start with "postcss-"\n\n${dashesSeparator}`); - } - } + test('package.json', async (t) => { + const packageData = await fs.readFile('./package.json', 'utf-8'); + const packageInfo = JSON.parse(packageData); - // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#14-keep-postcss-to-peerdependencies - // Keep postcss to peerDependencies - if (Object.keys(Object(packageInfo.dependencies)).includes('postcss') && !('postcssTapeSelfTest' in currentPlugin)) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'postcss should only be a peer and/or dev dependency', - 'error', - { file: './package.json', line: 1, col: 1 }, - )); - } else { - console.error(`\npostcss should only be a peer and/or dev dependency\n\n${dashesSeparator}`); - } - } - } + await t.test('includes "postcss-plugin" keyword', () => { + // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#54-include-postcss-plugin-keyword-in-packagejson + // Include postcss-plugin keyword in package.json - // Test cases - return async (options: Record) => { - const failureSummary = new Set(); + assert.ok(packageInfo.keywords); + assert.ok(packageInfo.keywords.includes('postcss-plugin')); + }); - for (const testCaseLabel in options) { - const testCaseOptions = options[testCaseLabel]; + await t.test('name starts with "postcss-"', { skip: runOptions?.skipPackageNameCheck }, () => { + // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#11-clear-name-with-postcss--prefix + // Clear name with postcss- prefix - // Run "before" immediately. - if (testCaseOptions.before) { - await testCaseOptions.before(); + let packageName = packageInfo.name; + if (packageName.startsWith('@')) { + const parts = packageInfo.name.split('/'); + packageName = parts.slice(1).join('/'); } - const testSourceFilePathWithoutExtension = path.join('.', 'test', testCaseLabel.split(':')[0]); - const testFilePathWithoutExtension = path.join('.', 'test', testCaseLabel.replace(/:/g, '.')); + assert.ok(packageName.startsWith('postcss-'), `package name "${packageName}" does not start with "postcss-"`); + }); - let extension = 'css'; - if (testCaseOptions.postcssSyntaxHTML) { - extension = 'html'; - } + await t.test('`postcss` is a peer dependency and not a direct dependency', { skip: ('postcssTapeSelfTest' in currentPlugin) }, () => { + // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#14-keep-postcss-to-peerdependencies + // Keep postcss to peerDependencies - const testFilePath = `${testSourceFilePathWithoutExtension}.${extension}`; - let expectFilePath = `${testFilePathWithoutExtension}.expect.${extension}`; - let resultFilePath = `${testFilePathWithoutExtension}.result.${extension}`; + assert.ok(packageInfo.peerDependencies); + assert.ok(Object.keys(Object(packageInfo.peerDependencies)).includes('postcss')); + assert.ok(!Object.keys(Object(packageInfo.dependencies)).includes('postcss')); + }); + }); - if (testCaseOptions.expect) { - expectFilePath = path.join('.', 'test', testCaseOptions.expect); - } - if (testCaseOptions.result) { - resultFilePath = path.join('.', 'test', testCaseOptions.result); - } + const pluginName = (currentPlugin() as Plugin).postcssPlugin; - const plugins = testCaseOptions.plugins ?? [currentPlugin(testCaseOptions.options)]; - - const input = fs.readFileSync(testFilePath, 'utf8'); - - // Check errors on expect file being missing - let expected: string | false = ''; - try { - expected = fs.readFileSync(expectFilePath, 'utf8'); - } catch (_) { - hasErrors = true; - expected = false; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - `${testCaseLabel}\n\nmissing or broken "expect" file: "${path.parse(expectFilePath).base}"`, - 'error', - { file: testFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(`\n${testCaseLabel}\n\nmissing or broken "expect" file: "${path.parse(expectFilePath).base}"\n\n${dashesSeparator}`); - } - } + // Test cases + return async (options: Record) => { + await test(pluginName, async (t1) => { + for (const testCaseLabel in options) { + await t1.test(testCaseLabel, async (t2) => { + const testCaseOptions = options[testCaseLabel]; + + // Run "before" immediately. + if (testCaseOptions.before) { + await testCaseOptions.before(); + } - let result: Result; - - let sawException = false; - try { - result = await postcss(plugins).process(input, { - from: testFilePath, - to: resultFilePath, - map: postcssSyntaxSupportsSourceMaps(testCaseOptions) ? { - inline: false, - annotation: false, - } : false, - syntax: postcssSyntax(testCaseOptions), - }); - } catch (err) { - reduceInformationInCssSyntaxError(err); - sawException = true; - if (testCaseOptions.exception && testCaseOptions.exception.test(err.message)) { - // expected an exception and got one. - continue; - } + const testSourceFilePathWithoutExtension = path.join('.', 'test', testCaseLabel.split(':')[0]); + const testFilePathWithoutExtension = path.join('.', 'test', testCaseLabel.replace(/:/g, '.')); - // rethrow - throw err; - } + const extension = 'css'; + const testFilePath = `${testSourceFilePathWithoutExtension}.${extension}`; + let expectFilePath = `${testFilePathWithoutExtension}.expect.${extension}`; + let resultFilePath = `${testFilePathWithoutExtension}.result.${extension}`; - if (!sawException && testCaseOptions.exception) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - `${testCaseLabel}\n\nexpected an exception but got none`, - 'error', - { file: testFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(`\n${testCaseLabel}\n\nexpected an exception but got none\n\n${dashesSeparator}`); - } - } + if (testCaseOptions.expect) { + expectFilePath = path.join('.', 'test', testCaseOptions.expect); + } + if (testCaseOptions.result) { + resultFilePath = path.join('.', 'test', testCaseOptions.result); + } - // Try to write the result file, even if further checks fails. - // This helps writing new tests for plugins. - // Taking the result file as a starting point for the expect file. - const resultString = result.css.toString(); - fs.writeFileSync(resultFilePath, resultString, 'utf8'); + const plugins = testCaseOptions.plugins ?? [currentPlugin(testCaseOptions.options)]; + + const input = await fileContentsOrEmptyString(testFilePath); + const expected = await fileContentsOrEmptyString(expectFilePath); + + let result: Result; + let sawException = false; + + try { + result = await postcss(plugins).process(input, { + from: testFilePath, + to: resultFilePath, + map: { + inline: false, + annotation: false, + }, + }); + } catch (err) { + reduceInformationInCssSyntaxError(err); + sawException = true; + if (testCaseOptions.exception && testCaseOptions.exception.test(err.message)) { + // expected an exception and got one. + return; + } + + assert.ifError(err); + } - // Allow contributors to rewrite `.expect.css` files through postcss-tape. - if (process.env.REWRITE_EXPECTS) { - fs.writeFileSync(expectFilePath, resultString, 'utf8'); - } + assert.notEqual(!sawException, testCaseOptions.exception, 'expected an exception but got none'); - // Can't do further checks if "expect" is missing. - if (expected === false) { - continue; - } + const resultString = result.css.toString(); - // Assert result with recent PostCSS. - // - // NOTE: - // The version we declare as a peer dependency in plugins. - { - try { - assert.strictEqual(resultString, expected); - } catch (err) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - formatCSSAssertError(testCaseLabel, testCaseOptions, err, true), - 'error', - { file: expectFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(formatCSSAssertError(testCaseLabel, testCaseOptions, err)); - } - } - } + // Try to write the result file, even if further checks fails. + // This helps writing new tests for plugins. + // Taking the result file as a starting point for the expect file. + { + const fileWriters: Array> = [fs.writeFile(resultFilePath, resultString, 'utf8')]; - // Assert result sourcemaps with recent PostCSS. - { - try { - if ( - !testCaseOptions.postcssSyntaxHTML && - result.map.toJSON().sources.includes('') - ) { - throw new Error('Sourcemap is broken'); - } - } catch (_) { - hasErrors = true; - - const helpText = '\nThis is most likely a newly created PostCSS AST Node without a value for "source".\nsee :\n- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes\n- https://postcss.org/api/#node-source'; - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - `${testCaseLabel}\n\nbroken source map: ${JSON.stringify(result.map.toJSON().sources)}\n${helpText}`, - 'error', - { file: testFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(`\n${testCaseLabel}\n\nbroken source map: ${JSON.stringify(result.map.toJSON().sources)}\n${helpText}\n\n${dashesSeparator}`); + // Allow contributors to rewrite `.expect.css` files through postcss-tape. + if (process.env.REWRITE_EXPECTS) { + fileWriters.push(fs.writeFile(expectFilePath, resultString, 'utf8')); + } + + await Promise.all(fileWriters); } - } - } - // Run "after" when initial postcss run has completely. - if (testCaseOptions.after) { - await testCaseOptions.after(); - } + assert.ok(expected, 'Missing expected result file'); - // Assert that the result can be passed back to PostCSS and still parses. - { - try { - const resultContents = fs.readFileSync(resultFilePath, 'utf8'); - const secondPassResult = await postcss([noopPlugin()]).process(resultContents, { - from: resultFilePath, - to: resultFilePath, - map: postcssSyntaxSupportsSourceMaps(testCaseOptions) ? { - inline: false, - annotation: false, - } : false, - syntax: postcssSyntax(testCaseOptions), - }); + await t2.test('has expected output', () => { + assert.strictEqual(resultString, expected); - if (secondPassResult.warnings().length) { - throw new Error('Unexpected warnings on second pass'); - } - } catch (_) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - `${testCaseLabel}\n\nresult was not parsable with PostCSS.`, - 'error', - { file: expectFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(`\n${testCaseLabel}\n\nresult was not parsable with PostCSS.\n\n${dashesSeparator}`); - } - } - } + // Assert that warnings have the expected amount. + assert.deepStrictEqual(result.warnings().length, testCaseOptions.warnings ?? 0, 'Unexpected number warnings'); + }); - // Assert result with oldest supported PostCSS. - // Check against the actual result to avoid duplicate warnings. - // - // NOTE: - // The oldest version of PostCSS we support at this time. - // This does not need to be a different version than the latest version of PostCSS. - // There is no system behind setting this. - // It is here to allow testing a specific older version, if parts of the community can't update yet. - if (postcss([noopPlugin()]).version !== postcssOldestSupported([noopPlugin()]).version) { // https://postcss.org/api/#processor-version - const resultFromOldestPostCSS = await postcssOldestSupported(plugins as Array).process(input, { - from: testFilePath, - to: resultFilePath, - map: postcssSyntaxSupportsSourceMaps(testCaseOptions) ? { - inline: false, - annotation: false, - } : false, - }); + // Assert result sourcemaps with recent PostCSS. + await t2.test('sourcemaps', async () => { + assert.ok(!result.map.toJSON().sources.includes(''), 'Sourcemap is broken. This is most likely a newly created PostCSS AST Node without a value for "source". See: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes'); + }); - try { - assert.strictEqual(resultFromOldestPostCSS.css.toString(), resultString); - } catch (err) { - reduceInformationInCssSyntaxError(err); - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - 'testing older PostCSS:\n' + formatCSSAssertError(testCaseLabel, testCaseOptions, err, true), - 'error', - { file: expectFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error('testing older PostCSS:\n' + formatCSSAssertError(testCaseLabel, testCaseOptions, err)); + // Run "after" when initial postcss run has completely. + if (testCaseOptions.after) { + await testCaseOptions.after(); } - } - } - // Assert that warnings have the expected amount. - { - try { - if (result.warnings().length || testCaseOptions.warnings) { - assert.strictEqual(result.warnings().length, testCaseOptions.warnings); - } - } catch (_) { - hasErrors = true; - - if (emitGitHubAnnotations) { - console.log(formatGitHubActionAnnotation( - formatWarningsAssertError(testCaseLabel, testCaseOptions, result.warnings(), testCaseOptions.warnings ?? 0, true), - 'error', - { file: expectFilePath, line: 1, col: 1 }, - )); - } else { - failureSummary.add(testCaseLabel); - console.error(formatWarningsAssertError(testCaseLabel, testCaseOptions, result.warnings(), testCaseOptions.warnings ?? 0)); - } - } - } - } + // Assert that the result can be passed back to PostCSS and still parses. + await t2.test('output is parsable with PostCSS', async () => { + const resultContents = await fileContentsOrEmptyString(resultFilePath); + const secondPassResult = await postcss([noopPlugin()]).process(resultContents, { + from: resultFilePath, + to: resultFilePath, + map: { + inline: false, + annotation: false, + }, + }); + + assert.deepStrictEqual(secondPassResult.warnings(), [], 'Unexpected warnings on second pass'); + }); - if (failureSummary.size) { - console.error('\nunexpected failures:'); - for (const label of failureSummary.values()) { - console.error(' - ' + label); + await t2.test( + 'The oldest and current PostCSS version produce the same result', + { skip: postcss([noopPlugin()]).version === postcssOldestSupported([noopPlugin()]).version }, + async () => { + const resultFromOldestPostCSS = await postcssOldestSupported(plugins as Array).process(input, { + from: testFilePath, + to: resultFilePath, + map: { + inline: false, + annotation: false, + }, + }); + + assert.strictEqual(resultFromOldestPostCSS.css.toString(), resultString); + }, + ); + }); } - } - - if (hasErrors) { - process.exit(1); - } - - console.warn('pass ' + (currentPlugin() as Plugin).postcssPlugin); + }); }; } +/** + * A dummy PostCSS plugin that clones any declaration with the property `to-clone` to a new declaration with the property `cloned`. + */ export const declarationClonerPlugin = { postcssPlugin: 'declaration-cloner', Declaration(decl: Declaration) { @@ -412,6 +268,9 @@ export const declarationClonerPlugin = { }, }; +/** + * A dummy PostCSS plugin that clones any rule with the selector `to-clone` to a new rule with the selector `cloned`. + */ export const ruleClonerPlugin = { postcssPlugin: 'rule-cloner', prepare() { @@ -432,6 +291,9 @@ export const ruleClonerPlugin = { }, }; +/** + * A dummy PostCSS plugin that clones any at rule with params `to-clone` to a new at rule with params `cloned`. + */ export const atRuleClonerPlugin = { postcssPlugin: 'at-rule-cloner', prepare() { diff --git a/packages/postcss-tape/src/test-case-options.ts b/packages/postcss-tape/src/test-case-options.ts index d1ddaf03b..c4461c6e9 100644 --- a/packages/postcss-tape/src/test-case-options.ts +++ b/packages/postcss-tape/src/test-case-options.ts @@ -10,7 +10,6 @@ export type TestCaseOptions = { /** The expected number of warnings. */ warnings?: number, /** Expected exception */ - /** NOTE: plugins should not throw exceptions, this goes against best practices. Use `errors` instead. */ exception?: RegExp, /** Override the file name of the "expect" file. */ @@ -19,10 +18,7 @@ export type TestCaseOptions = { result?: string, /** Do something before the test is run. */ - before?: () => void, + before?: () => void | Promise, /** Do something after the test is run. */ after?: () => void | Promise, - - /** Process the test cases with "postcss-html" as the syntax */ - postcssSyntaxHTML?: boolean, } diff --git a/packages/postcss-tape/test-self/basic.before-after.expect.log b/packages/postcss-tape/test-self/basic.before-after.expect.log index 60b832bb6..6b70a20d3 100644 --- a/packages/postcss-tape/test-self/basic.before-after.expect.log +++ b/packages/postcss-tape/test-self/basic.before-after.expect.log @@ -1 +1 @@ -pass a-plugin +............. diff --git a/packages/postcss-tape/test-self/basic.break-css.expect.log b/packages/postcss-tape/test-self/basic.break-css.expect.log index ac614bab7..b12e3cbd9 100644 --- a/packages/postcss-tape/test-self/basic.break-css.expect.log +++ b/packages/postcss-tape/test-self/basic.break-css.expect.log @@ -1,9 +1 @@ - -basic:break-css - -result was not parsable with PostCSS. - ----------------------------------------- - -unexpected failures: - - basic:break-css +.........X.XX diff --git a/packages/postcss-tape/test-self/basic.broken-sourcemap.expect.log b/packages/postcss-tape/test-self/basic.broken-sourcemap.expect.log index eb8c27fc4..1bb86acbe 100644 --- a/packages/postcss-tape/test-self/basic.broken-sourcemap.expect.log +++ b/packages/postcss-tape/test-self/basic.broken-sourcemap.expect.log @@ -1,14 +1 @@ - -basic:broken-sourcemap - -broken source map: ["basic.css",""] - -This is most likely a newly created PostCSS AST Node without a value for "source". -see : -- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes -- https://postcss.org/api/#node-source - ----------------------------------------- - -unexpected failures: - - basic:broken-sourcemap +........X..XX diff --git a/packages/postcss-tape/test-self/basic.expect.log b/packages/postcss-tape/test-self/basic.expect.log index 60b832bb6..6b70a20d3 100644 --- a/packages/postcss-tape/test-self/basic.expect.log +++ b/packages/postcss-tape/test-self/basic.expect.log @@ -1 +1 @@ -pass a-plugin +............. diff --git a/packages/postcss-tape/test-self/basic.with-diff-in-expect.expect.log b/packages/postcss-tape/test-self/basic.with-diff-in-expect.expect.log index 1eb8f910d..3f3d2753b 100644 --- a/packages/postcss-tape/test-self/basic.with-diff-in-expect.expect.log +++ b/packages/postcss-tape/test-self/basic.with-diff-in-expect.expect.log @@ -1,17 +1 @@ - -basic:with-diff-in-expect - -message : - supports basic usage - -output changed : -+ actual - expected - -+ '.baz { order: 1; } ' -- '.bar { order: 1; } ' - ^ - ----------------------------------------- - -unexpected failures: - - basic:with-diff-in-expect +.......X...XX diff --git a/packages/postcss-tape/test-self/basic.with-warnings.expect.log b/packages/postcss-tape/test-self/basic.with-warnings.expect.log index cccfbded7..58f1e10e0 100644 --- a/packages/postcss-tape/test-self/basic.with-warnings.expect.log +++ b/packages/postcss-tape/test-self/basic.with-warnings.expect.log @@ -1,44 +1,2 @@ - -basic:with-one-missing-warning - -message : - supports basic usage - -unexpected or missing warnings : -+ actual 0 -- expected 1 - ----------------------------------------- - -basic:with-one-unexpected-warning - -message : - supports basic usage - -unexpected or missing warnings : -+ actual 1 -- expected 0 - -[a-plugin]: a warning - ----------------------------------------- - -basic:with-multiple-warnings - -message : - supports basic usage - -unexpected or missing warnings : -+ actual 3 -- expected 7 - -[a-plugin]: a warning -[a-plugin]: a warning -[a-plugin]: a warning - ----------------------------------------- - -unexpected failures: - - basic:with-one-missing-warning - - basic:with-one-unexpected-warning - - basic:with-multiple-warnings +............X...XX.. +.XX...XX diff --git a/packages/postcss-tape/test-self/basic.without-expect.expect.log b/packages/postcss-tape/test-self/basic.without-expect.expect.log index 47750e7cd..878800c1b 100644 --- a/packages/postcss-tape/test-self/basic.without-expect.expect.log +++ b/packages/postcss-tape/test-self/basic.without-expect.expect.log @@ -1,9 +1 @@ - -basic:without-expect - -missing or broken "expect" file: "basic.without-expect.expect.css" - ----------------------------------------- - -unexpected failures: - - basic:without-expect +.......XX diff --git a/packages/postcss-tape/test-self/document.expect.code b/packages/postcss-tape/test-self/document.expect.code deleted file mode 100644 index 573541ac9..000000000 --- a/packages/postcss-tape/test-self/document.expect.code +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/packages/postcss-tape/test-self/document.expect.log b/packages/postcss-tape/test-self/document.expect.log deleted file mode 100644 index 1ce3d6ee0..000000000 --- a/packages/postcss-tape/test-self/document.expect.log +++ /dev/null @@ -1 +0,0 @@ -pass b-plugin diff --git a/packages/postcss-tape/test-self/test.sh b/packages/postcss-tape/test-self/test.sh index 6020840d8..ba5b896af 100644 --- a/packages/postcss-tape/test-self/test.sh +++ b/packages/postcss-tape/test-self/test.sh @@ -1,12 +1,18 @@ # Run tests as if local. unset GITHUB_ACTIONS +# if node version begins with "v16" then exit 0; +if [[ "$(node --version)" =~ ^v16 ]]; then + echo "Skip tests on node v16" + exit 0 +fi + # region:Basic set +e echo "" > ./test-self/basic.result.log -node ./test/basic.mjs > ./test-self/basic.result.log 2>&1 +node --test-reporter dot ./test/basic.mjs > ./test-self/basic.result.log 2>&1 echo "$?" > ./test-self/basic.result.code set -e @@ -19,7 +25,7 @@ set +e echo "" > ./test-self/basic.with-diff-in-expect.result.log -node ./test/basic.with-diff-in-expect.mjs > ./test-self/basic.with-diff-in-expect.result.log 2>&1 +node --test-reporter dot ./test/basic.with-diff-in-expect.mjs > ./test-self/basic.with-diff-in-expect.result.log 2>&1 echo "$?" > ./test-self/basic.with-diff-in-expect.result.code set -e @@ -32,7 +38,7 @@ set +e echo "" > ./test-self/basic.without-expect.result.log -node ./test/basic.without-expect.mjs > ./test-self/basic.without-expect.result.log 2>&1 +node --test-reporter dot ./test/basic.without-expect.mjs > ./test-self/basic.without-expect.result.log 2>&1 echo "$?" > ./test-self/basic.without-expect.result.code set -e @@ -45,7 +51,7 @@ set +e echo "" > ./test-self/basic.with-warnings.result.log -node ./test/basic.with-warnings.mjs > ./test-self/basic.with-warnings.result.log 2>&1 +node --test-reporter dot ./test/basic.with-warnings.mjs > ./test-self/basic.with-warnings.result.log 2>&1 echo "$?" > ./test-self/basic.with-warnings.result.code set -e @@ -58,7 +64,7 @@ set +e echo "" > ./test-self/basic.broken-sourcemap.result.log -node ./test/basic.broken-sourcemap.mjs > ./test-self/basic.broken-sourcemap.result.log 2>&1 +node --test-reporter dot ./test/basic.broken-sourcemap.mjs > ./test-self/basic.broken-sourcemap.result.log 2>&1 echo "$?" > ./test-self/basic.broken-sourcemap.result.code set -e @@ -71,7 +77,7 @@ set +e echo "" > ./test-self/basic.before-after.result.log -node ./test/basic.before-after.mjs > ./test-self/basic.before-after.result.log 2>&1 +node --test-reporter dot ./test/basic.before-after.mjs > ./test-self/basic.before-after.result.log 2>&1 echo "$?" > ./test-self/basic.before-after.result.code set -e @@ -84,7 +90,7 @@ set +e echo "" > ./test-self/basic.break-css.result.log -node ./test/basic.break-css.mjs > ./test-self/basic.break-css.result.log 2>&1 +node --test-reporter dot ./test/basic.break-css.mjs > ./test-self/basic.break-css.result.log 2>&1 echo "$?" > ./test-self/basic.break-css.result.code set -e @@ -92,15 +98,4 @@ git --no-pager diff --no-index --word-diff ./test-self/basic.break-css.expect.lo git --no-pager diff --no-index --word-diff ./test-self/basic.break-css.expect.code ./test-self/basic.break-css.result.code # endregion:Basic with broken result CSS -# region:Document -set +e - -echo "" > ./test-self/document.result.log - -node ./test/document.mjs > ./test-self/document.result.log 2>&1 -echo "$?" > ./test-self/document.result.code - -set -e -git --no-pager diff --no-index --word-diff ./test-self/document.expect.log ./test-self/document.result.log -git --no-pager diff --no-index --word-diff ./test-self/document.expect.code ./test-self/document.result.code -# endregion:Document +echo "ok"; diff --git a/packages/postcss-tape/test/document.expect.html b/packages/postcss-tape/test/document.expect.html deleted file mode 100644 index 322d0105d..000000000 --- a/packages/postcss-tape/test/document.expect.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/packages/postcss-tape/test/document.html b/packages/postcss-tape/test/document.html deleted file mode 100644 index 1916455d4..000000000 --- a/packages/postcss-tape/test/document.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/packages/postcss-tape/test/document.mjs b/packages/postcss-tape/test/document.mjs deleted file mode 100644 index 1eba0cf35..000000000 --- a/packages/postcss-tape/test/document.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import { postcssTape } from '../dist/index.mjs'; -import plugin from './_b-plugin.mjs'; - -postcssTape(plugin)({ - 'document': { - postcssSyntaxHTML: true, - message: 'supports basic usage', - }, -}); diff --git a/packages/postcss-tape/test/document.result.html b/packages/postcss-tape/test/document.result.html deleted file mode 100644 index 322d0105d..000000000 --- a/packages/postcss-tape/test/document.result.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/packages/selector-specificity/package.json b/packages/selector-specificity/package.json index 77b1734ea..e4b1b4f2b 100644 --- a/packages/selector-specificity/package.json +++ b/packages/selector-specificity/package.json @@ -58,7 +58,7 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node ./test/index.mjs && node ./test/_import.mjs && node ./test/_require.cjs" + "test": "node --test ./test/index.mjs ./test/_import.mjs && node ./test/_require.cjs" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/selector-specificity#readme", "repository": { diff --git a/plugin-packs/postcss-bundler/package.json b/plugin-packs/postcss-bundler/package.json index 5d2b01694..32aa525d1 100644 --- a/plugin-packs/postcss-bundler/package.json +++ b/plugin-packs/postcss-bundler/package.json @@ -67,8 +67,8 @@ "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", "stryker": "stryker run --logLevel error", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-bundler#readme", "repository": { diff --git a/plugin-packs/postcss-bundler/stryker.conf.json b/plugin-packs/postcss-bundler/stryker.conf.json index 8597822a1..30cba5246 100644 --- a/plugin-packs/postcss-bundler/stryker.conf.json +++ b/plugin-packs/postcss-bundler/stryker.conf.json @@ -8,7 +8,7 @@ "coverageAnalysis": "perTest", "tempDirName": "../../.stryker-tmp", "commandRunner": { - "command": "node ./.tape.mjs" + "command": "node --test" }, "thresholds": { "high": 100, diff --git a/plugin-packs/postcss-bundler/.tape.mjs b/plugin-packs/postcss-bundler/test/_tape.mjs similarity index 85% rename from plugin-packs/postcss-bundler/.tape.mjs rename to plugin-packs/postcss-bundler/test/_tape.mjs index 4521bae5e..096d40166 100644 --- a/plugin-packs/postcss-bundler/.tape.mjs +++ b/plugin-packs/postcss-bundler/test/_tape.mjs @@ -5,30 +5,30 @@ import path from 'path'; const testCases = { basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'leading-slash': { - message: "does not infer a root to resolve leading slash imports", - exception: /Failed to find \'\/imports\/basic.css\'/, + message: 'does not infer a root to resolve leading slash imports', + exception: /Failed to find '\/imports\/basic.css'/, }, 'charset-utf8': { - message: "errors on mismatched charset", + message: 'errors on mismatched charset', exception: /Incompatible @charset statements/, }, 'does-not-exist-1': { - message: "throws on files that don't exist", + message: 'throws on files that don\'t exist', exception: /Failed to find 'imports\/does-not-exist.css'/, }, 'does-not-exist-2': { - message: "throws on files that don't exist", + message: 'throws on files that don\'t exist', exception: /Failed to find 'node_modules:does-not-exist.css'/, }, 'ignore': { - message: "ignores incorrect syntax", + message: 'ignores incorrect syntax', warnings: 4, }, 'regexp': { - message: "regexp sanity checks", + message: 'regexp sanity checks', warnings: 2, }, 'examples/example': { @@ -37,12 +37,12 @@ const testCases = { } ;(await fs.readdir('./test/css-import-tests', { withFileTypes: true, recursive: true })).filter(dirent => { - return dirent.isFile() && dirent.name === 'style.css' + return dirent.isFile() && dirent.name === 'style.css'; }).sort().forEach(dirent => { const key = path.join(path.relative('./test', dirent.path), 'style'); testCases[key] = { message: `passes 'css-import-tests' case : ${path.relative('./test/css-import-tests', dirent.path).split(path.sep).join(' - ')}`, - } + }; switch (dirent.path.split(path.sep).join(path.posix.sep)) { case 'test/css-import-tests/002-sub-features/004-at-supports/007': diff --git a/plugin-packs/postcss-preset-env/package.json b/plugin-packs/postcss-preset-env/package.json index 2b4294a21..cecd2961b 100644 --- a/plugin-packs/postcss-preset-env/package.json +++ b/plugin-packs/postcss-preset-env/package.json @@ -126,8 +126,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ./docs/generate.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./src/test/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env#readme", "repository": { diff --git a/plugin-packs/postcss-preset-env/src/test/test.mjs b/plugin-packs/postcss-preset-env/src/test/test.mjs deleted file mode 100644 index 0a5b6650a..000000000 --- a/plugin-packs/postcss-preset-env/src/test/test.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import './lib/feature-is-inserted-or-has-plugin.mjs'; -import './lib/feature-is-less.mjs'; -import './lib/format-staged-feature.mjs'; -import './lib/get-unsupported-browsers-by-feature.mjs'; -import './lib/list-features/list-features.mjs'; -import './lib/prepare-features-list.mjs'; -import './lib/stage.mjs'; -import './lib/transformed-insertions.mjs'; diff --git a/plugin-packs/postcss-preset-env/test/_lib.mjs b/plugin-packs/postcss-preset-env/test/_lib.mjs new file mode 100644 index 000000000..e108f0b7b --- /dev/null +++ b/plugin-packs/postcss-preset-env/test/_lib.mjs @@ -0,0 +1,8 @@ +import '../src/test/lib/feature-is-inserted-or-has-plugin.mjs'; +import '../src/test/lib/feature-is-less.mjs'; +import '../src/test/lib/format-staged-feature.mjs'; +import '../src/test/lib/get-unsupported-browsers-by-feature.mjs'; +import '../src/test/lib/list-features/list-features.mjs'; +import '../src/test/lib/prepare-features-list.mjs'; +import '../src/test/lib/stage.mjs'; +import '../src/test/lib/transformed-insertions.mjs'; diff --git a/plugin-packs/postcss-preset-env/.tape.mjs b/plugin-packs/postcss-preset-env/test/_tape.mjs similarity index 86% rename from plugin-packs/postcss-preset-env/.tape.mjs rename to plugin-packs/postcss-preset-env/test/_tape.mjs index 1540efc04..32fa13d76 100644 --- a/plugin-packs/postcss-preset-env/.tape.mjs +++ b/plugin-packs/postcss-preset-env/test/_tape.mjs @@ -11,58 +11,58 @@ const orderDetectionPlugin = (prop, changeWhenMatches) => { decl.value = 'changed-this-declaration'; } }, - } -} + }; +}; -orderDetectionPlugin.postcss = true +orderDetectionPlugin.postcss = true; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:ff49': { message: 'supports { browsers: "ff >= 49" } usage', options: { - browsers: 'ff >= 49' - } + browsers: 'ff >= 49', + }, }, 'basic:ff66': { message: 'supports { browsers: "ff >= 66" } usage', options: { - browsers: 'ff >= 66' - } + browsers: 'ff >= 66', + }, }, 'basic:ch38': { message: 'supports { browsers: "chrome >= 38" } usage', options: { - browsers: 'chrome >= 38' - } + browsers: 'chrome >= 38', + }, }, 'basic:ie10': { message: 'supports { browsers: "ie >= 10" } usage', options: { - browsers: 'ie >= 10' - } + browsers: 'ie >= 10', + }, }, 'basic:ch88-ff78': { message: 'uses :is pseudo for nesting with modern browsers { browsers: "chrome >= 88, firefox >= 78", stage: 0 }', options: { browsers: 'chrome >= 88, firefox >= 78', - stage: 0 - } + stage: 0, + }, }, 'basic:safari15': { message: 'supports { browsers: "safari >= 15" } usage', options: { - browsers: 'safari >= 15' - } + browsers: 'safari >= 15', + }, }, 'basic:op_mini': { message: 'supports { browsers: "op_mini all" } usage', options: { stage: 0, - browsers: 'op_mini all' - } + browsers: 'op_mini all', + }, }, 'basic:ch88-ff78:no-is-pseudo': { message: ':is pseudo for nesting can be disable with modern browsers { browsers: "chrome >= 88, firefox >= 78", stage: 0, features: { nesting-rules: { noIsPseudoSelector: true } } } usage', @@ -71,76 +71,76 @@ postcssTape(plugin)({ stage: 0, features: { 'nesting-rules': { - noIsPseudoSelector: true - } - } - } + noIsPseudoSelector: true, + }, + }, + }, }, 'basic:ch88-ff78-saf10': { message: 'does not use :is pseudo for nesting with an older browser { browsers: "chrome >= 88, firefox >= 78, safari >= 10", stage: 0 } usage', options: { browsers: 'chrome >= 88, firefox >= 78, safari >= 10', - stage: 0 - } + stage: 0, + }, }, 'basic:supports-query': { message: 'supports { browsers: "defaults and supports css-variables" } usage', options: { - browsers: 'defaults and supports css-variables' - } + browsers: 'defaults and supports css-variables', + }, }, 'basic:stage0': { message: 'supports { stage: 0 } usage', options: { - stage: 0 - } + stage: 0, + }, }, 'basic:stage0-ff49': { message: 'supports { browsers: "ff >= 49", stage: 0 } usage', options: { browsers: 'ff >= 49', - stage: 0 - } + stage: 0, + }, }, 'basic:stage0-ff66': { message: 'supports { browsers: "ff >= 66", stage: 0 } usage', options: { browsers: 'ff >= 66', - stage: 0 - } + stage: 0, + }, }, 'basic:vendors-1': { message: 'supports { minimumVendorImplementations: 1, enableClientSidePolyfills: false } usage', options: { stage: 1, minimumVendorImplementations: 1, - enableClientSidePolyfills: false - } + enableClientSidePolyfills: false, + }, }, 'basic:vendors-2': { message: 'supports { minimumVendorImplementations: 2, enableClientSidePolyfills: false } usage', options: { stage: 1, minimumVendorImplementations: 2, - enableClientSidePolyfills: false - } + enableClientSidePolyfills: false, + }, }, 'basic:vendors-3': { message: 'supports { minimumVendorImplementations: 3, enableClientSidePolyfills: false } usage', options: { stage: 1, minimumVendorImplementations: 3, - enableClientSidePolyfills: false - } + enableClientSidePolyfills: false, + }, }, 'basic:nesting:true': { message: 'supports { stage: false, features: { "nesting-rules": true } } usage', options: { stage: false, features: { - 'nesting-rules': true - } - } + 'nesting-rules': true, + }, + }, }, 'basic:nesting:noIsPseudoSelector:false': { message: 'supports { stage: false, features: { "nesting-rules": { "noIsPseudoSelector": false } } } usage', @@ -148,40 +148,40 @@ postcssTape(plugin)({ stage: false, features: { 'nesting-rules': { - noIsPseudoSelector: false - } - } - } + noIsPseudoSelector: false, + }, + }, + }, }, 'basic:nesting:false': { message: 'supports { stage: 0, features: { "nesting-rules": false } } usage', options: { stage: 0, features: { - 'nesting-rules': false - } - } + 'nesting-rules': false, + }, + }, }, 'basic:autoprefixer': { message: 'supports { autoprefixer: { add: false } } usage', options: { autoprefixer: { - add: false - } - } + add: false, + }, + }, }, 'basic:autoprefixer:false': { message: 'supports { autoprefixer: false } usage', options: { - autoprefixer: false - } + autoprefixer: false, + }, }, 'basic:preserve:true': { message: 'supports { preserve: true, stage: 0, browsers: "> 0%" } usage', options: { preserve: true, stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, }, 'basic:preserve:false': { @@ -189,7 +189,7 @@ postcssTape(plugin)({ options: { preserve: false, stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, }, 'basic:hebrew': { @@ -197,8 +197,8 @@ postcssTape(plugin)({ options: { stage: 0, logical: { - inlineDirection: 'right-to-left' - } + inlineDirection: 'right-to-left', + }, }, }, 'basic:hebrew:all-browsers-have-support': { @@ -207,26 +207,26 @@ postcssTape(plugin)({ stage: 0, browsers: 'Chrome 114', logical: { - inlineDirection: 'right-to-left' - } + inlineDirection: 'right-to-left', + }, }, }, 'layers-basic': { message: 'supports layers usage', options: { stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, - warnings: 0 + warnings: 0, }, 'layers-basic:preserve:true': { message: 'supports layers usage with { preserve: true }', options: { preserve: true, stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, - warnings: 0 + warnings: 0, }, 'client-side-polyfills:stage-1': { message: 'stable client side polyfill behavior', @@ -234,7 +234,7 @@ postcssTape(plugin)({ preserve: false, stage: 1, enableClientSidePolyfills: true, - } + }, }, 'client-side-polyfills:stage-2': { message: 'stable client side polyfill behavior', @@ -242,7 +242,7 @@ postcssTape(plugin)({ preserve: false, stage: 2, enableClientSidePolyfills: true, - } + }, }, 'client-side-polyfills:stage-3': { message: 'stable client side polyfill behavior', @@ -250,7 +250,7 @@ postcssTape(plugin)({ preserve: false, stage: 3, enableClientSidePolyfills: true, - } + }, }, 'client-side-polyfills:stage-4': { message: 'stable client side polyfill behavior', @@ -258,45 +258,45 @@ postcssTape(plugin)({ preserve: false, stage: 4, enableClientSidePolyfills: true, - } + }, }, 'custom-properties': { message: 'supports { browsers: "ie >= 10" } usage', options: { - browsers: 'ie >= 10' - } + browsers: 'ie >= 10', + }, }, 'custom-properties:disabled': { message: 'supports { browsers: "ie >= 10", features: { "custom-properties": false } } usage', options: { browsers: 'ie >= 10', features: { - 'custom-properties': false - } - } + 'custom-properties': false, + }, + }, }, 'custom-properties:enabled': { message: 'supports { browsers: "chrome >= 60", features: { "custom-properties": true } } usage', options: { browsers: 'chrome >= 60', features: { - 'custom-properties': true - } - } + 'custom-properties': true, + }, + }, }, 'enable-client-side-polyfills': { message: 'supports { enableClientSidePolyfills: false } usage', options: { enableClientSidePolyfills: false, stage: 0, - } + }, }, 'enable-client-side-polyfills:enabled': { message: 'supports { enableClientSidePolyfills: true } usage (default)', options: { enableClientSidePolyfills: true, stage: 0, - } + }, }, 'insert:baseline': { message: 'supports { insertBefore/insertAfter } usage baseline', @@ -305,8 +305,8 @@ postcssTape(plugin)({ features: { 'lab-function': true, 'color-function': false, - } - } + }, + }, }, 'insert:before:match-source': { message: 'supports { insertBefore } usage when looking for source', @@ -320,10 +320,10 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('before', (decl) => { return decl.prop === 'color' && decl.value.indexOf('lab(') === 0; - }) - ] - } - } + }), + ], + }, + }, }, 'insert:before:match-result': { message: 'supports { insertBefore } usage when looking for a result', @@ -337,10 +337,10 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('before', (decl) => { return decl.prop === 'color' && decl.value.indexOf('rgb(') === 0; - }) - ] - } - } + }), + ], + }, + }, }, 'insert:after:match-source': { message: 'supports { insertAfter } usage when looking for source', @@ -354,10 +354,10 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('after', (decl) => { return decl.prop === 'color' && decl.value.indexOf('lab(') === 0; - }) - ] - } - } + }), + ], + }, + }, }, 'insert:after:match-result': { message: 'supports { insertAfter } usage when looking for a result', @@ -371,10 +371,10 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('after', (decl) => { return decl.prop === 'color' && decl.value.indexOf('rgb(') === 0; - }) - ] - } - } + }), + ], + }, + }, }, 'insert:after:match-result:no-array': { message: 'supports { insertAfter with a single plugin, not an array } usage when looking for a result', @@ -387,8 +387,8 @@ postcssTape(plugin)({ insertAfter: { 'lab-function': orderDetectionPlugin('after', (decl) => { return decl.prop === 'color' && decl.value.indexOf('rgb(') === 0; - }) - } + }), + }, }, }, 'insert:before:match-result:feature-is-skipped': { @@ -402,10 +402,10 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('before', (decl) => { return decl.prop === 'color' && decl.value !== 'changed-this-declaration'; - }) - ] - } - } + }), + ], + }, + }, }, 'insert:after:match-result:feature-is-skipped': { message: 'supports { insertAfter } usage when looking for a result and the attached feature is skipped', @@ -418,17 +418,17 @@ postcssTape(plugin)({ 'lab-function': [ orderDetectionPlugin('after', (decl) => { return decl.prop === 'color' && decl.value !== 'changed-this-declaration'; - }) - ] - } - } + }), + ], + }, + }, }, 'logical-properties': { message: 'supports all known logical properties', options: { autoprefixer: false, stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, }, 'progressive-custom-properties': { @@ -436,7 +436,7 @@ postcssTape(plugin)({ options: { preserve: true, stage: 0, - browsers: '> 0%' + browsers: '> 0%', }, }, 'unknown-feature': { @@ -447,8 +447,8 @@ postcssTape(plugin)({ 'custom-media': true, 'postcss-logical': true, 'postcss-logica': true, - 'environment-variables': true - } + 'environment-variables': true, + }, }, }, 'postcss-import/styles': { @@ -457,8 +457,8 @@ postcssTape(plugin)({ postcssBundler(), plugin({ stage: 0, - browsers: '> 0%' - }) - ] - } + browsers: '> 0%', + }), + ], + }, }); diff --git a/plugins/css-blank-pseudo/package.json b/plugins/css-blank-pseudo/package.json index 251083114..088dac732 100644 --- a/plugins/css-blank-pseudo/package.json +++ b/plugins/css-blank-pseudo/package.json @@ -74,9 +74,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs && node ./test/_valid-replacements.mjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-blank-pseudo#readme", "repository": { diff --git a/plugins/css-blank-pseudo/test/_browser.mjs b/plugins/css-blank-pseudo/test/_browser.mjs index 31545cffb..89475fe62 100644 --- a/plugins/css-blank-pseudo/test/_browser.mjs +++ b/plugins/css-blank-pseudo/test/_browser.mjs @@ -2,53 +2,62 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; + +const requestListener = async function (req, res) { + + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; + + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/replace-with': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser_replace.html', 'utf8')); + break; + case '/test/browser.expect.css': + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + case '/test/browser.replacewith.expect.css': + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.replacewith.expect.css', 'utf8')); + break; + case '/dist/browser-global.js': + res.setHeader('Content-type', 'text/javascript'); + res.writeHead(200); + res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); + break; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; -(async () => { - const requestListener = async function (req, res) { - - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; - - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/replace-with': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser_replace.html', 'utf8')); - break; - case '/test/browser.expect.css': - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - case '/test/browser.replacewith.expect.css': - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.replacewith.expect.css', 'utf8')); - break; - case '/dist/browser-global.js': - res.setHeader('Content-type', 'text/javascript'); - res.writeHead(200); - res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); - break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; - - // Use different servers for HTML/CSS/JS to trigger CORS +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -221,8 +230,10 @@ import { promises as fsp } from 'fs'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/css-blank-pseudo/.tape.mjs b/plugins/css-blank-pseudo/test/_tape.mjs similarity index 77% rename from plugins/css-blank-pseudo/.tape.mjs rename to plugins/css-blank-pseudo/test/_tape.mjs index bfacf3a6d..935e329fe 100644 --- a/plugins/css-blank-pseudo/.tape.mjs +++ b/plugins/css-blank-pseudo/test/_tape.mjs @@ -1,47 +1,47 @@ import { declarationClonerPlugin, postcssTape } from '@csstools/postcss-tape'; import plugin from 'css-blank-pseudo'; -postcssTape(plugin)({ +postcssTape(plugin, { skipPackageNameCheck: true })({ 'basic': { message: 'supports basic usage', }, 'basic:replacewith': { message: 'supports { replaceWith: ".css-blank" } usage', options: { - replaceWith: '.css-blank' - } + replaceWith: '.css-blank', + }, }, 'basic:preserve': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:wrong-replacewith': { message: 'correctly warns when replace with is invalid', warnings: 1, options: { - replaceWith: '#css-blank' - } + replaceWith: '#css-blank', + }, }, 'basic:disable-polyfill-ready-class': { message: 'supports { disablePolyfillReadyClass: true } usage', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'invalid-selector': { message: 'warns on invalid selectors', - warnings: 1 + warnings: 1, }, 'examples/example': { message: 'minimal example', @@ -49,20 +49,20 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'examples/example:replacewith': { message: 'minimal example', options: { - replaceWith: '.css-blank' - } + replaceWith: '.css-blank', + }, }, 'examples/example:disable-polyfill-ready-class': { message: 'minimal example', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, 'browser': { message: 'css for browser tests', @@ -70,7 +70,7 @@ postcssTape(plugin)({ 'browser:replacewith': { message: 'css for browser tests', options: { - replaceWith: '.css-blank' - } + replaceWith: '.css-blank', + }, }, }); diff --git a/plugins/css-has-pseudo/package.json b/plugins/css-has-pseudo/package.json index 377212eee..a1ab69102 100644 --- a/plugins/css-has-pseudo/package.json +++ b/plugins/css-has-pseudo/package.json @@ -80,9 +80,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./src/encode/test.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-has-pseudo#readme", "repository": { diff --git a/plugins/css-has-pseudo/test/_browser.mjs b/plugins/css-has-pseudo/test/_browser.mjs index 5d1da3c93..882bb43ac 100644 --- a/plugins/css-has-pseudo/test/_browser.mjs +++ b/plugins/css-has-pseudo/test/_browser.mjs @@ -1,47 +1,49 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { +const requestListener = async function (req, res) { - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/test/basic.expect.css': - // Stylesheet WITHOUT CORS headers - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/basic.expect.css', 'utf8')); - break; - case '/test/browser.expect.css': - // Stylesheet WITH CORS headers - res.setHeader('Content-type', 'text/css'); - res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - case '/dist/browser-global.js': - res.setHeader('Content-type', 'text/javascript'); - res.writeHead(200); - res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); - break; + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/test/basic.expect.css': + // Stylesheet WITHOUT CORS headers + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/basic.expect.css', 'utf8')); + break; + case '/test/browser.expect.css': + // Stylesheet WITH CORS headers + res.setHeader('Content-type', 'text/css'); + res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + case '/dist/browser-global.js': + res.setHeader('Content-type', 'text/javascript'); + res.writeHead(200); + res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); + break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; +function startServers() { // Use different servers for HTML/CSS/JS to trigger CORS // // HTML: @@ -54,7 +56,17 @@ import { promises as fsp } from 'fs'; const serverC = http.createServer(requestListener); serverC.listen(8082); - if (!process.env.DEBUG) { + return () => { + serverA.close(); + serverB.close(); + serverC.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -78,7 +90,7 @@ import { promises as fsp } from 'fs'; { await page.goto('http://localhost:8080#force-polyfill'); - const result = await page.evaluate(async() => { + const result = await page.evaluate(async () => { // eslint-disable-next-line no-undef return await window.runTest(); }); @@ -89,10 +101,10 @@ import { promises as fsp } from 'fs'; await browser.close(); - await serverA.close(); - await serverB.close(); - await serverC.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/css-has-pseudo/src/encode/test.mjs b/plugins/css-has-pseudo/test/_encode-decode.mjs similarity index 96% rename from plugins/css-has-pseudo/src/encode/test.mjs rename to plugins/css-has-pseudo/test/_encode-decode.mjs index 7ff593799..de45470c3 100644 --- a/plugins/css-has-pseudo/src/encode/test.mjs +++ b/plugins/css-has-pseudo/test/_encode-decode.mjs @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; -import encodeCSS from './encode.mjs'; -import decodeCSS from './decode.mjs'; -import extractEncodedSelectors from './extract.mjs'; +import encodeCSS from '../src/encode/encode.mjs'; +import decodeCSS from '../src/encode/decode.mjs'; +import extractEncodedSelectors from '../src/encode/extract.mjs'; function testEncoderDecoder(decoded, encoded) { assert.strictEqual(encodeCSS(decoded), encoded); diff --git a/plugins/css-has-pseudo/.tape.mjs b/plugins/css-has-pseudo/test/_tape.mjs similarity index 91% rename from plugins/css-has-pseudo/.tape.mjs rename to plugins/css-has-pseudo/test/_tape.mjs index 91423a1ac..a355371e6 100644 --- a/plugins/css-has-pseudo/.tape.mjs +++ b/plugins/css-has-pseudo/test/_tape.mjs @@ -4,21 +4,21 @@ import postcssLogical from 'postcss-logical'; import postcssNesting from 'postcss-nesting'; import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; -postcssTape(plugin)({ +postcssTape(plugin, { skipPackageNameCheck: true })({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:specificity-matching-name': { message: 'supports { specificityMatchingName: "other-thing-that-does-not-exist" } usage', options: { - specificityMatchingName: 'other-thing-that-does-not-exist' - } + specificityMatchingName: 'other-thing-that-does-not-exist', + }, }, 'examples/example': { message: 'minimal example', @@ -26,15 +26,15 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'generated-selector-cases': { message: 'correctly handles generated cases', warnings: 1, options: { - preserve: false - } + preserve: false, + }, }, 'browser': { message: 'prepare CSS for chrome test', @@ -70,5 +70,5 @@ postcssTape(plugin)({ 'plugin-order-nesting:after:preserve': { message: 'works with other plugins that modify selectors', plugins: [plugin({ preserve: true }), postcssNesting({ preserve: true })], - } + }, }); diff --git a/plugins/css-has-pseudo/tsconfig.json b/plugins/css-has-pseudo/tsconfig.json index 1b60a463a..25270c542 100644 --- a/plugins/css-has-pseudo/tsconfig.json +++ b/plugins/css-has-pseudo/tsconfig.json @@ -5,6 +5,6 @@ "declarationDir": ".", "strict": true }, - "include": ["./src/**/*"], + "include": ["./src/**/*", "test/_encode-decode.mjs"], "exclude": ["dist"], } diff --git a/plugins/css-prefers-color-scheme/package.json b/plugins/css-prefers-color-scheme/package.json index 87e60ced6..0aa9e904e 100644 --- a/plugins/css-prefers-color-scheme/package.json +++ b/plugins/css-prefers-color-scheme/package.json @@ -71,9 +71,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-prefers-color-scheme#readme", "repository": { diff --git a/plugins/css-prefers-color-scheme/test/_browser.mjs b/plugins/css-prefers-color-scheme/test/_browser.mjs index 4819469b7..203a4e51f 100644 --- a/plugins/css-prefers-color-scheme/test/_browser.mjs +++ b/plugins/css-prefers-color-scheme/test/_browser.mjs @@ -1,52 +1,54 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { +const requestListener = async function (req, res) { - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/no-polyfill.html': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser-no-polyfill.html', 'utf8')); - break; - case '/test/basic.expect.css': - // Stylesheet WITHOUT CORS headers - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/basic.expect.css', 'utf8')); - break; - case '/test/browser.expect.css': - // Stylesheet WITH CORS headers - res.setHeader('Content-type', 'text/css'); - res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - case '/dist/browser-global.js': - res.setHeader('Content-type', 'text/javascript'); - res.writeHead(200); - res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); - break; + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/no-polyfill.html': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser-no-polyfill.html', 'utf8')); + break; + case '/test/basic.expect.css': + // Stylesheet WITHOUT CORS headers + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/basic.expect.css', 'utf8')); + break; + case '/test/browser.expect.css': + // Stylesheet WITH CORS headers + res.setHeader('Content-type', 'text/css'); + res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + case '/dist/browser-global.js': + res.setHeader('Content-type', 'text/javascript'); + res.writeHead(200); + res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); + break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; +function startServers() { // Use different servers for HTML/CSS/JS to trigger CORS // // HTML: @@ -59,7 +61,17 @@ import { promises as fsp } from 'fs'; const serverC = http.createServer(requestListener); serverC.listen(8082); - if (!process.env.DEBUG) { + return () => { + serverA.close(); + serverB.close(); + serverC.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -149,10 +161,10 @@ import { promises as fsp } from 'fs'; await browser.close(); - await serverA.close(); - await serverB.close(); - await serverC.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/css-prefers-color-scheme/.tape.mjs b/plugins/css-prefers-color-scheme/test/_tape.mjs similarity index 77% rename from plugins/css-prefers-color-scheme/.tape.mjs rename to plugins/css-prefers-color-scheme/test/_tape.mjs index 184208c43..c84cf186c 100644 --- a/plugins/css-prefers-color-scheme/.tape.mjs +++ b/plugins/css-prefers-color-scheme/test/_tape.mjs @@ -1,30 +1,30 @@ import { declarationClonerPlugin, postcssTape } from '@csstools/postcss-tape'; import plugin from 'css-prefers-color-scheme'; -postcssTape(plugin)({ +postcssTape(plugin, { skipPackageNameCheck: true })({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:preserve:false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'examples/example': { message: 'minimal example', @@ -32,8 +32,8 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'browser': { message: 'css for browser tests', diff --git a/plugins/postcss-attribute-case-insensitive/package.json b/plugins/postcss-attribute-case-insensitive/package.json index 403e001fe..e203b17c4 100644 --- a/plugins/postcss-attribute-case-insensitive/package.json +++ b/plugins/postcss-attribute-case-insensitive/package.json @@ -64,8 +64,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-attribute-case-insensitive#readme", "repository": { diff --git a/plugins/postcss-attribute-case-insensitive/.tape.mjs b/plugins/postcss-attribute-case-insensitive/test/_tape.mjs similarity index 82% rename from plugins/postcss-attribute-case-insensitive/.tape.mjs rename to plugins/postcss-attribute-case-insensitive/test/_tape.mjs index f1a5a5fab..abb1fe490 100644 --- a/plugins/postcss-attribute-case-insensitive/.tape.mjs +++ b/plugins/postcss-attribute-case-insensitive/test/_tape.mjs @@ -3,26 +3,26 @@ import plugin from 'postcss-attribute-case-insensitive'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'invalid-selector': { message: 'warns on invalid selectors', - warnings: 1 + warnings: 1, }, 'examples/example': { message: 'minimal example', @@ -30,7 +30,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-base-plugin/package.json b/plugins/postcss-base-plugin/package.json index e04bfb38d..b1e808007 100644 --- a/plugins/postcss-base-plugin/package.json +++ b/plugins/postcss-base-plugin/package.json @@ -59,8 +59,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "repository": { "type": "git", diff --git a/plugins/postcss-base-plugin/test/_import.mjs b/plugins/postcss-base-plugin/test/_import.mjs index 0e4c84832..ea3cefc1a 100644 --- a/plugins/postcss-base-plugin/test/_import.mjs +++ b/plugins/postcss-base-plugin/test/_import.mjs @@ -1,6 +1,10 @@ -import assert from 'assert'; +import assert from 'node:assert/strict'; +import test from 'node:test'; import plugin from '@csstools/postcss-base-plugin'; -plugin(); -assert.ok(plugin.postcss, 'should have "postcss flag"'); -assert.equal(typeof plugin, 'function', 'should return a function'); +test('import', () => { + plugin(); + assert.ok(plugin.postcss, 'should have "postcss flag"'); + assert.equal(typeof plugin, 'function', 'should return a function'); +}); + diff --git a/plugins/postcss-base-plugin/test/_require.cjs b/plugins/postcss-base-plugin/test/_require.cjs index 8b21a7929..c39005284 100644 --- a/plugins/postcss-base-plugin/test/_require.cjs +++ b/plugins/postcss-base-plugin/test/_require.cjs @@ -1,6 +1,9 @@ -const assert = require('assert'); +const assert = require('node:assert/strict'); +const test = require('node:test'); const plugin = require('@csstools/postcss-base-plugin'); -plugin(); -assert.ok(plugin.postcss, 'should have "postcss flag"'); -assert.equal(typeof plugin, 'function', 'should return a function'); +test('require', () => { + plugin(); + assert.ok(plugin.postcss, 'should have "postcss flag"'); + assert.equal(typeof plugin, 'function', 'should return a function'); +}); diff --git a/plugins/postcss-base-plugin/.tape.mjs b/plugins/postcss-base-plugin/test/_tape.mjs similarity index 60% rename from plugins/postcss-base-plugin/.tape.mjs rename to plugins/postcss-base-plugin/test/_tape.mjs index 5cc051b0b..39211f696 100644 --- a/plugins/postcss-base-plugin/.tape.mjs +++ b/plugins/postcss-base-plugin/test/_tape.mjs @@ -3,17 +3,13 @@ import plugin from '@csstools/postcss-base-plugin'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:color': { - message: "supports { color: '
' }", + message: 'supports { color: \'\' }', options: { - color: 'purple' - } - }, - document: { - postcssSyntaxHTML: true, - message: "supports document usage", + color: 'purple', + }, }, 'examples/example': { message: 'minimal example', @@ -21,7 +17,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-base-plugin/test/document.expect.html b/plugins/postcss-base-plugin/test/document.expect.html deleted file mode 100644 index 65a369d89..000000000 --- a/plugins/postcss-base-plugin/test/document.expect.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/plugins/postcss-base-plugin/test/document.html b/plugins/postcss-base-plugin/test/document.html deleted file mode 100644 index 87d683cc9..000000000 --- a/plugins/postcss-base-plugin/test/document.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/plugins/postcss-cascade-layers/package.json b/plugins/postcss-cascade-layers/package.json index fe43ee2b5..a8ce457f4 100644 --- a/plugins/postcss-cascade-layers/package.json +++ b/plugins/postcss-cascade-layers/package.json @@ -72,9 +72,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-cascade-layers#readme", "repository": { diff --git a/plugins/postcss-cascade-layers/test/_browser.mjs b/plugins/postcss-cascade-layers/test/_browser.mjs index e99452513..9380660cc 100644 --- a/plugins/postcss-cascade-layers/test/_browser.mjs +++ b/plugins/postcss-cascade-layers/test/_browser.mjs @@ -3,21 +3,22 @@ import http from 'http'; import { promises as fsp } from 'fs'; import plugin from '@csstools/postcss-cascade-layers'; import postcss from 'postcss'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { +const requestListener = async function (req, res) { - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); - // write html string with list of links to cases. - res.end(` + // write html string with list of links to cases. + res.end(` Cascade Layers Test @@ -37,56 +38,65 @@ import postcss from 'postcss'; `); - break; - case '/wpt/layer-basic.html': - case '/wpt/layer-buckets.html': - case '/wpt/layer-counter-style-override.html': - case '/wpt/layer-important.html': - case '/wpt/layer-keyframes-override.html': - case '/wpt/layer-media-query.html': - case '/wpt/layer-property-override.html': - case '/wpt/layer-vs-inline-style.html': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test' + pathname, 'utf8')); - break; - case '/test/styles.css': - if (req.method === 'POST') { - const data = await new Promise((resolve, reject) => { - let buf = []; - req.on('data', (chunk) => { - buf.push(chunk); - }); - - req.on('end', () => { - resolve(Buffer.concat(buf).toString()); - }); - - req.on('error', (err) => { - reject(err); - }); + break; + case '/wpt/layer-basic.html': + case '/wpt/layer-buckets.html': + case '/wpt/layer-counter-style-override.html': + case '/wpt/layer-important.html': + case '/wpt/layer-keyframes-override.html': + case '/wpt/layer-media-query.html': + case '/wpt/layer-property-override.html': + case '/wpt/layer-vs-inline-style.html': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test' + pathname, 'utf8')); + break; + case '/test/styles.css': + if (req.method === 'POST') { + const data = await new Promise((resolve, reject) => { + let buf = []; + req.on('data', (chunk) => { + buf.push(chunk); + }); + + req.on('end', () => { + resolve(Buffer.concat(buf).toString()); + }); + + req.on('error', (err) => { + reject(err); }); + }); - const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(css.css); - break; - } - - // eslint-disable-next-line no-fallthrough - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); + const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(css.css); break; - } - }; + } + // eslint-disable-next-line no-fallthrough + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; + +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -118,8 +128,10 @@ import postcss from 'postcss'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-cascade-layers/.tape.mjs b/plugins/postcss-cascade-layers/test/_tape.mjs similarity index 58% rename from plugins/postcss-cascade-layers/.tape.mjs rename to plugins/postcss-cascade-layers/test/_tape.mjs index 175b09b74..7d5ff162c 100644 --- a/plugins/postcss-cascade-layers/.tape.mjs +++ b/plugins/postcss-cascade-layers/test/_tape.mjs @@ -4,40 +4,40 @@ import postcssBundler from '@csstools/postcss-bundler'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, atrules: { - message: "supports @keyframes usage", + message: 'supports @keyframes usage', }, 'container-scope--reference': { - message: "Layered styles without @container or @scope but with the same layers and layer order as the @container/@scope test", + message: 'Layered styles without @container or @scope but with the same layers and layer order as the @container/@scope test', }, 'container-scope': { - message: "Layered styles with @container or @scope, these at rules are expected not to have any effect on the final order or specificity", + message: 'Layered styles with @container or @scope, these at rules are expected not to have any effect on the final order or specificity', }, nested: { - message: "supports nested layer usage", + message: 'supports nested layer usage', }, 'nested-case-insensitive': { - message: "supports layer and other keywords written in any case", + message: 'supports layer and other keywords written in any case', }, 'nested-complex': { - message: "supports nested layer usage", + message: 'supports nested layer usage', }, important: { - message: "supports important usage", + message: 'supports important usage', }, 'anon-layer': { - message: "supports anonymous layer usage", + message: 'supports anonymous layer usage', }, 'invalid-nested-css': { - message: "ignores nested css", + message: 'ignores nested css', }, 'extensions': { - message: "css custom extensions", + message: 'css custom extensions', }, 'pre-defined-order-for-nested-layer': { - message: 'supports pre-defined orders for nested layers' + message: 'supports pre-defined orders for nested layers', }, 'unlayered-styles': { message: 'supports unlayered styles alongside layers', @@ -50,7 +50,7 @@ postcssTape(plugin)({ options: { onRevertLayerKeyword: 'warn', onConditionalRulesChangingLayerOrder: 'warn', - onImportLayerRule: 'warn' + onImportLayerRule: 'warn', }, warnings: 4, }, @@ -59,24 +59,24 @@ postcssTape(plugin)({ options: { onRevertLayerKeyword: 'warn', onConditionalRulesChangingLayerOrder: 'warn', - onImportLayerRule: 'warn' + onImportLayerRule: 'warn', }, warnings: 2, plugins: [ postcssBundler(), plugin(), - ] + ], }, 'where': { - message: "works with zero specificity selectors", + message: 'works with zero specificity selectors', }, 'specificity-buckets-a': { - message: "creates non overlapping specificity buckets", + message: 'creates non overlapping specificity buckets', }, 'specificity-buckets-b': { - message: "creates non overlapping specificity buckets", + message: 'creates non overlapping specificity buckets', }, 'examples/example': { - message: "minimal example", + message: 'minimal example', }, }); diff --git a/plugins/postcss-color-function/package.json b/plugins/postcss-color-function/package.json index 3e56242ab..177f777c2 100644 --- a/plugins/postcss-color-function/package.json +++ b/plugins/postcss-color-function/package.json @@ -55,8 +55,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-function#readme", "repository": { diff --git a/plugins/postcss-color-function/.tape.mjs b/plugins/postcss-color-function/test/_tape.mjs similarity index 92% rename from plugins/postcss-color-function/.tape.mjs rename to plugins/postcss-color-function/test/_tape.mjs index b3f81e97e..5af7d8029 100644 --- a/plugins/postcss-color-function/.tape.mjs +++ b/plugins/postcss-color-function/test/_tape.mjs @@ -9,31 +9,31 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'lab-function-interop': { message: 'supports usage along side postcss-lab-function', plugins: [ plugin({ preserve: true }), lab({ preserve: true, subFeatures: { displayP3: true } }), - ] + ], }, 'lab-function-interop:preserve:false': { message: 'supports usage along side postcss-lab-function with { preserve: false }', plugins: [ plugin({ preserve: false}), lab({ preserve: false, subFeatures: { displayP3: true } }), - ] + ], }, 'variables': { message: 'supports variables', @@ -41,15 +41,15 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'variables:preserve-true:progressive-false': { message: 'supports variables with { preserve: true, enableProgressiveCustomProperties: false } usage', options: { preserve: true, enableProgressiveCustomProperties: false, - } + }, }, 'examples/example': { message: 'minimal example', @@ -57,14 +57,14 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, 'examples/example:preserve-true:progressive-false': { message: 'minimal example', options: { preserve: true, enableProgressiveCustomProperties: false, - } - } + }, + }, }); diff --git a/plugins/postcss-color-functional-notation/package.json b/plugins/postcss-color-functional-notation/package.json index 069820065..1374d8e8e 100644 --- a/plugins/postcss-color-functional-notation/package.json +++ b/plugins/postcss-color-functional-notation/package.json @@ -54,8 +54,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-functional-notation#readme", "repository": { diff --git a/plugins/postcss-color-functional-notation/.tape.mjs b/plugins/postcss-color-functional-notation/test/_tape.mjs similarity index 85% rename from plugins/postcss-color-functional-notation/.tape.mjs rename to plugins/postcss-color-functional-notation/test/_tape.mjs index fe3d35221..be0bf86c2 100644 --- a/plugins/postcss-color-functional-notation/.tape.mjs +++ b/plugins/postcss-color-functional-notation/test/_tape.mjs @@ -8,17 +8,17 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -26,19 +26,19 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'generated-value-cases': { message: 'correctly handles generated cases', options: { - preserve: false - } + preserve: false, + }, }, 'generated-value-cases:preserve': { message: 'correctly handles generated cases', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-color-hex-alpha/package.json b/plugins/postcss-color-hex-alpha/package.json index ac47226a3..6bca052f1 100644 --- a/plugins/postcss-color-hex-alpha/package.json +++ b/plugins/postcss-color-hex-alpha/package.json @@ -68,8 +68,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-hex-alpha#readme", "repository": { diff --git a/plugins/postcss-color-hex-alpha/.tape.mjs b/plugins/postcss-color-hex-alpha/test/_tape.mjs similarity index 76% rename from plugins/postcss-color-hex-alpha/.tape.mjs rename to plugins/postcss-color-hex-alpha/test/_tape.mjs index 21a07f435..789213bc7 100644 --- a/plugins/postcss-color-hex-alpha/.tape.mjs +++ b/plugins/postcss-color-hex-alpha/test/_tape.mjs @@ -3,25 +3,25 @@ import plugin from 'postcss-color-hex-alpha'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'clip-path': { - message: 'ignores clip-path with hash in url' + message: 'ignores clip-path with hash in url', }, 'examples/example': { message: 'minimal example', @@ -29,7 +29,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-color-mix-function/package.json b/plugins/postcss-color-mix-function/package.json index b722bee54..80207bfb6 100644 --- a/plugins/postcss-color-mix-function/package.json +++ b/plugins/postcss-color-mix-function/package.json @@ -64,8 +64,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-mix-function#readme", "repository": { diff --git a/plugins/postcss-color-mix-function/.tape.mjs b/plugins/postcss-color-mix-function/test/_tape.mjs similarity index 88% rename from plugins/postcss-color-mix-function/.tape.mjs rename to plugins/postcss-color-mix-function/test/_tape.mjs index 2f095f02f..de43c4892 100644 --- a/plugins/postcss-color-mix-function/.tape.mjs +++ b/plugins/postcss-color-mix-function/test/_tape.mjs @@ -8,17 +8,17 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports basic usage with { preserve: true }', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -26,7 +26,7 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-color-rebeccapurple/package.json b/plugins/postcss-color-rebeccapurple/package.json index 37af694fd..7c3a8df0f 100644 --- a/plugins/postcss-color-rebeccapurple/package.json +++ b/plugins/postcss-color-rebeccapurple/package.json @@ -68,8 +68,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-rebeccapurple#readme", "repository": { diff --git a/plugins/postcss-color-rebeccapurple/.tape.mjs b/plugins/postcss-color-rebeccapurple/test/_tape.mjs similarity index 69% rename from plugins/postcss-color-rebeccapurple/.tape.mjs rename to plugins/postcss-color-rebeccapurple/test/_tape.mjs index afc5bac1f..0d4c83c25 100644 --- a/plugins/postcss-color-rebeccapurple/.tape.mjs +++ b/plugins/postcss-color-rebeccapurple/test/_tape.mjs @@ -3,25 +3,25 @@ import plugin from 'postcss-color-rebeccapurple'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { - message: "supports basic usage with { preserve: true }", + message: 'supports basic usage with { preserve: true }', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-value-cases': { - message: "supports generated test cases", + message: 'supports generated test cases', }, 'examples/example': { message: 'minimal example', @@ -29,7 +29,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-conditional-values/package.json b/plugins/postcss-conditional-values/package.json index 7119b8332..596bfabd6 100644 --- a/plugins/postcss-conditional-values/package.json +++ b/plugins/postcss-conditional-values/package.json @@ -59,8 +59,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-conditional-values#readme", "repository": { diff --git a/plugins/postcss-conditional-values/.tape.mjs b/plugins/postcss-conditional-values/test/_tape.mjs similarity index 67% rename from plugins/postcss-conditional-values/.tape.mjs rename to plugins/postcss-conditional-values/test/_tape.mjs index e1044f408..0f33d27d6 100644 --- a/plugins/postcss-conditional-values/.tape.mjs +++ b/plugins/postcss-conditional-values/test/_tape.mjs @@ -3,16 +3,16 @@ import plugin from '@csstools/postcss-conditional-values'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'default-false': { - message: "supports default false in :root{}", + message: 'supports default false in :root{}', }, 'pre-existing-false': { - message: "supports default false in :root{}", + message: 'supports default false in :root{}', }, 'complex': { - message: "supports complex usage", + message: 'supports complex usage', }, 'examples/example': { message: 'minimal example', @@ -20,7 +20,7 @@ postcssTape(plugin)({ 'examples/example-custom-function-name': { message: 'minimal example with { functionName: "if" }', options: { - functionName: 'if' - } + functionName: 'if', + }, }, }); diff --git a/plugins/postcss-custom-media/package.json b/plugins/postcss-custom-media/package.json index 1829c0a24..239cb4a8a 100644 --- a/plugins/postcss-custom-media/package.json +++ b/plugins/postcss-custom-media/package.json @@ -71,8 +71,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media#readme", "repository": { diff --git a/plugins/postcss-custom-media/.tape.mjs b/plugins/postcss-custom-media/test/_tape.mjs similarity index 67% rename from plugins/postcss-custom-media/.tape.mjs rename to plugins/postcss-custom-media/test/_tape.mjs index 422bd3209..d525540b5 100644 --- a/plugins/postcss-custom-media/.tape.mjs +++ b/plugins/postcss-custom-media/test/_tape.mjs @@ -3,13 +3,13 @@ import plugin from 'postcss-custom-media'; postcssTape(plugin)({ 'basic-after-v9': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic-after-v9:preserve': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic': { message: 'supports basic usage (old)', @@ -21,9 +21,9 @@ postcssTape(plugin)({ plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'cascade-layers': { message: 'supports cascade layers', @@ -34,8 +34,8 @@ postcssTape(plugin)({ 'examples/example:preserve': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, 'examples/true': { message: 'minimal example with "true"', @@ -47,13 +47,13 @@ postcssTape(plugin)({ message: 'minimal example complex queries', }, 'nesting': { - message: 'works when nested' + message: 'works when nested', }, 'not-processable': { - message: 'only handles processable @custom-media rules' + message: 'only handles processable @custom-media rules', }, 'parser-checks': { - message: 'supports more obscure CSS' + message: 'supports more obscure CSS', }, 'eof-1': { message: 'handles EOF correctly (1)', @@ -72,37 +72,37 @@ postcssTape(plugin)({ warnings: 1, }, 'complex': { - message: 'supports complex usage' + message: 'supports complex usage', }, 'cyclic': { message: 'handles cyclic references', warnings: 3, }, 'override': { - message: 'handles reference overrides' + message: 'handles reference overrides', }, 'modifiers': { - message: 'supports media query modifiers' + message: 'supports media query modifiers', }, 'list': { - message: 'supports media query lists' + message: 'supports media query lists', }, 'true-false': { - message: 'supports true|false keywords' + message: 'supports true|false keywords', }, 'comma-1': { - message: 'can correctly split media query lists' + message: 'can correctly split media query lists', }, 'comma-2': { - message: 'can correctly split media query lists' + message: 'can correctly split media query lists', }, 'and': { - message: 'supports media queries with "and"' + message: 'supports media queries with "and"', }, 'not': { - message: 'supports media queries with "not"' + message: 'supports media queries with "not"', }, 'or': { - message: 'supports media queries with "or"' - } + message: 'supports media queries with "or"', + }, }); diff --git a/plugins/postcss-custom-properties/package.json b/plugins/postcss-custom-properties/package.json index 4d9cb4fed..24007ccca 100644 --- a/plugins/postcss-custom-properties/package.json +++ b/plugins/postcss-custom-properties/package.json @@ -59,8 +59,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-properties#readme", "repository": { diff --git a/plugins/postcss-custom-properties/.tape.mjs b/plugins/postcss-custom-properties/test/_tape.mjs similarity index 75% rename from plugins/postcss-custom-properties/.tape.mjs rename to plugins/postcss-custom-properties/test/_tape.mjs index f45c80b5e..a53fecd7a 100644 --- a/plugins/postcss-custom-properties/.tape.mjs +++ b/plugins/postcss-custom-properties/test/_tape.mjs @@ -4,28 +4,28 @@ import postcssBundler from '@csstools/postcss-bundler'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'cascade-layers': { - message: 'supports cascade layers' + message: 'supports cascade layers', }, 'chained': { - message: 'supports chained variables' + message: 'supports chained variables', }, 'issue-838': { message: 'prevent regressions of https://github.com/csstools/postcss-plugins/issues/838', options: { - preserve: false - } + preserve: false, + }, }, 'specificity': { - message: 'supports different specificities of html and :root selectors' + message: 'supports different specificities of html and :root selectors', }, 'examples/example': { message: 'minimal example', @@ -33,11 +33,11 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example with { preserve: false }', options: { - preserve: false - } + preserve: false, + }, }, 'import': { message: 'supports "postcss-bundler"', - plugins: [postcssBundler(), plugin()] - } + plugins: [postcssBundler(), plugin()], + }, }); diff --git a/plugins/postcss-custom-selectors/package.json b/plugins/postcss-custom-selectors/package.json index 3492af6d6..77565eddf 100644 --- a/plugins/postcss-custom-selectors/package.json +++ b/plugins/postcss-custom-selectors/package.json @@ -74,8 +74,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-selectors#readme", "repository": { diff --git a/plugins/postcss-custom-selectors/.tape.mjs b/plugins/postcss-custom-selectors/test/_tape.mjs similarity index 77% rename from plugins/postcss-custom-selectors/.tape.mjs rename to plugins/postcss-custom-selectors/test/_tape.mjs index f6c6d883f..3d0e7a6e6 100644 --- a/plugins/postcss-custom-selectors/.tape.mjs +++ b/plugins/postcss-custom-selectors/test/_tape.mjs @@ -3,32 +3,32 @@ import plugin from 'postcss-custom-selectors'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'cascade-layers': { message: 'supports cascade layers', }, 'conditionals': { - message: 'handles conditional rules' + message: 'handles conditional rules', }, 'invalid-selector': { message: 'warns on invalid selectors', - warnings: 2 + warnings: 2, }, 'examples/example': { message: 'minimal example', @@ -36,13 +36,13 @@ postcssTape(plugin)({ 'examples/example:preserve': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, 'complex': { - message: 'supports complex usage' + message: 'supports complex usage', }, 'safety': { - message: 'supports safe tag ordering (.foo:--h1 becomes h1.foo instead of .fooh1)' + message: 'supports safe tag ordering (.foo:--h1 becomes h1.foo instead of .fooh1)', }, }); diff --git a/plugins/postcss-debug-logger/package.json b/plugins/postcss-debug-logger/package.json index c372d2fcb..183bdc4ea 100644 --- a/plugins/postcss-debug-logger/package.json +++ b/plugins/postcss-debug-logger/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-debug-logger#readme", "repository": { diff --git a/plugins/postcss-debug-logger/.tape.mjs b/plugins/postcss-debug-logger/test/_tape.mjs similarity index 53% rename from plugins/postcss-debug-logger/.tape.mjs rename to plugins/postcss-debug-logger/test/_tape.mjs index 4742cba87..c15b8f781 100644 --- a/plugins/postcss-debug-logger/.tape.mjs +++ b/plugins/postcss-debug-logger/test/_tape.mjs @@ -3,11 +3,7 @@ import plugin from '@csstools/postcss-debug-logger'; postcssTape(plugin)({ basic: { - message: "supports basic usage", - options: {} - }, - document: { - postcssSyntaxHTML: true, - message: "supports document usage", + message: 'supports basic usage', + options: {}, }, }); diff --git a/plugins/postcss-debug-logger/test/document.expect.html b/plugins/postcss-debug-logger/test/document.expect.html deleted file mode 100644 index 87d683cc9..000000000 --- a/plugins/postcss-debug-logger/test/document.expect.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/plugins/postcss-debug-logger/test/document.html b/plugins/postcss-debug-logger/test/document.html deleted file mode 100644 index 87d683cc9..000000000 --- a/plugins/postcss-debug-logger/test/document.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Document - - - -
- - diff --git a/plugins/postcss-design-tokens/package.json b/plugins/postcss-design-tokens/package.json index c130e792b..72c37499f 100644 --- a/plugins/postcss-design-tokens/package.json +++ b/plugins/postcss-design-tokens/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-design-tokens#readme", "repository": { diff --git a/plugins/postcss-design-tokens/.tape.mjs b/plugins/postcss-design-tokens/test/_tape.mjs similarity index 53% rename from plugins/postcss-design-tokens/.tape.mjs rename to plugins/postcss-design-tokens/test/_tape.mjs index 08de780a0..cea7acdd0 100644 --- a/plugins/postcss-design-tokens/.tape.mjs +++ b/plugins/postcss-design-tokens/test/_tape.mjs @@ -1,102 +1,101 @@ import { postcssTape } from '@csstools/postcss-tape'; import plugin from '@csstools/postcss-design-tokens'; import postcssBundler from '@csstools/postcss-bundler'; -import postcss from 'postcss'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', plugins: [ postcssBundler(), - plugin() + plugin(), ], - warnings: 1 + warnings: 1, }, 'at-rule': { - message: "supports at rules", + message: 'supports at rules', }, 'at-rule-error': { - message: "supports at rules", - warnings: 1 + message: 'supports at rules', + warnings: 1, }, 'units': { - message: "supports units usage", + message: 'supports units usage', plugins: [ - plugin() + plugin(), ], - warnings: 2 + warnings: 2, }, 'units:rootFontSize-20': { - message: "supports units usage with { unitsAndValues { rootFontSize: 20 } }", + message: 'supports units usage with { unitsAndValues { rootFontSize: 20 } }', plugins: [ plugin({ unitsAndValues: { - rootFontSize: 20 - } - }) + rootFontSize: 20, + }, + }), ], - warnings: 2 + warnings: 2, }, 'units:rootFontSize-NaN': { - message: "supports units usage with { unitsAndValues { rootFontSize: NaN } }", + message: 'supports units usage with { unitsAndValues { rootFontSize: NaN } }', plugins: [ plugin({ unitsAndValues: { - rootFontSize: NaN - } - }) + rootFontSize: NaN, + }, + }), ], - warnings: 2 + warnings: 2, }, 'units:rootFontSize-invalid': { - message: "supports units usage with { unitsAndValues { rootFontSize: invalid } }", + message: 'supports units usage with { unitsAndValues { rootFontSize: invalid } }', plugins: [ plugin({ unitsAndValues: { - rootFontSize: 'invalid' - } - }) + rootFontSize: 'invalid', + }, + }), ], - warnings: 2 + warnings: 2, }, 'errors': { - message: "handles issues correctly", + message: 'handles issues correctly', options: {}, - warnings: 4 + warnings: 4, }, 'is': { - message: "supports basic usage with { is ['dark', 'tablet', 'branded-green'] }", + message: 'supports basic usage with { is [\'dark\', \'tablet\', \'branded-green\'] }', options: { - is: ['dark', 'tablet', 'branded-green'] - } + is: ['dark', 'tablet', 'branded-green'], + }, }, 'value-parsing-a': { - message: "supports value parsing (A)", + message: 'supports value parsing (A)', }, 'value-parsing-b': { - message: "supports value parsing (B)", + message: 'supports value parsing (B)', }, 'value-parsing-c': { - message: "supports value parsing (C)", - warnings: 2 + message: 'supports value parsing (C)', + warnings: 2, }, 'value-parsing-d': { - message: "supports value parsing (D)", - warnings: 2 + message: 'supports value parsing (D)', + warnings: 2, }, 'value-parsing-e': { - message: "supports value parsing (E)", - warnings: 2 + message: 'supports value parsing (E)', + warnings: 2, }, 'value-parsing-f': { - message: "supports value parsing (F)", + message: 'supports value parsing (F)', }, 'value-parsing-g': { - message: "supports value parsing (G)", - warnings: 2 + message: 'supports value parsing (G)', + warnings: 2, }, 'imported-double-slash': { - message: "supports 'node_modules://'", + message: 'supports \'node_modules://\'', }, 'examples/example': { message: 'minimal example', @@ -109,31 +108,31 @@ postcssTape(plugin)({ 'examples/example-conditional:brand-2': { message: 'minimal example with conditional imports : brand-2', options: { - is: ['brand-2'] + is: ['brand-2'], }, }, 'examples/example:rootFontSize-20': { - message: "minimal example with { unitsAndValues { rootFontSize: 20 } }", + message: 'minimal example with { unitsAndValues { rootFontSize: 20 } }', options: { unitsAndValues: { - rootFontSize: 20 - } - } + rootFontSize: 20, + }, + }, }, 'examples/example-custom-value-function-name': { message: 'minimal example with { valueFunctionName: "token" }', options: { - valueFunctionName: 'token' - } + valueFunctionName: 'token', + }, }, 'examples/example-custom-import-at-rule-name': { message: 'minimal example with { importAtRuleName: "tokens" }', options: { - importAtRuleName: 'tokens' - } + importAtRuleName: 'tokens', + }, }, 'issue-583': { message: 'A meaningful error message is given and no stack overflow.', - warnings: 1 + warnings: 1, }, }); diff --git a/plugins/postcss-dir-pseudo-class/package.json b/plugins/postcss-dir-pseudo-class/package.json index 2e37d3845..ab3b88c30 100644 --- a/plugins/postcss-dir-pseudo-class/package.json +++ b/plugins/postcss-dir-pseudo-class/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-dir-pseudo-class#readme", "repository": { diff --git a/plugins/postcss-dir-pseudo-class/.tape.mjs b/plugins/postcss-dir-pseudo-class/test/_tape.mjs similarity index 56% rename from plugins/postcss-dir-pseudo-class/.tape.mjs rename to plugins/postcss-dir-pseudo-class/test/_tape.mjs index 6d7de825d..d8c25c17d 100644 --- a/plugins/postcss-dir-pseudo-class/.tape.mjs +++ b/plugins/postcss-dir-pseudo-class/test/_tape.mjs @@ -3,31 +3,31 @@ import plugin from 'postcss-dir-pseudo-class'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', warnings: 2, }, - "basic:dir": { + 'basic:dir': { message: 'supports { dir: "ltr" } usage', - source: "basic.css", + source: 'basic.css', warnings: 2, options: { - dir: "ltr", + dir: 'ltr', }, }, - "basic:preserve": { - message: "supports { preserve: true } usage", - source: "basic.css", + 'basic:preserve': { + message: 'supports { preserve: true } usage', + source: 'basic.css', warnings: 2, options: { preserve: true, }, }, - "basic:shadow": { - message: "support { shadow: true } usage", - source: "basic.css", + 'basic:shadow': { + message: 'support { shadow: true } usage', + source: 'basic.css', warnings: 2, options: { - shadow: true + shadow: true, }, }, 'basic:with-cloned-declarations': { @@ -36,42 +36,42 @@ postcssTape(plugin)({ plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-selector-cases': { message: 'correctly handles generated cases', warnings: 38, options: { - preserve: false - } + preserve: false, + }, }, 'examples/example': { - message: "supports examples", + message: 'supports examples', }, 'examples/example:preserve-true': { - message: "supports examples with { preserve: true }", + message: 'supports examples with { preserve: true }', options: { - preserve: true + preserve: true, }, }, 'examples/example:shadow-true': { - message: "supports examples with { shadow: true }", + message: 'supports examples with { shadow: true }', options: { - shadow: true + shadow: true, }, }, 'examples/example:dir-ltr': { - message: "supports examples with { dir: 'ltr' }", + message: 'supports examples with { dir: \'ltr\' }', options: { - dir: 'ltr' + dir: 'ltr', }, }, 'examples/example:dir-rtl': { - message: "supports examples with { dir: 'rtl' }", + message: 'supports examples with { dir: \'rtl\' }', options: { - dir: 'rtl' + dir: 'rtl', }, }, }); diff --git a/plugins/postcss-double-position-gradients/package.json b/plugins/postcss-double-position-gradients/package.json index df6cbc452..d58f4ea29 100644 --- a/plugins/postcss-double-position-gradients/package.json +++ b/plugins/postcss-double-position-gradients/package.json @@ -52,8 +52,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-double-position-gradients#readme", "repository": { diff --git a/plugins/postcss-double-position-gradients/.tape.mjs b/plugins/postcss-double-position-gradients/test/_tape.mjs similarity index 79% rename from plugins/postcss-double-position-gradients/.tape.mjs rename to plugins/postcss-double-position-gradients/test/_tape.mjs index 55d04fbd1..40eff6541 100644 --- a/plugins/postcss-double-position-gradients/.tape.mjs +++ b/plugins/postcss-double-position-gradients/test/_tape.mjs @@ -3,31 +3,31 @@ import plugin from 'postcss-double-position-gradients'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve': { message: 'supports { preserve: false } usage', - options: { preserve: false } + options: { preserve: false }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-value-cases': { message: 'correctly handles generated cases', options: { - preserve: false - } + preserve: false, + }, }, 'generated-value-cases:preserve': { message: 'correctly handles generated cases', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-env-function/package.json b/plugins/postcss-env-function/package.json index e550a775b..3e692b790 100644 --- a/plugins/postcss-env-function/package.json +++ b/plugins/postcss-env-function/package.json @@ -46,8 +46,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.cjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.cjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-env-function#readme", "repository": { diff --git a/plugins/postcss-env-function/.tape.cjs b/plugins/postcss-env-function/test/_tape.cjs similarity index 75% rename from plugins/postcss-env-function/.tape.cjs rename to plugins/postcss-env-function/test/_tape.cjs index 99f4630bb..0b5a2f098 100644 --- a/plugins/postcss-env-function/.tape.cjs +++ b/plugins/postcss-env-function/test/_tape.cjs @@ -12,10 +12,10 @@ postcssTape.postcssTape(plugin)({ importFrom: { environmentVariables: { '--some-custom-padding': '20px', - '--another-custom-width': '600px' - } - } - } + '--another-custom-width': '600px', + }, + }, + }, }, 'basic:import-fn': { message: 'supports { importFrom() } usage', @@ -25,13 +25,13 @@ postcssTape.postcssTape(plugin)({ return { environmentVariables: { '--some-custom-padding': '20px', - '--another-custom-width': '600px' - } + '--another-custom-width': '600px', + }, }; - } + }, }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-fn-promise': { message: 'supports { async importFrom() } usage', @@ -42,64 +42,64 @@ postcssTape.postcssTape(plugin)({ resolve({ environmentVariables: { '--some-custom-padding': '20px', - '--another-custom-width': '600px' - } - }) + '--another-custom-width': '600px', + }, + }); }); - } + }, }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-json': { message: 'supports { importFrom: "test/import-variables.json" } usage', warnings: 1, options: { - importFrom: 'test/import-variables.json' + importFrom: 'test/import-variables.json', }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-js': { message: 'supports { importFrom: "test/import-variables.js" } usage', warnings: 1, options: { - importFrom: 'test/import-variables.js' + importFrom: 'test/import-variables.js', }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-cjs': { message: 'supports { importFrom: "test/import-variables.cjs" } usage', warnings: 1, options: { - importFrom: 'test/import-variables.cjs' + importFrom: 'test/import-variables.cjs', }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-js-from': { message: 'supports { importFrom: { from: "test/import-variables.js" } } usage', warnings: 1, options: { - importFrom: { from: 'test/import-variables.js' } + importFrom: { from: 'test/import-variables.js' }, }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-js-from-type': { message: 'supports { importFrom: [ { from: "test/import-variables.js", type: "js" } ] } usage', warnings: 1, options: { - importFrom: [ { from: 'test/import-variables.js', type: 'js' } ] + importFrom: [ { from: 'test/import-variables.js', type: 'js' } ], }, expect: 'basic.import.expect.css', - result: 'basic.import.result.css' + result: 'basic.import.result.css', }, 'basic:import-is-empty': { message: 'supports { importFrom: {} } usage', options: { - importFrom: {} - } - } + importFrom: {}, + }, + }, }); diff --git a/plugins/postcss-exponential-functions/package.json b/plugins/postcss-exponential-functions/package.json index c70d1caa5..a7b618684 100644 --- a/plugins/postcss-exponential-functions/package.json +++ b/plugins/postcss-exponential-functions/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-exponential-functions#readme", "repository": { diff --git a/plugins/postcss-exponential-functions/.tape.mjs b/plugins/postcss-exponential-functions/test/_tape.mjs similarity index 74% rename from plugins/postcss-exponential-functions/.tape.mjs rename to plugins/postcss-exponential-functions/test/_tape.mjs index 8d4b93cd7..bb5fb1919 100644 --- a/plugins/postcss-exponential-functions/.tape.mjs +++ b/plugins/postcss-exponential-functions/test/_tape.mjs @@ -3,13 +3,13 @@ import plugin from '@csstools/postcss-exponential-functions'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve': { - message: "supports basic usage", + message: 'supports basic usage', options: { - preserve: true - } + preserve: true, + }, }, 'examples/example': { message: 'minimal example', @@ -17,7 +17,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-extract/package.json b/plugins/postcss-extract/package.json index 90039d989..5b48d6544 100644 --- a/plugins/postcss-extract/package.json +++ b/plugins/postcss-extract/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-extract#readme", "repository": { diff --git a/plugins/postcss-extract/.tape.mjs b/plugins/postcss-extract/test/_tape.mjs similarity index 72% rename from plugins/postcss-extract/.tape.mjs rename to plugins/postcss-extract/test/_tape.mjs index 9e96b872d..310f13739 100644 --- a/plugins/postcss-extract/.tape.mjs +++ b/plugins/postcss-extract/test/_tape.mjs @@ -4,11 +4,11 @@ import assert from 'assert'; postcssTape(plugin)({ 'variables': { - message: "Can extract custom props from root", + message: 'Can extract custom props from root', options: { queries: { 'custom-props-in-root': 'rule[selector*=":ROOT" i] decl[variable]', - 'not-variable': 'decl:not([variable])' + 'not-variable': 'decl:not([variable])', }, results: function(results) { assert.deepStrictEqual( @@ -19,11 +19,11 @@ postcssTape(plugin)({ type: 'decl', prop: '--bar', value: 'calc(1px * 100)', - variable: true + variable: true, }, - { type: 'decl', prop: '--baz', value: '"a value"', variable: true } - ] - ) + { type: 'decl', prop: '--baz', value: '"a value"', variable: true }, + ], + ); assert.deepStrictEqual( results['not-variable'], @@ -32,34 +32,34 @@ postcssTape(plugin)({ type: 'decl', prop: 'not-a-variable', value: '1', - variable: false - } - ] - ) - } - } + variable: false, + }, + ], + ); + }, + }, }, 'variables:adjacent-sibling': { - message: "Respects adjacent siblings", + message: 'Respects adjacent siblings', options: { queries: { - 'adjacent-sibling': 'comment[text="extract only this one"] + decl[variable]' + 'adjacent-sibling': 'comment[text="extract only this one"] + decl[variable]', }, results: function (results) { assert.deepStrictEqual( results, { - 'adjacent-sibling': [{ type: 'decl', prop: '--foo', value: '1', variable: true }] - } - ) - } - } + 'adjacent-sibling': [{ type: 'decl', prop: '--foo', value: '1', variable: true }], + }, + ); + }, + }, }, 'variables:adjacent-sibling-with-not': { - message: "Respects adjacent siblings and supports :not", + message: 'Respects adjacent siblings and supports :not', options: { queries: { - 'adjacent-sibling': 'rule[selector*=":root"] :not([selector*=":root"] comment[text="extract only this one"]) + decl[variable]' + 'adjacent-sibling': 'rule[selector*=":root"] :not([selector*=":root"] comment[text="extract only this one"]) + decl[variable]', }, results: function (results) { assert.deepStrictEqual( @@ -70,19 +70,19 @@ postcssTape(plugin)({ type: 'decl', prop: '--bar', value: 'calc(1px * 100)', - variable: true - } - ] - } - ) - } - } + variable: true, + }, + ], + }, + ); + }, + }, }, 'media': { - message: "At rules : media", + message: 'At rules : media', options: { queries: { - 'media': 'atrule[name=media]' + 'media': 'atrule[name=media]', }, results: function (results) { assert.deepStrictEqual( @@ -92,19 +92,19 @@ postcssTape(plugin)({ { type: 'atrule', name: 'media', - params: '(prefers-color-scheme: dark)' - } - ] - } - ) - } - } + params: '(prefers-color-scheme: dark)', + }, + ], + }, + ); + }, + }, }, 'media:custom-media': { - message: "At rules : custom-media", + message: 'At rules : custom-media', options: { queries: { - 'media': 'atrule[name=custom-media]' + 'media': 'atrule[name=custom-media]', }, results: function (results) { assert.deepStrictEqual( @@ -114,19 +114,19 @@ postcssTape(plugin)({ { type: 'atrule', name: 'custom-media', - params: 'screen and (min-width: 300px)' - } - ] - } - ) - } - } + params: 'screen and (min-width: 300px)', + }, + ], + }, + ); + }, + }, }, 'mixed': { - message: "Mixed results", + message: 'Mixed results', options: { queries: { - 'mixed-results': '[name=supports], [value=red]' + 'mixed-results': '[name=supports], [value=red]', }, results: function (results) { assert.deepStrictEqual( @@ -134,18 +134,18 @@ postcssTape(plugin)({ { 'mixed-results': [ { type: 'atrule', name: 'supports', params: '(display: grid)' }, - { type: 'decl', prop: '--color', value: 'red', variable: true } - ] + { type: 'decl', prop: '--color', value: 'red', variable: true }, + ], }, - ) - } - } + ); + }, + }, }, 'mixed:alpha': { - message: "Mixed results : *", + message: 'Mixed results : *', options: { queries: { - 'mixed-results': '*' + 'mixed-results': '*', }, results: function (results) { assert.deepStrictEqual( @@ -154,7 +154,7 @@ postcssTape(plugin)({ 'mixed-results': [ { type: 'rule', - selectors: ['.a-selector', 'another-selector'] + selectors: ['.a-selector', 'another-selector'], }, { type: 'decl', prop: 'order', value: '1', variable: false }, { type: 'decl', prop: '--color', value: 'red', variable: true }, @@ -166,28 +166,28 @@ postcssTape(plugin)({ type: 'decl', prop: 'color', value: 'var(--color)', - variable: false - } - ] + variable: false, + }, + ], }, - ) - } - } + ); + }, + }, }, 'mixed:beta': { - message: "Mixed results : * ~ * > *", + message: 'Mixed results : * ~ * > *', options: { queries: { - 'mixed-results': '* ~ * > *' + 'mixed-results': '* ~ * > *', }, results: function (results) { assert.deepStrictEqual( results, { - 'mixed-results': [{ type: 'rule', selectors: ['[more=selectors]'] }] + 'mixed-results': [{ type: 'rule', selectors: ['[more=selectors]'] }], }, - ) - } - } + ); + }, + }, }, }); diff --git a/plugins/postcss-focus-visible/package.json b/plugins/postcss-focus-visible/package.json index fe37e90a4..c050c9d54 100644 --- a/plugins/postcss-focus-visible/package.json +++ b/plugins/postcss-focus-visible/package.json @@ -62,9 +62,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-visible#readme", "repository": { diff --git a/plugins/postcss-focus-visible/test/_browser.mjs b/plugins/postcss-focus-visible/test/_browser.mjs index 7ae197c3d..d3452ed84 100644 --- a/plugins/postcss-focus-visible/test/_browser.mjs +++ b/plugins/postcss-focus-visible/test/_browser.mjs @@ -2,38 +2,47 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; + +const requestListener = async function (req, res) { + + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; + + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/test/browser.expect.css': + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; -(async () => { - const requestListener = async function (req, res) { - - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; - - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/test/browser.expect.css': - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; - - // Use different servers for HTML/CSS/JS to trigger CORS +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -90,8 +99,10 @@ import { promises as fsp } from 'fs'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-focus-visible/.tape.mjs b/plugins/postcss-focus-visible/test/_tape.mjs similarity index 77% rename from plugins/postcss-focus-visible/.tape.mjs rename to plugins/postcss-focus-visible/test/_tape.mjs index 099890c00..8497d4dd2 100644 --- a/plugins/postcss-focus-visible/.tape.mjs +++ b/plugins/postcss-focus-visible/test/_tape.mjs @@ -3,41 +3,41 @@ import plugin from 'postcss-focus-visible'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:replacewith': { message: 'supports { replaceWith: "[focus-visible]" } usage', options: { - replaceWith: '[data-focus-visible-added]' - } + replaceWith: '[data-focus-visible-added]', + }, }, 'basic:disable-polyfill-ready-class': { message: 'supports { disablePolyfillReadyClass: true } usage', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, 'basic:preserve': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-selector-cases': { message: 'correctly handles generated cases', warnings: 1, options: { - preserve: false - } + preserve: false, + }, }, 'browser': { message: 'css for browser tests', @@ -48,19 +48,19 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'examples/example:replacewith': { message: 'minimal example', options: { - replaceWith: '[focus-visible]' - } + replaceWith: '[focus-visible]', + }, }, 'examples/example:disable-polyfill-ready-class': { message: 'minimal example', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, }); diff --git a/plugins/postcss-focus-within/package.json b/plugins/postcss-focus-within/package.json index f4d996028..adf88877d 100644 --- a/plugins/postcss-focus-within/package.json +++ b/plugins/postcss-focus-within/package.json @@ -74,9 +74,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme", "repository": { diff --git a/plugins/postcss-focus-within/test/_browser.mjs b/plugins/postcss-focus-within/test/_browser.mjs index 04d0be059..5e067449b 100644 --- a/plugins/postcss-focus-within/test/_browser.mjs +++ b/plugins/postcss-focus-within/test/_browser.mjs @@ -2,53 +2,62 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; + +const requestListener = async function (req, res) { + + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; + + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/test/browser.expect.css': + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + case '/dist/browser-global.js': + res.setHeader('Content-type', 'text/javascript'); + res.writeHead(200); + res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); + break; + case '/replace-with': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser_replace.html', 'utf8')); + break; + case '/test/browser.replacewith.expect.css': + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(await fsp.readFile('test/browser.replacewith.expect.css', 'utf8')); + break; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; -(async () => { - const requestListener = async function (req, res) { - - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; - - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/test/browser.expect.css': - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - case '/dist/browser-global.js': - res.setHeader('Content-type', 'text/javascript'); - res.writeHead(200); - res.end(await fsp.readFile('dist/browser-global.js', 'utf8')); - break; - case '/replace-with': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser_replace.html', 'utf8')); - break; - case '/test/browser.replacewith.expect.css': - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(await fsp.readFile('test/browser.replacewith.expect.css', 'utf8')); - break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; - - // Use different servers for HTML/CSS/JS to trigger CORS +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -153,8 +162,10 @@ import { promises as fsp } from 'fs'; } await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-focus-within/.tape.mjs b/plugins/postcss-focus-within/test/_tape.mjs similarity index 92% rename from plugins/postcss-focus-within/.tape.mjs rename to plugins/postcss-focus-within/test/_tape.mjs index de736301f..371505f85 100644 --- a/plugins/postcss-focus-within/.tape.mjs +++ b/plugins/postcss-focus-within/test/_tape.mjs @@ -14,8 +14,8 @@ postcssTape(plugin)({ 'basic:disable-polyfill-ready-class': { message: 'supports { disablePolyfillReadyClass: true } usage', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, 'basic:preserve': { message: 'supports { preserve: false } usage', @@ -28,9 +28,9 @@ postcssTape(plugin)({ plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-selector-cases': { message: 'correctly handles generated cases', @@ -54,8 +54,8 @@ postcssTape(plugin)({ 'examples/example:disable-polyfill-ready-class': { message: 'minimal example', options: { - disablePolyfillReadyClass: true - } + disablePolyfillReadyClass: true, + }, }, 'browser': { message: 'css for browser tests', diff --git a/plugins/postcss-font-format-keywords/package.json b/plugins/postcss-font-format-keywords/package.json index 7019e3551..df8f0fa76 100644 --- a/plugins/postcss-font-format-keywords/package.json +++ b/plugins/postcss-font-format-keywords/package.json @@ -51,8 +51,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-font-format-keywords#readme", "repository": { diff --git a/plugins/postcss-font-format-keywords/.tape.mjs b/plugins/postcss-font-format-keywords/test/_tape.mjs similarity index 88% rename from plugins/postcss-font-format-keywords/.tape.mjs rename to plugins/postcss-font-format-keywords/test/_tape.mjs index 9131d71cf..747b40b64 100644 --- a/plugins/postcss-font-format-keywords/.tape.mjs +++ b/plugins/postcss-font-format-keywords/test/_tape.mjs @@ -8,16 +8,16 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ atRuleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, }); diff --git a/plugins/postcss-gamut-mapping/package.json b/plugins/postcss-gamut-mapping/package.json index 6339d4ecb..8d81e2f9e 100644 --- a/plugins/postcss-gamut-mapping/package.json +++ b/plugins/postcss-gamut-mapping/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gamut-mapping#readme", "repository": { diff --git a/plugins/postcss-gamut-mapping/.tape.mjs b/plugins/postcss-gamut-mapping/test/_tape.mjs similarity index 85% rename from plugins/postcss-gamut-mapping/.tape.mjs rename to plugins/postcss-gamut-mapping/test/_tape.mjs index 99dbd92cc..73a5c34d0 100644 --- a/plugins/postcss-gamut-mapping/.tape.mjs +++ b/plugins/postcss-gamut-mapping/test/_tape.mjs @@ -3,7 +3,7 @@ import plugin from '@csstools/postcss-gamut-mapping'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'examples/example': { message: 'minimal example', diff --git a/plugins/postcss-gap-properties/package.json b/plugins/postcss-gap-properties/package.json index a76df2c42..06e14b0ad 100644 --- a/plugins/postcss-gap-properties/package.json +++ b/plugins/postcss-gap-properties/package.json @@ -62,8 +62,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gap-properties#readme", "repository": { diff --git a/plugins/postcss-gap-properties/.tape.mjs b/plugins/postcss-gap-properties/test/_tape.mjs similarity index 71% rename from plugins/postcss-gap-properties/.tape.mjs rename to plugins/postcss-gap-properties/test/_tape.mjs index 9714f7824..1ec6f97a9 100644 --- a/plugins/postcss-gap-properties/.tape.mjs +++ b/plugins/postcss-gap-properties/test/_tape.mjs @@ -3,19 +3,19 @@ import plugin from 'postcss-gap-properties'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve-false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'ignore-flexbox': { - message: 'ignore flexbox declarations' + message: 'ignore flexbox declarations', }, 'ignore-multicolumn': { - message: 'ignore multi column declarations' + message: 'ignore multi column declarations', }, 'examples/example': { message: 'minimal example', @@ -23,7 +23,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-global-data/package.json b/plugins/postcss-global-data/package.json index ca1e6148c..5c0d23013 100644 --- a/plugins/postcss-global-data/package.json +++ b/plugins/postcss-global-data/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-global-data#readme", "repository": { diff --git a/plugins/postcss-global-data/.tape.mjs b/plugins/postcss-global-data/test/_tape.mjs similarity index 87% rename from plugins/postcss-global-data/.tape.mjs rename to plugins/postcss-global-data/test/_tape.mjs index 87b0ac622..752e91197 100644 --- a/plugins/postcss-global-data/.tape.mjs +++ b/plugins/postcss-global-data/test/_tape.mjs @@ -5,24 +5,24 @@ import postcssCustomProperties from 'postcss-custom-properties'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', plugins: [ plugin({ files: [ './test/fixtures/fixture.css', - ] + ], }), postcssCustomMedia(), ], }, 'open-props': { - message: "supports open-props usage", + message: 'supports open-props usage', plugins: [ plugin({ files: [ 'node_modules:open-props/media.min.css', 'node_modules://open-props/open-props.min.css', - ] + ], }), postcssCustomProperties({ preserve: false }), postcssCustomMedia({ preserve: false }), diff --git a/plugins/postcss-gradients-interpolation-method/package.json b/plugins/postcss-gradients-interpolation-method/package.json index 9ef584423..07f2387bd 100644 --- a/plugins/postcss-gradients-interpolation-method/package.json +++ b/plugins/postcss-gradients-interpolation-method/package.json @@ -54,8 +54,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method#readme", "repository": { diff --git a/plugins/postcss-gradients-interpolation-method/.tape.mjs b/plugins/postcss-gradients-interpolation-method/test/_tape.mjs similarity index 88% rename from plugins/postcss-gradients-interpolation-method/.tape.mjs rename to plugins/postcss-gradients-interpolation-method/test/_tape.mjs index 526638452..30b22776d 100644 --- a/plugins/postcss-gradients-interpolation-method/.tape.mjs +++ b/plugins/postcss-gradients-interpolation-method/test/_tape.mjs @@ -3,22 +3,22 @@ import plugin from '@csstools/postcss-gradients-interpolation-method'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -26,8 +26,8 @@ postcssTape(plugin)({ 'variables:preserve-false': { message: 'supports variables with { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'variables:preserve-true': { message: 'supports { preserve: true, enableProgressiveCustomProperties: true } usage', @@ -37,7 +37,7 @@ postcssTape(plugin)({ options: { preserve: true, enableProgressiveCustomProperties: false, - } + }, }, 'examples/example': { message: 'minimal example', @@ -45,13 +45,13 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'examples/example:progressive-false': { message: 'minimal example', options: { enableProgressiveCustomProperties: false, - } - } + }, + }, }); diff --git a/plugins/postcss-hwb-function/package.json b/plugins/postcss-hwb-function/package.json index 32e49e6f1..cacffe921 100644 --- a/plugins/postcss-hwb-function/package.json +++ b/plugins/postcss-hwb-function/package.json @@ -54,8 +54,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-hwb-function#readme", "repository": { diff --git a/plugins/postcss-hwb-function/.tape.mjs b/plugins/postcss-hwb-function/test/_tape.mjs similarity index 88% rename from plugins/postcss-hwb-function/.tape.mjs rename to plugins/postcss-hwb-function/test/_tape.mjs index 8deaa9c07..dd405cf26 100644 --- a/plugins/postcss-hwb-function/.tape.mjs +++ b/plugins/postcss-hwb-function/test/_tape.mjs @@ -8,17 +8,17 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports basic usage with { preserve: true }', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -26,7 +26,7 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-ic-unit/package.json b/plugins/postcss-ic-unit/package.json index 9f369d0ba..2a32b86c9 100644 --- a/plugins/postcss-ic-unit/package.json +++ b/plugins/postcss-ic-unit/package.json @@ -52,8 +52,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-ic-unit#readme", "repository": { diff --git a/plugins/postcss-ic-unit/.tape.mjs b/plugins/postcss-ic-unit/test/_tape.mjs similarity index 86% rename from plugins/postcss-ic-unit/.tape.mjs rename to plugins/postcss-ic-unit/test/_tape.mjs index 69b166af2..f110ad538 100644 --- a/plugins/postcss-ic-unit/.tape.mjs +++ b/plugins/postcss-ic-unit/test/_tape.mjs @@ -3,22 +3,22 @@ import plugin from '@csstools/postcss-ic-unit'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -26,14 +26,14 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'variables:preserve-true:progressive-false': { message: 'supports variables with { preserve: true, enableProgressiveCustomProperties: false } usage', options: { preserve: true, enableProgressiveCustomProperties: false, - } + }, }, }); diff --git a/plugins/postcss-image-set-function/package.json b/plugins/postcss-image-set-function/package.json index acea78f63..108f84257 100644 --- a/plugins/postcss-image-set-function/package.json +++ b/plugins/postcss-image-set-function/package.json @@ -51,8 +51,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-image-set-function#readme", "repository": { diff --git a/plugins/postcss-image-set-function/.tape.mjs b/plugins/postcss-image-set-function/test/_tape.mjs similarity index 81% rename from plugins/postcss-image-set-function/.tape.mjs rename to plugins/postcss-image-set-function/test/_tape.mjs index df5789adb..c4e8c7472 100644 --- a/plugins/postcss-image-set-function/.tape.mjs +++ b/plugins/postcss-image-set-function/test/_tape.mjs @@ -8,51 +8,51 @@ postcssTape(plugin)({ 'basic:no-preserve': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'invalid': { message: 'ignores invalid usage', expect: 'invalid.css', - result: 'invalid.css' + result: 'invalid.css', }, 'invalid:warn': { message: 'warns invalid usage when { onvalid: "warn" }', options: { - onInvalid: 'warn' + onInvalid: 'warn', }, expect: 'invalid.css', result: 'invalid.css', - warnings: 9 + warnings: 9, }, 'invalid:throw': { message: 'throws invalid usage when { onvalid: "throw" }', options: { - onInvalid: 'throw' + onInvalid: 'throw', }, expect: 'invalid.css', result: 'invalid.css', - exception: /unexpected image/ + exception: /unexpected image/, }, 'generated-value-cases': { message: 'correctly handles generated cases', options: { - preserve: false - } + preserve: false, + }, }, 'generated-value-cases:preserve': { message: 'correctly handles generated cases', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-initial/package.json b/plugins/postcss-initial/package.json index 79ccd4b79..81263d162 100644 --- a/plugins/postcss-initial/package.json +++ b/plugins/postcss-initial/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-initial#readme", "repository": { diff --git a/plugins/postcss-initial/.tape.mjs b/plugins/postcss-initial/test/_tape.mjs similarity index 66% rename from plugins/postcss-initial/.tape.mjs rename to plugins/postcss-initial/test/_tape.mjs index ec382e9f6..2e9da8a8e 100644 --- a/plugins/postcss-initial/.tape.mjs +++ b/plugins/postcss-initial/test/_tape.mjs @@ -3,40 +3,40 @@ import plugin from '@csstools/postcss-initial'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'all-initial-default': { - message: "all default", + message: 'all default', }, 'combined:preserve-false': { - message: "combined", + message: 'combined', options: { preserve: false, - } + }, }, 'combined': { - message: "combined" + message: 'combined', }, 'multivalue': { - message: "multi value" + message: 'multi value', }, 'negative': { - message: "negative" + message: 'negative', }, 'no-duplication': { - message: "no duplication" + message: 'no duplication', }, 'simple:preserve-false': { - message: "simple", + message: 'simple', options: { preserve: false, - } + }, }, 'simple': { - message: "simple" + message: 'simple', }, 'unknown': { - message: "unknown" + message: 'unknown', }, 'examples/example': { message: 'minimal example', @@ -44,7 +44,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-is-pseudo-class/.tape.mjs b/plugins/postcss-is-pseudo-class/.tape.mjs deleted file mode 100644 index a3ef0c8fc..000000000 --- a/plugins/postcss-is-pseudo-class/.tape.mjs +++ /dev/null @@ -1,77 +0,0 @@ -import { declarationClonerPlugin, postcssTape } from '@csstools/postcss-tape'; -import plugin from '@csstools/postcss-is-pseudo-class'; - -postcssTape(plugin)({ - basic: { - message: "supports basic usage", - }, - 'basic:preserve': { - message: "supports basic usage with { preserve: true }", - options: { - preserve: true - } - }, - 'basic:does-not-exist': { - message: "supports basic usage with { specificityMatchingName: 'something-random' }", - options: { - specificityMatchingName: 'something-random' - } - }, - 'basic:oncomplex:warning': { - message: "warns on complex selectors", - warnings: 9, - options: { - onComplexSelector: 'warning' - } - }, - 'basic:oncomplex:no-warning': { - message: "can silence warnings on complex selectors", - }, - 'basic:with-cloned-declarations': { - message: 'doesn\'t cause duplicate CSS', - plugins: [ - declarationClonerPlugin, - plugin({ - preserve: true - }) - ] - }, - 'browser': { - message: "prepare CSS for chrome test", - options: { - preserve: false - } - }, - 'compound-after-complex-is': { - message: "can handle compound selectors after complex selectors in :is()", - options: { - preserve: false - } - }, - 'complex': { - message: "supports complex selectors", - options: { - preserve: false - } - }, - 'generated-selector-class-function-cases': { - message: "supports generated selector class function cases", - warnings: 1, - options: { - preserve: true - } - }, - example: { - message: "minimal example", - }, - 'pseudo-element:warning': { - message: "warns when pseudo elements are found", - warnings: 4, - options: { - onPseudoElement: 'warning' - } - }, - 'pseudo-element:no-warning': { - message: "can silence warnings when pseudo elements are found", - }, -}); diff --git a/plugins/postcss-is-pseudo-class/package.json b/plugins/postcss-is-pseudo-class/package.json index 035230997..2871ed245 100644 --- a/plugins/postcss-is-pseudo-class/package.json +++ b/plugins/postcss-is-pseudo-class/package.json @@ -53,9 +53,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-is-pseudo-class#readme", "repository": { diff --git a/plugins/postcss-is-pseudo-class/test/_browser.mjs b/plugins/postcss-is-pseudo-class/test/_browser.mjs index 5dd796c3a..381f69242 100644 --- a/plugins/postcss-is-pseudo-class/test/_browser.mjs +++ b/plugins/postcss-is-pseudo-class/test/_browser.mjs @@ -1,36 +1,46 @@ import puppeteer from 'puppeteer'; import http from 'http'; import { promises as fsp } from 'fs'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { - - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; - - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test/_browser.html', 'utf8')); - break; - case '/test/browser.expect.css': - res.writeHead(200); - res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); - break; - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); - break; - } - }; +const requestListener = async function (req, res) { + + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; + + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test/_browser.html', 'utf8')); + break; + case '/test/browser.expect.css': + res.writeHead(200); + res.end(await fsp.readFile('test/browser.expect.css', 'utf8')); + break; + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -40,7 +50,7 @@ import { promises as fsp } from 'fs'; throw msg; }); await page.goto('http://localhost:8080'); - const result = await page.evaluate(async() => { + const result = await page.evaluate(async () => { // eslint-disable-next-line no-undef return await window.runTest(); }); @@ -50,8 +60,10 @@ import { promises as fsp } from 'fs'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-is-pseudo-class/test/_tape.mjs b/plugins/postcss-is-pseudo-class/test/_tape.mjs new file mode 100644 index 000000000..649a4054f --- /dev/null +++ b/plugins/postcss-is-pseudo-class/test/_tape.mjs @@ -0,0 +1,77 @@ +import { declarationClonerPlugin, postcssTape } from '@csstools/postcss-tape'; +import plugin from '@csstools/postcss-is-pseudo-class'; + +postcssTape(plugin)({ + basic: { + message: 'supports basic usage', + }, + 'basic:preserve': { + message: 'supports basic usage with { preserve: true }', + options: { + preserve: true, + }, + }, + 'basic:does-not-exist': { + message: 'supports basic usage with { specificityMatchingName: \'something-random\' }', + options: { + specificityMatchingName: 'something-random', + }, + }, + 'basic:oncomplex:warning': { + message: 'warns on complex selectors', + warnings: 9, + options: { + onComplexSelector: 'warning', + }, + }, + 'basic:oncomplex:no-warning': { + message: 'can silence warnings on complex selectors', + }, + 'basic:with-cloned-declarations': { + message: 'doesn\'t cause duplicate CSS', + plugins: [ + declarationClonerPlugin, + plugin({ + preserve: true, + }), + ], + }, + 'browser': { + message: 'prepare CSS for chrome test', + options: { + preserve: false, + }, + }, + 'compound-after-complex-is': { + message: 'can handle compound selectors after complex selectors in :is()', + options: { + preserve: false, + }, + }, + 'complex': { + message: 'supports complex selectors', + options: { + preserve: false, + }, + }, + 'generated-selector-class-function-cases': { + message: 'supports generated selector class function cases', + warnings: 1, + options: { + preserve: true, + }, + }, + example: { + message: 'minimal example', + }, + 'pseudo-element:warning': { + message: 'warns when pseudo elements are found', + warnings: 4, + options: { + onPseudoElement: 'warning', + }, + }, + 'pseudo-element:no-warning': { + message: 'can silence warnings when pseudo elements are found', + }, +}); diff --git a/plugins/postcss-lab-function/package.json b/plugins/postcss-lab-function/package.json index 577bdb5db..9d664e9a1 100644 --- a/plugins/postcss-lab-function/package.json +++ b/plugins/postcss-lab-function/package.json @@ -54,8 +54,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-lab-function#readme", "repository": { diff --git a/plugins/postcss-lab-function/.tape.mjs b/plugins/postcss-lab-function/test/_tape.mjs similarity index 83% rename from plugins/postcss-lab-function/.tape.mjs rename to plugins/postcss-lab-function/test/_tape.mjs index 1f6299eb8..c334d27ee 100644 --- a/plugins/postcss-lab-function/.tape.mjs +++ b/plugins/postcss-lab-function/test/_tape.mjs @@ -8,34 +8,34 @@ postcssTape(plugin)({ 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:display-p3-false': { message: 'supports { subFeatures: { displayP3: false } } usage', options: { subFeatures: { - displayP3: false - } - } + displayP3: false, + }, + }, }, 'basic:display-p3-false:preserve-true': { message: 'supports { subFeatures: { displayP3: false }, preserve: true } usage', options: { subFeatures: { - displayP3: false + displayP3: false, }, - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'variables': { message: 'supports variables', @@ -43,24 +43,24 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'variables:display-p3-false': { message: 'supports variables with { displayP3: false } usage', options: { subFeatures: { - displayP3: false - } - } + displayP3: false, + }, + }, }, 'variables:display-p3-false:preserve-true': { message: 'supports variables with { subFeatures: { displayP3: false }, preserve: true } usage', options: { subFeatures: { - displayP3: false + displayP3: false, }, - preserve: true - } - } + preserve: true, + }, + }, }); diff --git a/plugins/postcss-logical-float-and-clear/package.json b/plugins/postcss-logical-float-and-clear/package.json index a10dd9641..ce8c7f80e 100644 --- a/plugins/postcss-logical-float-and-clear/package.json +++ b/plugins/postcss-logical-float-and-clear/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical-float-and-clear#readme", "repository": { diff --git a/plugins/postcss-logical-float-and-clear/.tape.mjs b/plugins/postcss-logical-float-and-clear/test/_tape.mjs similarity index 56% rename from plugins/postcss-logical-float-and-clear/.tape.mjs rename to plugins/postcss-logical-float-and-clear/test/_tape.mjs index f5475167e..94f2c6bce 100644 --- a/plugins/postcss-logical-float-and-clear/.tape.mjs +++ b/plugins/postcss-logical-float-and-clear/test/_tape.mjs @@ -3,19 +3,19 @@ import plugin from '@csstools/postcss-logical-float-and-clear'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:hebrew': { - message: "supports { inlineDirection: 'right-to-left' }", + message: 'supports { inlineDirection: \'right-to-left\' }', options: { - inlineDirection: 'right-to-left' - } + inlineDirection: 'right-to-left', + }, }, 'basic:vertical': { - message: "supports { inlineDirection: 'top-to-bottom' }", + message: 'supports { inlineDirection: \'top-to-bottom\' }', options: { - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, 'examples/example': { message: 'minimal example', @@ -23,7 +23,7 @@ postcssTape(plugin)({ 'examples/example:hebrew': { message: 'minimal example', options: { - inlineDirection: 'right-to-left' - } + inlineDirection: 'right-to-left', + }, }, }); diff --git a/plugins/postcss-logical-overflow/package.json b/plugins/postcss-logical-overflow/package.json index aa40db3f2..fc61129de 100644 --- a/plugins/postcss-logical-overflow/package.json +++ b/plugins/postcss-logical-overflow/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical-overflow#readme", "repository": { diff --git a/plugins/postcss-logical-overflow/.tape.mjs b/plugins/postcss-logical-overflow/test/_tape.mjs similarity index 74% rename from plugins/postcss-logical-overflow/.tape.mjs rename to plugins/postcss-logical-overflow/test/_tape.mjs index 2b3a95690..c2e0965d2 100644 --- a/plugins/postcss-logical-overflow/.tape.mjs +++ b/plugins/postcss-logical-overflow/test/_tape.mjs @@ -3,18 +3,18 @@ import plugin from '@csstools/postcss-logical-overflow'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:rtl': { message: 'basic test with rtl', options: { - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'basic:chinese': { message: 'basic test with rtl and bt', options: { - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'examples/example': { @@ -23,7 +23,7 @@ postcssTape(plugin)({ 'examples/example:chinese': { message: 'minimal example', options: { - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, }); diff --git a/plugins/postcss-logical-overscroll-behavior/package.json b/plugins/postcss-logical-overscroll-behavior/package.json index 2fa117441..572a0cd13 100644 --- a/plugins/postcss-logical-overscroll-behavior/package.json +++ b/plugins/postcss-logical-overscroll-behavior/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical-overscroll-behavior#readme", "repository": { diff --git a/plugins/postcss-logical-overscroll-behavior/.tape.mjs b/plugins/postcss-logical-overscroll-behavior/test/_tape.mjs similarity index 75% rename from plugins/postcss-logical-overscroll-behavior/.tape.mjs rename to plugins/postcss-logical-overscroll-behavior/test/_tape.mjs index eeaec3ffd..33d770e9d 100644 --- a/plugins/postcss-logical-overscroll-behavior/.tape.mjs +++ b/plugins/postcss-logical-overscroll-behavior/test/_tape.mjs @@ -3,18 +3,18 @@ import plugin from '@csstools/postcss-logical-overscroll-behavior'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:rtl': { message: 'basic test with rtl', options: { - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'basic:chinese': { message: 'basic test with rtl and bt', options: { - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'examples/example': { @@ -23,7 +23,7 @@ postcssTape(plugin)({ 'examples/example:chinese': { message: 'minimal example', options: { - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, }); diff --git a/plugins/postcss-logical-resize/package.json b/plugins/postcss-logical-resize/package.json index 9099356f7..93233934e 100644 --- a/plugins/postcss-logical-resize/package.json +++ b/plugins/postcss-logical-resize/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical-resize#readme", "repository": { diff --git a/plugins/postcss-logical-resize/.tape.mjs b/plugins/postcss-logical-resize/test/_tape.mjs similarity index 79% rename from plugins/postcss-logical-resize/.tape.mjs rename to plugins/postcss-logical-resize/test/_tape.mjs index f6a0433a1..8a02010aa 100644 --- a/plugins/postcss-logical-resize/.tape.mjs +++ b/plugins/postcss-logical-resize/test/_tape.mjs @@ -8,27 +8,27 @@ postcssTape(plugin)({ 'basic:rtl': { message: 'basic test with rtl', options: { - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'basic:bt': { message: 'basic test with bt', options: { - blockDirection: 'bottom-to-top' + blockDirection: 'bottom-to-top', }, }, 'basic:rtl-and-bt': { message: 'basic test with rtl and bt', options: { blockDirection: 'bottom-to-top', - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'basic:chinese': { message: 'basic test with rtl and bt', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'examples/example': { @@ -38,7 +38,7 @@ postcssTape(plugin)({ message: 'minimal example', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, }); diff --git a/plugins/postcss-logical-viewport-units/package.json b/plugins/postcss-logical-viewport-units/package.json index b798d6a10..9b0df41f0 100644 --- a/plugins/postcss-logical-viewport-units/package.json +++ b/plugins/postcss-logical-viewport-units/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical-viewport-units#readme", "repository": { diff --git a/plugins/postcss-logical-viewport-units/.tape.mjs b/plugins/postcss-logical-viewport-units/test/_tape.mjs similarity index 63% rename from plugins/postcss-logical-viewport-units/.tape.mjs rename to plugins/postcss-logical-viewport-units/test/_tape.mjs index e17950e2f..02a067a71 100644 --- a/plugins/postcss-logical-viewport-units/.tape.mjs +++ b/plugins/postcss-logical-viewport-units/test/_tape.mjs @@ -3,28 +3,28 @@ import plugin from '@csstools/postcss-logical-viewport-units'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:hebrew': { - message: "supports { inlineDirection: 'right-to-left' }", + message: 'supports { inlineDirection: \'right-to-left\' }', options: { - inlineDirection: 'right-to-left' - } + inlineDirection: 'right-to-left', + }, }, 'basic:vertical': { - message: "supports { inlineDirection: 'top-to-bottom' }", + message: 'supports { inlineDirection: \'top-to-bottom\' }', options: { - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'examples/example': { message: 'minimal example', @@ -32,13 +32,13 @@ postcssTape(plugin)({ 'examples/example:vertical': { message: 'minimal example', options: { - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-logical/package.json b/plugins/postcss-logical/package.json index 4ed3f4f92..c60f10bdd 100644 --- a/plugins/postcss-logical/package.json +++ b/plugins/postcss-logical/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical#readme", "repository": { diff --git a/plugins/postcss-logical/.tape.mjs b/plugins/postcss-logical/test/_tape.mjs similarity index 87% rename from plugins/postcss-logical/.tape.mjs rename to plugins/postcss-logical/test/_tape.mjs index 94b7acb7c..c18422198 100644 --- a/plugins/postcss-logical/.tape.mjs +++ b/plugins/postcss-logical/test/_tape.mjs @@ -8,27 +8,27 @@ postcssTape(plugin)({ 'abstract:rtl': { message: 'abstract test with rtl', options: { - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'abstract:bt': { message: 'abstract test with bt', options: { - blockDirection: 'bottom-to-top' + blockDirection: 'bottom-to-top', }, }, 'abstract:rtl-and-bt': { message: 'abstract test with rtl and bt', options: { blockDirection: 'bottom-to-top', - inlineDirection: 'right-to-left' + inlineDirection: 'right-to-left', }, }, 'abstract:chinese': { message: 'abstract test with rtl and bt', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'caption-side': { @@ -38,7 +38,7 @@ postcssTape(plugin)({ message: 'supports logical "caption-side" properties { blockDirection: "right-to-left", inlineDirection: "top-to-bottom" }', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'text-align': { @@ -48,14 +48,14 @@ postcssTape(plugin)({ message: 'supports logical "text-align" property { blockDirection: "right-to-left", inlineDirection: "top-to-bottom" }', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'text-align:hebrew': { message: 'supports logical "text-align" property { inlineDirection: "right-to-left" }', options: { inlineDirection: 'right-to-left', - } + }, }, 'logical-size': { message: 'supports logical "block-size" & "inline-size" properties', @@ -64,7 +64,7 @@ postcssTape(plugin)({ message: 'supports logical "block-size" & "inline-size" properties { blockDirection: "right-to-left", inlineDirection: "top-to-bottom" }', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, margin: { @@ -76,7 +76,7 @@ postcssTape(plugin)({ warnings: 1, options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, offsets: { @@ -88,7 +88,7 @@ postcssTape(plugin)({ warnings: 3, options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, padding: { @@ -100,7 +100,7 @@ postcssTape(plugin)({ warnings: 1, options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, border: { @@ -112,7 +112,7 @@ postcssTape(plugin)({ warnings: 6, options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'transition': { @@ -122,14 +122,14 @@ postcssTape(plugin)({ message: 'supports logical "transition" property { blockDirection: "right-to-left", inlineDirection: "top-to-bottom" }', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' + inlineDirection: 'top-to-bottom', }, }, 'transition:hebrew': { message: 'supports logical "transition" property { inlineDirection: "right-to-left" }', options: { inlineDirection: 'right-to-left', - } + }, }, 'generated-declaration-cases': { message: 'generated test cases', @@ -141,7 +141,7 @@ postcssTape(plugin)({ message: 'minimal example', options: { blockDirection: 'right-to-left', - inlineDirection: 'top-to-bottom' - } + inlineDirection: 'top-to-bottom', + }, }, }); diff --git a/plugins/postcss-media-minmax/package.json b/plugins/postcss-media-minmax/package.json index 2a843f746..233d636bd 100644 --- a/plugins/postcss-media-minmax/package.json +++ b/plugins/postcss-media-minmax/package.json @@ -68,9 +68,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-media-minmax#readme", "repository": { diff --git a/plugins/postcss-media-minmax/test/_browser.mjs b/plugins/postcss-media-minmax/test/_browser.mjs index 2833493d0..8203cf85b 100644 --- a/plugins/postcss-media-minmax/test/_browser.mjs +++ b/plugins/postcss-media-minmax/test/_browser.mjs @@ -3,21 +3,22 @@ import http from 'http'; import { promises as fsp } from 'fs'; import plugin from '@csstools/postcss-media-minmax'; import postcss from 'postcss'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { +const requestListener = async function (req, res) { - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); - // write html string with list of links to cases. - res.end(` + // write html string with list of links to cases. + res.end(` Media Queries Test @@ -30,49 +31,58 @@ import postcss from 'postcss'; `); - break; - case '/browser/basic.html': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test' + pathname, 'utf8')); - break; - case '/test/styles.css': - if (req.method === 'POST') { - const data = await new Promise((resolve, reject) => { - let buf = []; - req.on('data', (chunk) => { - buf.push(chunk); - }); - - req.on('end', () => { - resolve(Buffer.concat(buf).toString()); - }); - - req.on('error', (err) => { - reject(err); - }); + break; + case '/browser/basic.html': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test' + pathname, 'utf8')); + break; + case '/test/styles.css': + if (req.method === 'POST') { + const data = await new Promise((resolve, reject) => { + let buf = []; + req.on('data', (chunk) => { + buf.push(chunk); + }); + + req.on('end', () => { + resolve(Buffer.concat(buf).toString()); + }); + + req.on('error', (err) => { + reject(err); }); + }); - const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(css.css); - break; - } - - // eslint-disable-next-line no-fallthrough - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); + const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(css.css); break; - } - }; + } + // eslint-disable-next-line no-fallthrough + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; + +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -104,8 +114,10 @@ import postcss from 'postcss'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-media-minmax/.tape.mjs b/plugins/postcss-media-minmax/test/_tape.mjs similarity index 67% rename from plugins/postcss-media-minmax/.tape.mjs rename to plugins/postcss-media-minmax/test/_tape.mjs index 8fae94bb0..8299dc85e 100644 --- a/plugins/postcss-media-minmax/.tape.mjs +++ b/plugins/postcss-media-minmax/test/_tape.mjs @@ -9,25 +9,25 @@ postcssTape(plugin)({ message: 'use calc() in range notation', }, 'color-index': { - message: 'color-index feature' + message: 'color-index feature', }, 'color': { - message: 'color feature' + message: 'color feature', }, 'comments': { message: 'use comments in range notation', }, 'complex': { - message: 'complex examples' + message: 'complex examples', }, 'custom-media': { - message: '@custom-media' + message: '@custom-media', }, 'device-aspect-ratio': { - message: 'device-aspect-ratio feature' + message: 'device-aspect-ratio feature', }, 'device-width-height': { - message: 'device-width-height feature' + message: 'device-width-height feature', }, 'env': { message: 'handling of `env()` function values', @@ -36,31 +36,31 @@ postcssTape(plugin)({ message: 'line breaks in range notation', }, 'min-max': { - message: 'various combinations of operators and orders of values and names' + message: 'various combinations of operators and orders of values and names', }, 'monochrome': { - message: 'monochrome feature' + message: 'monochrome feature', }, 'more-units': { - message: 'various units in values' + message: 'various units in values', }, 'operators': { - message: 'various combinations of operators and orders of values and names' + message: 'various combinations of operators and orders of values and names', }, 'other-name': { - message: 'various examples' + message: 'various examples', }, 'resolution': { - message: 'resolution feature' + message: 'resolution feature', }, 'shorthands': { - message: 'various examples' + message: 'various examples', }, 'unknown-feature': { - message: 'unknown feature' + message: 'unknown feature', }, 'width-height': { - message: 'width/height feature' + message: 'width/height feature', }, 'examples/example': { message: 'minimal example', diff --git a/plugins/postcss-media-queries-aspect-ratio-number-values/package.json b/plugins/postcss-media-queries-aspect-ratio-number-values/package.json index 1c5c3749e..f62c05fc7 100644 --- a/plugins/postcss-media-queries-aspect-ratio-number-values/package.json +++ b/plugins/postcss-media-queries-aspect-ratio-number-values/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-media-queries-aspect-ratio-number-values#readme", "repository": { diff --git a/plugins/postcss-media-queries-aspect-ratio-number-values/.tape.mjs b/plugins/postcss-media-queries-aspect-ratio-number-values/test/_tape.mjs similarity index 70% rename from plugins/postcss-media-queries-aspect-ratio-number-values/.tape.mjs rename to plugins/postcss-media-queries-aspect-ratio-number-values/test/_tape.mjs index ca140e24f..823b15242 100644 --- a/plugins/postcss-media-queries-aspect-ratio-number-values/.tape.mjs +++ b/plugins/postcss-media-queries-aspect-ratio-number-values/test/_tape.mjs @@ -3,16 +3,16 @@ import plugin from '@csstools/postcss-media-queries-aspect-ratio-number-values'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { - message: "supports basic usage", + message: 'supports basic usage', options: { - preserve: true - } + preserve: true, + }, }, 'invalid': { - message: "ignores invalid values", + message: 'ignores invalid values', }, 'examples/example': { message: 'minimal example', @@ -20,7 +20,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-minify/package.json b/plugins/postcss-minify/package.json index 399a36300..316b9c87a 100644 --- a/plugins/postcss-minify/package.json +++ b/plugins/postcss-minify/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-minify#readme", "repository": { diff --git a/plugins/postcss-minify/.tape.mjs b/plugins/postcss-minify/test/_tape.mjs similarity index 68% rename from plugins/postcss-minify/.tape.mjs rename to plugins/postcss-minify/test/_tape.mjs index 7d761e74a..3a56dc27b 100644 --- a/plugins/postcss-minify/.tape.mjs +++ b/plugins/postcss-minify/test/_tape.mjs @@ -3,13 +3,13 @@ import plugin from '@csstools/postcss-minify'; await postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, bootstrap: { - message: "minifies bootstrap", + message: 'minifies bootstrap', }, 'preset-env-basic': { - message: "minifies the basic preset-env test", + message: 'minifies the basic preset-env test', }, 'examples/example': { message: 'minimal example', diff --git a/plugins/postcss-nested-calc/package.json b/plugins/postcss-nested-calc/package.json index 1676750f8..138827d37 100644 --- a/plugins/postcss-nested-calc/package.json +++ b/plugins/postcss-nested-calc/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nested-calc#readme", "repository": { diff --git a/plugins/postcss-nested-calc/.tape.mjs b/plugins/postcss-nested-calc/test/_tape.mjs similarity index 72% rename from plugins/postcss-nested-calc/.tape.mjs rename to plugins/postcss-nested-calc/test/_tape.mjs index b05802256..4af7ab8ee 100644 --- a/plugins/postcss-nested-calc/.tape.mjs +++ b/plugins/postcss-nested-calc/test/_tape.mjs @@ -3,22 +3,22 @@ import plugin from '@csstools/postcss-nested-calc'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-false': { - message: "supports basic usage with { preserve: false }", + message: 'supports basic usage with { preserve: false }', options: { - preserve: false - } + preserve: false, + }, }, 'basic:with-cloned-rules': { message: 'doesn\'t cause duplicate CSS', plugins: [ ruleClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'examples/example': { message: 'minimal example', @@ -26,7 +26,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-nesting/package.json b/plugins/postcss-nesting/package.json index cf5da8d4f..64611261f 100644 --- a/plugins/postcss-nesting/package.json +++ b/plugins/postcss-nesting/package.json @@ -69,9 +69,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:browser": "node ./test/_browser.mjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting#readme", "repository": { diff --git a/plugins/postcss-nesting/test/_browser.mjs b/plugins/postcss-nesting/test/_browser.mjs index bf602a0e3..627ffc044 100644 --- a/plugins/postcss-nesting/test/_browser.mjs +++ b/plugins/postcss-nesting/test/_browser.mjs @@ -3,21 +3,22 @@ import http from 'http'; import { promises as fsp } from 'fs'; import plugin from 'postcss-nesting'; import postcss from 'postcss'; +import test from 'node:test'; +import process from 'node:process'; -(async () => { - const requestListener = async function (req, res) { +const requestListener = async function (req, res) { - const parsedUrl = new URL(req.url, 'http://localhost:8080'); - const pathname = parsedUrl.pathname; + const parsedUrl = new URL(req.url, 'http://localhost:8080'); + const pathname = parsedUrl.pathname; - switch (pathname) { - case '': - case '/': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); + switch (pathname) { + case '': + case '/': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); - // write html string with list of links to cases. - res.end(` + // write html string with list of links to cases. + res.end(` Cascade Layers Test @@ -33,52 +34,61 @@ import postcss from 'postcss'; `); - break; - case '/wpt/conditional.html': - case '/wpt/implicit-nesting.html': - case '/wpt/nest-containing.html': - case '/wpt/nesting-basics.html': - res.setHeader('Content-type', 'text/html'); - res.writeHead(200); - res.end(await fsp.readFile('test' + pathname, 'utf8')); - break; - case '/test/styles.css': - if (req.method === 'POST') { - const data = await new Promise((resolve, reject) => { - let buf = []; - req.on('data', (chunk) => { - buf.push(chunk); - }); - - req.on('end', () => { - resolve(Buffer.concat(buf).toString()); - }); - - req.on('error', (err) => { - reject(err); - }); + break; + case '/wpt/conditional.html': + case '/wpt/implicit-nesting.html': + case '/wpt/nest-containing.html': + case '/wpt/nesting-basics.html': + res.setHeader('Content-type', 'text/html'); + res.writeHead(200); + res.end(await fsp.readFile('test' + pathname, 'utf8')); + break; + case '/test/styles.css': + if (req.method === 'POST') { + const data = await new Promise((resolve, reject) => { + let buf = []; + req.on('data', (chunk) => { + buf.push(chunk); + }); + + req.on('end', () => { + resolve(Buffer.concat(buf).toString()); + }); + + req.on('error', (err) => { + reject(err); }); + }); - const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); - res.setHeader('Content-type', 'text/css'); - res.writeHead(200); - res.end(css.css); - break; - } - - // eslint-disable-next-line no-fallthrough - default: - res.setHeader('Content-type', 'text/plain'); - res.writeHead(404); - res.end('Not found'); + const css = await postcss([plugin]).process(data, { from: 'test/styles.css', to: 'test/styles.css' }); + res.setHeader('Content-type', 'text/css'); + res.writeHead(200); + res.end(css.css); break; - } - }; + } + // eslint-disable-next-line no-fallthrough + default: + res.setHeader('Content-type', 'text/plain'); + res.writeHead(404); + res.end('Not found'); + break; + } +}; + +function startServers() { const server = http.createServer(requestListener); server.listen(8080); - if (!process.env.DEBUG) { + return () => { + server.close(); + }; +} + +if (!process.env.DEBUG) { + test('browser', { skip: process.env.GITHUB_ACTIONS && !process.env.BROWSER_TESTS }, async () => { + const cleanup = startServers(); + const browser = await puppeteer.launch({ headless: 'new', }); @@ -106,8 +116,10 @@ import postcss from 'postcss'; await browser.close(); - await server.close(); - } else { - console.log('visit : http://localhost:8080'); - } -})(); + await cleanup(); + }); +} else { + startServers(); + + console.log('visit : http://localhost:8080'); +} diff --git a/plugins/postcss-nesting/.tape.mjs b/plugins/postcss-nesting/test/_tape.mjs similarity index 95% rename from plugins/postcss-nesting/.tape.mjs rename to plugins/postcss-nesting/test/_tape.mjs index 1e3a70796..e8c7d4e8a 100644 --- a/plugins/postcss-nesting/.tape.mjs +++ b/plugins/postcss-nesting/test/_tape.mjs @@ -9,10 +9,10 @@ const mixinPluginRule = () => { node.replaceWith(postcss.parse('& .in{ &.deep { color: blue; }}', {from : 'mixin.css'})); }, }, - } -} + }; +}; -mixinPluginRule.postcss = true +mixinPluginRule.postcss = true; const mixinPluginDeclaration = () => { return { @@ -22,10 +22,10 @@ const mixinPluginDeclaration = () => { node.replaceWith(postcss.parse('color: blue;', {from : 'mixin.css'})); }, }, - } -} + }; +}; -mixinPluginDeclaration.postcss = true +mixinPluginDeclaration.postcss = true; postcssTape(plugin)({ 'basic': { @@ -67,7 +67,7 @@ postcssTape(plugin)({ warnings: 4, options: { silenceAtNestWarning: true, - } + }, }, 'at-nest:no-is-pseudo-selector': { message: 'supports at-nest usage { noIsPseudoSelector: true }', @@ -99,7 +99,7 @@ postcssTape(plugin)({ }, 'invalid-selector': { message: 'warns on invalid selectors', - warnings: 4 + warnings: 4, }, 'media': { message: 'supports nested @media', @@ -148,7 +148,7 @@ postcssTape(plugin)({ }, 'mixin-declaration': { message: 'supports other visitors (mixin declaration)', - plugins: [mixinPluginDeclaration(), plugin()] + plugins: [mixinPluginDeclaration(), plugin()], }, 'mixin-declaration:no-is-pseudo-selector': { message: 'supports other visitors (mixin declaration) { noIsPseudoSelector: true }', @@ -159,7 +159,7 @@ postcssTape(plugin)({ }, 'mixin-rule': { message: 'supports other visitors (mixin rule)', - plugins: [mixinPluginRule(), plugin()] + plugins: [mixinPluginRule(), plugin()], }, 'mixin-rule:no-is-pseudo-selector': { message: 'supports other visitors (mixin rule) { noIsPseudoSelector: true }', @@ -190,6 +190,6 @@ postcssTape(plugin)({ }, }, 'examples/example': { - message: 'basic examples' + message: 'basic examples', }, }); diff --git a/plugins/postcss-normalize-display-values/package.json b/plugins/postcss-normalize-display-values/package.json index 838c4e085..849ff008f 100644 --- a/plugins/postcss-normalize-display-values/package.json +++ b/plugins/postcss-normalize-display-values/package.json @@ -51,8 +51,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "repository": { "type": "git", diff --git a/plugins/postcss-normalize-display-values/.tape.mjs b/plugins/postcss-normalize-display-values/test/_tape.mjs similarity index 92% rename from plugins/postcss-normalize-display-values/.tape.mjs rename to plugins/postcss-normalize-display-values/test/_tape.mjs index 680b0d0ae..be7e77f31 100644 --- a/plugins/postcss-normalize-display-values/.tape.mjs +++ b/plugins/postcss-normalize-display-values/test/_tape.mjs @@ -8,7 +8,7 @@ postcssTape(plugin)({ 'basic:preserve-false': { message: 'supports basic usage with { preserve: true }', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-oklab-function/package.json b/plugins/postcss-oklab-function/package.json index 04d140787..643d9bc3b 100644 --- a/plugins/postcss-oklab-function/package.json +++ b/plugins/postcss-oklab-function/package.json @@ -54,8 +54,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-oklab-function#readme", "repository": { diff --git a/plugins/postcss-oklab-function/.tape.mjs b/plugins/postcss-oklab-function/test/_tape.mjs similarity index 87% rename from plugins/postcss-oklab-function/.tape.mjs rename to plugins/postcss-oklab-function/test/_tape.mjs index 13f18e3b5..69d30ccf4 100644 --- a/plugins/postcss-oklab-function/.tape.mjs +++ b/plugins/postcss-oklab-function/test/_tape.mjs @@ -9,8 +9,8 @@ postcssTape(plugin)({ message: 'supports { preserve: true } usage', warnings: 0, options: { - preserve: true - } + preserve: true, + }, }, 'basic:preserve-true:display-p3-false': { message: 'supports { subFeatures: { displayP3: false }, preserve: true } usage', @@ -18,9 +18,9 @@ postcssTape(plugin)({ options: { preserve: true, subFeatures: { - displayP3: false - } - } + displayP3: false, + }, + }, }, 'variables': { message: 'supports variables', @@ -28,16 +28,16 @@ postcssTape(plugin)({ 'variables:preserve-true': { message: 'supports variables with { preserve: true } usage', options: { - preserve: true - } + preserve: true, + }, }, 'variables:preserve-true:display-p3-false': { message: 'supports variables with { subFeatures: { displayP3: false }, preserve: true } usage', options: { preserve: true, subFeatures: { - displayP3: false - } - } - } + displayP3: false, + }, + }, + }, }); diff --git a/plugins/postcss-overflow-shorthand/package.json b/plugins/postcss-overflow-shorthand/package.json index 90614ce99..ab3f15ff4 100644 --- a/plugins/postcss-overflow-shorthand/package.json +++ b/plugins/postcss-overflow-shorthand/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-overflow-shorthand#readme", "repository": { diff --git a/plugins/postcss-overflow-shorthand/.tape.mjs b/plugins/postcss-overflow-shorthand/test/_tape.mjs similarity index 81% rename from plugins/postcss-overflow-shorthand/.tape.mjs rename to plugins/postcss-overflow-shorthand/test/_tape.mjs index 4b4b93efe..1b449ab2e 100644 --- a/plugins/postcss-overflow-shorthand/.tape.mjs +++ b/plugins/postcss-overflow-shorthand/test/_tape.mjs @@ -3,25 +3,25 @@ import plugin from 'postcss-overflow-shorthand'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve-false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'generated-declaration-cases': { message: 'correctly handles generated cases', options: { - preserve: false - } + preserve: false, + }, }, 'generated-declaration-cases:preserve': { message: 'correctly handles generated cases', options: { - preserve: true - } + preserve: true, + }, }, 'examples/example': { message: 'minimal example', @@ -29,7 +29,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-place/package.json b/plugins/postcss-place/package.json index edc6f10af..19f77c50b 100644 --- a/plugins/postcss-place/package.json +++ b/plugins/postcss-place/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-place#readme", "repository": { diff --git a/plugins/postcss-place/.tape.mjs b/plugins/postcss-place/test/_tape.mjs similarity index 86% rename from plugins/postcss-place/.tape.mjs rename to plugins/postcss-place/test/_tape.mjs index 2058ada5d..9c7cab486 100644 --- a/plugins/postcss-place/.tape.mjs +++ b/plugins/postcss-place/test/_tape.mjs @@ -8,20 +8,20 @@ postcssTape(plugin)({ 'basic:preserve-false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'generated-declaration-cases': { message: 'correctly handles generated cases', options: { - preserve: false - } + preserve: false, + }, }, 'generated-declaration-cases:preserve': { message: 'correctly handles generated cases', options: { - preserve: true - } + preserve: true, + }, }, 'examples/example': { message: 'minimal example', @@ -29,7 +29,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-progressive-custom-properties/package.json b/plugins/postcss-progressive-custom-properties/package.json index 03adfe72e..6395887ed 100644 --- a/plugins/postcss-progressive-custom-properties/package.json +++ b/plugins/postcss-progressive-custom-properties/package.json @@ -51,8 +51,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "repository": { "type": "git", diff --git a/plugins/postcss-progressive-custom-properties/.tape.mjs b/plugins/postcss-progressive-custom-properties/test/_tape.mjs similarity index 82% rename from plugins/postcss-progressive-custom-properties/.tape.mjs rename to plugins/postcss-progressive-custom-properties/test/_tape.mjs index a4e3f8d50..0faff76aa 100644 --- a/plugins/postcss-progressive-custom-properties/.tape.mjs +++ b/plugins/postcss-progressive-custom-properties/test/_tape.mjs @@ -3,6 +3,6 @@ import plugin from '@csstools/postcss-progressive-custom-properties'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, }); diff --git a/plugins/postcss-pseudo-class-any-link/package.json b/plugins/postcss-pseudo-class-any-link/package.json index 10f9c9cca..af3f8c38a 100644 --- a/plugins/postcss-pseudo-class-any-link/package.json +++ b/plugins/postcss-pseudo-class-any-link/package.json @@ -65,8 +65,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-pseudo-class-any-link#readme", "repository": { diff --git a/plugins/postcss-pseudo-class-any-link/.tape.mjs b/plugins/postcss-pseudo-class-any-link/test/_tape.mjs similarity index 79% rename from plugins/postcss-pseudo-class-any-link/.tape.mjs rename to plugins/postcss-pseudo-class-any-link/test/_tape.mjs index c03372104..bb7c271a0 100644 --- a/plugins/postcss-pseudo-class-any-link/.tape.mjs +++ b/plugins/postcss-pseudo-class-any-link/test/_tape.mjs @@ -3,21 +3,21 @@ import plugin from 'postcss-pseudo-class-any-link'; postcssTape(plugin)({ 'basic': { - message: 'supports basic usage' + message: 'supports basic usage', }, 'basic:preserve-false': { message: 'supports { preserve: false } usage', options: { - preserve: false - } + preserve: false, + }, }, 'basic:sub-features-area-href': { message: 'supports { subFeatures: { areaHrefNeedsFixing: true } } usage', options: { subFeatures: { - areaHrefNeedsFixing: true - } - } + areaHrefNeedsFixing: true, + }, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', @@ -26,17 +26,17 @@ postcssTape(plugin)({ plugin({ preserve: true, subFeatures: { - areaHrefNeedsFixing: true - } - }) - ] + areaHrefNeedsFixing: true, + }, + }), + ], }, 'generated-selector-cases': { message: 'correctly handles generated cases', warnings: 1, options: { - preserve: false - } + preserve: false, + }, }, 'generated-selector-cases:sub-features-area-href': { message: 'correctly handles generated cases with areaHrefNeedsFixing: true', @@ -44,9 +44,9 @@ postcssTape(plugin)({ options: { preserve: false, subFeatures: { - areaHrefNeedsFixing: true - } - } + areaHrefNeedsFixing: true, + }, + }, }, 'examples/example': { message: 'minimal example', @@ -54,15 +54,15 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, 'examples/example:area-false': { message: 'minimal example', options: { subFeatures: { - areaHrefNeedsFixing: true - } - } + areaHrefNeedsFixing: true, + }, + }, }, }); diff --git a/plugins/postcss-rebase-url/package.json b/plugins/postcss-rebase-url/package.json index 21ac30189..d154778f2 100644 --- a/plugins/postcss-rebase-url/package.json +++ b/plugins/postcss-rebase-url/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-rebase-url#readme", "repository": { diff --git a/plugins/postcss-rebase-url/.tape.mjs b/plugins/postcss-rebase-url/test/_tape.mjs similarity index 75% rename from plugins/postcss-rebase-url/.tape.mjs rename to plugins/postcss-rebase-url/test/_tape.mjs index f3635dc8e..a5ef8bde9 100644 --- a/plugins/postcss-rebase-url/.tape.mjs +++ b/plugins/postcss-rebase-url/test/_tape.mjs @@ -2,21 +2,21 @@ import { postcssTape } from '@csstools/postcss-tape'; import plugin from '@csstools/postcss-rebase-url'; import postcssImport from 'postcss-import'; -import './test/unit/index.mjs'; +import './unit/index.mjs'; await postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', plugins: [ postcssImport(), - plugin() - ] + plugin(), + ], }, 'examples/example': { message: 'minimal example', plugins: [ postcssImport(), - plugin() - ] - } + plugin(), + ], + }, }); diff --git a/plugins/postcss-relative-color-syntax/package.json b/plugins/postcss-relative-color-syntax/package.json index d63d1a4fd..af38ef3b3 100644 --- a/plugins/postcss-relative-color-syntax/package.json +++ b/plugins/postcss-relative-color-syntax/package.json @@ -64,8 +64,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-relative-color-syntax#readme", "repository": { diff --git a/plugins/postcss-relative-color-syntax/.tape.mjs b/plugins/postcss-relative-color-syntax/test/_tape.mjs similarity index 74% rename from plugins/postcss-relative-color-syntax/.tape.mjs rename to plugins/postcss-relative-color-syntax/test/_tape.mjs index d0afe7a41..049141d58 100644 --- a/plugins/postcss-relative-color-syntax/.tape.mjs +++ b/plugins/postcss-relative-color-syntax/test/_tape.mjs @@ -3,13 +3,13 @@ import plugin from '@csstools/postcss-relative-color-syntax'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { - message: "supports basic usage", + message: 'supports basic usage', options: { - preserve: true - } + preserve: true, + }, }, 'examples/example': { message: 'minimal example', @@ -17,7 +17,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-scope-pseudo-class/package.json b/plugins/postcss-scope-pseudo-class/package.json index 232dc815d..c0a60b76b 100644 --- a/plugins/postcss-scope-pseudo-class/package.json +++ b/plugins/postcss-scope-pseudo-class/package.json @@ -61,8 +61,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-scope-pseudo-class#readme", "repository": { diff --git a/plugins/postcss-scope-pseudo-class/.tape.mjs b/plugins/postcss-scope-pseudo-class/test/_tape.mjs similarity index 80% rename from plugins/postcss-scope-pseudo-class/.tape.mjs rename to plugins/postcss-scope-pseudo-class/test/_tape.mjs index eb750237d..accf8845d 100644 --- a/plugins/postcss-scope-pseudo-class/.tape.mjs +++ b/plugins/postcss-scope-pseudo-class/test/_tape.mjs @@ -3,22 +3,22 @@ import plugin from '@csstools/postcss-scope-pseudo-class'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { - message: "supports basic usage", + message: 'supports basic usage', options: { - preserve: true - } + preserve: true, + }, }, 'basic:with-cloned-declarations': { message: 'doesn\'t cause duplicate CSS', plugins: [ declarationClonerPlugin, plugin({ - preserve: true - }) - ] + preserve: true, + }), + ], }, 'generated-selector-cases': { message: 'handles all generated selector cases correctly', @@ -30,7 +30,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, }); diff --git a/plugins/postcss-selector-not/package.json b/plugins/postcss-selector-not/package.json index eb5ae4329..b44215531 100644 --- a/plugins/postcss-selector-not/package.json +++ b/plugins/postcss-selector-not/package.json @@ -64,8 +64,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-selector-not#readme", "repository": { diff --git a/plugins/postcss-selector-not/.tape.mjs b/plugins/postcss-selector-not/test/_tape.mjs similarity index 84% rename from plugins/postcss-selector-not/.tape.mjs rename to plugins/postcss-selector-not/test/_tape.mjs index 2b9c8a01d..d9d71ff21 100644 --- a/plugins/postcss-selector-not/.tape.mjs +++ b/plugins/postcss-selector-not/test/_tape.mjs @@ -3,7 +3,7 @@ import plugin from 'postcss-selector-not'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'examples/example': { message: 'minimal example', diff --git a/plugins/postcss-slow-plugins/package.json b/plugins/postcss-slow-plugins/package.json index c456b20d4..bebc69c27 100644 --- a/plugins/postcss-slow-plugins/package.json +++ b/plugins/postcss-slow-plugins/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-slow-plugins#readme", "repository": { diff --git a/plugins/postcss-slow-plugins/.tape.mjs b/plugins/postcss-slow-plugins/test/_tape.mjs similarity index 92% rename from plugins/postcss-slow-plugins/.tape.mjs rename to plugins/postcss-slow-plugins/test/_tape.mjs index 0b465ce02..145dc19a5 100644 --- a/plugins/postcss-slow-plugins/.tape.mjs +++ b/plugins/postcss-slow-plugins/test/_tape.mjs @@ -6,15 +6,15 @@ const variableSpeedCreator = (delay) => { postcssPlugin: `postcss-${delay}ms`, Once: async () => { await new Promise((resolve) => setTimeout(resolve, delay)); - } - } -} + }, + }; +}; variableSpeedCreator.postcss = true; await postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', plugins: [ plugin({ ignore: ['postcss-30ms'] }), variableSpeedCreator(10), diff --git a/plugins/postcss-stepped-value-functions/package.json b/plugins/postcss-stepped-value-functions/package.json index 88d458096..5da07e504 100644 --- a/plugins/postcss-stepped-value-functions/package.json +++ b/plugins/postcss-stepped-value-functions/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-stepped-value-functions#readme", "repository": { diff --git a/plugins/postcss-stepped-value-functions/.tape.mjs b/plugins/postcss-stepped-value-functions/test/_tape.mjs similarity index 82% rename from plugins/postcss-stepped-value-functions/.tape.mjs rename to plugins/postcss-stepped-value-functions/test/_tape.mjs index 7c045d5e6..bea75a102 100644 --- a/plugins/postcss-stepped-value-functions/.tape.mjs +++ b/plugins/postcss-stepped-value-functions/test/_tape.mjs @@ -3,12 +3,12 @@ import plugin from '@csstools/postcss-stepped-value-functions'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true + preserve: true, }, }, 'examples/example': { @@ -17,7 +17,7 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } - } + preserve: true, + }, + }, }); diff --git a/plugins/postcss-text-decoration-shorthand/package.json b/plugins/postcss-text-decoration-shorthand/package.json index dc91ad6e7..0b67b1f5f 100644 --- a/plugins/postcss-text-decoration-shorthand/package.json +++ b/plugins/postcss-text-decoration-shorthand/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-text-decoration-shorthand#readme", "repository": { diff --git a/plugins/postcss-text-decoration-shorthand/.tape.mjs b/plugins/postcss-text-decoration-shorthand/test/_tape.mjs similarity index 77% rename from plugins/postcss-text-decoration-shorthand/.tape.mjs rename to plugins/postcss-text-decoration-shorthand/test/_tape.mjs index 5c4370ab9..d7eff4d87 100644 --- a/plugins/postcss-text-decoration-shorthand/.tape.mjs +++ b/plugins/postcss-text-decoration-shorthand/test/_tape.mjs @@ -4,33 +4,33 @@ import autoprefixer from 'autoprefixer'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-false': { message: 'supports basic usage with { preserve: false }', options: { - preserve: false - } + preserve: false, + }, }, 'basic:autoprefixer': { message: 'supports basic usage with autoprefixer', plugins: [ plugin(), autoprefixer({ - overrideBrowserslist: ['Safari >= 8'] - }) - ] + overrideBrowserslist: ['Safari >= 8'], + }), + ], }, 'basic:autoprefixer:preserve-false': { message: 'supports basic usage with autoprefixer and { preserve: false }', plugins: [ plugin({ - preserve: false + preserve: false, }), autoprefixer({ - overrideBrowserslist: ['Safari >= 8'] - }) - ] + overrideBrowserslist: ['Safari >= 8'], + }), + ], }, 'examples/example': { message: 'minimal example', @@ -38,7 +38,7 @@ postcssTape(plugin)({ 'examples/example:preserve-false': { message: 'minimal example', options: { - preserve: false - } + preserve: false, + }, }, }); diff --git a/plugins/postcss-todo-or-die/package.json b/plugins/postcss-todo-or-die/package.json index 8af9ae686..757745a5e 100644 --- a/plugins/postcss-todo-or-die/package.json +++ b/plugins/postcss-todo-or-die/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-todo-or-die#readme", "repository": { diff --git a/plugins/postcss-todo-or-die/.tape.mjs b/plugins/postcss-todo-or-die/test/_tape.mjs similarity index 70% rename from plugins/postcss-todo-or-die/.tape.mjs rename to plugins/postcss-todo-or-die/test/_tape.mjs index 177be58f2..455792b6f 100644 --- a/plugins/postcss-todo-or-die/.tape.mjs +++ b/plugins/postcss-todo-or-die/test/_tape.mjs @@ -5,35 +5,35 @@ process.env['BROWSERSLIST'] = '> 1%, chrome 79, safari 16'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'before-date-001': { - message: "throws", - exception: /Died because 2000-1-2 is in the past/ + message: 'throws', + exception: /Died because 2000-1-2 is in the past/, }, 'browserslist-001': { - message: "throws", - exception: /Died because the browsers matching "chrome <= 30" do not have any overlap with your project browserslist/ + message: 'throws', + exception: /Died because the browsers matching "chrome <= 30" do not have any overlap with your project browserslist/, }, 'keyword-001': { - message: "throws", - exception: /Died because A \(left\) is no longer equal to B \(center\)/ + message: 'throws', + exception: /Died because A \(left\) is no longer equal to B \(center\)/, }, 'number-001': { - message: "throws", - exception: /Died because A \(10\) is no longer greater than B \(16\)/ + message: 'throws', + exception: /Died because A \(10\) is no longer greater than B \(16\)/, }, 'number-002': { - message: "throws", - exception: /Died because A \(20\) is no longer less than B \(16\)/ + message: 'throws', + exception: /Died because A \(20\) is no longer less than B \(16\)/, }, 'number-003': { - message: "throws", - exception: /Died because A \(-1\) is no longer equal to B \(1\)/ + message: 'throws', + exception: /Died because A \(-1\) is no longer equal to B \(1\)/, }, 'number-004': { - message: "throws", - exception: /Died because A \(10px\) is no longer greater than B \(15px\)/ + message: 'throws', + exception: /Died because A \(10px\) is no longer greater than B \(15px\)/, }, 'examples/example': { message: 'minimal example', diff --git a/plugins/postcss-trigonometric-functions/package.json b/plugins/postcss-trigonometric-functions/package.json index 85b51a570..79ad78e9a 100644 --- a/plugins/postcss-trigonometric-functions/package.json +++ b/plugins/postcss-trigonometric-functions/package.json @@ -63,8 +63,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-trigonometric-functions#readme", "repository": { diff --git a/plugins/postcss-trigonometric-functions/.tape.mjs b/plugins/postcss-trigonometric-functions/test/_tape.mjs similarity index 78% rename from plugins/postcss-trigonometric-functions/.tape.mjs rename to plugins/postcss-trigonometric-functions/test/_tape.mjs index 342e0368b..5fa717a27 100644 --- a/plugins/postcss-trigonometric-functions/.tape.mjs +++ b/plugins/postcss-trigonometric-functions/test/_tape.mjs @@ -3,12 +3,12 @@ import plugin from '@csstools/postcss-trigonometric-functions'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve-true': { message: 'supports { preserve: true } usage', options: { - preserve: true + preserve: true, }, }, 'examples/example': { @@ -17,10 +17,10 @@ postcssTape(plugin)({ 'examples/example:preserve-true': { message: 'minimal example', options: { - preserve: true - } + preserve: true, + }, }, wpt: { - message: "supports wpt cases", + message: 'supports wpt cases', }, }); diff --git a/plugins/postcss-unset-value/package.json b/plugins/postcss-unset-value/package.json index 001c60218..e1d5f9f44 100644 --- a/plugins/postcss-unset-value/package.json +++ b/plugins/postcss-unset-value/package.json @@ -58,8 +58,8 @@ "docs": "node ../../.github/bin/generate-docs/install.mjs", "lint": "node ../../.github/bin/format-package-json.mjs", "prepublishOnly": "npm run build && npm run test", - "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs", - "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" + "test": "node --test", + "test:rewrite-expects": "REWRITE_EXPECTS=true node --test" }, "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-unset-value#readme", "repository": { diff --git a/plugins/postcss-unset-value/.tape.mjs b/plugins/postcss-unset-value/test/_tape.mjs similarity index 60% rename from plugins/postcss-unset-value/.tape.mjs rename to plugins/postcss-unset-value/test/_tape.mjs index 6f283880e..5127af13b 100644 --- a/plugins/postcss-unset-value/.tape.mjs +++ b/plugins/postcss-unset-value/test/_tape.mjs @@ -3,21 +3,21 @@ import plugin from '@csstools/postcss-unset-value'; postcssTape(plugin)({ basic: { - message: "supports basic usage", + message: 'supports basic usage', }, 'basic:preserve:true': { - message: "supports basic usage", + message: 'supports basic usage', options: { preserve: true, - } + }, }, 'generated-value-cases': { - message: "supports generated value cases", + message: 'supports generated value cases', options: { - preserve: true - } + preserve: true, + }, }, example: { - message: "minimal example", + message: 'minimal example', }, }); diff --git a/rollup/configs/externals.mjs b/rollup/configs/externals.mjs index d038832b5..002eac4a3 100644 --- a/rollup/configs/externals.mjs +++ b/rollup/configs/externals.mjs @@ -2,6 +2,8 @@ export const externalsForCLI = [ 'fs', 'fs/promises', 'https', + 'node:assert/strict', + 'node:test', 'path', 'url', @@ -94,6 +96,8 @@ export const externalsForPlugin = [ 'fs/promises', 'https', 'module', + 'node:assert/strict', + 'node:test', 'path', 'url', diff --git a/rollup/default.mjs b/rollup/default.mjs index 2596303c2..e0212ab8f 100644 --- a/rollup/default.mjs +++ b/rollup/default.mjs @@ -17,11 +17,16 @@ const isTypescript = (() => { } })(); +let nodeCoverageDisable = false; +if (packageInfo.name === '@csstools/postcss-tape') { + nodeCoverageDisable = true; +} + const presets = []; if (isTypescript) { if (packageInfo.main || packageInfo.module) { - presets.push(...packageTypescript()); + presets.push(...packageTypescript({nodeCoverageDisable: nodeCoverageDisable})); } if (packageInfo.exports && ('./browser' in packageInfo.exports)) { diff --git a/rollup/presets/package-typescript.mjs b/rollup/presets/package-typescript.mjs index 151630a8c..f7dd1bf5b 100644 --- a/rollup/presets/package-typescript.mjs +++ b/rollup/presets/package-typescript.mjs @@ -2,8 +2,10 @@ import terser from '@rollup/plugin-terser'; import typescript from '@rollup/plugin-typescript'; import { externalsForPlugin } from '../configs/externals.mjs'; import { apiExtractor } from '../transforms/api-extractor.mjs'; +import { nodeCoverageDisable } from '../transforms/node-coverage-disable.mjs'; -export function packageTypescript() { +export function packageTypescript(options) { + options = options || {}; return [ { input: 'src/index.ts', @@ -25,6 +27,7 @@ export function packageTypescript() { keep_classnames: true, keep_fnames: true, }), + options.nodeCoverageDisable ? nodeCoverageDisable() : undefined, ], }, { @@ -47,6 +50,7 @@ export function packageTypescript() { keep_classnames: true, keep_fnames: true, }), + options.nodeCoverageDisable ? nodeCoverageDisable() : undefined, apiExtractor(), ], }, diff --git a/rollup/transforms/node-coverage-disable.mjs b/rollup/transforms/node-coverage-disable.mjs new file mode 100644 index 000000000..8da8000f3 --- /dev/null +++ b/rollup/transforms/node-coverage-disable.mjs @@ -0,0 +1,8 @@ +export function nodeCoverageDisable () { + return { + name: 'node-coverage-disable', + renderChunk (code) { + return `/* node:coverage disable */\n${code}\n/* node:coverage enable */\n`; + }, + }; +}