Skip to content

Commit a8a4742

Browse files
authored
Convert ES6/TypeScript/CoffeeScript Tests to createRoot + act (#21598)
* Convert ES6/TypeScript CoffeeScript Tests to createRoot + act * Change expectation for WWW+VARIANT because the deferRenderPhaseUpdateToNextBatch flag breaks this behavior
1 parent 1d35589 commit a8a4742

File tree

7 files changed

+152
-113
lines changed

7 files changed

+152
-113
lines changed

packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@ This source code is licensed under the MIT license found in the
55
LICENSE file in the root directory of this source tree.
66
###
77

8+
PropTypes = null
89
React = null
910
ReactDOM = null
10-
PropTypes = null
11+
act = null
1112

1213
describe 'ReactCoffeeScriptClass', ->
1314
container = null
15+
root = null
1416
InnerComponent = null
1517
attachedListener = null;
1618
renderedName = null;
1719

1820
beforeEach ->
1921
React = require 'react'
2022
ReactDOM = require 'react-dom'
23+
act = require('react-dom/test-utils').act
2124
PropTypes = require 'prop-types'
2225
container = document.createElement 'div'
26+
root = ReactDOM.createRoot container
2327
attachedListener = null
2428
renderedName = null
2529
InnerComponent = class extends React.Component
@@ -30,11 +34,11 @@ describe 'ReactCoffeeScriptClass', ->
3034
return React.createElement('div', className: this.props.name)
3135

3236
test = (element, expectedTag, expectedClassName) ->
33-
instance = ReactDOM.render(element, container)
37+
act ->
38+
root.render(element)
3439
expect(container.firstChild).not.toBeNull()
3540
expect(container.firstChild.tagName).toBe(expectedTag)
3641
expect(container.firstChild.className).toBe(expectedClassName)
37-
instance;
3842

3943
it 'preserves the name of the class for use in error messages', ->
4044
class Foo extends React.Component
@@ -44,14 +48,16 @@ describe 'ReactCoffeeScriptClass', ->
4448
class Foo extends React.Component
4549
expect(->
4650
expect(->
47-
ReactDOM.render React.createElement(Foo), container
51+
act ->
52+
root.render React.createElement(Foo)
4853
).toThrow()
4954
).toErrorDev([
50-
# A failed component renders twice in DEV
55+
# A failed component renders four times in DEV in concurrent mode
56+
'No `render` method found on the returned component instance',
57+
'No `render` method found on the returned component instance',
5158
'No `render` method found on the returned component instance',
5259
'No `render` method found on the returned component instance',
5360
])
54-
undefined
5561

5662
it 'renders a simple stateless component with prop', ->
5763
class Foo extends React.Component
@@ -62,7 +68,6 @@ describe 'ReactCoffeeScriptClass', ->
6268

6369
test React.createElement(Foo, bar: 'foo'), 'DIV', 'foo'
6470
test React.createElement(Foo, bar: 'bar'), 'DIV', 'bar'
65-
undefined
6671

6772
it 'renders based on state using initial values in this.props', ->
6873
class Foo extends React.Component
@@ -76,7 +81,6 @@ describe 'ReactCoffeeScriptClass', ->
7681
)
7782

7883
test React.createElement(Foo, initialValue: 'foo'), 'SPAN', 'foo'
79-
undefined
8084

8185
it 'renders based on state using props in the constructor', ->
8286
class Foo extends React.Component
@@ -95,10 +99,10 @@ describe 'ReactCoffeeScriptClass', ->
9599
className: @state.bar
96100
)
97101

98-
instance = test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
99-
instance.changeState()
102+
ref = React.createRef()
103+
test React.createElement(Foo, initialValue: 'foo', ref: ref), 'DIV', 'foo'
104+
ref.current.changeState()
100105
test React.createElement(Foo), 'SPAN', 'bar'
101-
undefined
102106

103107
it 'sets initial state with value returned by static getDerivedStateFromProps', ->
104108
class Foo extends React.Component
@@ -115,7 +119,6 @@ describe 'ReactCoffeeScriptClass', ->
115119
bar: 'bar'
116120
}
117121
test React.createElement(Foo, foo: 'foo'), 'DIV', 'foo bar'
118-
undefined
119122

120123
it 'warns if getDerivedStateFromProps is not static', ->
121124
class Foo extends React.Component
@@ -124,9 +127,9 @@ describe 'ReactCoffeeScriptClass', ->
124127
getDerivedStateFromProps: ->
125128
{}
126129
expect(->
127-
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
130+
act ->
131+
root.render React.createElement(Foo, foo: 'foo')
128132
).toErrorDev 'Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.'
129-
undefined
130133

