diff --git a/package.json b/package.json index 7811865fb..3dd3550f1 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,7 @@ "smoke": "node tests/smoke/run" }, "lint-staged": { - "*.js": [ - "prettier --write \"**/*.{js,json}\"", - "git add" - ] + "*.js": ["prettier --write \"**/*.{js,json}\"", "git add"] }, "author": { "name": "Algolia, Inc.", @@ -72,7 +69,6 @@ "react-test-renderer": "16.14.0", "rollup": "1.32.1", "rollup-plugin-babel": "4.4.0", - "rollup-plugin-commonjs": "10.1.0", "rollup-plugin-node-builtins": "2.1.2", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-node-resolve": "5.2.0", @@ -84,11 +80,10 @@ }, "dependencies": { "@base2/pretty-print-object": "1.0.0", - "is-plain-object": "3.0.1" + "is-plain-object": "3.0.1", + "react-is": "^17.0.2" }, "jest": { - "setupFilesAfterEnv": [ - "tests/setupTests.js" - ] + "setupFilesAfterEnv": ["tests/setupTests.js"] } } diff --git a/rollup.config.js b/rollup.config.js index d582d022c..aa07cb4a6 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,12 +1,13 @@ import babel from 'rollup-plugin-babel'; -import commonjs from 'rollup-plugin-commonjs'; import resolve from 'rollup-plugin-node-resolve'; import builtins from 'rollup-plugin-node-builtins'; import globals from 'rollup-plugin-node-globals'; import pkg from './package.json'; -const extractPackagePeerDependencies = () => - Object.keys(pkg.peerDependencies) || []; +const extractExternals = () => [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), +]; export default { input: 'src/index.js', @@ -22,7 +23,7 @@ export default { sourcemap: true, }, ], - external: extractPackagePeerDependencies(), + external: extractExternals(), plugins: [ babel({ babelrc: false, @@ -36,12 +37,6 @@ export default { resolve({ mainFields: ['module', 'main', 'jsnext', 'browser'], }), - commonjs({ - sourceMap: true, - namedExports: { - react: ['isValidElement'], - }, - }), globals(), builtins(), ], diff --git a/src/index.spec.js b/src/index.spec.js index c2b4c288c..790d3177d 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1160,4 +1160,174 @@ describe('reactElementToJSXString(ReactElement)', () => { } mount(); }); + + it('should use inferred function name as display name for `forwardRef` element', () => { + const Tag = React.forwardRef(function Tag({ text }, ref) { + return {text}; + }); + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should use `displayName` instead of inferred function name as display name for `forwardRef` element', () => { + const Tag = React.forwardRef(function Tag({ text }, ref) { + return {text}; + }); + Tag.displayName = 'MyTag'; + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should use inferred function name as display name for `memo` element', () => { + const Tag = React.memo(function Tag({ text }) { + return {text}; + }); + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should use `displayName` instead of inferred function name as display name for `memo` element', () => { + const Tag = React.memo(function Tag({ text }) { + return {text}; + }); + Tag.displayName = 'MyTag'; + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should use inferred function name as display name for a `forwardRef` wrapped in `memo`', () => { + const Tag = React.memo( + React.forwardRef(function Tag({ text }, ref) { + return {text}; + }) + ); + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should use inferred function name as display name for a component wrapped in `memo` multiple times', () => { + const Tag = React.memo( + React.memo( + React.memo(function Tag({ text }) { + return {text}; + }) + ) + ); + expect(reactElementToJSXString()).toEqual( + `` + ); + }); + + it('should stringify `StrictMode` correctly', () => { + const App = () => null; + + expect( + reactElementToJSXString( + + + + ) + ).toEqual(` + +`); + }); + + it('should stringify `Suspense` correctly', () => { + const Spinner = () => null; + const ProfilePage = () => null; + + expect( + reactElementToJSXString( + }> + + + ) + ).toEqual(`}> + +`); + }); + + it('should stringify `Profiler` correctly', () => { + const Navigation = () => null; + + expect( + reactElementToJSXString( + {}}> + + + ) + ).toEqual(` + +`); + }); + + it('should stringify `Contex.Provider` correctly', () => { + const Ctx = React.createContext(); + const App = () => {}; + + expect( + reactElementToJSXString( + + + + ) + ).toEqual(` + +`); + }); + + it('should stringify `Contex.Provider` with `displayName` correctly', () => { + const Ctx = React.createContext(); + Ctx.displayName = 'MyCtx'; + + const App = () => {}; + + expect( + reactElementToJSXString( + + + + ) + ).toEqual(` + +`); + }); + + it('should stringify `Contex.Consumer` correctly', () => { + const Ctx = React.createContext(); + const Button = () => null; + + expect( + reactElementToJSXString( + {theme =>