11package org .scalajs .jsenv .jsdomnodejs
22
3+ import java .nio .charset .StandardCharsets
4+ import java .nio .file .{Files , Path }
5+
36import scala .concurrent .duration ._
47
8+ import com .google .common .jimfs .Jimfs
9+
510import org .junit .Test
611
12+ import org .scalajs .jsenv .Input
713import org .scalajs .jsenv .test .kit .TestKit
814
915class JSDOMNodeJSEnvTest {
16+ import JSDOMNodeJSEnvTest ._
17+
1018 private val kit = new TestKit (new JSDOMNodeJSEnv , 1 .minute)
1119
1220 @ Test
@@ -21,4 +29,98 @@ class JSDOMNodeJSEnvTest {
2129 .expectOut(" http://localhost/foo\n " )
2230 }
2331 }
32+
33+ @ Test
34+ def reactUnhandledExceptionHack_issue42 : Unit = {
35+ val code =
36+ """
37+ |const rootElement = document.createElement("div");
38+ |document.body.appendChild(rootElement);
39+ |
40+ |class ThrowingComponent extends React.Component {
41+ | render() {
42+ | throw new Error("boom");
43+ | }
44+ |}
45+ |
46+ |class ErrorBoundary extends React.Component {
47+ | constructor(props) {
48+ | super(props);
49+ | this.state = { hasError: false };
50+ | }
51+ |
52+ | componentDidCatch(error, info) {
53+ | this.setState({error: error.message, hasError: true});
54+ | }
55+ |
56+ | render() {
57+ | if (this.state.hasError) {
58+ | console.log("render-error");
59+ | return React.createElement("p", null,
60+ | `Caught error: ${this.state.error}`);
61+ | } else {
62+ | return this.props.children;
63+ | }
64+ | }
65+ |}
66+ |
67+ |class MyMainComponent extends React.Component {
68+ | render() {
69+ | console.log("two");
70+ | return React.createElement(ErrorBoundary, null,
71+ | React.createElement(ThrowingComponent)
72+ | );
73+ | }
74+ |}
75+ |
76+ |console.log("begin");
77+ |
78+ |const mounted = ReactDOM.render(
79+ | React.createElement(ErrorBoundary, null,
80+ | React.createElement(ThrowingComponent, null)
81+ | ),
82+ | rootElement
83+ |);
84+ |
85+ |console.log(document.querySelector("p").textContent);
86+ |
87+ |console.log("end");
88+ """ .stripMargin
89+
90+ kit.withRun(ReactJSFiles :+ codeToInput(code)) {
91+ _.expectOut(" begin\n render-error\n Caught error: boom\n end\n " )
92+ .succeeds()
93+ }
94+ }
95+ }
96+
97+ object JSDOMNodeJSEnvTest {
98+ private lazy val ReactJSFiles : List [Input ] = {
99+ val fs = Jimfs .newFileSystem()
100+ val reactFile = copyResource(
101+ " /META-INF/resources/webjars/react/16.13.1/umd/react.development.js" ,
102+ fs.getPath(" react.development.js" ))
103+ val reactDOMFile = copyResource(
104+ " /META-INF/resources/webjars/react-dom/16.13.1/umd/react-dom.development.js" ,
105+ fs.getPath(" react-dom.development.js" ))
106+ List (reactFile, reactDOMFile).map(Input .Script (_))
107+ }
108+
109+ private def copyResource (name : String , out : Path ): out.type = {
110+ val inputStream = getClass().getResourceAsStream(name)
111+ assert(inputStream != null , s " couldn't load $name from resources " )
112+ try {
113+ Files .copy(inputStream, out)
114+ } finally {
115+ inputStream.close()
116+ }
117+ out
118+ }
119+
120+ private def codeToInput (code : String ): Input = {
121+ val p = Files .write(
122+ Jimfs .newFileSystem().getPath(" testScript.js" ),
123+ code.getBytes(StandardCharsets .UTF_8 ))
124+ Input .Script (p)
125+ }
24126}
0 commit comments