Skip to content

Commit c105605

Browse files
committed
Support ReactTestUtilsConfig.aroundReact in new testing API
1 parent 53d95d7 commit c105605

File tree

7 files changed

+50
-38
lines changed

7 files changed

+50
-38
lines changed

doc/CONFIG.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ object CustomConfig extends ScalaJsReactConfig.Defaults {
164164

165165
# `.test.warnings.react`
166166

167-
When using `LegacyReactTestUtils`, this setting can be used to catch React warnings and turn them into exceptions.
167+
When using `ReactTestUtils` or `LegacyReactTestUtils`, this setting can be used to catch React warnings and turn them into exceptions.
168168

169169
### Usage:
170170

@@ -196,9 +196,8 @@ object ExampleTest extends TestSuite {
196196
override def tests = Tests {
197197
"example" - {
198198
val comp = ScalaFnComponent[Int](i => <.p(<.td(s"i = $i")))
199-
LegacyReactTestUtils.withRenderedIntoBody(comp(123)).withParent { m =>
200-
val html = m.outerHTML
201-
assert(html == "<p><td>i = 123</td></p>")
199+
ReactTestUtils.withRenderedSync(comp(123)) { t =>
200+
t.outerHTML.assert("<p><td>i = 123</td></p>")
202201
}
203202
}
204203
}
@@ -241,7 +240,8 @@ object Main {
241240

242241
// Start app
243242
val container = dom.document.getElementById("root")
244-
MyApp().renderIntoDOM(container)
243+
val root = ReactDOMClient.createRoot(container)
244+
root.render(MyApp())
245245
}
246246
}
247247
```
@@ -293,7 +293,8 @@ object Main {
293293

294294
// Start app
295295
val container = dom.document.getElementById("root")
296-
MyApp().renderIntoDOM(container)
296+
val root = ReactDOMClient.createRoot(container)
297+
root.render(MyApp())
297298
}
298299
}
299300
```

doc/TESTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ for how to write tests for real-world scalajs-react applications.
290290

291291
# Fatal React warnings
292292

293-
The easiest way to make `LegacyReactTestUtils` to turn React warnings into runtime exceptions,
293+
The easiest way to make `ReactTestUtils` or `LegacyReactTestUtils` to turn React warnings into runtime exceptions,
294294
is via a [config option](./CONFIG.md#testwarningsreact).
295295

296296
Alternatively, you can do any of the following...
@@ -304,7 +304,7 @@ Alternatively, you can do any of the following...
304304
}
305305
```
306306

307-
- Installing for all `LegacyReactTestUtils` usage
307+
- Installing for all `ReactTestUtils` usage
308308

309309
```scala
310310
import japgolly.scalajs.react.test.ReactTestUtilsConfig

downstream-tests/js/src/test/scala/downstream/RuntimeTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ object RuntimeTests extends AsyncTestSuite {
9797
val c = ScalaFnComponent[Int](i => <.p(<.td(s"i = $i")))
9898
ReactTestUtils.withRendered_(c(123))(_ => ()).attemptTry.map { t =>
9999
assertEq(t.isFailure, testWarningsReact.contains("react"))
100+
t.toEither
100101
}
101102
}
102103

library/testUtil/src/main/scala/japgolly/scalajs/react/test/LegacyReactTestUtils.scala

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import japgolly.scalajs.react._
44
import japgolly.scalajs.react.facade.{React => RawReact, ReactDOM => RawReactDOM}
55
import japgolly.scalajs.react.hooks.Hooks
66
import japgolly.scalajs.react.internal.CoreGeneral._
7-
import japgolly.scalajs.react.test.ReactTestUtilsConfig.aroundReact
87
import japgolly.scalajs.react.util.DefaultEffects.{Async => DA, Sync => DS}
98
import japgolly.scalajs.react.util.Effect._
109
import japgolly.scalajs.react.util.JsUtil
@@ -106,30 +105,13 @@ object LegacyReactTestUtils extends LegacyReactTestUtils {
106105

107106
def _withRenderedAsync[F[_], M, A](u: Unmounted[M], parent: Element, f: (M, Element) => F[A])
108107
(implicit F: Async[F]): F[A] =
109-
aroundReactAsync {
108+
ReactTestUtilsConfig.aroundReact.async {
110109
F.flatMap(F.delay(act(RawReactDOM.render(u.raw, parent)))) { c =>
111110
val m = u.mountRawOrNull(c)
112111
F.finallyRun(f(m, parent), F.delay(act(unmountRawComponent(c))))
113112
}
114113
}
115114

116-
def aroundReactAsync[F[_], A](body: F[A])(implicit F: Async[F]): F[A] = {
117-
val start = F.delay {
118-
val stop = aroundReact.start()
119-
F.delay(stop())
120-
}
121-
F.flatMap(start) { stop =>
122-
F.finallyRun(body, stop)
123-
}
124-
}
125-
126-
def aroundReactFuture[A](body: => Future[A])(implicit ec: ExecutionContext): Future[A] = {
127-
val stop = aroundReact.start()
128-
val f = body
129-
f.onComplete { _ => stop() }
130-
f
131-
}
132-
133115
} // Internals
134116
}
135117

@@ -279,7 +261,7 @@ trait LegacyReactTestUtils extends japgolly.scalajs.react.test.internal.ReactTes
279261
new WithRenderedDsl[M, Element] {
280262
override def apply[A](f: (M, Element) => A): A =
281263
withNewBodyElement { parent =>
282-
aroundReact.sync {
264+
ReactTestUtilsConfig.aroundReact.sync {
283265
val c = act(RawReactDOM.render(u.raw, parent))
284266
try
285267
f(u.mountRawOrNull(c), parent)
@@ -308,7 +290,7 @@ trait LegacyReactTestUtils extends japgolly.scalajs.react.test.internal.ReactTes
308290
*/
309291
def withRenderedIntoBodyFuture[M, A](u: Unmounted[M])(f: M => Future[A])(implicit ec: ExecutionContext): Future[A] =
310292
withNewBodyElementFuture { parent =>
311-
aroundReactFuture {
293+
ReactTestUtilsConfig.aroundReact.future {
312294
val c = act(RawReactDOM.render(u.raw, parent))
313295
val m = u.mountRawOrNull(c)
314296
attemptFuture(f(m)).andThen { case _ => act(unmountRawComponent(c)) }
@@ -357,7 +339,7 @@ trait LegacyReactTestUtils extends japgolly.scalajs.react.test.internal.ReactTes
357339
def withRenderedIntoDocument[M](u: Unmounted[M]): WithRenderedDsl[M, Element] =
358340
new WithRenderedDsl[M, Element] {
359341
override def apply[A](f: (M, Element) => A): A =
360-
aroundReact.sync {
342+
ReactTestUtilsConfig.aroundReact.sync {
361343
val c = act(raw.renderIntoDocument(u.raw))
362344
try {
363345
val p = parentElement(c)
@@ -377,7 +359,7 @@ trait LegacyReactTestUtils extends japgolly.scalajs.react.test.internal.ReactTes
377359
* and asynchronously waits for the Future to complete before unmounting.
378360
*/
379361
def withRenderedIntoDocumentFuture[M, A](u: Unmounted[M])(f: M => Future[A])(implicit ec: ExecutionContext): Future[A] =
380-
aroundReactFuture {
362+
ReactTestUtilsConfig.aroundReact.future {
381363
val c = act(raw.renderIntoDocument(u.raw))
382364
val m = u.mountRawOrNull(c)
383365
attemptFuture(f(m)).andThen { case _ => act(unmountRawComponent(c)) }

library/testUtil/src/main/scala/japgolly/scalajs/react/test/ReactTestUtils.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,18 @@ trait ReactTestUtils extends japgolly.scalajs.react.test.internal.ReactTestUtilE
120120
Resource.make(Effect[F].delay(newElement()), e => Effect[F].delay(removeElement(e)))
121121

122122
val withReactRootSync: WithDsl[TestReactRoot, ImplicitUnit] =
123-
withElementSync.mapResource(TestReactRoot(_))(_.unmountSync())
124-
125-
def withReactRoot[F[_]: Async]: Resource[F, TestReactRoot] =
126-
withElement[F].flatMap{ e =>
127-
Resource.make_[F, TestReactRoot](TestReactRoot(e), _.unmount[F]())
123+
withElementSync
124+
.mapResource(e => {
125+
val stop = ReactTestUtilsConfig.aroundReact.start()
126+
(e, stop)
127+
})(_._2())
128+
.mapResource(x => TestReactRoot(x._1))(_.unmountSync())
129+
130+
def withReactRoot[F[_]](implicit F: Async[F]): Resource[F, TestReactRoot] =
131+
withElement[F].flatMap { e =>
132+
Resource.make_[F, () => Unit](ReactTestUtilsConfig.aroundReact.start(), stop => F.delay(stop())).flatMap { _ =>
133+
Resource.make_[F, TestReactRoot](TestReactRoot(e), _.unmount[F]())
134+
}
128135
}
129136

130137
def withRenderedSync[A](unmounted: A): WithDsl[TestDomWithRoot, Renderable[A]] =

library/testUtil/src/main/scala/japgolly/scalajs/react/test/ReactTestUtilsConfig.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package japgolly.scalajs.react.test
22

33
import japgolly.scalajs.react.test.internal._
4+
import japgolly.scalajs.react.util.Effect.Async
5+
import scala.concurrent.ExecutionContext
6+
import scala.concurrent.Future
47

58
object ReactTestUtilsConfig extends ReactTestUtilsConfigTypes {
69

@@ -20,5 +23,22 @@ object ReactTestUtilsConfig extends ReactTestUtilsConfigTypes {
2023

2124
override def start(): () => Unit =
2225
value.start()
26+
27+
def async[F[_], A](body: F[A])(implicit F: Async[F]): F[A] = {
28+
val start = F.delay {
29+
val stop = ReactTestUtilsConfig.aroundReact.start()
30+
F.delay(stop())
31+
}
32+
F.flatMap(start) { stop =>
33+
F.finallyRun(body, stop)
34+
}
35+
}
36+
37+
def future[A](body: => Future[A])(implicit ec: ExecutionContext): Future[A] = {
38+
val stop = ReactTestUtilsConfig.aroundReact.start()
39+
val f = body
40+
f.onComplete { _ => stop() }
41+
f
42+
}
2343
}
2444
}

library/tests/src/test/scala/japgolly/scalajs/react/test/ReactTestUtilsConfigTest.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ object ReactTestUtilsConfigTest extends AsyncTestSuite {
2828
"warnings" - {
2929
"react" - AroundReact.fatalReactWarnings {
3030
val c = ScalaFnComponent[Int](i => <.p(<.td(s"i = $i")))
31-
ReactTestUtils.withRendered_(c(123))(_ => ()).attemptTry.map( t =>
31+
ReactTestUtils.withRendered_(c(123))(_ => ()).attemptTry.map { t =>
3232
assertEq(t.isFailure, true)
33-
)
33+
t.toEither
34+
}
3435
}
3536

3637
"unlreated" - AroundReact.fatalReactWarnings {

0 commit comments

Comments
 (0)