-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathformat-element.ts
93 lines (82 loc) · 2.64 KB
/
format-element.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import type { ReactTestInstance, ReactTestRendererJSON } from 'react-test-renderer';
import type { NewPlugin } from 'pretty-format';
import prettyFormat, { plugins } from 'pretty-format';
import type { MapPropsFunction } from './map-props';
import { defaultMapProps } from './map-props';
export type FormatElementOptions = {
/** Minimize used space. */
compact?: boolean;
/** Highlight the output. */
highlight?: boolean;
/** Filter or map props to display. */
mapProps?: MapPropsFunction | null;
};
/***
* Format given element as a pretty-printed string.
*
* @param element Element to format.
*/
export function formatElement(
element: ReactTestInstance | null,
{ compact, highlight = true, mapProps = defaultMapProps }: FormatElementOptions = {},
) {
if (element == null) {
return '(null)';
}
const { children, ...props } = element.props;
const childrenToDisplay = typeof children === 'string' ? [children] : undefined;
return prettyFormat(
{
// This prop is needed persuade the prettyFormat that the element is
// a ReactTestRendererJSON instance, so it is formatted as JSX.
$$typeof: Symbol.for('react.test.json'),
type: `${element.type}`,
props: mapProps ? mapProps(props) : props,
children: childrenToDisplay,
},
// See: https://www.npmjs.com/package/pretty-format#usage-with-options
{
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
printFunctionName: false,
printBasicPrototype: false,
highlight: highlight,
min: compact,
},
);
}
export function formatElementList(elements: ReactTestInstance[], options?: FormatElementOptions) {
if (elements.length === 0) {
return '(no elements)';
}
return elements.map((element) => formatElement(element, options)).join('\n');
}
export function formatJson(
json: ReactTestRendererJSON | ReactTestRendererJSON[],
{ compact, highlight = true, mapProps = defaultMapProps }: FormatElementOptions = {},
) {
return prettyFormat(json, {
plugins: [getElementJsonPlugin(mapProps), plugins.ReactElement],
highlight: highlight,
printBasicPrototype: false,
min: compact,
});
}
function getElementJsonPlugin(mapProps?: MapPropsFunction | null): NewPlugin {
return {
test: (val) => plugins.ReactTestComponent.test(val),
serialize: (val, config, indentation, depth, refs, printer) => {
let newVal = val;
if (mapProps && val.props) {
newVal = { ...val, props: mapProps(val.props) };
}
return plugins.ReactTestComponent.serialize(
newVal,
config,
indentation,
depth,
refs,
printer,
);
},
};
}