131134
it 'warns if getDerivedStateFromError is not static', ->
132135
class Foo extends React.Component
@@ -135,9 +138,9 @@ describe 'ReactCoffeeScriptClass', ->
135138
getDerivedStateFromError: ->
136139
{}
137140
expect(->
138-
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
141+
act ->
142+
root.render React.createElement(Foo, foo: 'foo')
139143
).toErrorDev 'Foo: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.'
140-
undefined
141144

142145
it 'warns if getSnapshotBeforeUpdate is static', ->
143146
class Foo extends React.Component
@@ -146,9 +149,9 @@ describe 'ReactCoffeeScriptClass', ->
146149
Foo.getSnapshotBeforeUpdate = () ->
147150
{}
148151
expect(->
149-
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
152+
act ->
153+
root.render React.createElement(Foo, foo: 'foo')
150154
).toErrorDev 'Foo: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.'
151-
undefined
152155

153156
it 'warns if state not initialized before static getDerivedStateFromProps', ->
154157
class Foo extends React.Component
@@ -162,14 +165,14 @@ describe 'ReactCoffeeScriptClass', ->
162165
bar: 'bar'
163166
}
164167
expect(->
165-
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
168+
act ->
169+
root.render React.createElement(Foo, foo: 'foo')
166170
).toErrorDev (
167171
'`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
168172
'undefined. This is not recommended. Instead, define the initial state by ' +
169173
'assigning an object to `this.state` in the constructor of `Foo`. ' +
170174
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.'
171175
)
172-
undefined
173176

174177
it 'updates initial state with values returned by static getDerivedStateFromProps', ->
175178
class Foo extends React.Component
@@ -187,7 +190,6 @@ describe 'ReactCoffeeScriptClass', ->
187190
foo: "not-#{prevState.foo}"
188191
}
189192
test React.createElement(Foo), 'DIV', 'not-foo bar'
190-
undefined
191193

192194
it 'renders updated state with values returned by static getDerivedStateFromProps', ->
193195
class Foo extends React.Component
@@ -207,7 +209,6 @@ describe 'ReactCoffeeScriptClass', ->
207209
return null
208210
test React.createElement(Foo, update: false), 'DIV', 'initial'
209211
test React.createElement(Foo, update: true), 'DIV', 'updated'
210-
undefined
211212

212213
it 'renders based on context in the constructor', ->
213214
class Foo extends React.Component
@@ -239,7 +240,6 @@ describe 'ReactCoffeeScriptClass', ->
239240
React.createElement Foo
240241

241242
test React.createElement(Outer), 'SPAN', 'foo'
242-
undefined
243243

244244
it 'renders only once when setting state in componentWillMount', ->
245245
renderCount = 0
@@ -255,8 +255,9 @@ describe 'ReactCoffeeScriptClass', ->
255255
React.createElement('span', className: @state.bar)
256256

257257
test React.createElement(Foo, initialValue: 'foo'), 'SPAN', 'bar'
258-
expect(renderCount).toBe 1
259-
undefined
258+
# This is broken with deferRenderPhaseUpdateToNextBatch flag on.
259+
# We can't use the gate feature here because this test is also in CoffeeScript and TypeScript.
260+
expect(renderCount).toBe(if global.__WWW__ and !global.__VARIANT__ then 2 else 1)
260261

261262
it 'should warn with non-object in the initial state property', ->
262263
[['an array'], 'a string', 1234].forEach (state) ->
@@ -270,7 +271,6 @@ describe 'ReactCoffeeScriptClass', ->
270271
expect(->
271272
test React.createElement(Foo), 'SPAN', ''
272273
).toErrorDev('Foo.state: must be set to an object or null')
273-
undefined
274274

275275
it 'should render with null in the initial state property', ->
276276
class Foo extends React.Component
@@ -281,7 +281,6 @@ describe 'ReactCoffeeScriptClass', ->
281281
React.createElement('span')
282282

283283
test React.createElement(Foo), 'SPAN', ''
284-
undefined
285284

286285
it 'setState through an event handler', ->
287286
class Foo extends React.Component
@@ -298,9 +297,9 @@ describe 'ReactCoffeeScriptClass', ->
298297
)
299298

300299
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
301-
attachedListener()
300+
act ->
301+
attachedListener()
302302
expect(renderedName).toBe 'bar'
303-
undefined
304303

305304
it 'should not implicitly bind event handlers', ->
306305
class Foo extends React.Component
@@ -318,7 +317,6 @@ describe 'ReactCoffeeScriptClass', ->
318317

319318
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
320319
expect(attachedListener).toThrow()
321-
undefined
322320

323321
it 'renders using forceUpdate even when there is no state', ->
324322
class Foo extends React.Component
@@ -336,9 +334,9 @@ describe 'ReactCoffeeScriptClass', ->
336334
)
337335

