diff --git a/src/formatter/formatTreeNode.js b/src/formatter/formatTreeNode.js
index 512edc753..cf2328435 100644
--- a/src/formatter/formatTreeNode.js
+++ b/src/formatter/formatTreeNode.js
@@ -4,8 +4,17 @@ import formatReactElementNode from './formatReactElementNode';
import type { Options } from './../options';
import type { TreeNode } from './../tree';
-const escape = (s: string): string =>
- s.replace(/{/g, '{').replace(/}/g, '}');
+const jsxStopChars = ['<', '>', '{', '}'];
+const shouldBeEscaped = (s: string) =>
+ jsxStopChars.some(jsxStopChar => s.includes(jsxStopChar));
+
+const escape = (s: string) => {
+ if (!shouldBeEscaped(s)) {
+ return s;
+ }
+
+ return `{\`${s}\`}`;
+};
export default (
node: TreeNode,
@@ -13,8 +22,12 @@ export default (
lvl: number,
options: Options
): string => {
- if (node.type === 'string' || node.type === 'number') {
- return node.value ? escape(node.value.toString()) : '';
+ if (node.type === 'number') {
+ return String(node.value);
+ }
+
+ if (node.type === 'string') {
+ return node.value ? escape(String(node.value)) : '';
}
if (node.type === 'ReactElement') {
diff --git a/src/formatter/formatTreeNode.spec.js b/src/formatter/formatTreeNode.spec.js
index 737c2ebe9..a3d172e51 100644
--- a/src/formatter/formatTreeNode.spec.js
+++ b/src/formatter/formatTreeNode.spec.js
@@ -2,10 +2,70 @@
import formatTreeNode from './formatTreeNode';
+jest.mock('./formatReactElementNode', () => () =>
+ ''
+);
+
describe('formatTreeNode', () => {
- it('should escape JSX entity on string node', () => {
+ it('should format number tree node', () => {
+ expect(formatTreeNode({ type: 'number', value: 42 }, true, 0, {})).toBe(
+ '42'
+ );
+ });
+
+ it('should format string tree node', () => {
+ expect(formatTreeNode({ type: 'string', value: 'foo' }, true, 0, {})).toBe(
+ 'foo'
+ );
+ });
+
+ it('should format react element tree node', () => {
+ expect(
+ formatTreeNode(
+ {
+ type: 'ReactElement',
+ displayName: 'Foo',
+ },
+ true,
+ 0,
+ {}
+ )
+ ).toBe('');
+ });
+
+ const jsxDelimiters = ['<', '>', '{', '}'];
+ jsxDelimiters.forEach(char => {
+ it(`should escape string that contains the JSX delimiter "${char}"`, () => {
+ expect(
+ formatTreeNode(
+ { type: 'string', value: `I contain ${char}, is will be escaped` },
+ true,
+ 0,
+ {}
+ )
+ ).toBe(`{\`I contain ${char}, is will be escaped\`}`);
+ });
+ });
+
+ it('should preserve the format of string', () => {
+ expect(formatTreeNode({ type: 'string', value: 'foo\nbar' }, true, 0, {}))
+ .toBe(`foo
+bar`);
+
expect(
- formatTreeNode({ type: 'string', value: '{ foo: "bar" }' }, true, 0, {})
- ).toBe('{ foo: "bar" }');
+ formatTreeNode(
+ {
+ type: 'string',
+ value: JSON.stringify({ foo: 'bar' }, null, 2),
+ },
+ false,
+ 0,
+ {
+ tabStop: 2,
+ }
+ )
+ ).toBe(`{\`{
+ "foo": "bar"
+}\`}`);
});
});
diff --git a/src/index.spec.js b/src/index.spec.js
index e54ba7311..b830ad896 100644
--- a/src/index.spec.js
+++ b/src/index.spec.js
@@ -206,16 +206,16 @@ describe('reactElementToJSXString(ReactElement)', () => {
);
});
- it('reactElementToJSXString()', () => {
+ it('reactElementToJSXString()', () => {
expect(
reactElementToJSXString(
)
).toEqual(
``
);
});
@@ -227,31 +227,7 @@ describe('reactElementToJSXString(ReactElement)', () => {
)
).toEqual(
``
- );
- });
-
- it('reactElementToJSXString()', () => {
- expect(
- reactElementToJSXString(
-
- )
- ).toEqual(
- ``
- );
- });
-
- it('reactElementToJSXString()', () => {
- expect(
- reactElementToJSXString(
-
- )
- ).toEqual(
- ``
);
});