Fix message truncating failing in production builds
Summary: Message truncated worked in devs build, but failed in production build, as it JSON formatted React elements in prod build (incorreclty), while it didn't do so in Dev builds, as in dev that generates an exception (undesired) meaning the serialisation gets skipped (desired). Reviewed By: passy, nikoant, priteshrnandgaonkar Differential Revision: D27467280 fbshipit-source-id: 1f8e0ca4750464c778c33b69a8cf13d05f019143
This commit is contained in:
committed by
Facebook GitHub Bot
parent
77abba6459
commit
1060ea6e9e
@@ -13,7 +13,7 @@ import {
|
||||
CopyOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {Button, Typography} from 'antd';
|
||||
import {pad} from 'lodash';
|
||||
import {isPlainObject, pad} from 'lodash';
|
||||
import React, {createElement, Fragment, isValidElement, useState} from 'react';
|
||||
import {tryGetFlipperLibImplementation} from '../plugin/FlipperLib';
|
||||
import {safeStringify} from '../utils/safeStringify';
|
||||
@@ -97,6 +97,9 @@ export const DataFormatter = {
|
||||
},
|
||||
|
||||
prettyPrintJson(value: any) {
|
||||
if (isValidElement(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'string' && value.length >= 2) {
|
||||
const last = value.length - 1;
|
||||
// kinda looks like json
|
||||
@@ -112,7 +115,11 @@ export const DataFormatter = {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
if (
|
||||
typeof value === 'object' &&
|
||||
value !== null &&
|
||||
(Array.isArray(value) || isPlainObject(value))
|
||||
) {
|
||||
try {
|
||||
// Note: we don't need to be inserted <br/>'s in the output, but assume the text container uses
|
||||
// white-space: pre-wrap (or pre)
|
||||
@@ -137,7 +144,8 @@ export const DataFormatter = {
|
||||
},
|
||||
};
|
||||
|
||||
function TruncateHelper({
|
||||
// exported for testing
|
||||
export function TruncateHelper({
|
||||
value,
|
||||
maxLength,
|
||||
}: {
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {DataFormatter} from '../DataFormatter';
|
||||
import {render, fireEvent} from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import {act} from 'react-dom/test-utils';
|
||||
import {DataFormatter, TruncateHelper} from '../DataFormatter';
|
||||
|
||||
test('default formatter', () => {
|
||||
expect(DataFormatter.format(true)).toMatchInlineSnapshot(`"true"`);
|
||||
@@ -126,7 +129,7 @@ test('linkify formatter', () => {
|
||||
expect(linkify('fb.com')).toMatchInlineSnapshot(`"fb.com"`);
|
||||
});
|
||||
|
||||
test('linkify formatter', () => {
|
||||
test('jsonify formatter', () => {
|
||||
const jsonify = (value: any) =>
|
||||
DataFormatter.format(value, DataFormatter.prettyPrintJson);
|
||||
|
||||
@@ -162,3 +165,174 @@ test('linkify formatter', () => {
|
||||
</React.Fragment>
|
||||
`);
|
||||
});
|
||||
|
||||
test("jsonify doesn't process react elements", () => {
|
||||
const jsonify = (value: any) =>
|
||||
DataFormatter.format(value, DataFormatter.prettyPrintJson);
|
||||
|
||||
expect(jsonify('abcde')).toEqual('abcde');
|
||||
expect(jsonify('{ a: 1 }')).toMatchInlineSnapshot(`"{ a: 1 }"`);
|
||||
expect(jsonify({a: 1})).toMatchInlineSnapshot(`
|
||||
"{
|
||||
\\"a\\": 1
|
||||
}"
|
||||
`);
|
||||
expect(jsonify(<span>hi</span>)).toMatchInlineSnapshot(`
|
||||
<span>
|
||||
hi
|
||||
</span>
|
||||
`);
|
||||
});
|
||||
|
||||
test('truncate formatter', () => {
|
||||
const truncate = (value: any) =>
|
||||
DataFormatter.format(value, DataFormatter.truncate(5));
|
||||
|
||||
expect(truncate({test: true})).toMatchInlineSnapshot(`
|
||||
"{
|
||||
\\"test\\": true
|
||||
}"
|
||||
`);
|
||||
expect(truncate('abcde')).toEqual('abcde');
|
||||
expect(truncate('abcdefghi')).toMatchInlineSnapshot(`
|
||||
<TruncateHelper
|
||||
maxLength={5}
|
||||
value="abcdefghi"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
test('render truncate helper', () => {
|
||||
const res = render(
|
||||
<TruncateHelper value="!! COOL CONTENT !!" maxLength={4} />,
|
||||
);
|
||||
expect(res.baseElement).toMatchInlineSnapshot(`
|
||||
<body>
|
||||
<div>
|
||||
!! C
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-sm"
|
||||
style="margin-left: 4px;"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-right"
|
||||
class="anticon anticon-caret-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="caret-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>
|
||||
and 14 more
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-sm"
|
||||
style="margin-left: 4px;"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="copy"
|
||||
class="anticon anticon-copy"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="copy"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>
|
||||
copy
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</body>
|
||||
`);
|
||||
act(() => {
|
||||
fireEvent.click(res.getAllByText(/and \d+ more/)[0]);
|
||||
});
|
||||
expect(res.baseElement).toMatchInlineSnapshot(`
|
||||
<body>
|
||||
<div>
|
||||
!! COOL CONTENT !!
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-sm"
|
||||
style="margin-left: 4px;"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="caret-up"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>
|
||||
collapse
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-sm"
|
||||
style="margin-left: 4px;"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="copy"
|
||||
class="anticon anticon-copy"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="copy"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>
|
||||
copy
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</body>
|
||||
`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user