Skip to content

Commit cb7e203

Browse files
Added options to TestRendererUtils.testRender
1 parent 3257e46 commit cb7e203

File tree

4 files changed

+162
-43
lines changed

4 files changed

+162
-43
lines changed

test/src/main/scala/scommons/react/test/raw/TestRenderer.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object TestRenderer extends js.Object {
2020
*/
2121
def act(block: js.Function0[Unit]): Unit = js.native
2222

23-
def create(element: ReactElement): TestRenderer = js.native
23+
def create(element: ReactElement, options: TestRendererOptions): TestRenderer = js.native
2424
}
2525

2626
@js.native
@@ -38,3 +38,8 @@ trait TestInstance extends RenderedInstance {
3838

3939
val children: js.Array[TestInstance] = js.native
4040
}
41+
42+
trait TestRendererOptions extends js.Object {
43+
44+
val createNodeMock: js.UndefOr[js.Function1[TestInstance, js.Any]] = js.undefined
45+
}

test/src/main/scala/scommons/react/test/util/TestRendererUtils.scala

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,35 @@ import io.github.shogowada.scalajs.reactjs.classes.ReactClass
44
import io.github.shogowada.scalajs.reactjs.elements.ReactElement
55
import org.scalatest.{Assertion, Succeeded}
66
import scommons.react.UiComponent
7+
import scommons.react.test.raw
78
import scommons.react.test.raw.{TestInstance, TestRenderer}
89
import scommons.react.test.util.RendererUtils.{testInstanceUtils => utils}
910

