11let React ;
2+ let ReactDOM ;
23let ReactTestRenderer ;
34let Scheduler ;
45let Suspense ;
@@ -25,6 +26,7 @@ describe('ReactLazy', () => {
2526 beforeEach ( ( ) => {
2627 jest . resetModules ( ) ;
2728 React = require ( 'react' ) ;
29+ ReactDOM = require ( 'react-dom' ) ;
2830 Suspense = React . Suspense ;
2931 lazy = React . lazy ;
3032 ReactTestRenderer = require ( 'react-test-renderer' ) ;
@@ -791,7 +793,7 @@ describe('ReactLazy', () => {
791793 ) ;
792794 } ) ;
793795
794- it ( 'throws with a useful error when wrapping fragment with lazy()' , async ( ) => {
796+ it ( 'throws with a useful error when wrapping Fragment with lazy()' , async ( ) => {
795797 const BadLazy = lazy ( ( ) => fakeImport ( React . Fragment ) ) ;
796798
797799 const root = ReactTestRenderer . create (
@@ -817,6 +819,275 @@ describe('ReactLazy', () => {
817819 ) ;
818820 } ) ;
819821
822+ it ( 'throws with a useful error when wrapping createPortal with lazy()' , async ( ) => {
823+ const container = document . createElement ( 'div' ) ;
824+ const portal = ReactDOM . createPortal ( < div /> , container ) ;
825+ const BadLazy = lazy ( ( ) => fakeImport ( portal ) ) ;
826+
827+ const root = ReactTestRenderer . create (
828+ < Suspense fallback = { < Text text = "Loading..." /> } >
829+ < BadLazy />
830+ </ Suspense > ,
831+ {
832+ unstable_isConcurrent : true ,
833+ } ,
834+ ) ;
835+
836+ await waitForAll ( [ 'Loading...' ] ) ;
837+
838+ await resolveFakeImport ( portal ) ;
839+ root . update (
840+ < Suspense fallback = { < Text text = "Loading..." /> } >
841+ < BadLazy />
842+ </ Suspense > ,
843+ ) ;
844+ await waitForThrow (
845+ 'Element type is invalid. Received a promise that resolves to: Portal. ' +
846+ 'Lazy element type must resolve to a class or function.' ,
847+ ) ;
848+ } ) ;
849+
850+ it ( 'throws with a useful error when wrapping Profiler with lazy()' , async ( ) => {
851+ const BadLazy = lazy ( ( ) => fakeImport ( React . Profiler ) ) ;
852+
853+ const root = ReactTestRenderer . create (
854+ < Suspense fallback = { < Text text = "Loading..." /> } >
855+ < BadLazy />
856+ </ Suspense > ,
857+ {
858+ unstable_isConcurrent : true ,
859+ } ,
860+ ) ;
861+
862+ await waitForAll ( [ 'Loading...' ] ) ;
863+
864+ await resolveFakeImport ( React . Profiler ) ;
865+ root . update (
866+ < Suspense fallback = { < Text text = "Loading..." /> } >
867+ < BadLazy />
868+ </ Suspense > ,
869+ ) ;
870+ await waitForThrow (
871+ 'Element type is invalid. Received a promise that resolves to: Profiler. ' +
872+ 'Lazy element type must resolve to a class or function.' ,
873+ ) ;
874+ } ) ;
875+
876+ it ( 'throws with a useful error when wrapping StrictMode with lazy()' , async ( ) => {
877+ const BadLazy = lazy ( ( ) => fakeImport ( React . StrictMode ) ) ;
878+
879+ const root = ReactTestRenderer . create (
880+ < Suspense fallback = { < Text text = "Loading..." /> } >
881+ < BadLazy />
882+ </ Suspense > ,
883+ {
884+ unstable_isConcurrent : true ,
885+ } ,
886+ ) ;
887+
888+ await waitForAll ( [ 'Loading...' ] ) ;
889+
890+ await resolveFakeImport ( React . StrictMode ) ;
891+ root . update (
892+ < Suspense fallback = { < Text text = "Loading..." /> } >
893+ < BadLazy />
894+ </ Suspense > ,
895+ ) ;
896+ await waitForThrow (
897+ 'Element type is invalid. Received a promise that resolves to: StrictMode. ' +
898+ 'Lazy element type must resolve to a class or function.' ,
899+ ) ;
900+ } ) ;
901+
902+ it ( 'throws with a useful error when wrapping Suspense with lazy()' , async ( ) => {
903+ const BadLazy = lazy ( ( ) => fakeImport ( React . Suspense ) ) ;
904+
905+ const root = ReactTestRenderer . create (
906+ < Suspense fallback = { < Text text = "Loading..." /> } >
907+ < BadLazy />
908+ </ Suspense > ,
909+ {
910+ unstable_isConcurrent : true ,
911+ } ,
912+ ) ;
913+
914+ await waitForAll ( [ 'Loading...' ] ) ;
915+
916+ await resolveFakeImport ( React . Suspense ) ;
917+ root . update (
918+ < Suspense fallback = { < Text text = "Loading..." /> } >
919+ < BadLazy />
920+ </ Suspense > ,
921+ ) ;
922+ await waitForThrow (
923+ 'Element type is invalid. Received a promise that resolves to: Suspense. ' +
924+ 'Lazy element type must resolve to a class or function.' ,
925+ ) ;
926+ } ) ;
927+
928+ it ( 'throws with a useful error when wrapping Context with lazy()' , async ( ) => {
929+ const Context = React . createContext ( null ) ;
930+ const BadLazy = lazy ( ( ) => fakeImport ( Context ) ) ;
931+
932+ const root = ReactTestRenderer . create (
933+ < Suspense fallback = { < Text text = "Loading..." /> } >
934+ < BadLazy />
935+ </ Suspense > ,
936+ {
937+ unstable_isConcurrent : true ,
938+ } ,
939+ ) ;
940+
941+ await waitForAll ( [ 'Loading...' ] ) ;
942+
943+ await resolveFakeImport ( Context ) ;
944+ root . update (
945+ < Suspense fallback = { < Text text = "Loading..." /> } >
946+ < BadLazy />
947+ </ Suspense > ,
948+ ) ;
949+ await waitForThrow (
950+ 'Element type is invalid. Received a promise that resolves to: Context.Provider. ' +
951+ 'Lazy element type must resolve to a class or function.' ,
952+ ) ;
953+ } ) ;
954+
955+ // @gate enableRenderableContext
956+ it ( 'throws with a useful error when wrapping Context.Consumer with lazy()' , async ( ) => {
957+ const Context = React . createContext ( null ) ;
958+ const BadLazy = lazy ( ( ) => fakeImport ( Context . Consumer ) ) ;
959+
960+ const root = ReactTestRenderer . create (
961+ < Suspense fallback = { < Text text = "Loading..." /> } >
962+ < BadLazy />
963+ </ Suspense > ,
964+ {
965+ unstable_isConcurrent : true ,
966+ } ,
967+ ) ;
968+
969+ await waitForAll ( [ 'Loading...' ] ) ;
970+
971+ await resolveFakeImport ( Context . Consumer ) ;
972+ root . update (
973+ < Suspense fallback = { < Text text = "Loading..." /> } >
974+ < BadLazy />
975+ </ Suspense > ,
976+ ) ;
977+ await waitForThrow (
978+ 'Element type is invalid. Received a promise that resolves to: Context.Consumer. ' +
979+ 'Lazy element type must resolve to a class or function.' ,
980+ ) ;
981+ } ) ;
982+
983+ // @gate enableSuspenseList
984+ it ( 'throws with a useful error when wrapping SuspenseList with lazy()' , async ( ) => {
985+ const BadLazy = lazy ( ( ) => fakeImport ( React . unstable_SuspenseList ) ) ;
986+
987+ const root = ReactTestRenderer . create (
988+ < Suspense fallback = { < Text text = "Loading..." /> } >
989+ < BadLazy />
990+ </ Suspense > ,
991+ {
992+ unstable_isConcurrent : true ,
993+ } ,
994+ ) ;
995+
996+ await waitForAll ( [ 'Loading...' ] ) ;
997+
998+ await resolveFakeImport ( React . unstable_SuspenseList ) ;
999+ root . update (
1000+ < Suspense fallback = { < Text text = "Loading..." /> } >
1001+ < BadLazy />
1002+ </ Suspense > ,
1003+ ) ;
1004+ await waitForThrow (
1005+ 'Element type is invalid. Received a promise that resolves to: SuspenseList. ' +
1006+ 'Lazy element type must resolve to a class or function.' ,
1007+ ) ;
1008+ } ) ;
1009+
1010+ // @gate enableViewTransition
1011+ it ( 'throws with a useful error when wrapping ViewTransition with lazy()' , async ( ) => {
1012+ const BadLazy = lazy ( ( ) => fakeImport ( React . unstable_ViewTransition ) ) ;
1013+
1014+ const root = ReactTestRenderer . create (
1015+ < Suspense fallback = { < Text text = "Loading..." /> } >
1016+ < BadLazy />
1017+ </ Suspense > ,
1018+ {
1019+ unstable_isConcurrent : true ,
1020+ } ,
1021+ ) ;
1022+
1023+ await waitForAll ( [ 'Loading...' ] ) ;
1024+
1025+ await resolveFakeImport ( React . unstable_ViewTransition ) ;
1026+ root . update (
1027+ < Suspense fallback = { < Text text = "Loading..." /> } >
1028+ < BadLazy />
1029+ </ Suspense > ,
1030+ ) ;
1031+ await waitForThrow (
1032+ 'Element type is invalid. Received a promise that resolves to: ViewTransition. ' +
1033+ 'Lazy element type must resolve to a class or function.' ,
1034+ ) ;
1035+ } ) ;
1036+
1037+ // @gate enableActivity
1038+ it ( 'throws with a useful error when wrapping Activity with lazy()' , async ( ) => {
1039+ const BadLazy = lazy ( ( ) => fakeImport ( React . unstable_Activity ) ) ;
1040+
1041+ const root = ReactTestRenderer . create (
1042+ < Suspense fallback = { < Text text = "Loading..." /> } >
1043+ < BadLazy />
1044+ </ Suspense > ,
1045+ {
1046+ unstable_isConcurrent : true ,
1047+ } ,
1048+ ) ;
1049+
1050+ await waitForAll ( [ 'Loading...' ] ) ;
1051+
1052+ await resolveFakeImport ( React . unstable_Activity ) ;
1053+ root . update (
1054+ < Suspense fallback = { < Text text = "Loading..." /> } >
1055+ < BadLazy />
1056+ </ Suspense > ,
1057+ ) ;
1058+ await waitForThrow (
1059+ 'Element type is invalid. Received a promise that resolves to: Activity. ' +
1060+ 'Lazy element type must resolve to a class or function.' ,
1061+ ) ;
1062+ } ) ;
1063+
1064+ // @gate enableTransitionTracing
1065+ it ( 'throws with a useful error when wrapping TracingMarker with lazy()' , async ( ) => {
1066+ const BadLazy = lazy ( ( ) => fakeImport ( React . unstable_TracingMarker ) ) ;
1067+
1068+ const root = ReactTestRenderer . create (
1069+ < Suspense fallback = { < Text text = "Loading..." /> } >
1070+ < BadLazy />
1071+ </ Suspense > ,
1072+ {
1073+ unstable_isConcurrent : true ,
1074+ } ,
1075+ ) ;
1076+
1077+ await waitForAll ( [ 'Loading...' ] ) ;
1078+
1079+ await resolveFakeImport ( React . unstable_TracingMarker ) ;
1080+ root . update (
1081+ < Suspense fallback = { < Text text = "Loading..." /> } >
1082+ < BadLazy />
1083+ </ Suspense > ,
1084+ ) ;
1085+ await waitForThrow (
1086+ 'Element type is invalid. Received a promise that resolves to: TracingMarker. ' +
1087+ 'Lazy element type must resolve to a class or function.' ,
1088+ ) ;
1089+ } ) ;
1090+
8201091 it ( 'throws with a useful error when wrapping lazy() multiple times' , async ( ) => {
8211092 const Lazy1 = lazy ( ( ) => fakeImport ( Text ) ) ;
8221093 const Lazy2 = lazy ( ( ) => fakeImport ( Lazy1 ) ) ;
0 commit comments