From bfcc1447984e81a1294ca2c49cb0cc9ccee02a3d Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Wed, 27 Nov 2024 17:06:19 +0100 Subject: [PATCH] Reduce precision of `oklab()` arguments in test snapshots (#15210) After the changes in #15201, our Windows CI started to fail. The problem is that lightningcss now needs to convert `oklch` colors into the `oklab` space to inline some `color-mix()` functions. The problem, though, is that this calculation seems to have rounding differences between macOS, Linux, and Windows. Since we still want to _define the default color space in `oklch`_ and _use lightningcss as a post-processor in our unit tests so we have a better coverage of the output_, this PR attempts to fix the issue by adding a custom vitest serializer. It will find usages of the `oklab()` function with arguments that have lots of decimal places (at least 6 decimal places). What it then does is simply cut off any excess decimal places to truncate the output to 5 places. E.g.: ```diff - oklab(62.7955% .224863 .125846 / .75); + oklab(62.7955% .22486 .12584 / .75); ``` ## Test Plan I updated the CI workflow file to make all three builds run in CI and observed that they are now all green again. Screenshot 2024-11-27 at 14 54 52 --- .../src/__snapshots__/utilities.test.ts.snap | 18 +++++----- .../tailwindcss/src/compat/plugin-api.test.ts | 2 +- .../tailwindcss/src/css-functions.test.ts | 26 ++++++-------- packages/tailwindcss/src/index.test.ts | 2 +- .../src/test-utils/custom-serializer.ts | 22 ++++++++++++ packages/tailwindcss/src/utilities.test.ts | 36 +++++++++---------- packages/tailwindcss/vitest.config.ts | 5 +++ 7 files changed, 66 insertions(+), 45 deletions(-) create mode 100644 packages/tailwindcss/src/test-utils/custom-serializer.ts diff --git a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap index 1b51e5fc0..e39b3dea6 100644 --- a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap @@ -63,7 +63,7 @@ exports[`border-* 1`] = ` } .border-\\[\\#0088cc\\]\\/50 { - border-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-\\[color\\:var\\(--my-color\\)\\] { @@ -196,7 +196,7 @@ exports[`border-b-* 1`] = ` } .border-b-\\[\\#0088cc\\]\\/50 { - border-bottom-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-bottom-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-b-\\[color\\:var\\(--my-color\\)\\] { @@ -329,7 +329,7 @@ exports[`border-e-* 1`] = ` } .border-e-\\[\\#0088cc\\]\\/50 { - border-inline-end-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-inline-end-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-e-\\[color\\:var\\(--my-color\\)\\] { @@ -462,7 +462,7 @@ exports[`border-l-* 1`] = ` } .border-l-\\[\\#0088cc\\]\\/50 { - border-left-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-left-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-l-\\[color\\:var\\(--my-color\\)\\] { @@ -595,7 +595,7 @@ exports[`border-r-* 1`] = ` } .border-r-\\[\\#0088cc\\]\\/50 { - border-right-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-right-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-r-\\[color\\:var\\(--my-color\\)\\] { @@ -728,7 +728,7 @@ exports[`border-s-* 1`] = ` } .border-s-\\[\\#0088cc\\]\\/50 { - border-inline-start-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-inline-start-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-s-\\[color\\:var\\(--my-color\\)\\] { @@ -861,7 +861,7 @@ exports[`border-t-* 1`] = ` } .border-t-\\[\\#0088cc\\]\\/50 { - border-top-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-top-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-t-\\[color\\:var\\(--my-color\\)\\] { @@ -994,7 +994,7 @@ exports[`border-x-* 1`] = ` } .border-x-\\[\\#0088cc\\]\\/50 { - border-inline-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-inline-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-x-\\[color\\:var\\(--my-color\\)\\] { @@ -1127,7 +1127,7 @@ exports[`border-y-* 1`] = ` } .border-y-\\[\\#0088cc\\]\\/50 { - border-block-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-block-color: oklab(59.9824% -.06725 -.12414 / .5); } .border-y-\\[color\\:var\\(--my-color\\)\\] { diff --git a/packages/tailwindcss/src/compat/plugin-api.test.ts b/packages/tailwindcss/src/compat/plugin-api.test.ts index 0de2cfa46..6a0c0e4bc 100644 --- a/packages/tailwindcss/src/compat/plugin-api.test.ts +++ b/packages/tailwindcss/src/compat/plugin-api.test.ts @@ -3462,7 +3462,7 @@ describe('matchUtilities()', () => { } .scrollbar-\\[\\#08c\\]\\/50 { - scrollbar-color: oklab(59.9824% -.0672516 -.124144 / .5); + scrollbar-color: oklab(59.9824% -.06725 -.12414 / .5); } .scrollbar-\\[2px\\] { diff --git a/packages/tailwindcss/src/css-functions.test.ts b/packages/tailwindcss/src/css-functions.test.ts index 940389c22..f042b40c2 100644 --- a/packages/tailwindcss/src/css-functions.test.ts +++ b/packages/tailwindcss/src/css-functions.test.ts @@ -152,7 +152,7 @@ describe('theme function', () => { } .red { - color: oklab(62.7955% .224863 .125846 / .75); + color: oklab(62.7955% .22486 .12584 / .75); }" `) }) @@ -173,7 +173,7 @@ describe('theme function', () => { } .red { - color: oklab(62.7955% .224863 .125846 / .75); + color: oklab(62.7955% .22486 .12584 / .75); }" `) }) @@ -194,7 +194,7 @@ describe('theme function', () => { } .red { - color: oklab(62.7955% .224863 .125846 / .75); + color: oklab(62.7955% .22486 .12584 / .75); }" `) }) @@ -455,7 +455,7 @@ describe('theme function', () => { } .red { - color: oklab(62.7955% .224863 .125846 / .25); + color: oklab(62.7955% .22486 .12584 / .25); }" `) }) @@ -533,11 +533,11 @@ describe('theme function', () => { ).toMatchInlineSnapshot(` ":root { --color-red-500: red; - --color-foo: oklab(62.7955% .224863 .125846 / .5); + --color-foo: oklab(62.7955% .22486 .12584 / .5); } .red { - color: oklab(62.7955% .224863 .125846 / .25); + color: oklab(62.7955% .22486 .12584 / .25); }" `) }) @@ -581,7 +581,7 @@ describe('theme function', () => { } .red { - color: oklab(62.7955% .224863 .125846 / .5); + color: oklab(62.7955% .22486 .12584 / .5); }" `) }) @@ -873,13 +873,7 @@ describe('in plugins', () => { --color-red: oklch(62% 0.25 30); --color-orange: oklch(79% 0.17 70); --color-blue: oklch(45% 0.31 264); - - /* - Using oklab because Lightning converts the color to oklab when using - color-mix() and the results are off by 0.00000001 between macOS and - Linux. - */ - --color-pink: oklab(87% 0.07 0); + --color-pink: oklch(87% 0.07 7); } @layer utilities { @tailwind utilities; @@ -915,8 +909,8 @@ describe('in plugins', () => { .my-base-rule { color: oklch(62% .25 30); background-color: oklch(45% .31 264); - border-color: oklab(87% .07 0 / .1); - outline-color: oklab(79% .0581434 .159748 / .15); + border-color: oklab(87% .06947 .00853 / .1); + outline-color: oklab(79% .05814 .15974 / .15); } } diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 6ebcb7f24..4a471ffc4 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -182,7 +182,7 @@ describe('arbitrary properties', () => { it('should generate arbitrary properties with modifiers', async () => { expect(await run(['[color:red]/50'])).toMatchInlineSnapshot(` ".\\[color\\:red\\]\\/50 { - color: oklab(62.7955% .224863 .125846 / .5); + color: oklab(62.7955% .22486 .12584 / .5); }" `) }) diff --git a/packages/tailwindcss/src/test-utils/custom-serializer.ts b/packages/tailwindcss/src/test-utils/custom-serializer.ts new file mode 100644 index 000000000..ff2b0a3f0 --- /dev/null +++ b/packages/tailwindcss/src/test-utils/custom-serializer.ts @@ -0,0 +1,22 @@ +import type { SnapshotSerializer } from 'vitest' + +// We're reducing the precision of parameters to the `oklab()` function from +// our snapshots as we've observed lightningcss generating different decimal +// places in the last position when run on different operating systems. +const HIGH_PRECISION_OKLAB = /oklab\(\d{1,2}\.?\d{0,4}% -?\.(\d{6,8}) -?\.(\d{6,8}) \/ \.\d{1,2}\)/g + +export default { + test(val) { + return typeof val === 'string' && val.match(HIGH_PRECISION_OKLAB) !== null + }, + serialize(val, config, indentation, depth, refs, printer) { + if (typeof val !== 'string') { + throw new Error('This was already tested in the test() callback') + } + + let replaced = val.replaceAll(HIGH_PRECISION_OKLAB, (match, first, second) => { + return match.replaceAll(first, first.slice(0, 5)).replaceAll(second, second.slice(0, 5)) + }) + return printer(replaced, config, indentation, depth, refs) + }, +} satisfies SnapshotSerializer diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 83af79ff3..65602d7ab 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -8373,7 +8373,7 @@ test('accent', async () => { } .accent-\\[\\#0088cc\\]\\/50, .accent-\\[\\#0088cc\\]\\/\\[0\\.5\\], .accent-\\[\\#0088cc\\]\\/\\[50\\%\\] { - accent-color: oklab(59.9824% -.0672516 -.124144 / .5); + accent-color: oklab(59.9824% -.06725 -.12414 / .5); } .accent-current { @@ -8488,7 +8488,7 @@ test('caret', async () => { } .caret-\\[\\#0088cc\\]\\/50, .caret-\\[\\#0088cc\\]\\/\\[0\\.5\\], .caret-\\[\\#0088cc\\]\\/\\[50\\%\\] { - caret-color: oklab(59.9824% -.0672516 -.124144 / .5); + caret-color: oklab(59.9824% -.06725 -.12414 / .5); } .caret-current { @@ -8601,7 +8601,7 @@ test('divide-color', async () => { } :where(.divide-\\[\\#0088cc\\]\\/50 > :not(:last-child)), :where(.divide-\\[\\#0088cc\\]\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-\\[\\#0088cc\\]\\/\\[50\\%\\] > :not(:last-child)) { - border-color: oklab(59.9824% -.0672516 -.124144 / .5); + border-color: oklab(59.9824% -.06725 -.12414 / .5); } :where(.divide-current > :not(:last-child)) { @@ -10499,7 +10499,7 @@ test('bg', async () => { } .bg-\\[\\#0088cc\\]\\/50, .bg-\\[\\#0088cc\\]\\/\\[0\\.5\\], .bg-\\[\\#0088cc\\]\\/\\[50\\%\\] { - background-color: oklab(59.9824% -.0672516 -.124144 / .5); + background-color: oklab(59.9824% -.06725 -.12414 / .5); } .bg-\\[color\\:var\\(--some-var\\)\\] { @@ -11113,7 +11113,7 @@ test('from', async () => { } .from-\\[\\#0088cc\\]\\/50, .from-\\[\\#0088cc\\]\\/\\[0\\.5\\], .from-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-gradient-from: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-gradient-from: oklab(59.9824% -.06725 -.12414 / .5); --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position, ) var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); } @@ -11349,7 +11349,7 @@ test('via', async () => { } .via-\\[\\#0088cc\\]\\/50, .via-\\[\\#0088cc\\]\\/\\[0\\.5\\], .via-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-gradient-via: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-gradient-via: oklab(59.9824% -.06725 -.12414 / .5); --tw-gradient-via-stops: var(--tw-gradient-position, ) var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); --tw-gradient-stops: var(--tw-gradient-via-stops); } @@ -11593,7 +11593,7 @@ test('to', async () => { } .to-\\[\\#0088cc\\]\\/50, .to-\\[\\#0088cc\\]\\/\\[0\\.5\\], .to-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-gradient-to: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-gradient-to: oklab(59.9824% -.06725 -.12414 / .5); --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position, ) var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); } @@ -12157,7 +12157,7 @@ test('fill', async () => { } .fill-\\[\\#0088cc\\]\\/50, .fill-\\[\\#0088cc\\]\\/\\[0\\.5\\], .fill-\\[\\#0088cc\\]\\/\\[50\\%\\] { - fill: oklab(59.9824% -.0672516 -.124144 / .5); + fill: oklab(59.9824% -.06725 -.12414 / .5); } .fill-current { @@ -12278,7 +12278,7 @@ test('stroke', async () => { } .stroke-\\[\\#0088cc\\]\\/50, .stroke-\\[\\#0088cc\\]\\/\\[0\\.5\\], .stroke-\\[\\#0088cc\\]\\/\\[50\\%\\] { - stroke: oklab(59.9824% -.0672516 -.124144 / .5); + stroke: oklab(59.9824% -.06725 -.12414 / .5); } .stroke-\\[color\\:var\\(--my-color\\)\\] { @@ -13276,7 +13276,7 @@ test('placeholder', async () => { } .placeholder-\\[\\#0088cc\\]\\/50::placeholder, .placeholder-\\[\\#0088cc\\]\\/\\[0\\.5\\]::placeholder, .placeholder-\\[\\#0088cc\\]\\/\\[50\\%\\]::placeholder { - color: oklab(59.9824% -.0672516 -.124144 / .5); + color: oklab(59.9824% -.06725 -.12414 / .5); } .placeholder-current::placeholder { @@ -13401,7 +13401,7 @@ test('decoration', async () => { } .decoration-\\[\\#0088cc\\]\\/50, .decoration-\\[\\#0088cc\\]\\/\\[0\\.5\\], .decoration-\\[\\#0088cc\\]\\/\\[50\\%\\] { - text-decoration-color: oklab(59.9824% -.0672516 -.124144 / .5); + text-decoration-color: oklab(59.9824% -.06725 -.12414 / .5); } .decoration-\\[color\\:var\\(--my-color\\)\\] { @@ -15180,7 +15180,7 @@ test('outline', async () => { } .outline-\\[\\#0088cc\\]\\/50, .outline-\\[\\#0088cc\\]\\/\\[0\\.5\\], .outline-\\[\\#0088cc\\]\\/\\[50\\%\\] { - outline-color: oklab(59.9824% -.0672516 -.124144 / .5); + outline-color: oklab(59.9824% -.06725 -.12414 / .5); } .outline-\\[black\\] { @@ -15612,7 +15612,7 @@ test('text', async () => { } .text-\\[\\#0088cc\\]\\/50, .text-\\[\\#0088cc\\]\\/\\[0\\.5\\], .text-\\[\\#0088cc\\]\\/\\[50\\%\\] { - color: oklab(59.9824% -.0672516 -.124144 / .5); + color: oklab(59.9824% -.06725 -.12414 / .5); } .text-\\[color\\:var\\(--my-color\\)\\] { @@ -15781,7 +15781,7 @@ test('shadow', async () => { } .shadow-\\[\\#0088cc\\]\\/50, .shadow-\\[\\#0088cc\\]\\/\\[0\\.5\\], .shadow-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-shadow-color: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-shadow-color: oklab(59.9824% -.06725 -.12414 / .5); } .shadow-\\[color\\:var\\(--value\\)\\] { @@ -16024,7 +16024,7 @@ test('inset-shadow', async () => { } .inset-shadow-\\[\\#0088cc\\]\\/50, .inset-shadow-\\[\\#0088cc\\]\\/\\[0\\.5\\], .inset-shadow-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-inset-shadow-color: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-inset-shadow-color: oklab(59.9824% -.06725 -.12414 / .5); } .inset-shadow-\\[color\\:var\\(--value\\)\\] { @@ -16273,7 +16273,7 @@ test('ring', async () => { } .ring-\\[\\#0088cc\\]\\/50, .ring-\\[\\#0088cc\\]\\/\\[0\\.5\\], .ring-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-ring-color: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-ring-color: oklab(59.9824% -.06725 -.12414 / .5); } .ring-\\[color\\:var\\(--my-color\\)\\] { @@ -16548,7 +16548,7 @@ test('inset-ring', async () => { } .inset-ring-\\[\\#0088cc\\]\\/50, .inset-ring-\\[\\#0088cc\\]\\/\\[0\\.5\\], .inset-ring-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-inset-ring-color: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-inset-ring-color: oklab(59.9824% -.06725 -.12414 / .5); } .inset-ring-\\[color\\:var\\(--my-color\\)\\] { @@ -16811,7 +16811,7 @@ test('ring-offset', async () => { } .ring-offset-\\[\\#0088cc\\]\\/50, .ring-offset-\\[\\#0088cc\\]\\/\\[0\\.5\\], .ring-offset-\\[\\#0088cc\\]\\/\\[50\\%\\] { - --tw-ring-offset-color: oklab(59.9824% -.0672516 -.124144 / .5); + --tw-ring-offset-color: oklab(59.9824% -.06725 -.12414 / .5); } .ring-offset-\\[color\\:var\\(--my-color\\)\\] { diff --git a/packages/tailwindcss/vitest.config.ts b/packages/tailwindcss/vitest.config.ts index 880f8aaa9..b13b94d07 100644 --- a/packages/tailwindcss/vitest.config.ts +++ b/packages/tailwindcss/vitest.config.ts @@ -1,7 +1,12 @@ +import path from 'node:path' +import { fileURLToPath } from 'node:url' import { defineConfig } from 'vitest/config' +const __dirname = fileURLToPath(new URL('.', import.meta.url)) + export default defineConfig({ test: { + snapshotSerializers: [path.resolve(__dirname, 'src/test-utils/custom-serializer.ts')], exclude: ['**/*.spec.?(c|m)[jt]s?(x)', 'integrations/**/*'], }, })