11+
import scala.scalajs.js
12+
1013
trait TestRendererUtils {
1114

12-
def createTestRenderer(element: ReactElement): TestRenderer = {
15+
def createTestRenderer(element: ReactElement,
16+
createMock: js.Function1[TestInstance, js.Any] = null): TestRenderer = {
17+
1318
var result: TestRenderer = null
1419
TestRenderer.act { () =>
15-
result = TestRenderer.create(element)
20+
result = TestRenderer.create(
21+
element,
22+
if (createMock != null) new raw.TestRendererOptions {
23+
override val createNodeMock = createMock
24+
}
25+
else null
26+
)
1627
}
1728

1829
result
1930
}
2031

21-
def testRender(element: ReactElement): TestInstance = {
22-
val root = createTestRenderer(element).root
32+
def testRender(element: ReactElement,
33+
createMock: js.Function1[TestInstance, js.Any] = null): TestInstance = {
34+
35+
val root = createTestRenderer(element, createMock).root
2336
root.children(0)
2437
}
2538

Lines changed: 93 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,72 @@
11
package scommons.react.test.raw
22

3-
import io.github.shogowada.scalajs.reactjs.React
3+
import org.scalajs.dom.raw.HTMLInputElement
4+
import scommons.react._
45
import scommons.react.test.TestSpec
6+
import scommons.react.test.raw.TestRendererSpec._
7+
8+
import scala.scalajs.js
9+
import scala.scalajs.js.annotation.JSExportAll
510

611
class TestRendererSpec extends TestSpec {
712

8-
it should "render and mount component" in {
13+
it should "mock reference" in {
914
//given
10-
var isMounted = false
11-
val compClass = React.createClass[Unit, Unit](
12-
componentDidMount = { _ =>
13-
isMounted = true
14-
},
15-
render = { _ =>
16-
<.div(^("testProp") := "test")(
17-
<.span()("Test")
18-
)
15+
val comp = new ClassComponent[Unit] {
16+
protected def create(): ReactClass = createClass[ReactRef[HTMLInputElement]](
17+
getInitialState = { _ =>
18+
ReactRef.create[HTMLInputElement]
19+
},
20+
componentDidMount = { self =>
21+
self.state.current.focus()
22+
},
23+
render = { self =>
24+
<.input(
25+
^.`type` := "text",
26+
^.reactRef := self.state
27+
)()
28+
}
29+
)
30+
}
31+
val inputMock = mock[HTMLInputElementMock]
32+
val compMock: js.Function1[TestInstance, js.Any] = { el =>
33+
if (el.`type` == "input".asInstanceOf[js.Any]) {
34+
inputMock.asInstanceOf[HTMLInputElement]
1935
}
20-
)
36+
else null
37+
}
2138

39+
//then
40+
(inputMock.focus _).expects()
41+
2242
//when
23-
val result = TestRenderer.create(<(compClass)()()).root
43+
TestRenderer.create(<(comp())()(), new TestRendererOptions {
44+
override val createNodeMock = compMock
45+
})
46+
}
47+
48+
it should "mount component" in {
49+
//given
50+
var isMounted = false
51+
val comp = new ClassComponent[Unit] {
52+
protected def create(): ReactClass = createClass[Unit](
53+
componentDidMount = { _ =>
54+
isMounted = true
55+
},
56+
render = { _ =>
57+
<.div(^("testProp") := "test")(
58+
<.span()("Test")
59+
)
60+
}
61+
)
62+
}
63+
64+
//when
65+
val result = TestRenderer.create(<(comp())()(), null).root
2466

2567
//then
2668
isMounted shouldBe true
27-
result.`type` shouldBe compClass
69+
result.`type` shouldBe comp()
2870

2971
val container = result.children(0)
3072
container.`type` shouldBe "div"
@@ -34,26 +76,28 @@ class TestRendererSpec extends TestSpec {
3476
it should "update component" in {
3577
//given
3678
var isUpdated = false
37-
val compClass = React.createClass[Unit, Unit](
38-
componentDidUpdate = { (_, _, _) =>
39-
isUpdated = true
40-
},
41-
render = { self =>
42-
<.div(^("testProp") := self.props.native.test.asInstanceOf[String])(
43-
<.span()("Test")
44-
)
45-
}
46-
)
47-
val renderer = TestRenderer.create(<(compClass)(^("test") := "test")())
79+
val comp = new ClassComponent[Unit] {
80+
protected def create(): ReactClass = createClass[Unit](
81+
componentDidUpdate = { (_, _, _) =>
82+
isUpdated = true
83+
},
84+
render = { self =>
85+
<.div(^("testProp") := self.props.native.test.asInstanceOf[String])(
86+
<.span()("Test")
87+
)
88+
}
89+
)
90+
}
91+
val renderer = TestRenderer.create(<(comp())(^("test") := "test")(), null)
4892
isUpdated shouldBe false
4993

5094
//when
51-
renderer.update(<(compClass)(^("test") := "updated")())
95+
renderer.update(<(comp())(^("test") := "updated")())
5296

5397
//then
5498
val result = renderer.root
5599
isUpdated shouldBe true
56-
result.`type` shouldBe compClass
100+
result.`type` shouldBe comp()
57101

58102
val container = result.children(0)
59103
container.`type` shouldBe "div"
@@ -63,17 +107,19 @@ class TestRendererSpec extends TestSpec {
63107
it should "unmount component" in {
64108
//given
65109
var isUnmounted = false
66-
val compClass = React.createClass[Unit, Unit](
67-
componentWillUnmount = { _ =>
68-
isUnmounted = true
69-
},
70-
render = { _ =>
71-
<.div(^("testProp") := "test")(
72-
<.span()("Test")
73-
)
74-
}
75-
)
76-
val renderer = TestRenderer.create(<(compClass)()())
110+
val comp = new ClassComponent[Unit] {
111+
protected def create(): ReactClass = createClass[Unit](
112+
componentWillUnmount = { _ =>
113+
isUnmounted = true
114+
},
115+
render = { _ =>
116+
<.div(^("testProp") := "test")(
117+
<.span()("Test")
118+
)
119+
}
120+
)
121+
}
122+
val renderer = TestRenderer.create(<(comp())()(), null)
77123
isUnmounted shouldBe false
78124

79125
//when
@@ -83,3 +129,12 @@ class TestRendererSpec extends TestSpec {
83129
isUnmounted shouldBe true
84130
}
85131
}
132+
133+
object TestRendererSpec {
134+
135+
@JSExportAll
136+
trait HTMLInputElementMock {
137+
138+
def focus(): Unit
139+
}
140+
}

test/src/test/scala/scommons/react/test/util/TestRendererUtilsSpec.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,51 @@
11
package scommons.react.test.util
22

33
import io.github.shogowada.scalajs.reactjs.elements.ReactElement
4+
import org.scalajs.dom.raw.HTMLInputElement
5+
import scommons.react._
6+
import scommons.react.hooks._
47
import scommons.react.test.raw.TestInstance
58
import scommons.react.test.util.RendererUtilsSpec._
9+
import scommons.react.test.util.TestRendererUtilsSpec._
10+
11+
import scala.scalajs.js
12+
import scala.scalajs.js.annotation.JSExportAll
613

714
class TestRendererUtilsSpec extends RendererUtilsSpec[TestInstance]
815
with TestRendererUtils {
916

1017
protected def doRender(element: ReactElement): TestInstance = testRender(element)
1118

19+
it should "render mock reference" in {
20+
//given
21+
val comp = new FunctionComponent[Unit] {
22+
protected def render(props: Props): ReactElement = {
23+
val elementRef = useRef[HTMLInputElement](null)
24+
25+
useLayoutEffect({ () =>
26+
elementRef.current.focus()
27+
}, Nil)
28+
29+
<.input(
30+
^.`type` := "text",
31+
^.reactRef := elementRef
32+
)()
33+
}
34+
}
35+
val inputMock = mock[HTMLInputElementMock]
36+
37+
//then
38+
(inputMock.focus _).expects()
39+
40+
//when
41+
testRender(<(comp())()(), { el =>
42+
if (el.`type` == "input".asInstanceOf[js.Any]) {
43+
inputMock.asInstanceOf[HTMLInputElement]
44+
}
45+
else null
46+
})
47+
}
48+
1249
it should "return top child instance when render" in {
1350
//when
1451
val comp = testRender(<(TestComp())(^.wrapped := Comp1Props(1))("test1 child"))
@@ -63,3 +100,12 @@ class TestRendererUtilsSpec extends RendererUtilsSpec[TestInstance]
63100
})
64101
}
65102
}
103+
104+
object TestRendererUtilsSpec {
105+
106+
@JSExportAll
107+
trait HTMLInputElementMock {
108+
109+
def focus(): Unit
110+
}
111+
}

0 commit comments

Comments
 (0)