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( - `` ); });