Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,860 changes: 2,403 additions & 2,457 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/postcss-tape/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to PostCSS Tape

### Unreleased (patch)

- Ignore whitespace when comparing latest and oldest PostCSS versions.

### 7.0.0

_January 14, 2026_
Expand Down
2 changes: 1 addition & 1 deletion packages/postcss-tape/dist/index.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* node:coverage disable */
import e from"node:assert/strict";import t from"node:fs/promises";import s from"node:fs";import o from"node:path";import n from"postcss";import r from"postcss-8.4";import i from"node:test";import a from"node:url";const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function fileContentsOrEmptyString(e){try{return await t.readFile(e,"utf8")}catch{return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}function postcssTape(a,c){return async p=>{c=c??{},await i("`postcss` flag is set on exported plugin creator",()=>{e.equal(a.postcss,!0)}),await i("exported plugin creator is a function",()=>{e.equal(typeof a,"function")}),await i("`postcssPlugin` is set on a plugin instance",()=>{const t=a();e.ok(t.postcssPlugin),e.equal(typeof t.postcssPlugin,"string")}),await 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(Array.isArray(n.keywords)&&n.keywords?.includes("postcss-plugin"),new PackageDescriptionError('Missing "postcss-plugin" keyword in package.json',"keywords"))}),await s.test('name starts with "postcss-"',{skip:c?.skipPackageNameCheck},()=>{let t="string"==typeof n.name?n.name:"";if(t.startsWith("@")){const e=t.split("/");t=e.slice(1).join("/")}e.ok(t.startsWith("postcss-"),new PackageDescriptionError(`package name "${t}" does not start with "postcss-"`,"name"))}),await s.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in a},()=>{e.ok(Object.keys(Object(n.peerDependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must be listed in "peerDependencies"',"peerDependencies")),e.ok(!Object.keys(Object(n.dependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must not be listed in "dependencies"',"dependencies"))})});const l=a().postcssPlugin;await i(l,async i=>{for(const c in p)await i.test(c,async i=>{const l=p[c];l.before&&await l.before();const u=o.join(".","test",...c.split(":")[0].split(o.posix.sep)),d=o.join(".","test",...c.replace(/:/g,".").split(o.posix.sep)),m="css";let g=`${u}.${m}`,w=`${d}.expect.${m}`,f=`${d}.result.${m}`;l.source&&(g=o.join(".","test",l.source)),l.expect&&(w=o.join(".","test",l.expect)),l.result&&(f=o.join(".","test",l.result));const k=l.plugins??[a(l.options)],h=await fileContentsOrEmptyString(g),y=await fileContentsOrEmptyString(w);let E,x=null;const S=n([noopPlugin()]).version===r([noopPlugin()]).version;try{E=await n(k).process(h,{from:g,to:f,map:{inline:!1,annotation:!1}});try{x=S?null:await r(k).process(h,{from:g,to:f,map:{inline:!1,annotation:!1}})}catch{}}catch(e){if(!(e instanceof Error))throw e;if(reduceInformationInCssSyntaxError(e),l.exception&&l.exception.test(e.message))return;throw e}e.ok(!l.exception,new OutcomeError(`expected an exception matching "${l.exception}"`,g));const P=E.css.toString();{const e=[t.writeFile(f,P,"utf8")];process.env.REWRITE_EXPECTS&&e.push(t.writeFile(w,P,"utf8")),await Promise.all(e)}y||e.ok(s.existsSync(w),new OutcomeError(`Missing expect file: "${w}"`,g)),l.after&&await l.after();const $=await fileContentsOrEmptyString(f);let O=null;try{O=await n([noopPlugin()]).process($,{from:f,to:f,map:{inline:!1,annotation:!1}})}catch{}await i.test("has expected output",()=>{e.deepEqual(P,y),e.deepEqual(E.warnings().length,l.warnings??0,`Unexpected number warnings:\n${E.warnings().toString()}`)}),await i.test("sourcemaps",()=>{e.ok(!E.map.toJSON().sources.includes("<no source>"),'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')}),await i.test("output is parsable with PostCSS",()=>{e.deepEqual(O?.warnings(),[],"Unexpected warnings on second pass")}),await i.test("The oldest and current PostCSS version produce the same result",{skip:S},()=>{e.deepEqual(x?.css?.toString(),P)})})})}}noopPlugin.postcss=!0;const c={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},p={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"rule-cloner",RuleExit(t){e.has(t)||"to-clone"===t.selector&&(e.add(t),t.cloneBefore({selector:"cloned"}))}}}},l={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"at-rule-cloner",AtRuleExit(t){if(!e.has(t))return"to-clone"===t.params?(e.add(t),void t.cloneBefore({params:"cloned"})):void("to-clone"===t.name&&(e.add(t),t.cloneBefore({name:"cloned"})))}}}};class PackageDescriptionError extends Error{constructor(e,t){super(e),this.name="PackageDescriptionError",this.stack=`${this.name}: ${this.message}\n at "${t}" (${a.pathToFileURL(o.resolve("package.json")).href}:1:1)`}}class OutcomeError extends Error{constructor(e,t){super(e),this.name="OutcomeError",this.stack=`${this.name}: ${this.message}\n at ${a.pathToFileURL(o.resolve(t)).href}:1:1`}}export{l as atRuleClonerPlugin,c as declarationClonerPlugin,postcssTape,p as ruleClonerPlugin};
import e from"node:assert/strict";import s from"node:fs/promises";import t from"node:fs";import o from"node:path";import n from"postcss";import r from"postcss-8.4";import i from"node:test";import a from"node:url";const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function fileContentsOrEmptyString(e){try{return await s.readFile(e,"utf8")}catch{return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}function postcssTape(a,c){return async p=>{c=c??{},await i("`postcss` flag is set on exported plugin creator",()=>{e.equal(a.postcss,!0)}),await i("exported plugin creator is a function",()=>{e.equal(typeof a,"function")}),await i("`postcssPlugin` is set on a plugin instance",()=>{const s=a();e.ok(s.postcssPlugin),e.equal(typeof s.postcssPlugin,"string")}),await i("package.json",async t=>{const o=await s.readFile("./package.json","utf-8"),n=JSON.parse(o);await t.test('includes "postcss-plugin" keyword',()=>{e.ok(Array.isArray(n.keywords)&&n.keywords?.includes("postcss-plugin"),new PackageDescriptionError('Missing "postcss-plugin" keyword in package.json',"keywords"))}),await t.test('name starts with "postcss-"',{skip:c?.skipPackageNameCheck},()=>{let s="string"==typeof n.name?n.name:"";if(s.startsWith("@")){const e=s.split("/");s=e.slice(1).join("/")}e.ok(s.startsWith("postcss-"),new PackageDescriptionError(`package name "${s}" does not start with "postcss-"`,"name"))}),await t.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in a},()=>{e.ok(Object.keys(Object(n.peerDependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must be listed in "peerDependencies"',"peerDependencies")),e.ok(!Object.keys(Object(n.dependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must not be listed in "dependencies"',"dependencies"))})});const l=a().postcssPlugin;await i(l,async i=>{for(const c in p)await i.test(c,async i=>{const l=p[c];l.before&&await l.before();const u=o.join(".","test",...c.split(":")[0].split(o.posix.sep)),d=o.join(".","test",...c.replace(/:/g,".").split(o.posix.sep)),m="css";let g=`${u}.${m}`,w=`${d}.expect.${m}`,f=`${d}.result.${m}`;l.source&&(g=o.join(".","test",l.source)),l.expect&&(w=o.join(".","test",l.expect)),l.result&&(f=o.join(".","test",l.result));const k=l.plugins??[a(l.options)],h=await fileContentsOrEmptyString(g),y=await fileContentsOrEmptyString(w);let E,x=null;const S=n([noopPlugin()]).version===r([noopPlugin()]).version;try{E=await n(k).process(h,{from:g,to:f,map:{inline:!1,annotation:!1}});try{x=S?null:await r(k).process(h,{from:g,to:f,map:{inline:!1,annotation:!1}})}catch{}}catch(e){if(!(e instanceof Error))throw e;if(reduceInformationInCssSyntaxError(e),l.exception&&l.exception.test(e.message))return;throw e}e.ok(!l.exception,new OutcomeError(`expected an exception matching "${l.exception}"`,g));const P=E.css.toString();{const e=[s.writeFile(f,P,"utf8")];process.env.REWRITE_EXPECTS&&e.push(s.writeFile(w,P,"utf8")),await Promise.all(e)}y||e.ok(t.existsSync(w),new OutcomeError(`Missing expect file: "${w}"`,g)),l.after&&await l.after();const $=await fileContentsOrEmptyString(f);let O=null;try{O=await n([noopPlugin()]).process($,{from:f,to:f,map:{inline:!1,annotation:!1}})}catch{}await i.test("has expected output",()=>{e.deepEqual(P,y),e.deepEqual(E.warnings().length,l.warnings??0,`Unexpected number warnings:\n${E.warnings().toString()}`)}),await i.test("sourcemaps",()=>{e.ok(!E.map.toJSON().sources.includes("<no source>"),'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')}),await i.test("output is parsable with PostCSS",()=>{e.deepEqual(O?.warnings(),[],"Unexpected warnings on second pass")}),await i.test("The oldest and current PostCSS version produce the same result",{skip:S},()=>{e.deepEqual(x?.css?.toString()?.replaceAll(/\s+/g,""),P.replaceAll(/\s+/g,""))})})})}}noopPlugin.postcss=!0;const c={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},p={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"rule-cloner",RuleExit(s){e.has(s)||"to-clone"===s.selector&&(e.add(s),s.cloneBefore({selector:"cloned"}))}}}},l={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"at-rule-cloner",AtRuleExit(s){if(!e.has(s))return"to-clone"===s.params?(e.add(s),void s.cloneBefore({params:"cloned"})):void("to-clone"===s.name&&(e.add(s),s.cloneBefore({name:"cloned"})))}}}};class PackageDescriptionError extends Error{constructor(e,s){super(e),this.name="PackageDescriptionError",this.stack=`${this.name}: ${this.message}\n at "${s}" (${a.pathToFileURL(o.resolve("package.json")).href}:1:1)`}}class OutcomeError extends Error{constructor(e,s){super(e),this.name="OutcomeError",this.stack=`${this.name}: ${this.message}\n at ${a.pathToFileURL(o.resolve(s)).href}:1:1`}}export{l as atRuleClonerPlugin,c as declarationClonerPlugin,postcssTape,p as ruleClonerPlugin};
/* node:coverage enable */
2 changes: 1 addition & 1 deletion packages/postcss-tape/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ export function postcssTape(pluginCreator: PluginCreator<unknown>, runOptions?:
'The oldest and current PostCSS version produce the same result',
{ skip: olderVersionAndCurrentVersionAreTheSame },
() => {
assert.deepEqual(resultFromOldestPostCSS?.css?.toString(), resultString);
assert.deepEqual(resultFromOldestPostCSS?.css?.toString()?.replaceAll(/\s+/g, ''), resultString.replaceAll(/\s+/g, ''));
},
);
});
Expand Down
24 changes: 2 additions & 22 deletions plugin-packs/postcss-bundler/test/basic.expect.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,8 @@
background: url("images/green.png?foo=bar");
}

