Source code

Revision control

Copy as Markdown

Other Tools

/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/PL/2.0/.
*/
// Bug 1948378: remove this exception when the eslint import plugin fully
// supports exports in package.json files
// eslint-disable-next-line import/no-unresolved
import { testRule } from "stylelint-test-rule-node";
import stylelint from "stylelint";
import useDesignTokens from "../rules/use-design-tokens.mjs";
let plugin = stylelint.createPlugin(useDesignTokens.ruleName, useDesignTokens);
let {
ruleName,
rule: { messages },
} = plugin;
testRule({
plugins: [plugin],
ruleName,
config: true,
fix: false,
accept: [
{
code: ".bg { background-color: var(--background-color-box); }",
description: "Using background-color token is valid.",
},
{
code: ".bg { background-color: var(--background-color-box, #666); }",
description:
"Using background-color token with a raw color fallback is valid.",
},
{
code: ".bg { background-color: var(--background-color-box, var(--another-token)); }",
description:
"Using background-color token with a variable fallback is valid.",
},
{
code: `
:root { --custom-token: var(--background-color-box); }
.bg { background-color: var(--custom-token); }
`,
description:
"Using a custom token that resolves to a background-color token is valid.",
},
{
code: ".bg { background-color: inherit; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: initial; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: revert; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: revert-layer; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: unset; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: transparent; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: currentColor; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: auto; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: normal; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background-color: none; }",
description: "Using a keyword is valid.",
},
{
code: ".bg { background: var(--background-color-box); }",
description: "Using background-color token is valid in the shorthand.",
},
{
code: ".bg { background: var(--background-color-box, #666); }",
description:
"Using background-color token with a raw color fallback is valid in the shorthand.",
},
{
code: ".bg { background: var(--background-color-box, var(--another-token)); }",
description:
"Using background-color token with a token fallback is valid in the shorthand.",
},
{
code: `
:root { --custom-token: var(--background-color-box); }
.bg { background: var(--custom-token); }
`,
description:
"Using a custom token that resolves to a background-color token is valid in the shorthand.",
},
{
code: ".bg { background: url('image.png'); }",
description:
"Using the background shorthand without any color declarations is valid.",
},
{
code: ".bg { background: linear-gradient(to bottom, #fff, #000) var(--background-color-box); }",
description:
"Using the background shorthand, other properties plus a background-color token is valid.",
},
{
code: ".bg { background: url('image.png') no-repeat center center / auto var(--background-color-box, oklch(69% 0.19 15)); }",
description:
"Using a background-color token with a raw color value fallback is valid in the shorthand.",
},
{
code: ".bg { background: url('image.png') fixed content-box var(--background-color-box, var(--another-token)); }",
description:
"Using a background-color token with another token fallback is valid in the shorthand.",
},
{
code: `
:root { --custom-token: var(--background-color-box); }
.bg { background: url('image.png') var(--custom-token) repeat-y fixed; }
`,
description:
"Using a custom token that resolves to a background-color token is valid in the shorthand.",
},
{
code: ".bg { background: inherit; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: initial; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: revert; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: revert-layer; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: unset; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: transparent; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: currentColor; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: auto; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: normal; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background: none; }",
description: "Using a keyword is valid in the shorthand.",
},
{
code: ".bg { background-color: calc(2 * var(--background-color-box)); }",
description: "Using calc() with a valid token inside is valid.",
},
{
code: ".bg { background-color: calc(var(--background-color-box) * -1); }",
description:
"Using calc() with negative number and background-color token is valid.",
},
{
code: ".bg { background-color: calc(var(--background-color-box) * -0.5); }",
description:
"Using calc() with negative decimal and background-color token is valid.",
},
{
code: ".bg { background-color: light-dark(var(--background-color-box), var(--background-color-box)); }",
description: "Using light-dark() with valid tokens is valid.",
},
{
code: ".bg { background-color: light-dark(transparent, transparent); }",
description: "Using light-dark() with valid keywords is valid.",
},
{
code: ".bg { background-color: color-mix(in srgb, currentColor 10%, transparent); }",
description: "Using color-mix() with valid colors is valid.",
},
{
code: ".bg { background-color: color-mix(in srgb, var(--background-color-box) 20%, transparent); }",
description: "Using color-mix() with valid token and keyword is valid.",
},
],
reject: [
{
code: ".bg { background-color: #666; }",
message: messages.rejected("#666", ["background-color"]),
description: "#666 should use a background-color design token.",
},
{
code: ".bg { background-color: #fff0; }",
message: messages.rejected("#fff0", ["background-color"]),
description: "#fff0 should use a background-color design token.",
},
{
code: ".bg { background-color: #666666; }",
message: messages.rejected("#666666", ["background-color"]),
description: "#666666 should use a background-color design token.",
},
{
code: ".bg { background-color: #ffffff00; }",
message: messages.rejected("#ffffff00", ["background-color"]),
description: "#ffffff00 should use a background-color design token.",
},
{
code: ".bg { background-color: oklch(69% 0.19 15); }",
message: messages.rejected("oklch(69% 0.19 15)", ["background-color"]),
description:
"oklch(69% 0.19 15) should use a background-color design token.",
},
{
code: ".bg { background-color: rgba(42 42 42 / 0.15); }",
message: messages.rejected("rgba(42 42 42 / 0.15)", ["background-color"]),
description:
"rgba(42 42 42 / 0.15) should use a background-color design token.",
},
{
code: ".bg { background-color: ButtonFace; }",
message: messages.rejected("ButtonFace", ["background-color"]),
description: "ButtonFace should use a background-color design token.",
},
{
code: ".bg { background-color: var(--random-token, oklch(69% 0.19 15)); }",
message: messages.rejected("var(--random-token, oklch(69% 0.19 15))", [
"background-color",
]),
description:
"var(--random-token, oklch(69% 0.19 15)) should use a background-color design token.",
},
{
code: `
:root { --custom-token: #666; }
.bg { background-color: var(--custom-token); }
`,
message: messages.rejected("var(--custom-token)", ["background-color"]),
description:
"var(--custom-token) should use a background-color design token.",
},
{
code: ".bg { background: #666; }",
message: messages.rejected("#666", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "#666 should use a background design token.",
},
{
code: ".bg { background: #fff0; }",
message: messages.rejected("#fff0", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "#fff0 should use a background design token.",
},
{
code: ".bg { background: #666666; }",
message: messages.rejected("#666666", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "#666666 should use a background design token.",
},
{
code: ".bg { background: #ffffff00; }",
message: messages.rejected("#ffffff00", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "#ffffff00 should use a background design token.",
},
{
code: ".bg { background: oklch(69% 0.19 15); }",
message: messages.rejected("oklch(69% 0.19 15)", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "oklch(69% 0.19 15) should use a background design token.",
},
{
code: ".bg { background: rgba(42 42 42 / 0.15); }",
message: messages.rejected("rgba(42 42 42 / 0.15)", [
"background-color",
"size",
"space",
"icon-size",
]),
description:
"rgba(42 42 42 / 0.15) should use a background design token.",
},
{
code: ".bg { background: border-box #666; }",
message: messages.rejected("border-box #666", [
"background-color",
"size",
"space",
"icon-size",
]),
description: "border-box #666 should use a background design token.",
},
{
code: ".bg { background: url('image.png') #fff0, #666; }",
message: messages.rejected("url('image.png') #fff0, #666", [
"background-color",
"size",
"space",
"icon-size",
]),
description:
"url('image.png') #fff0, #666 should use a background design token.",
},
{
code: ".bg { background: url('image.png') oklch(69% 0.19 15) repeat-y; }",
message: messages.rejected(
"url('image.png') oklch(69% 0.19 15) repeat-y",
["background-color", "size", "space", "icon-size"]
),
description:
"url('image.png') oklch(69% 0.19 15) repeat-y should use a background design token.",
},
{
code: ".bg { background: url('image.png') top center fixed #ffffff00; }",
message: messages.rejected(
"url('image.png') top center fixed #ffffff00",
["background-color", "size", "space", "icon-size"]
),
description:
"url('image.png') top center fixed #ffffff00 should use a background design token.",
},
{
code: ".bg { background: url('image.png') center left / auto no-repeat scroll content-box padding-box red, rgba(42 42 42 / 0.15); }",
message: messages.rejected(
"url('image.png') center left / auto no-repeat scroll content-box padding-box red, rgba(42 42 42 / 0.15)",
["background-color", "size", "space", "icon-size"]
),
description:
"url('image.png') center left / auto no-repeat scroll content-box padding-box red, rgba(42 42 42 / 0.15) should use a background design token.",
},
{
code: ".bg { background: url('image.png') var(--random-token, rgba(42 42 42 / 0.15)); }",
message: messages.rejected(
"url('image.png') var(--random-token, rgba(42 42 42 / 0.15))",
["background-color", "size", "space", "icon-size"]
),
description:
"url('image.png') var(--random-token, rgba(42 42 42 / 0.15)) should use a background design token.",
},
{
code: ".bg { background: url('image.png') Canvas; }",
message: messages.rejected("url('image.png') Canvas", [
"background-color",
"size",
"space",
"icon-size",
]),
description:
"url('image.png') Canvas should use a background design token.",
},
{
code: `
:root { --custom-token: #666666; }
.bg { background: url('image.png') no-repeat center / auto var(--custom-token); }
`,
message: messages.rejected(
"url('image.png') no-repeat center / auto var(--custom-token)",
["background-color", "size", "space", "icon-size"]
),
description:
"url('image.png') no-repeat center / auto var(--custom-token) should use a background design token.",
},
{
code: ".bg { background-color: calc(2 * #666); }",
message: messages.rejected("calc(2 * #666)", ["background-color"]),
description: "calc() with invalid color inside should be rejected.",
},
{
code: ".bg { background-color: light-dark(#666, var(--background-color-box)); }",
message: messages.rejected(
"light-dark(#666, var(--background-color-box))",
["background-color"]
),
description: "light-dark() with invalid first color should be rejected.",
},
{
code: ".bg { background-color: light-dark(var(--background-color-box), #666); }",
message: messages.rejected(
"light-dark(var(--background-color-box), #666)",
["background-color"]
),
description: "light-dark() with invalid second color should be rejected.",
},
{
code: ".bg { background-color: color-mix(in srgb, #666 10%, transparent); }",
message: messages.rejected("color-mix(in srgb, #666 10%, transparent)", [
"background-color",
]),
description: "color-mix() with invalid first color should be rejected.",
},
{
code: ".bg { background-color: color-mix(in srgb, currentColor 10%, #666); }",
message: messages.rejected("color-mix(in srgb, currentColor 10%, #666)", [
"background-color",
]),
description: "color-mix() with invalid second color should be rejected.",
},
],
});
testRule({
plugins: [plugin],
ruleName,
config: true,
fix: true,
reject: [
{
code: ".bg { background-color: #fff; }",
fixed: ".bg { background-color: white; }",
message: messages.rejected("#fff", ["background-color"], "white"),
description: "#fff should be fixed to white.",
},
{
code: ".bg { background-color: #ffffff; }",
fixed: ".bg { background-color: white; }",
message: messages.rejected("#ffffff", ["background-color"], "white"),
description: "#ffffff should be fixed to white.",
},
{
code: ".bg { background-color: #FFF; }",
fixed: ".bg { background-color: white; }",
message: messages.rejected("#FFF", ["background-color"], "white"),
description: "#FFF should be fixed to white.",
},
{
code: ".bg { background-color: #FFFFFF; }",
fixed: ".bg { background-color: white; }",
message: messages.rejected("#FFFFFF", ["background-color"], "white"),
description: "#FFFFFF should be fixed to white.",
},
{
code: ".bg { background-color: #000; }",
fixed: ".bg { background-color: black; }",
message: messages.rejected("#000", ["background-color"], "black"),
description: "#000 should be fixed to black.",
},
{
code: ".bg { background-color: #000000; }",
fixed: ".bg { background-color: black; }",
message: messages.rejected("#000000", ["background-color"], "black"),
description: "#000000 should be fixed to black.",
},
{
code: ".bg { background: #fff; }",
fixed: ".bg { background: white; }",
message: messages.rejected(
"#fff",
["background-color", "size", "space", "icon-size"],
"white"
),
description: "#fff should be fixed to white in background shorthand.",
},
{
code: ".bg { background: #ffffff; }",
fixed: ".bg { background: white; }",
message: messages.rejected(
"#ffffff",
["background-color", "size", "space", "icon-size"],
"white"
),
description: "#ffffff should be fixed to white in background shorthand.",
},
{
code: ".bg { background: #000; }",
fixed: ".bg { background: black; }",
message: messages.rejected(
"#000",
["background-color", "size", "space", "icon-size"],
"black"
),
description: "#000 should be fixed to black in background shorthand.",
},
{
code: ".bg { background: #000000; }",
fixed: ".bg { background: black; }",
message: messages.rejected(
"#000000",
["background-color", "size", "space", "icon-size"],
"black"
),
description: "#000000 should be fixed to black in background shorthand.",
},
{
code: ".bg { background: url('image.png') #fff; }",
fixed: ".bg { background: url('image.png') white; }",
message: messages.rejected(
"url('image.png') #fff",
["background-color", "size", "space", "icon-size"],
"url('image.png') white"
),
description:
"#fff should be fixed to white in background shorthand with other properties.",
},
{
code: ".bg { background: url('image.png') #000 repeat-y; }",
fixed: ".bg { background: url('image.png') black repeat-y; }",
message: messages.rejected(
"url('image.png') #000 repeat-y",
["background-color", "size", "space", "icon-size"],
"url('image.png') black repeat-y"
),
description:
"#000 should be fixed to black in background shorthand with other properties.",
},
],
});