UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

157 lines (143 loc) 4.19 kB
import {createEnv} from "../stubs/TestEnvironment"; import {should} from "fuse-test-runner"; import {CSSPlugin} from "../../plugins/stylesheet/CSSplugin"; import {PostCSS} from "../../plugins/stylesheet/PostCSSPlugin"; const postcss = require("postcss"); const changeDisplayPlugin = postcss.plugin("ChangeDisplayPlugin", function (options) { return function (css) { css.walkRules(function (rule) { rule.walkDecls(function (decl, i) { if (decl.prop === "display") { decl.value = "block"; } }); }); }; }); // This is essentially how the url plugin works // It requires the global postcss options to be passed through ("from", "to") const urlPlugin = postcss.plugin("UrlPlugin", function (options) { return function (css, result) { let opts = result.opts; css.walkRules(function (rule) { rule.walkDecls(function (decl) { let pattern = /(url\(\s*['"]?)([^"')]+)(["']?\s*\))/g; if (pattern.test(decl.value)) { decl.value = decl.value .replace(pattern, (matched, before, url, after) => { const newUrl = opts.from + "/" + url; return `${before}${newUrl}${after}`; }); } }); }); }; }); const idToClassPlugin = postcss.plugin("IdToClass", function (options) { return function (css) { css.walkRules(function (rule) { if (rule.selector && rule.selector[0] === "#") { rule.selector = "." + rule.selector.slice(1); } }); }; }); export class PostcssPluginTest { "Should be unmodified with no plugins"() { return setup({ plugins: [ [PostCSS(), CSSPlugin({})] ] }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`display: grid;`); }); } "Should execute single plugin"() { return setup({ plugins: [ [PostCSS([changeDisplayPlugin]), CSSPlugin({})] ] }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`display: block`); }); } "Should execute several plugins"() { return setup({ plugins: [ [PostCSS([changeDisplayPlugin, idToClassPlugin]), CSSPlugin({})] ] }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`display: block`); should(out).notFindString(`#moon`); should(out).findString(`.moon`); }); } "Should execute several plugins (legacy option)"() { return setup({ plugins: [ [PostCSS([changeDisplayPlugin], {plugins: [idToClassPlugin]}), CSSPlugin({})] ] }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`display: block`); should(out).notFindString(`#moon`); should(out).findString(`.moon`); }); } "Should execute several plugins (legacy option 2)"() { return setup({ plugins: [ [PostCSS({plugins: [changeDisplayPlugin, idToClassPlugin]}), CSSPlugin({})] ] }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`display: block`); should(out).notFindString(`#moon`); should(out).findString(`.moon`); }); } "Should be able to pass options to postcss"() { return setup({ plugins: [ [PostCSS([urlPlugin], {from: "./somedir"}), CSSPlugin({})] ], styleContent: ` body { background-image: url("paper.gif"); } ` }) .then((result) => { const out = result.projectContents.toString(); should(out).findString(`background-image: url(\\"./somedir/paper.gif\\")`); }); } } const style = ` .grid { display: grid; } #moon { color: #555; } `; function setup({plugins, styleContent = style}) { return createEnv({ project: { files: { "index.ts": `exports.style = require("./style.css")`, "style.css": styleContent }, plugins: plugins, instructions: "index.ts", }, }) }