@@ -21,6 +21,10 @@ describe('ReactIncrementalErrorHandling', () => {
21
21
ReactNoop = require ( 'react-noop-renderer' ) ;
22
22
} ) ;
23
23
24
+ afterEach ( ( ) => {
25
+ jest . unmock ( '../ReactFiberErrorLogger' ) ;
26
+ } ) ;
27
+
24
28
function div ( ...children ) {
25
29
children = children . map ( c => ( typeof c === 'string' ? { text : c } : c ) ) ;
26
30
return { type : 'div' , children, prop : undefined } ;
@@ -952,49 +956,22 @@ describe('ReactIncrementalErrorHandling', () => {
952
956
} ) ;
953
957
954
958
describe ( 'ReactFiberErrorLogger' , ( ) => {
955
- function initReactFiberErrorLoggerMock ( mock ) {
956
- jest . resetModules ( ) ;
957
- if ( mock ) {
958
- jest . mock ( '../ReactFiberErrorLogger' ) ;
959
- } else {
960
- jest . unmock ( '../ReactFiberErrorLogger' ) ;
961
- }
962
- React = require ( 'react' ) ;
963
- ReactNoop = require ( 'react-noop-renderer' ) ;
964
- }
965
-
966
- beforeEach ( ( ) => {
967
- // Assert that we're mocking this file by default.
968
- // If this ever changes, we'll need to update this test suite anyway.
969
- expect (
970
- require ( '../ReactFiberErrorLogger' ) . logCapturedError . _isMockFunction ,
971
- ) . toBe ( true ) ;
972
- } ) ;
973
-
974
- afterEach ( ( ) => {
975
- // Restore the default (we verified it was being mocked in beforeEach).
976
- jest . mock ( '../ReactFiberErrorLogger' ) ;
977
- } ) ;
978
-
979
959
function normalizeCodeLocInfo ( str ) {
980
960
return str && str . replace ( / \( a t .+ ?: \d + \) / g, '(at **)' ) ;
981
961
}
982
962
983
963
it ( 'should log errors that occur during the begin phase' , ( ) => {
984
- initReactFiberErrorLoggerMock ( false ) ;
985
964
// Intentionally spy in production too.
986
- // TODO: It is confusing how these tests correctly "see" console.error()s
987
- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
988
- // and thus unmocked the error logger. It is globally mocked in all other
989
- // tests. We did this to silence warnings from intentionally caught errors
990
- // in tests. But perhaps we should instead make a pass through all tests,
991
- // intentionally assert console.error() is always called for uncaught
992
- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
993
965
spyOn ( console , 'error' ) ;
994
966
995
967
class ErrorThrowingComponent extends React . Component {
996
968
componentWillMount ( ) {
997
- throw Error ( 'componentWillMount error' ) ;
969
+ const error = new Error ( 'componentWillMount error' ) ;
970
+ // Note: it's `true` on the Error prototype our test environment.
971
+ // That lets us avoid asserting on warnings for each expected error.
972
+ // Here we intentionally shadow it to test logging, like in real apps.
973
+ error . suppressReactErrorLogging = undefined ;
974
+ throw error ;
998
975
}
999
976
render ( ) {
1000
977
return < div /> ;
@@ -1030,19 +1007,17 @@ describe('ReactIncrementalErrorHandling', () => {
1030
1007
} ) ;
1031
1008
1032
1009
it ( 'should log errors that occur during the commit phase' , ( ) => {
1033
- initReactFiberErrorLoggerMock ( false ) ;
1034
- // TODO: It is confusing how these tests correctly "see" console.error()s
1035
- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
1036
- // and thus unmocked the error logger. It is globally mocked in all other
1037
- // tests. We did this to silence warnings from intentionally caught errors
1038
- // in tests. But perhaps we should instead make a pass through all tests,
1039
- // intentionally assert console.error() is always called for uncaught
1040
- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
1010
+ // Intentionally spy in production too.
1041
1011
spyOn ( console , 'error' ) ;
1042
1012
1043
1013
class ErrorThrowingComponent extends React . Component {
1044
1014
componentDidMount ( ) {
1045
- throw Error ( 'componentDidMount error' ) ;
1015
+ const error = new Error ( 'componentDidMount error' ) ;
1016
+ // Note: it's `true` on the Error prototype our test environment.
1017
+ // That lets us avoid asserting on warnings for each expected error.
1018
+ // Here we intentionally shadow it to test logging, like in real apps.
1019
+ error . suppressReactErrorLogging = undefined ;
1020
+ throw error ;
1046
1021
}
1047
1022
render ( ) {
1048
1023
return < div /> ;
@@ -1078,18 +1053,16 @@ describe('ReactIncrementalErrorHandling', () => {
1078
1053
} ) ;
1079
1054
1080
1055
it ( 'should ignore errors thrown in log method to prevent cycle' , ( ) => {
1081
- initReactFiberErrorLoggerMock ( true ) ;
1056
+ jest . resetModules ( ) ;
1057
+ jest . mock ( '../ReactFiberErrorLogger' ) ;
1058
+ React = require ( 'react' ) ;
1059
+ ReactNoop = require ( 'react-noop-renderer' ) ;
1082
1060
// Intentionally spy in production too.
1083
- // Note: we're seeing console.error() even though ReactFiberErrorLogger is
1084
- // mocked because we're currently testing the console.error() call inside
1085
- // ReactFiberScheduler (for cycles). It doesn't get affected by mocking.
1086
- // TODO: mocking is confusing and we should simplify this and remove
1087
- // special cases.
1088
1061
spyOn ( console , 'error' ) ;
1089
1062
1090
1063
class ErrorThrowingComponent extends React . Component {
1091
1064
render ( ) {
1092
- throw Error ( 'render error' ) ;
1065
+ throw new Error ( 'render error' ) ;
1093
1066
}
1094
1067
}
1095
1068
@@ -1099,7 +1072,12 @@ describe('ReactIncrementalErrorHandling', () => {
1099
1072
ReactFiberErrorLogger . logCapturedError . mockImplementation (
1100
1073
capturedError => {
1101
1074
logCapturedErrorCalls . push ( capturedError ) ;
1102
- throw Error ( 'logCapturedError error' ) ;
1075
+ const error = new Error ( 'logCapturedError error' ) ;
1076
+ // Note: it's `true` on the Error prototype our test environment.
1077
+ // That lets us avoid asserting on warnings for each expected error.
1078
+ // Here we intentionally shadow it to test logging, like in real apps.
1079
+ error . suppressReactErrorLogging = undefined ;
1080
+ throw error ;
1103
1081
} ,
1104
1082
) ;
1105
1083
@@ -1124,14 +1102,7 @@ describe('ReactIncrementalErrorHandling', () => {
1124
1102
} ) ;
1125
1103
1126
1104
it ( 'should relay info about error boundary and retry attempts if applicable' , ( ) => {
1127
- initReactFiberErrorLoggerMock ( false ) ;
1128
- // TODO: It is confusing how these tests correctly "see" console.error()s
1129
- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
1130
- // and thus unmocked the error logger. It is globally mocked in all other
1131
- // tests. We did this to silence warnings from intentionally caught errors
1132
- // in tests. But perhaps we should instead make a pass through all tests,
1133
- // intentionally assert console.error() is always called for uncaught
1134
- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
1105
+ // Intentionally spy in production too.
1135
1106
spyOn ( console , 'error' ) ;
1136
1107
1137
1108
class ParentComponent extends React . Component {
@@ -1155,7 +1126,12 @@ describe('ReactIncrementalErrorHandling', () => {
1155
1126
1156
1127
class ErrorThrowingComponent extends React . Component {
1157
1128
componentDidMount ( ) {
1158
- throw Error ( 'componentDidMount error' ) ;
1129
+ const error = new Error ( 'componentDidMount error' ) ;
1130
+ // Note: it's `true` on the Error prototype our test environment.
1131
+ // That lets us avoid asserting on warnings for each expected error.
1132
+ // Here we intentionally shadow it to test logging, like in real apps.
1133
+ error . suppressReactErrorLogging = undefined ;
1134
+ throw error ;
1159
1135
}
1160
1136
render ( ) {
1161
1137
renderAttempts ++ ;
0 commit comments