/* ./imports/minified-source.css */

.foo { --var: /* a comment */; bar: red }

.foo { color: red }

.foo { color: red }

.foo { color: rgb(0 0 0) }

.foo { color: rgb(0 0 0) }

.foo { color: rgb(0 0 0) }

/* node_modules:@rmenke/css-package-main */

.box {
/* ./imports/minified-source.css */ .foo { --var: /* a comment */; bar: red } .foo { color: red } .foo { color: red } .foo { color: rgb(0 0 0) } .foo { color: rgb(0 0 0) } .foo { color: rgb(0 0 0) } /* node_modules:@rmenke/css-package-main */ .box {
background-color: green;
}

/* node_modules:@rmenke/css-package-conditional-3/styles */

.box {
} /* node_modules:@rmenke/css-package-conditional-3/styles */ .box {
background-color: green;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* imports/layer-before-external.css */

@import "data:text/css;base64,QGxheWVyIHJlc2V0LCBib290c3RyYXA=" (min-width: 300px);

@import "data:text/css;base64,QGltcG9ydCB1cmwoJ2h0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vYm9vdHN0cmFwQDUuMy4wL2Rpc3QvY3NzL2Jvb3RzdHJhcC5jc3MnKSAobWluLXdpZHRoOiAzMDBweCk=" layer(bootstrap);

@media (min-width: 300px){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
@charset "utf-8";

/* a.css */

.box {
background-color: red;
}

/* b.css */

.box {
background-color: green;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* a.css */
/* b.css */

.box {
background-color: red;
}

.box {
background-color: green;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
/* a.css */

/* b.css */

.box {
background-color: green;
}

.box {
background-color: red;
}

/* b.css */

/* a.css */

.box {
background-color: red;
}

.box {
background-color: green;
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
/* a.css */

/* b.css */

.box {
background-color: red;
}

.box {
background-color: green;
}

/* b.css */

/* a.css */

.box {
background-color: green;
}

.box {
background-color: red;
}

/* a.css */

/* b.css */

.box {
background-color: red;
}

.box {
background-color: green;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* ./styles/green.css */

@property --background-image {
syntax: '<url>';
inherits: true;
initial-value: url(./styles/green.png);
}

.box {
background-image: var(--background-image);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* ./styles/green.css */

@property --background-image {
syntax: '<url>';
inherits: true;
initial-value: url(./green.png);
}

.box {
background-image: var(--background-image);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/* a.css */
/* green.css */

@media all {

@layer alpha {

@media print {

@layer alpha {

.box {
background-color: green;
}
Expand All @@ -13,22 +18,29 @@
}
/* b.css */
/* red.css */

@media all {

@layer beta {

@media print {

@layer beta {

.box {
background-color: red;
}
}
}
}
}

@layer beta {
.box {
background-color: green;
}
}

@layer alpha {
.box {
background-color: red;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
/* a.css */
/* b.css */

@media (min-width: 1px) {

@layer a {

@media (width: 1px) {

@layer b {

.box {
background-color: red;
}
}
}
}
}

@layer a.c {
.box {
background-color: red;
}
}

@layer a.b {
.box {
background-color: green;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
/* a.css */
/* b.css */

@media (min-width: 1px) {

@layer a {

@media (min-width: 1px) {

@layer b {

.box {
background-color: red;
}
}
}
}
}

@layer a.c {
.box {
background-color: green;
}
}

@layer a.b {
.box {
background-color: red;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
@layer a;
/* green.css */

@layer b{

.box {
background-color: green;
}
}
@layer c;

@layer a {
.box {
color: red;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/* ./a.css */
@import "data:text/css;base64,QGxheWVyIGIsIGE=" print;

/* ./b.css */

/* a comment */

@import "data:text/css;base64,QGxheWVyIGEsIGI=" screen;

@import url("http://localhost:8080/green.css") screen;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@layer a, b;

/* a.css */

@layer b{
Expand All @@ -15,6 +16,7 @@
}
}
}

/* b.css */

@layer a{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/* a.css */
/* green.css */

@supports (display: block) {

@layer alpha {

@supports (foo: bar) {

@layer alpha {

.box {
background-color: green;
}
Expand All @@ -13,22 +18,29 @@
}
/* b.css */
/* red.css */

@supports (display: block) {

@layer beta {

@supports (foo: bar) {

@layer beta {

.box {
background-color: red;
}
}
}
}
}

@layer beta {
.box {
background-color: green;
}
}

@layer alpha {
.box {
background-color: red;
Expand Down
Loading
Loading