Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pretty-format): allow to opt out from sorting object keys with compareKeys: null #12443

Merged
merged 6 commits into from Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/jest-schemas/src/index.ts
Expand Up @@ -10,6 +10,7 @@ import {Static, Type} from '@sinclair/typebox';
const RawSnapshotFormat = Type.Partial(
Type.Object({
callToJSON: Type.Readonly(Type.Boolean()),
compareKeys: Type.Readonly(Type.Null()),
SimenB marked this conversation as resolved.
Show resolved Hide resolved
escapeRegex: Type.Readonly(Type.Boolean()),
escapeString: Type.Readonly(Type.Boolean()),
highlight: Type.Readonly(Type.Boolean()),
Expand Down
4 changes: 2 additions & 2 deletions packages/pretty-format/README.md
Expand Up @@ -69,7 +69,7 @@ console.log(prettyFormat(onClick, options));
| key | type | default | description |
| :-------------------- | :-------- | :--------- | :------------------------------------------------------ |
| `callToJSON` | `boolean` | `true` | call `toJSON` method (if it exists) on objects |
| `compareKeys` | `function`| `undefined`| compare function used when sorting object keys |
| `compareKeys` | `function|null`| `undefined`| compare function used when sorting object keys, `null` can be used to skip over sorting |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table should be realigned

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for the other one 😀

there's also a type error here, but I guess you might know that already? (I need to read through the issues here, I've forgotten all context)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed both - let me know if the solution for the types of problem satisfies your needs. The problem was that when DEFAULT_OPTIONS were typed as Options they included a function type on the snapshotFormat property. This was OK for the pretty-format lib itself but later on, those DEFAULT_OPTIONS were used in the jest-config where the function type on that property is not valid. By changing the type to a subtype of Options we don't lose any type-safety and we fix the problem because now DEFAULT_OPTIONS don't include that function type there and that runtime object just doesn't include snapshotFormat property.

| `escapeRegex` | `boolean` | `false` | escape special characters in regular expressions |
| `escapeString` | `boolean` | `true` | escape special characters in strings |
| `highlight` | `boolean` | `false` | highlight syntax with colors in terminal (some plugins) |
Expand Down Expand Up @@ -209,7 +209,7 @@ Write `serialize` to return a string, given the arguments:
| key | type | description |
| :------------------ | :-------- | :------------------------------------------------------ |
| `callToJSON` | `boolean` | call `toJSON` method (if it exists) on objects |
| `compareKeys` | `function`| compare function used when sorting object keys |
| `compareKeys` | `function|null`| compare function used when sorting object keys, `null` can be used to skip over sorting |
| `colors` | `Object` | escape codes for colors to highlight syntax |
| `escapeRegex` | `boolean` | escape special characters in regular expressions |
| `escapeString` | `boolean` | escape special characters in strings |
Expand Down
10 changes: 9 additions & 1 deletion packages/pretty-format/src/__tests__/prettyFormat.test.ts
Expand Up @@ -334,7 +334,7 @@ describe('prettyFormat()', () => {
expect(prettyFormat(val)).toEqual('Object {\n "a": 2,\n "b": 1,\n}');
});

it('prints an object with keys in their original order', () => {
it('prints an object with keys in their original order with the appropriate comparing function', () => {
// eslint-disable-next-line sort-keys
const val = {b: 1, a: 2};
const compareKeys = () => 0;
Expand All @@ -343,6 +343,14 @@ describe('prettyFormat()', () => {
);
});

it('prints an object with keys in their original order with compareKeys set to null', () => {
// eslint-disable-next-line sort-keys
const val = {b: 1, a: 2};
expect(prettyFormat(val, {compareKeys: null})).toEqual(
'Object {\n "b": 1,\n "a": 2,\n}',
);
});

it('prints an object with keys sorted in reverse order', () => {
const val = {a: 1, b: 2};
const compareKeys = (a: string, b: string) => (a > b ? -1 : 1);
Expand Down
4 changes: 3 additions & 1 deletion packages/pretty-format/src/collections.ts
Expand Up @@ -12,7 +12,9 @@ const getKeysOfEnumerableProperties = (
object: Record<string, unknown>,
compareKeys: CompareKeys,
) => {
const keys: Array<string | symbol> = Object.keys(object).sort(compareKeys);
const rawKeys = Object.keys(object);
const keys: Array<string | symbol> =
compareKeys !== null ? rawKeys.sort(compareKeys) : rawKeys;

if (Object.getOwnPropertySymbols) {
Object.getOwnPropertySymbols(object).forEach(symbol => {
Expand Down
2 changes: 1 addition & 1 deletion packages/pretty-format/src/index.ts
Expand Up @@ -482,7 +482,7 @@ const getConfig = (options?: OptionsReceived): Config => ({
callToJSON: options?.callToJSON ?? DEFAULT_OPTIONS.callToJSON,
colors: options?.highlight ? getColorsHighlight(options) : getColorsEmpty(),
compareKeys:
typeof options?.compareKeys === 'function'
typeof options?.compareKeys === 'function' || options?.compareKeys === null
? options.compareKeys
: DEFAULT_OPTIONS.compareKeys,
escapeRegex: getEscapeRegex(options),
Expand Down
5 changes: 3 additions & 2 deletions packages/pretty-format/src/types.ts
Expand Up @@ -20,7 +20,7 @@ type Print = (arg0: unknown) => string;

export type Theme = Options['theme'];

export type CompareKeys = ((a: string, b: string) => number) | undefined;
export type CompareKeys = ((a: string, b: string) => number) | null | undefined;

type RequiredOptions = Required<PrettyFormatOptions>;

Expand All @@ -30,7 +30,8 @@ export interface Options
theme: Required<RequiredOptions['theme']>;
}

export interface PrettyFormatOptions extends SnapshotFormat {
export interface PrettyFormatOptions
extends Omit<SnapshotFormat, 'compareKeys'> {
compareKeys?: CompareKeys;
plugins?: Plugins;
}
Expand Down