{
- >>
+ >
>mouse>
- >>
+ >
>rat>
>
>
@@ -24,9 +24,9 @@ exports[`ReactElement plugin highlights syntax with color from theme option 1`]
exports[`ReactTestComponent plugin highlights syntax 1`] = `
"
prop>={
- >>
+ >
>mouse>
- >>
+ >
>rat>
>
>
diff --git a/packages/pretty-format/src/__tests__/asymmetric_matcher.test.js b/packages/pretty-format/src/__tests__/asymmetric_matcher.test.js
index bc82c84f2634..468b3f371906 100644
--- a/packages/pretty-format/src/__tests__/asymmetric_matcher.test.js
+++ b/packages/pretty-format/src/__tests__/asymmetric_matcher.test.js
@@ -11,7 +11,7 @@
import type {OptionsReceived} from 'types/PrettyFormat';
const prettyFormat = require('../');
-const AsymmetricMatcher = require('../plugins/asymmetric_matcher');
+const {AsymmetricMatcher} = prettyFormat.plugins;
let options: OptionsReceived;
function fnNameFor(func) {
diff --git a/packages/pretty-format/src/__tests__/convert_ansi.test.js b/packages/pretty-format/src/__tests__/convert_ansi.test.js
index 58cdc577cf6f..d4ab0344e1a4 100644
--- a/packages/pretty-format/src/__tests__/convert_ansi.test.js
+++ b/packages/pretty-format/src/__tests__/convert_ansi.test.js
@@ -10,11 +10,11 @@
const ansiStyle = require('ansi-styles');
const prettyFormat = require('../');
-const ConvertAnsiPlugin = require('../plugins/convert_ansi');
+const {ConvertAnsi} = prettyFormat.plugins;
const prettyFormatResult = (val: string) => {
return prettyFormat(val, {
- plugins: [ConvertAnsiPlugin],
+ plugins: [ConvertAnsi],
});
};
diff --git a/packages/pretty-format/src/__tests__/html_element.test.js b/packages/pretty-format/src/__tests__/html_element.test.js
index 4d0127072cc4..18a33f265523 100644
--- a/packages/pretty-format/src/__tests__/html_element.test.js
+++ b/packages/pretty-format/src/__tests__/html_element.test.js
@@ -12,10 +12,9 @@
'use strict';
-const HTMLElementPlugin = require('../plugins/html_element');
-const toPrettyPrintTo = require('./expect_util').getPrettyPrint([
- HTMLElementPlugin,
-]);
+const prettyFormat = require('../');
+const {HTMLElement} = prettyFormat.plugins;
+const toPrettyPrintTo = require('./expect_util').getPrettyPrint([HTMLElement]);
const expect: any = global.expect;
expect.extend({toPrettyPrintTo});
diff --git a/packages/pretty-format/src/__tests__/pretty_format.test.js b/packages/pretty-format/src/__tests__/pretty_format.test.js
index 731deee92665..e08dd09c29de 100644
--- a/packages/pretty-format/src/__tests__/pretty_format.test.js
+++ b/packages/pretty-format/src/__tests__/pretty_format.test.js
@@ -282,6 +282,45 @@ describe('prettyFormat()', () => {
expect(prettyFormat('\\ \\\\')).toEqual('"\\\\ \\\\\\\\"');
});
+ it('prints a multiline string', () => {
+ const val = ['line 1', 'line 2', 'line 3'].join('\n');
+ expect(prettyFormat(val)).toEqual('"' + val + '"');
+ });
+
+ it('prints a multiline string as value of object property', () => {
+ const polyline = {
+ props: {
+ id: 'J',
+ points: ['0.5,0.460', '0.5,0.875', '0.25,0.875'].join('\n'),
+ },
+ type: 'polyline',
+ };
+ const val = {
+ props: {
+ children: polyline,
+ },
+ type: 'svg',
+ };
+ expect(prettyFormat(val)).toEqual(
+ [
+ 'Object {',
+ ' "props": Object {',
+ ' "children": Object {',
+ ' "props": Object {',
+ ' "id": "J",',
+ ' "points": "0.5,0.460',
+ '0.5,0.875',
+ '0.25,0.875",',
+ ' },',
+ ' "type": "polyline",',
+ ' },',
+ ' },',
+ ' "type": "svg",',
+ '}',
+ ].join('\n'),
+ );
+ });
+
it('prints a symbol', () => {
const val = Symbol('symbol');
expect(prettyFormat(val)).toEqual('Symbol(symbol)');
@@ -323,11 +362,51 @@ describe('prettyFormat()', () => {
);
});
- it('can customize indent', () => {
- const val = {prop: 'value'};
- expect(prettyFormat(val, {indent: 4})).toEqual(
- 'Object {\n "prop": "value",\n}',
- );
+ describe('indent option', () => {
+ const val = [
+ {
+ id: '8658c1d0-9eda-4a90-95e1-8001e8eb6036',
+ text: 'Add alternative serialize API for pretty-format plugins',
+ type: 'ADD_TODO',
+ },
+ {
+ id: '8658c1d0-9eda-4a90-95e1-8001e8eb6036',
+ type: 'TOGGLE_TODO',
+ },
+ ];
+ const expected = [
+ 'Array [',
+ ' Object {',
+ ' "id": "8658c1d0-9eda-4a90-95e1-8001e8eb6036",',
+ ' "text": "Add alternative serialize API for pretty-format plugins",',
+ ' "type": "ADD_TODO",',
+ ' },',
+ ' Object {',
+ ' "id": "8658c1d0-9eda-4a90-95e1-8001e8eb6036",',
+ ' "type": "TOGGLE_TODO",',
+ ' },',
+ ']',
+ ].join('\n');
+ test('default implicit: 2 spaces', () => {
+ expect(prettyFormat(val)).toEqual(expected);
+ });
+ test('default explicit: 2 spaces', () => {
+ expect(prettyFormat(val, {indent: 2})).toEqual(expected);
+ });
+
+ // Tests assume that no strings in val contain multiple adjacent spaces!
+ test('non-default: 0 spaces', () => {
+ const indent = 0;
+ expect(prettyFormat(val, {indent})).toEqual(
+ expected.replace(/ {2}/g, ' '.repeat(indent)),
+ );
+ });
+ test('non-default: 4 spaces', () => {
+ const indent = 4;
+ expect(prettyFormat(val, {indent})).toEqual(
+ expected.replace(/ {2}/g, ' '.repeat(indent)),
+ );
+ });
});
it('can customize the max depth', () => {
diff --git a/packages/pretty-format/src/__tests__/react.test.js b/packages/pretty-format/src/__tests__/react.test.js
index e2e47f1ffc74..3ba0e280e5a2 100644
--- a/packages/pretty-format/src/__tests__/react.test.js
+++ b/packages/pretty-format/src/__tests__/react.test.js
@@ -8,58 +8,79 @@
* @flow
*/
+import type {OptionsReceived} from 'types/PrettyFormat';
+
const React = require('react');
const renderer = require('react-test-renderer');
const prettyFormat = require('../');
-const ReactTestComponent = require('../plugins/react_test_component');
-const ReactElement = require('../plugins/react_element');
-
-function assertPrintedJSX(actual, expected, opts) {
- expect(
- prettyFormat(
- actual,
- Object.assign(
- {
- min: undefined,
- plugins: [ReactElement],
- },
- opts,
- ),
+const {ReactElement, ReactTestComponent} = prettyFormat.plugins;
+
+const formatElement = (element: any, options?: OptionsReceived) =>
+ prettyFormat(
+ element,
+ Object.assign(
+ ({
+ plugins: [ReactElement],
+ }: OptionsReceived),
+ options,
),
- ).toEqual(expected);
- expect(
- prettyFormat(
- renderer.create(actual).toJSON(),
- Object.assign(
- {
- min: undefined,
- plugins: [ReactTestComponent, ReactElement],
- },
- opts,
- ),
+ );
+
+const formatTestObject = (object: any, options?: OptionsReceived) =>
+ prettyFormat(
+ object,
+ Object.assign(
+ ({
+ plugins: [ReactTestComponent, ReactElement],
+ }: OptionsReceived),
+ options,
),
- ).toEqual(expected);
+ );
+
+function assertPrintedJSX(
+ val: any,
+ expected: string,
+ options?: OptionsReceived,
+) {
+ expect(formatElement(val, options)).toEqual(expected);
+ expect(formatTestObject(renderer.create(val).toJSON(), options)).toEqual(
+ expected,
+ );
}
test('supports a single element with no props or children', () => {
assertPrintedJSX(React.createElement('Mouse'), '');
});
-test('supports a single element with no props', () => {
+test('supports a single element with non-empty string child', () => {
assertPrintedJSX(
React.createElement('Mouse', null, 'Hello World'),
'\n Hello World\n',
);
});
-test('supports a single element with number children', () => {
+test('supports a single element with empty string child', () => {
+ assertPrintedJSX(
+ React.createElement('Mouse', null, ''),
+ '\n \n',
+ );
+});
+
+test('supports a single element with non-zero number child', () => {
assertPrintedJSX(
React.createElement('Mouse', null, 4),
'\n 4\n',
);
});
+test('supports a single element with zero number child', () => {
+ assertPrintedJSX(
+ React.createElement('Mouse', null, 0),
+ '\n 0\n',
+ );
+});
+
test('supports a single element with mixed children', () => {
assertPrintedJSX(
React.createElement('Mouse', null, [[1, null], 2, undefined, [false, [3]]]),
@@ -74,6 +95,28 @@ test('supports props with strings', () => {
);
});
+test('supports props with multiline strings', () => {
+ const val = React.createElement(
+ 'svg',
+ null,
+ React.createElement('polyline', {
+ id: 'J',
+ points: ['0.5,0.460', '0.5,0.875', '0.25,0.875'].join('\n'),
+ }),
+ );
+ const expected = [
+ '',
+ ].join('\n');
+ assertPrintedJSX(val, expected);
+});
+
test('supports props with numbers', () => {
assertPrintedJSX(
React.createElement('Mouse', {size: 5}),
@@ -253,11 +296,7 @@ test('supports Unknown element', () => {
// Suppress React.createElement(undefined) console error
const consoleError = console.error;
(console: Object).error = jest.fn();
- expect(
- prettyFormat(React.createElement(undefined), {
- plugins: [ReactElement],
- }),
- ).toEqual('');
+ expect(formatElement(React.createElement(undefined))).toEqual('');
(console: Object).error = consoleError;
});
@@ -296,7 +335,88 @@ test('supports a single element with React elements with array children', () =>
);
});
-test('uses the supplied line seperator for min mode', () => {
+test('supports array of elements', () => {
+ const val = [
+ React.createElement('dt', null, 'jest'),
+ React.createElement('dd', null, 'to talk in a playful manner'),
+ React.createElement(
+ 'dd',
+ {style: {color: '#99424F'}},
+ 'painless JavaScript testing',
+ ),
+ ];
+ const expected = [
+ 'Array [',
+ ' ',
+ ' jest',
+ ' ,',
+ ' ',
+ ' to talk in a playful manner',
+ ' ,',
+ ' ',
+ ' painless JavaScript testing',
+ ' ,',
+ ']',
+ ].join('\n');
+ expect(formatElement(val)).toEqual(expected);
+ expect(
+ formatTestObject(val.map(element => renderer.create(element).toJSON())),
+ ).toEqual(expected);
+});
+
+describe('indent option', () => {
+ const val = React.createElement(
+ 'ul',
+ null,
+ React.createElement(
+ 'li',
+ {style: {color: 'green', textDecoration: 'none'}},
+ 'Test indent option',
+ ),
+ );
+ const expected = [
+ '',
+ ' - ',
+ ' Test indent option',
+ '
',
+ '
',
+ ].join('\n');
+ test('default implicit: 2 spaces', () => {
+ assertPrintedJSX(val, expected);
+ });
+ test('default explicit: 2 spaces', () => {
+ assertPrintedJSX(val, expected, {indent: 2});
+ });
+
+ // Tests assume that no strings in val contain multiple adjacent spaces!
+ test('non-default: 0 spaces', () => {
+ const indent = 0;
+ assertPrintedJSX(val, expected.replace(/ {2}/g, ' '.repeat(indent)), {
+ indent,
+ });
+ });
+ test('non-default: 4 spaces', () => {
+ const indent = 4;
+ assertPrintedJSX(val, expected.replace(/ {2}/g, ' '.repeat(indent)), {
+ indent,
+ });
+ });
+});
+
+test('min option', () => {
assertPrintedJSX(
React.createElement(
'Mouse',
@@ -326,9 +446,8 @@ test('ReactElement plugin highlights syntax', () => {
),
});
expect(
- prettyFormat(jsx, {
+ formatElement(jsx, {
highlight: true,
- plugins: [ReactElement],
}),
).toMatchSnapshot();
});
@@ -343,9 +462,8 @@ test('ReactTestComponent plugin highlights syntax', () => {
),
});
expect(
- prettyFormat(renderer.create(jsx).toJSON(), {
+ formatTestObject(renderer.create(jsx).toJSON(), {
highlight: true,
- plugins: [ReactTestComponent, ReactElement],
}),
).toMatchSnapshot();
});
@@ -357,9 +475,8 @@ test('throws if theme option is null', () => {
'Hello, Mouse!',
);
expect(() => {
- prettyFormat(jsx, {
+ formatElement(jsx, {
highlight: true,
- plugins: [ReactElement],
// $FlowFixMe
theme: null,
});
@@ -373,9 +490,8 @@ test('throws if theme option is not of type "object"', () => {
{style: 'color:red'},
'Hello, Mouse!',
);
- prettyFormat(jsx, {
+ formatElement(jsx, {
highlight: true,
- plugins: [ReactElement],
// $FlowFixMe
theme: 'beautiful',
});
@@ -391,9 +507,8 @@ test('throws if theme option has value that is undefined in ansi-styles', () =>
{style: 'color:red'},
'Hello, Mouse!',
);
- prettyFormat(jsx, {
+ formatElement(jsx, {
highlight: true,
- plugins: [ReactElement],
theme: {
content: 'unknown',
prop: 'yellow',
@@ -413,9 +528,8 @@ test('ReactElement plugin highlights syntax with color from theme option', () =>
'Hello, Mouse!',
);
expect(
- prettyFormat(jsx, {
+ formatElement(jsx, {
highlight: true,
- plugins: [ReactElement],
theme: {
value: 'red',
},
@@ -430,9 +544,8 @@ test('ReactTestComponent plugin highlights syntax with color from theme option',
'Hello, Mouse!',
);
expect(
- prettyFormat(renderer.create(jsx).toJSON(), {
+ formatTestObject(renderer.create(jsx).toJSON(), {
highlight: true,
- plugins: [ReactTestComponent, ReactElement],
theme: {
value: 'red',
},
diff --git a/packages/pretty-format/src/index.js b/packages/pretty-format/src/index.js
index b2a25ffc9737..140de3b86211 100644
--- a/packages/pretty-format/src/index.js
+++ b/packages/pretty-format/src/index.js
@@ -371,36 +371,39 @@ function printComplexValue(
function printPlugin(
plugin: Plugin,
- val,
+ val: any,
config: Config,
indentation: string,
depth: number,
refs: Refs,
): string {
- function boundPrint(val) {
- return print(val, config, indentation, depth, refs);
- }
-
- function boundIndent(str) {
- const indentationNext = indentation + config.indent;
- return (
- indentationNext + str.replace(NEWLINE_REGEXP, '\n' + indentationNext)
- );
- }
-
- const opts = {
- edgeSpacing: config.spacingOuter,
- min: config.min,
- spacing: config.spacingInner,
- };
-
- const printed = plugin.print(
- val,
- boundPrint,
- boundIndent,
- opts,
- config.colors,
- );
+ const printed = plugin.serialize
+ ? plugin.serialize(
+ val,
+ config,
+ (valChild, indentationChild, depthChild, refsChild) =>
+ print(valChild, config, indentationChild, depthChild, refsChild),
+ indentation,
+ depth,
+ refs,
+ )
+ : plugin.print(
+ val,
+ valChild => print(valChild, config, indentation, depth, refs),
+ str => {
+ const indentationNext = indentation + config.indent;
+ return (
+ indentationNext +
+ str.replace(NEWLINE_REGEXP, '\n' + indentationNext)
+ );
+ },
+ {
+ edgeSpacing: config.spacingOuter,
+ min: config.min,
+ spacing: config.spacingInner,
+ },
+ config.colors,
+ );
if (typeof printed !== 'string') {
throw new Error(
`pretty-format: Plugin must return type "string" but instead returned "${typeof printed}".`,
diff --git a/packages/pretty-format/src/plugins/react_element.js b/packages/pretty-format/src/plugins/react_element.js
index d4be69952fa5..1fd6ba26a33c 100644
--- a/packages/pretty-format/src/plugins/react_element.js
+++ b/packages/pretty-format/src/plugins/react_element.js
@@ -8,17 +8,11 @@
* @flow
*/
-import type {
- Colors,
- Indent,
- PluginOptions,
- Print,
- Plugin,
-} from 'types/PrettyFormat';
+import type {Config, NewPlugin, Printer, Refs} from 'types/PrettyFormat';
import escapeHTML from './lib/escape_html';
-const reactElement = Symbol.for('react.element');
+const elementSymbol = Symbol.for('react.element');
function traverseChildren(opaqueChildren, cb) {
if (Array.isArray(opaqueChildren)) {
@@ -28,43 +22,63 @@ function traverseChildren(opaqueChildren, cb) {
}
}
-function printChildren(flatChildren, print, indent, colors, opts) {
- return flatChildren
- .map(node => {
- if (typeof node === 'string') {
- return colors.content.open + escapeHTML(node) + colors.content.close;
- } else {
- return print(node);
- }
- })
- .join(opts.edgeSpacing);
+function printChildren(
+ children: Array,
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string {
+ const colors = config.colors;
+ return children
+ .map(
+ child =>
+ config.spacingOuter +
+ indentation +
+ (typeof child === 'string'
+ ? colors.content.open + escapeHTML(child) + colors.content.close
+ : printer(child, indentation, depth, refs)),
+ )
+ .join('');
}
-function printProps(props, print, indent, colors, opts) {
- return Object.keys(props)
+function printProps(
+ keys: Array,
+ props: Object,
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string {
+ const indentationNext = indentation + config.indent;
+ const colors = config.colors;
+ return keys
.sort()
- .map(name => {
- if (name === 'children') {
- return '';
- }
+ .map(key => {
+ const value = props[key];
+ let printed = printer(value, indentationNext, depth, refs);
- const prop = props[name];
- let printed = print(prop);
-
- if (typeof prop !== 'string') {
+ if (typeof value !== 'string') {
if (printed.indexOf('\n') !== -1) {
printed =
- '{' +
- opts.edgeSpacing +
- indent(indent(printed) + opts.edgeSpacing + '}');
- } else {
- printed = '{' + printed + '}';
+ config.spacingOuter +
+ indentationNext +
+ printed +
+ config.spacingOuter +
+ indentation;
}
+ printed = '{' + printed + '}';
}
return (
- opts.spacing +
- indent(colors.prop.open + name + colors.prop.close + '=') +
+ config.spacingInner +
+ indentation +
+ colors.prop.open +
+ key +
+ colors.prop.close +
+ '=' +
colors.value.open +
printed +
colors.value.close
@@ -73,14 +87,15 @@ function printProps(props, print, indent, colors, opts) {
.join('');
}
-export const print = (
+export const serialize = (
element: React$Element<*>,
- print: Print,
- indent: Indent,
- opts: PluginOptions,
- colors: Colors,
-) => {
- let result = colors.tag.open + '<';
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string => {
+ const tag = config.colors.tag;
let elementName;
if (typeof element.type === 'string') {
elementName = element.type;
@@ -89,45 +104,57 @@ export const print = (
} else {
elementName = 'Unknown';
}
- result += elementName + colors.tag.close;
- result += printProps(element.props, print, indent, colors, opts);
+ let result = tag.open + '<' + elementName;
- const opaqueChildren = element.props.children;
- const hasProps = !!Object.keys(element.props).filter(
- propName => propName !== 'children',
- ).length;
- const closeInNewLine = hasProps && !opts.min;
+ const keys = Object.keys(element.props).filter(key => key !== 'children');
+ const hasProps = keys.length !== 0;
+ if (hasProps) {
+ result +=
+ tag.close +
+ printProps(
+ keys,
+ element.props,
+ config,
+ printer,
+ indentation + config.indent,
+ depth,
+ refs,
+ ) +
+ config.spacingOuter +
+ indentation +
+ tag.open;
+ }
- if (opaqueChildren) {
- const flatChildren = [];
- traverseChildren(opaqueChildren, child => {
- flatChildren.push(child);
- });
- const children = printChildren(flatChildren, print, indent, colors, opts);
+ const flatChildren = [];
+ traverseChildren(element.props.children, child => {
+ flatChildren.push(child);
+ });
+ if (flatChildren.length !== 0) {
result +=
- colors.tag.open +
- (closeInNewLine ? '\n' : '') +
'>' +
- colors.tag.close +
- opts.edgeSpacing +
- indent(children) +
- opts.edgeSpacing +
- colors.tag.open +
+ tag.close +
+ printChildren(
+ flatChildren,
+ config,
+ printer,
+ indentation + config.indent,
+ depth,
+ refs,
+ ) +
+ config.spacingOuter +
+ indentation +
+ tag.open +
'' +
elementName +
'>' +
- colors.tag.close;
+ tag.close;
} else {
- result +=
- colors.tag.open + (closeInNewLine ? '\n' : ' ') + '/>' + colors.tag.close;
+ result += (hasProps && !config.min ? '' : ' ') + '/>' + tag.close;
}
return result;
};
-// Disabling lint rule as we don't know type ahead of time.
-/* eslint-disable flowtype/no-weak-types */
-export const test = (object: any) => object && object.$$typeof === reactElement;
-/* eslint-enable flowtype/no-weak-types */
+export const test = (val: any) => val && val.$$typeof === elementSymbol;
-export default ({print, test}: Plugin);
+export default ({serialize, test}: NewPlugin);
diff --git a/packages/pretty-format/src/plugins/react_test_component.js b/packages/pretty-format/src/plugins/react_test_component.js
index 622cdd93b3ba..de8e386c03c8 100644
--- a/packages/pretty-format/src/plugins/react_test_component.js
+++ b/packages/pretty-format/src/plugins/react_test_component.js
@@ -9,58 +9,75 @@
*/
import type {
- Colors,
- Indent,
- PluginOptions,
- Print,
- Plugin,
+ Config,
+ Printer,
+ NewPlugin,
ReactTestObject,
ReactTestChild,
+ Refs,
} from 'types/PrettyFormat';
import escapeHTML from './lib/escape_html';
-const reactTestInstance = Symbol.for('react.test.json');
+const testSymbol = Symbol.for('react.test.json');
function printChildren(
children: Array,
- print,
- indent,
- colors,
- opts,
-) {
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string {
+ const colors = config.colors;
return children
- .map(node => {
- if (typeof node === 'string') {
- return colors.content.open + escapeHTML(node) + colors.content.close;
- } else {
- return print(node);
- }
- })
- .join(opts.edgeSpacing);
+ .map(
+ child =>
+ config.spacingOuter +
+ indentation +
+ (typeof child === 'string'
+ ? colors.content.open + escapeHTML(child) + colors.content.close
+ : printer(child, indentation, depth, refs)),
+ )
+ .join('');
}
-function printProps(props: Object, print, indent, colors, opts) {
- return Object.keys(props)
+function printProps(
+ keys: Array,
+ props: Object,
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string {
+ const indentationNext = indentation + config.indent;
+ const colors = config.colors;
+ return keys
.sort()
- .map(name => {
- const prop = props[name];
- let printed = print(prop);
+ .map(key => {
+ const value = props[key];
+ let printed = printer(value, indentationNext, depth, refs);
- if (typeof prop !== 'string') {
+ if (typeof value !== 'string') {
if (printed.indexOf('\n') !== -1) {
printed =
- '{' +
- opts.edgeSpacing +
- indent(indent(printed) + opts.edgeSpacing + '}');
- } else {
- printed = '{' + printed + '}';
+ config.spacingOuter +
+ indentationNext +
+ printed +
+ config.spacingOuter +
+ indentation;
}
+ printed = '{' + printed + '}';
}
return (
- opts.spacing +
- indent(colors.prop.open + name + colors.prop.close + '=') +
+ config.spacingInner +
+ indentation +
+ colors.prop.open +
+ key +
+ colors.prop.close +
+ '=' +
colors.value.open +
printed +
colors.value.close
@@ -69,51 +86,65 @@ function printProps(props: Object, print, indent, colors, opts) {
.join('');
}
-export const print = (
+export const serialize = (
instance: ReactTestObject,
- print: Print,
- indent: Indent,
- opts: PluginOptions,
- colors: Colors,
-) => {
- let closeInNewLine = false;
- let result = colors.tag.open + '<' + instance.type + colors.tag.close;
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+): string => {
+ const tag = config.colors.tag;
+ let result = tag.open + '<' + instance.type;
+ let hasProps = false;
if (instance.props) {
- closeInNewLine = !!Object.keys(instance.props).length && !opts.min;
- result += printProps(instance.props, print, indent, colors, opts);
+ const keys = Object.keys(instance.props);
+ hasProps = keys.length !== 0;
+ if (hasProps) {
+ result +=
+ tag.close +
+ printProps(
+ keys,
+ instance.props,
+ config,
+ printer,
+ indentation + config.indent,
+ depth,
+ refs,
+ ) +
+ config.spacingOuter +
+ indentation +
+ tag.open;
+ }
}
if (instance.children) {
- const children = printChildren(
- instance.children,
- print,
- indent,
- colors,
- opts,
- );
result +=
- colors.tag.open +
- (closeInNewLine ? '\n' : '') +
'>' +
- colors.tag.close +
- opts.edgeSpacing +
- indent(children) +
- opts.edgeSpacing +
- colors.tag.open +
+ tag.close +
+ printChildren(
+ instance.children,
+ config,
+ printer,
+ indentation + config.indent,
+ depth,
+ refs,
+ ) +
+ config.spacingOuter +
+ indentation +
+ tag.open +
'' +
instance.type +
'>' +
- colors.tag.close;
+ tag.close;
} else {
- result +=
- colors.tag.open + (closeInNewLine ? '\n' : ' ') + '/>' + colors.tag.close;
+ result += (hasProps && !config.min ? '' : ' ') + '/>' + tag.close;
}
return result;
};
-export const test = (object: Object) =>
- object && object.$$typeof === reactTestInstance;
+export const test = (val: any) => val && val.$$typeof === testSymbol;
-export default ({print, test}: Plugin);
+export default ({serialize, test}: NewPlugin);
diff --git a/types/PrettyFormat.js b/types/PrettyFormat.js
index cd8ce0fa6db0..5a5358f63ac9 100644
--- a/types/PrettyFormat.js
+++ b/types/PrettyFormat.js
@@ -73,22 +73,45 @@ export type Config = {|
spacingOuter: string,
|};
+export type Printer = (
+ val: any,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+) => string;
+
+export type Test = any => boolean;
+
+export type NewPlugin = {|
+ serialize: (
+ val: any,
+ config: Config,
+ printer: Printer,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+ ) => string,
+ test: Test,
+|};
+
export type PluginOptions = {|
edgeSpacing: string,
min: boolean,
spacing: string,
|};
-export type Plugin = {
+export type OldPlugin = {|
print: (
val: any,
- serialize: Print,
+ print: Print,
indent: Indent,
- opts: PluginOptions,
+ options: PluginOptions,
colors: Colors,
) => string,
- test: any => boolean,
-};
+ test: Test,
+|};
+
+export type Plugin = NewPlugin | OldPlugin;
export type Plugins = Array;