@@ -11,7 +11,7 @@ import org.junit.Test
1111internal class DecorativeScreenViewFactoryTest {
1212 private val instrumentation = InstrumentationRegistry .getInstrumentation()
1313
14- @Test fun initializeView_is_only_call_to_showRendering () {
14+ @Test fun viewStarter_is_only_call_to_showRendering () {
1515 val events = mutableListOf<String >()
1616
1717 val innerViewFactory = object : ScreenViewFactory <InnerRendering > {
@@ -38,27 +38,25 @@ internal class DecorativeScreenViewFactoryTest {
3838 val enhancedEnv = env + (envString to " Updated environment" )
3939 Pair (outer.wrapped, enhancedEnv)
4040 },
41- initializeView = {
42- val outerRendering = getRendering<OuterRendering >()
43- events + = " initializeView $outerRendering ${environment!! [envString]} "
44- showFirstRendering()
45- events + = " exit initializeView"
41+ viewStarter = { view, doStart ->
42+ events + = " viewStarter ${view.getRendering<Any >()} ${view.environment!! [envString]} "
43+ doStart()
44+ events + = " exit viewStarter"
4645 }
4746 )
48- val viewRegistry = ViewRegistry (innerViewFactory)
47+ val viewRegistry = ViewRegistry (innerViewFactory, outerViewFactory )
4948 val viewEnvironment = ViewEnvironment (mapOf (ViewRegistry to viewRegistry))
5049
51- outerViewFactory.buildView(
52- OuterRendering (" outer" , InnerRendering (" inner" )),
50+ OuterRendering (" outer" , InnerRendering (" inner" )).buildView(
5351 viewEnvironment,
5452 instrumentation.context
55- )
53+ ).start()
5654
5755 assertThat(events).containsExactly(
58- " initializeView OuterRendering(outerData=outer, wrapped=InnerRendering(innerData=inner)) " +
56+ " viewStarter OuterRendering(outerData=outer, wrapped=InnerRendering(innerData=inner)) " +
5957 " Updated environment" ,
6058 " inner showRendering InnerRendering(innerData=inner)" ,
61- " exit initializeView "
59+ " exit viewStarter "
6260 )
6361 }
6462
@@ -86,21 +84,97 @@ internal class DecorativeScreenViewFactoryTest {
8684 innerShowRendering(outerRendering.wrapped, env)
8785 }
8886 )
89- val viewRegistry = ViewRegistry (innerViewFactory)
87+ val viewRegistry = ViewRegistry (innerViewFactory, outerViewFactory )
9088 val viewEnvironment = ViewEnvironment (mapOf (ViewRegistry to viewRegistry))
9189
92- outerViewFactory.buildView(
93- OuterRendering (" outer" , InnerRendering (" inner" )),
90+ OuterRendering (" outer" , InnerRendering (" inner" )).buildView(
9491 viewEnvironment,
9592 instrumentation.context
96- )
93+ ).start()
9794
9895 assertThat(events).containsExactly(
9996 " doShowRendering OuterRendering(outerData=outer, wrapped=InnerRendering(innerData=inner))" ,
10097 " inner showRendering InnerRendering(innerData=inner)"
10198 )
10299 }
103100
101+ // https://github.com/square/workflow-kotlin/issues/597
102+ @Test fun double_wrapping_only_calls_showRendering_once () {
103+ val events = mutableListOf<String >()
104+
105+ val innerViewFactory = object : ScreenViewFactory <InnerRendering > {
106+ override val type = InnerRendering ::class
107+ override fun buildView (
108+ initialRendering : InnerRendering ,
109+ initialViewEnvironment : ViewEnvironment ,
110+ contextForNewView : Context ,
111+ container : ViewGroup ?
112+ ): View = InnerView (contextForNewView).apply {
113+ bindShowRendering(initialRendering, initialViewEnvironment) { rendering, _ ->
114+ events + = " inner showRendering $rendering "
115+ }
116+ }
117+ }
118+
119+ val envString = object : ViewEnvironmentKey <String >(String ::class ) {
120+ override val default: String get() = " Not set"
121+ }
122+
123+ val outerViewFactory = DecorativeScreenViewFactory (
124+ type = OuterRendering ::class ,
125+ map = { outer, env ->
126+ val enhancedEnv = env + (envString to " Outer Updated environment" +
127+ " SHOULD NOT SEE THIS! It will be clobbered by WayOutRendering" )
128+ Pair (outer.wrapped, enhancedEnv)
129+ },
130+ viewStarter = { view, doStart ->
131+ events + = " outer viewStarter ${view.getRendering<Any >()} ${view.environment!! [envString]} "
132+ doStart()
133+ events + = " exit outer viewStarter"
134+ }
135+ )
136+
137+ val wayOutViewFactory = DecorativeScreenViewFactory (
138+ type = WayOutRendering ::class ,
139+ map = { wayOut, env ->
140+ val enhancedEnv = env + (envString to " Way Out Updated environment triumphs over all" )
141+ Pair (wayOut.wrapped, enhancedEnv)
142+ },
143+ viewStarter = { view, doStart ->
144+ events + = " way out viewStarter ${view.getRendering<Any >()} ${view.environment!! [envString]} "
145+ doStart()
146+ events + = " exit way out viewStarter"
147+ }
148+ )
149+ val viewRegistry = ViewRegistry (innerViewFactory, outerViewFactory, wayOutViewFactory)
150+ val viewEnvironment = ViewEnvironment (mapOf (ViewRegistry to viewRegistry))
151+
152+ WayOutRendering (" way out" , OuterRendering (" outer" , InnerRendering (" inner" ))).buildView(
153+ viewEnvironment,
154+ instrumentation.context
155+ ).start()
156+
157+ assertThat(events).containsExactly(
158+ " way out viewStarter " +
159+ " WayOutRendering(wayOutData=way out, wrapped=" +
160+ " OuterRendering(outerData=outer, wrapped=" +
161+ " InnerRendering(innerData=inner))) " +
162+ " Way Out Updated environment triumphs over all" ,
163+ " outer viewStarter " +
164+ // Notice that both the initial rendering and the ViewEnvironment are stomped by
165+ // the outermost wrapper before inners are invoked. Could try to give
166+ // the inner wrapper access to the rendering it expected, but there are no
167+ // use cases and it trashes the API.
168+ " WayOutRendering(wayOutData=way out, wrapped=" +
169+ " OuterRendering(outerData=outer, wrapped=" +
170+ " InnerRendering(innerData=inner))) " +
171+ " Way Out Updated environment triumphs over all" ,
172+ " inner showRendering InnerRendering(innerData=inner)" ,
173+ " exit outer viewStarter" ,
174+ " exit way out viewStarter"
175+ )
176+ }
177+
104178 @Test fun subsequent_showRendering_calls_wrapped_showRendering () {
105179 val events = mutableListOf<String >()
106180
@@ -125,14 +199,13 @@ internal class DecorativeScreenViewFactoryTest {
125199 innerShowRendering(outerRendering.wrapped, env)
126200 }
127201 )
128- val viewRegistry = ViewRegistry (innerViewFactory)
202+ val viewRegistry = ViewRegistry (innerViewFactory, outerViewFactory )
129203 val viewEnvironment = ViewEnvironment (mapOf (ViewRegistry to viewRegistry))
130204
131- val view = outerViewFactory.buildView(
132- OuterRendering (" out1" , InnerRendering (" in1" )),
205+ val view = OuterRendering (" out1" , InnerRendering (" in1" )).buildView(
133206 viewEnvironment,
134207 instrumentation.context
135- )
208+ ). apply { start() }
136209 events.clear()
137210
138211 view.showRendering(OuterRendering (" out2" , InnerRendering (" in2" )), viewEnvironment)
@@ -149,5 +222,10 @@ internal class DecorativeScreenViewFactoryTest {
149222 val wrapped : InnerRendering
150223 ) : Screen
151224
225+ private data class WayOutRendering (
226+ val wayOutData : String ,
227+ val wrapped : OuterRendering
228+ ) : Screen
229+
152230 private class InnerView (context : Context ) : View(context)
153231}
0 commit comments