@@ -9,6 +9,8 @@ PropTypes = null
99React = null
1010ReactDOM = null
1111ReactDOMClient = null
12+ assertConsoleErrorDev = null
13+ assertConsoleWarnDev = null
1214
1315featureFlags = require ' shared/ReactFeatureFlags'
1416
@@ -28,6 +30,9 @@ describe 'ReactCoffeeScriptClass', ->
2830 root = ReactDOMClient .createRoot container
2931 attachedListener = null
3032 renderedName = null
33+ TestUtils = require ' internal-test-utils'
34+ assertConsoleErrorDev = TestUtils .assertConsoleErrorDev
35+ assertConsoleWarnDev = TestUtils .assertConsoleWarnDev
3136 InnerComponent = class extends React.Component
3237 getName : -> this .props .name
3338 render : ->
@@ -53,14 +58,15 @@ describe 'ReactCoffeeScriptClass', ->
5358 event .preventDefault ()
5459 caughtErrors .push (event .error )
5560 window .addEventListener ' error' , errorHandler;
56- expect (->
57- ReactDOM .flushSync ->
58- root .render React .createElement (Foo)
59- ).toErrorDev ([
60- # A failed component renders twice in DEV in concurrent mode
61- ' No `render` method found on the Foo instance' ,
62- ' No `render` method found on the Foo instance' ,
63- ])
61+ ReactDOM .flushSync ->
62+ root .render React .createElement (Foo)
63+ assertConsoleErrorDev [
64+ # A failed component renders twice in DEV in concurrent mode
65+ ' No `render` method found on the Foo instance: you may have forgotten to define `render`.\n ' +
66+ ' in Foo (at **)' ,
67+ ' No `render` method found on the Foo instance: you may have forgotten to define `render`.\n ' +
68+ ' in Foo (at **)' ,
69+ ]
6470 window .removeEventListener ' error' , errorHandler;
6571 expect (caughtErrors).toEqual ([
6672 expect .objectContaining (
@@ -136,35 +142,39 @@ describe 'ReactCoffeeScriptClass', ->
136142 React .createElement (' div' )
137143 getDerivedStateFromProps : ->
138144 {}
139- expect ( ->
140- ReactDOM . flushSync ->
141- root . render React . createElement (Foo, foo : ' foo ' )
142- return
143- ). toErrorDev ' Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method. '
145+ ReactDOM . flushSync ->
146+ root . render React . createElement (Foo, foo : ' foo ' )
147+ assertConsoleErrorDev [
148+ ' Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method. \n ' +
149+ ' in Foo (at **) ' ]
144150
145151 it ' warns if getDerivedStateFromError is not static' , ->
146152 class Foo extends React.Component
147153 render : ->
148154 React .createElement (' div' )
149155 getDerivedStateFromError : ->
150156 {}
151- expect (->
152- ReactDOM .flushSync ->
153- root .render React .createElement (Foo, foo : ' foo' )
154- return
155- ).toErrorDev ' Foo: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.'
157+ ReactDOM .flushSync ->
158+ root .render React .createElement (Foo, foo : ' foo' )
159+
160+ assertConsoleErrorDev [
161+ ' Foo: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.\n ' +
162+ ' in Foo (at **)'
163+ ]
156164
157165 it ' warns if getSnapshotBeforeUpdate is static' , ->
158166 class Foo extends React.Component
159167 render : ->
160168 React .createElement (' div' )
161169 Foo .getSnapshotBeforeUpdate = () ->
162170 {}
163- expect (->
164- ReactDOM .flushSync ->
165- root .render React .createElement (Foo, foo : ' foo' )
166- return
167- ).toErrorDev ' Foo: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.'
171+ ReactDOM .flushSync ->
172+ root .render React .createElement (Foo, foo : ' foo' )
173+
174+ assertConsoleErrorDev [
175+ ' Foo: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.\n ' +
176+ ' in Foo (at **)'
177+ ]
168178
169179 it ' warns if state not initialized before static getDerivedStateFromProps' , ->
170180 class Foo extends React.Component
@@ -177,16 +187,16 @@ describe 'ReactCoffeeScriptClass', ->
177187 foo : nextProps .foo
178188 bar : ' bar'
179189 }
180- expect ( ->
181- ReactDOM . flushSync ->
182- root . render React . createElement (Foo, foo : ' foo ' )
183- return
184- ). toErrorDev (
185- ' `Foo` uses `getDerivedStateFromProps` but its initial state is ' +
186- ' undefined. This is not recommended. Instead, define the initial state by ' +
187- ' assigning an object to `this.state` in the constructor of `Foo`. ' +
188- ' This ensures that `getDerivedStateFromProps` arguments have a consistent shape. '
189- )
190+ ReactDOM . flushSync ->
191+ root . render React . createElement (Foo, foo : ' foo ' )
192+
193+ assertConsoleErrorDev [
194+ ' `Foo` uses `getDerivedStateFromProps` but its initial state is
195+ undefined. This is not recommended. Instead, define the initial state by
196+ assigning an object to `this.state` in the constructor of `Foo`.
197+ This ensures that `getDerivedStateFromProps` arguments have a consistent shape. \n ' +
198+ ' in Foo (at **) '
199+ ]
190200
191201 it ' updates initial state with values returned by static getDerivedStateFromProps' , ->
192202 class Foo extends React.Component
@@ -254,12 +264,28 @@ describe 'ReactCoffeeScriptClass', ->
254264 render : ->
255265 React .createElement Foo
256266
257- expect (->
258- test React .createElement (Outer), ' SPAN' , ' foo'
259- ).toErrorDev ([
260- ' Outer uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.' ,
261- ' Foo uses the legacy contextTypes API which will soon be removed. Use React.createContext() with static contextType instead.' ,
262- ])
267+ test React .createElement (Outer), ' SPAN' , ' foo'
268+
269+ if featureFlags .enableOwnerStacks
270+ assertConsoleErrorDev ([
271+ ' Outer uses the legacy childContextTypes API which will soon be removed.
272+ Use React.createContext() instead. (https://react.dev/link/legacy-context)\n ' +
273+ ' in Outer (at **)' ,
274+ ' Foo uses the legacy contextTypes API which will soon be removed.
275+ Use React.createContext() with static contextType instead. (https://react.dev/link/legacy-context)\n ' +
276+ ' in Outer (at **)' ,
277+ ]);
278+ else
279+ assertConsoleErrorDev ([
280+ ' Outer uses the legacy childContextTypes API which will soon be removed.
281+ Use React.createContext() instead. (https://react.dev/link/legacy-context)\n ' +
282+ ' in Outer (at **)' ,
283+ ' Foo uses the legacy contextTypes API which will soon be removed.
284+ Use React.createContext() with static contextType instead. (https://react.dev/link/legacy-context)\n ' +
285+ ' in Foo (at **)\n ' +
286+ ' in Outer (at **)' ,
287+ ]);
288+
263289
264290 it ' renders only once when setting state in componentWillMount' , ->
265291 renderCount = 0
@@ -286,9 +312,11 @@ describe 'ReactCoffeeScriptClass', ->
286312 render : ->
287313 React .createElement (' span' )
288314
289- expect (->
290- test React .createElement (Foo), ' SPAN' , ' '
291- ).toErrorDev (' Foo.state: must be set to an object or null' )
315+ test React .createElement (Foo), ' SPAN' , ' '
316+ assertConsoleErrorDev [
317+ ' Foo.state: must be set to an object or null\n ' +
318+ ' in Foo (at **)'
319+ ]
292320
293321 it ' should render with null in the initial state property' , ->
294322 class Foo extends React.Component
@@ -430,14 +458,21 @@ describe 'ReactCoffeeScriptClass', ->
430458 className : ' foo'
431459 )
432460
433- expect (->
434- test React .createElement (Foo), ' SPAN' , ' foo'
435- ).toErrorDev ([
436- ' getInitialState was defined on Foo, a plain JavaScript class.' ,
437- ' getDefaultProps was defined on Foo, a plain JavaScript class.' ,
438- ' contextTypes was defined as an instance property on Foo.' ,
439- ' contextType was defined as an instance property on Foo.' ,
440- ])
461+ test React .createElement (Foo), ' SPAN' , ' foo'
462+ assertConsoleErrorDev [
463+ ' getInitialState was defined on Foo, a plain JavaScript class.
464+ This is only supported for classes created using React.createClass.
465+ Did you mean to define a state property instead?\n ' +
466+ ' in Foo (at **)' ,
467+ ' getDefaultProps was defined on Foo, a plain JavaScript class.
468+ This is only supported for classes created using React.createClass.
469+ Use a static property to define defaultProps instead.\n ' +
470+ ' in Foo (at **)' ,
471+ ' contextType was defined as an instance property on Foo. Use a static property to define contextType instead.\n ' +
472+ ' in Foo (at **)' ,
473+ ' contextTypes was defined as an instance property on Foo. Use a static property to define contextTypes instead.\n ' +
474+ ' in Foo (at **)' ,
475+ ]
441476 expect (getInitialStateWasCalled).toBe false
442477 expect (getDefaultPropsWasCalled).toBe false
443478
@@ -468,13 +503,13 @@ describe 'ReactCoffeeScriptClass', ->
468503 className : ' foo'
469504 )
470505
471- expect (->
472- test React .createElement (NamedComponent), ' SPAN' , ' foo'
473- ).toErrorDev (
506+ test React .createElement (NamedComponent), ' SPAN' , ' foo'
507+ assertConsoleErrorDev [
474508 ' NamedComponent has a method called componentShouldUpdate().
475509 Did you mean shouldComponentUpdate()? The name is phrased as a
476- question because the function is expected to return a value.'
477- )
510+ question because the function is expected to return a value.\n ' +
511+ ' in NamedComponent (at **)'
512+ ]
478513
479514 it ' should warn when misspelling componentWillReceiveProps' , ->
480515 class NamedComponent extends React.Component
@@ -486,12 +521,12 @@ describe 'ReactCoffeeScriptClass', ->
486521 className : ' foo'
487522 )
488523
489- expect (->
490- test React .createElement (NamedComponent), ' SPAN' , ' foo'
491- ).toErrorDev (
524+ test React .createElement (NamedComponent), ' SPAN' , ' foo'
525+ assertConsoleErrorDev [
492526 ' NamedComponent has a method called componentWillRecieveProps().
493- Did you mean componentWillReceiveProps()?'
494- )
527+ Did you mean componentWillReceiveProps()?\n ' +
528+ ' in NamedComponent (at **)'
529+ ]
495530
496531 it ' should warn when misspelling UNSAFE_componentWillReceiveProps' , ->
497532 class NamedComponent extends React.Component
@@ -503,28 +538,28 @@ describe 'ReactCoffeeScriptClass', ->
503538 className : ' foo'
504539 )
505540
506- expect (->
507- test React .createElement (NamedComponent), ' SPAN' , ' foo'
508- ).toErrorDev (
541+ test React .createElement (NamedComponent), ' SPAN' , ' foo'
542+ assertConsoleErrorDev [
509543 ' NamedComponent has a method called UNSAFE_componentWillRecieveProps().
510- Did you mean UNSAFE_componentWillReceiveProps()?'
511- )
544+ Did you mean UNSAFE_componentWillReceiveProps()?\n ' +
545+ ' in NamedComponent (at **)'
546+ ]
512547
513548 it ' should throw AND warn when trying to access classic APIs' , ->
514549 ref = React .createRef ()
515550 test React .createElement (InnerComponent, name : ' foo' , ref : ref), ' DIV' , ' foo'
516- expect ( ->
517- expect (-> ref .current .replaceState {}).toThrow ()
518- ). toWarnDev (
519- ' replaceState(...) is deprecated in plain JavaScript React classes' ,
520- { withoutStack : true }
521- )
522- expect ( ->
523- expect (-> ref .current .isMounted ()).toThrow ()
524- ). toWarnDev (
525- ' isMounted(...) is deprecated in plain JavaScript React classes' ,
526- { withoutStack : true }
527- )
551+
552+ expect (-> ref .current .replaceState {}).toThrow ()
553+ assertConsoleWarnDev ([
554+ ' replaceState(...) is deprecated in plain JavaScript React classes.
555+ Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236). '
556+ ], { withoutStack : true } )
557+
558+ expect (-> ref .current .isMounted ()).toThrow ()
559+ assertConsoleWarnDev ([
560+ ' isMounted(...) is deprecated in plain JavaScript React classes.
561+ Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks. ' ,
562+ ], { withoutStack : true } )
528563
529564 if ! featureFlags .disableLegacyContext
530565 it ' supports this.context passed via getChildContext' , ->
@@ -542,13 +577,25 @@ describe 'ReactCoffeeScriptClass', ->
542577 render : ->
543578 React .createElement Bar
544579
545- expect (->
546- test React .createElement (Foo), ' DIV' , ' bar-through-context'
547- ).toErrorDev (
548- [
549- ' Foo uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.' ,
550- ' Bar uses the legacy contextTypes API which will soon be removed. Use React.createContext() with static contextType instead.' ,
551- ],
552- )
580+ test React .createElement (Foo), ' DIV' , ' bar-through-context'
581+ if featureFlags .enableOwnerStacks
582+ assertConsoleErrorDev [
583+ ' Foo uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.
584+ (https://react.dev/link/legacy-context)\n ' +
585+ ' in Foo (at **)' ,
586+ ' Bar uses the legacy contextTypes API which will soon be removed. Use React.createContext() with static contextType instead.
587+ (https://react.dev/link/legacy-context)\n ' +
588+ ' in Foo (at **)'
589+ ]
590+ else
591+ assertConsoleErrorDev [
592+ ' Foo uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.
593+ (https://react.dev/link/legacy-context)\n ' +
594+ ' in Foo (at **)' ,
595+ ' Bar uses the legacy contextTypes API which will soon be removed. Use React.createContext() with static contextType instead.
596+ (https://react.dev/link/legacy-context)\n ' +
597+ ' in Bar (at **)\n ' +
598+ ' in Foo (at **)'
599+ ]
553600
554601 undefined
0 commit comments