fix: support snapshot with no object key sorting (#8136)

Co-authored-by: Vladimir <sleuths.slews0s@icloud.com>
This commit is contained in:
Hiroshi Ogawa 2025-07-14 22:11:35 +09:00 committed by GitHub
parent 66a403acdc
commit e85e396f00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 150 additions and 2 deletions

View File

@ -24,6 +24,9 @@ export type Theme = Required<{
value?: string
}>
/**
* compare function used when sorting object keys, `null` can be used to skip over sorting.
*/
export type CompareKeys = ((a: string, b: string) => number) | null | undefined
type RequiredOptions = Required<PrettyFormatOptions>

View File

@ -489,6 +489,10 @@ export function resolveConfig(
if (resolved.snapshotFormat && 'plugins' in resolved.snapshotFormat) {
(resolved.snapshotFormat as any).plugins = []
// TODO: support it via separate config (like DiffOptions) or via `Function.toString()`
if (typeof resolved.snapshotFormat.compareKeys === 'function') {
throw new TypeError(`"snapshotFormat.compareKeys" function is not supported.`)
}
}
const UPDATE_SNAPSHOT = resolved.update || process.env.UPDATE_SNAPSHOT

View File

@ -120,7 +120,6 @@ export function serializeConfig(
updateSnapshot: coreConfig.snapshotOptions.updateSnapshot,
snapshotFormat: {
...coreConfig.snapshotOptions.snapshotFormat,
compareKeys: undefined,
},
expand:
config.snapshotOptions.expand

View File

@ -568,7 +568,9 @@ export interface InlineConfig {
/**
* Format options for snapshot testing.
*/
snapshotFormat?: Omit<PrettyFormatOptions, 'plugins'>
snapshotFormat?: Omit<PrettyFormatOptions, 'plugins' | 'compareKeys'> & {
compareKeys?: null | undefined
}
/**
* Path to a module which has a default export of diff config.

View File

@ -0,0 +1,85 @@
import fs from 'node:fs'
import { join } from 'node:path'
import { expect, test } from 'vitest'
import { runVitest } from '../../test-utils'
test('compareKeys', async () => {
const root = join(import.meta.dirname, 'fixtures/compare-keys')
fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true })
// compareKeys null
let vitest = await runVitest({
root,
update: true,
snapshotFormat: {
compareKeys: null,
},
})
expect(vitest.stderr).toBe('')
expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(`
"// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[\`compareKeys 1\`] = \`
{
"a": 1,
"b": 2,
"c": 3,
}
\`;
exports[\`compareKeys 2\`] = \`
{
"c": 1,
"b": 2,
"a": 3,
}
\`;
exports[\`compareKeys 3\`] = \`
{
"b": 1,
"a": 2,
"c": 3,
}
\`;
"
`)
// compareKeys undefined
vitest = await runVitest({
root,
update: true,
snapshotFormat: {
compareKeys: undefined,
},
})
expect(vitest.stderr).toBe('')
expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(`
"// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[\`compareKeys 1\`] = \`
{
"a": 1,
"b": 2,
"c": 3,
}
\`;
exports[\`compareKeys 2\`] = \`
{
"a": 3,
"b": 2,
"c": 1,
}
\`;
exports[\`compareKeys 3\`] = \`
{
"a": 2,
"b": 1,
"c": 3,
}
\`;
"
`)
})

View File

@ -0,0 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compareKeys 1`] = `
{
"a": 1,
"b": 2,
"c": 3,
}
`;
exports[`compareKeys 2`] = `
{
"a": 3,
"b": 2,
"c": 1,
}
`;
exports[`compareKeys 3`] = `
{
"a": 2,
"b": 1,
"c": 3,
}
`;

View File

@ -0,0 +1,21 @@
import { test, expect } from 'vitest';
test('compareKeys', () => {
expect({
a: 1,
b: 2,
c: 3,
}).toMatchSnapshot();
expect({
c: 1,
b: 2,
a: 3,
}).toMatchSnapshot();
expect({
b: 1,
a: 2,
c: 3,
}).toMatchSnapshot();
});

View File

@ -0,0 +1,9 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
snapshotFormat: {
// compareKeys: null,
}
}
})