338336
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
339-
attachedListener()
337+
act ->
338+
attachedListener()
340339
expect(renderedName).toBe 'bar'
341-
undefined
342340

343341
it 'will call all the normal life cycle methods', ->
344342
lifeCycles = []
@@ -387,9 +385,9 @@ describe 'ReactCoffeeScriptClass', ->
387385
'did-update', { value: 'foo' }, {}
388386
]
389387
lifeCycles = [] # reset
390-
ReactDOM.unmountComponentAtNode container
388+
act ->
389+
root.unmount()
391390
expect(lifeCycles).toEqual ['will-unmount']
392-
undefined
393391

394392
it 'warns when classic properties are defined on the instance,
395393
but does not invoke them.', ->
@@ -425,7 +423,6 @@ describe 'ReactCoffeeScriptClass', ->
425423
])
426424
expect(getInitialStateWasCalled).toBe false
427425
expect(getDefaultPropsWasCalled).toBe false
428-
undefined
429426

430427
it 'does not warn about getInitialState() on class components
431428
if state is also defined.', ->
@@ -443,7 +440,6 @@ describe 'ReactCoffeeScriptClass', ->
443440
)
444441

445442
test React.createElement(Foo), 'SPAN', 'foo'
446-
undefined
447443

448444
it 'should warn when misspelling shouldComponentUpdate', ->
449445
class NamedComponent extends React.Component
@@ -462,7 +458,6 @@ describe 'ReactCoffeeScriptClass', ->
462458
Did you mean shouldComponentUpdate()? The name is phrased as a
463459
question because the function is expected to return a value.'
464460
)
465-
undefined
466461

467462
it 'should warn when misspelling componentWillReceiveProps', ->
468463
class NamedComponent extends React.Component
@@ -480,7 +475,6 @@ describe 'ReactCoffeeScriptClass', ->
480475
'Warning: NamedComponent has a method called componentWillRecieveProps().
481476
Did you mean componentWillReceiveProps()?'
482477
)
483-
undefined
484478

485479
it 'should warn when misspelling UNSAFE_componentWillReceiveProps', ->
486480
class NamedComponent extends React.Component
@@ -498,24 +492,22 @@ describe 'ReactCoffeeScriptClass', ->
498492
'Warning: NamedComponent has a method called UNSAFE_componentWillRecieveProps().
499493
Did you mean UNSAFE_componentWillReceiveProps()?'
500494
)
501-
undefined
502495

503496
it 'should throw AND warn when trying to access classic APIs', ->
504-
instance =
505-
test React.createElement(InnerComponent, name: 'foo'), 'DIV', 'foo'
497+
ref = React.createRef()
498+
test React.createElement(InnerComponent, name: 'foo', ref: ref), 'DIV', 'foo'
506499
expect(->
507-
expect(-> instance.replaceState {}).toThrow()
500+
expect(-> ref.current.replaceState {}).toThrow()
508501
).toWarnDev(
509502
'replaceState(...) is deprecated in plain JavaScript React classes',
510503
{withoutStack: true}
511504
)
512505
expect(->
513-
expect(-> instance.isMounted()).toThrow()
506+
expect(-> ref.current.isMounted()).toThrow()
514507
).toWarnDev(
515508
'isMounted(...) is deprecated in plain JavaScript React classes',
516509
{withoutStack: true}
517510
)
518-
undefined
519511

520512
it 'supports this.context passed via getChildContext', ->
521513
class Bar extends React.Component
@@ -533,7 +525,6 @@ describe 'ReactCoffeeScriptClass', ->
533525
React.createElement Bar
534526

535527
test React.createElement(Foo), 'DIV', 'bar-through-context'
536-
undefined
537528

538529
it 'supports classic refs', ->
539530
class Foo extends React.Component
@@ -543,13 +534,14 @@ describe 'ReactCoffeeScriptClass', ->
543534
ref: 'inner'
544535
)
545536

546-
instance = test(React.createElement(Foo), 'DIV', 'foo')
547-
expect(instance.refs.inner.getName()).toBe 'foo'
548-
undefined
537+
ref = React.createRef()
538+
test(React.createElement(Foo, ref: ref), 'DIV', 'foo')
539+
expect(ref.current.refs.inner.getName()).toBe 'foo'
549540

550541
it 'supports drilling through to the DOM using findDOMNode', ->
551-
instance = test React.createElement(InnerComponent, name: 'foo'), 'DIV', 'foo'
552-
node = ReactDOM.findDOMNode(instance)
542+
ref = React.createRef()
543+
test React.createElement(InnerComponent, name: 'foo', ref: ref), 'DIV', 'foo'
544+
node = ReactDOM.findDOMNode(ref.current)
553545
expect(node).toBe container.firstChild
554-
undefined
546+
555547
undefined

0 commit comments

Comments
 (0)