Skip to content

Commit 5545efc

Browse files
authored
Merge pull request #1401 from theck13/heck/update-tutorial-documentation
Update Tutorial Documentation Code Samples and Typographical Errors
2 parents b7d293c + ffff388 commit 5545efc

File tree

4 files changed

+40
-30
lines changed

4 files changed

+40
-30
lines changed

samples/tutorial/Tutorial1.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The `tutorial-base` module will be our starting place to build from.
1010

1111
Go ahead and launch `TutorialActivity`. You should see this welcome screen:
1212

13-
![Welcome](im "An Android phone app with title text _Welcome!_, an EditText with prompt _Please enter your name_, and a Log In button")
13+
![Welcome](images/welcome.png "An Android phone app with title text _Welcome!_, an EditText with prompt _Please enter your name_, and a Log In button")
1414

1515
You can enter a name, but the login button won't do anything.
1616

@@ -142,7 +142,7 @@ private fun welcomeScreenRunner(
142142
viewBinding: WelcomeViewBinding
143143
) = ScreenViewRunner { screen: WelcomeScreen, _ ->
144144
viewBinding.prompt.text = screen.promptText
145-
viewBinding.login.setOnClickListener {
145+
viewBinding.logIn.setOnClickListener {
146146
screen.onLogInTapped(viewBinding.username.text.toString())
147147
}
148148
}
@@ -196,7 +196,8 @@ object WelcomeWorkflow : StatefulWorkflow<Unit, State, Output, WelcomeScreen>()
196196
}
197197
```
198198

199-
> [!TIP] This tutorial doesn't cover persistence support.
199+
> [!TIP]
200+
> This tutorial doesn't cover persistence support.
200201
> If you feel the need for it,
201202
> the easiest way to get there is by using the [`@Parcelize` annotation](https://developer.android.com/kotlin/parcelize) on your state types.
202203
> They will be saved and restored via the `savedStateHandler` of the JetPack `ViewModel`
@@ -372,7 +373,7 @@ You could also write:
372373
}
373374
```
374375
375-
And let's make an `onLogInTapped` event handler that enques one of those `updateName` actions.
376+
And let's make an `onLogInTapped` event handler that enqueues one of those `updateName` actions.
376377

377378
```kotlin
378379
object WelcomeWorkflow : StatefulWorkflow<Unit, State, Output, WelcomeScreen>() {

samples/tutorial/Tutorial2.md

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private fun todoListScreenRunner(
138138
todoListBinding.todoList.adapter = adapter
139139

140140
return ScreenViewRunner { screen: TodoListScreen, _ ->
141-
adapter.todoList = rendering.todoTitles
141+
adapter.todoList = screen.todoTitles
142142
adapter.notifyDataSetChanged()
143143
}
144144
}
@@ -208,7 +208,7 @@ object RootNavigationWorkflow : StatefulWorkflow<Unit, Unit, Nothing, Screen>()
208208
return welcomeScreen
209209
}
210210

211-
override fun snapshotState(state: State): Snapshot? = null
211+
override fun snapshotState(state: Unit): Snapshot? = null
212212
}
213213
```
214214

@@ -254,10 +254,10 @@ At the same time, add a `reportNavigation()` call when creating the `renderings`
254254
workflow = RootNavigationWorkflow,
255255
scope = viewModelScope,
256256
savedStateHandle = savedState
257-
)
258-
}.reportNavigation {
259-
Log.i("navigate", it.toString())
260-
}
257+
).reportNavigation {
258+
Log.i("navigate", it.toString())
259+
}
260+
}
261261
```
262262

263263
Now when you run the app we'll see the welcome screen again.
@@ -349,9 +349,9 @@ Finally, map the output event from `WelcomeWorkflow` in `RootNavigationWorkflow`
349349
```kotlin
350350
override fun render(
351351
renderProps: Unit,
352-
renderState: Unit,
352+
renderState: State,
353353
context: RenderContext
354-
): Screen {
354+
): WelcomeScreen {
355355
// Render a child workflow of type WelcomeWorkflow. When renderChild is called, the
356356
// infrastructure will start a child workflow session if one is not already running.
357357
val welcomeScreen = context.renderChild(WelcomeWorkflow) { output ->
@@ -396,7 +396,7 @@ object RootNavigationWorkflow : StatefulWorkflow<Unit, State, Nothing, Screen>()
396396
// infrastructure will create a child workflow with state if one is not already running.
397397
val welcomeScreen = context.renderChild(WelcomeWorkflow) { output ->
398398
// When WelcomeWorkflow emits LoggedIn, turn it into our login action.
399-
login(output.username)
399+
logIn(output.username)
400400
}
401401
return welcomeScreen
402402
}
@@ -486,8 +486,12 @@ object TodoListWorkflow : StatefulWorkflow<ListProps, State, Nothing, TodoListSc
486486
renderState: State,
487487
context: RenderContext
488488
): TodoListScreen {
489-
username = renderProps.username,
490-
todoTitles = titles,
489+
val titles = renderState.todos.map { it.title }
490+
491+
return TodoListScreen(
492+
username = renderProps.username,
493+
todoTitles = titles,
494+
)
491495
}
492496
```
493497

@@ -571,8 +575,8 @@ object RootNavigationWorkflow : StatefulWorkflow<Unit, State, Nothing, BackStack
571575

572576
is ShowingTodo -> {
573577
val todoBackStack = context.renderChild(
574-
child = TodoNavigationWorkflow,
575-
props = TodoProps(renderState.username),
578+
child = TodoListWorkflow,
579+
props = ListProps(renderState.username),
576580
handler = {
577581
// When TodoNavigationWorkflow emits Back, enqueue our log out action.
578582
logOut
@@ -591,7 +595,8 @@ Update `render()` to create an `eventHandler` function to post the new output ev
591595

592596
At the same time, use workflow's handy `View.setBackHandler` function to respond to Android back press events.
593597
594-
> [!NOTE] `View.setBackHandler` is implemented via
598+
> [!NOTE]
599+
> `View.setBackHandler` is implemented via
595600
> [OnBackPressedCallback](https://developer.android.com/reference/androidx/activity/OnBackPressedCallback)
596601
> and so plays nicely with the
597602
> [OnBackPressedDispatcher](https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher), Compose's [BackHandler](https://foso.github.io/Jetpack-Compose-Playground/activity/backhandler/)
@@ -653,7 +658,8 @@ navigate TodoListScreen(username=David, todoTitles=[Take the cat for a walk], o
653658
navigate WelcomeScreen(promptText=, onLogInTapped=Function1<E, kotlin.Unit>)
654659
```
655660
656-
> [!TIP] Note the logging above remains useful
661+
> [!TIP]
662+
> Note the logging above remains useful
657663
> even though we are now wrapping our leaf screens in a `BackStackScreen`.
658664
> The default `onNavigate` function used by `Flow<*>.reportNavigation()`
659665
> can drill through the stock `Unwrappable` interface implemented by `BackStackScreen`
@@ -709,6 +715,6 @@ We'll show you how in the next tutorial, when we add our Todo Editing screen.
709715
> - The `Overlay` marker interface, implemented by renderings that model things like Android `Dialog` windows
710716
> - `ScreenOverlay` for modeling an `Overlay` whose content comes from a `Screen`
711717
> - `BodyAndOverlaysScreen`, a class that arranges `Overlay` instances in layers over a body `Screen`.
712-
> - And `the [AndroidOverlay](https://github.com/square/workflow-kotlin/blob/main/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/navigation/AndroidOverlay.kt)` interface that simplifies implementing `ScreenOverlay` with Android's `AppCompatDialog` class.
718+
> - And the [`AndroidOverlay`](https://github.com/square/workflow-kotlin/blob/main/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/navigation/AndroidOverlay.kt) interface that simplifies implementing `ScreenOverlay` with Android's `AppCompatDialog` class.
713719

714720
[Tutorial 3](Tutorial3.md)

samples/tutorial/Tutorial4.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ object TodoListWorkflow : StatefulWorkflow<ListProps, State, Output, TodoListScr
109109
//
110110
}
111111

112-
override fun snapshotState(state: Unit): Snapshot? = null
112+
override fun snapshotState(state: State): Snapshot? = null
113113

114114
//
115115
}
@@ -213,7 +213,7 @@ object TodoNavigationWorkflow : StatefulWorkflow<TodoProps, State, Back, List<Sc
213213
val todoListScreen = context.renderChild(
214214
TodoListWorkflow,
215215
props = ListProps(
216-
username = renderProps.name,
216+
username = renderProps.username,
217217
todos = renderState.todos
218218
)
219219
) { output ->
@@ -294,7 +294,7 @@ object TodoNavigationWorkflow : StatefulWorkflow<TodoProps, State, Back, List<Sc
294294
val todoListScreen = context.renderChild(
295295
TodoListWorkflow,
296296
props = ListProps(
297-
username = renderProps.name,
297+
username = renderProps.username,
298298
todos = renderState.todos
299299
)
300300
) { output ->
@@ -403,7 +403,7 @@ object TodoNavigationWorkflow : StatefulWorkflow<TodoProps, State, Back, List<Sc
403403
val todoListScreen = context.renderChild(
404404
TodoListWorkflow,
405405
props = ListProps(
406-
username = renderProps.name,
406+
username = renderProps.username,
407407
todos = renderState.todos
408408
)
409409
) { output ->
@@ -441,3 +441,5 @@ Additionally, now the `TodoList` and `TodoEdit` workflows are completely decoupl
441441
there is no longer a requirement that the `TodoEdit` workflow is displayed after the list.
442442
For instance, we could change the list to have "viewing" or "editing" modes,
443443
where tapping on an item might only allow it to be viewed, but another mode would allow editing.
444+
445+
[Tutorial 5](Tutorial5.md)

samples/tutorial/Tutorial5.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ The child's rendering _must_ be specified when declaring an expected workflow
241241
since the parent's call to `renderChild` _must_ return a value of the appropriate rendering type,
242242
and the workflow library can't know how to create those instances of your own types.
243243
244-
> [!NOTE] Under `testRender` all children are mocked
244+
> [!NOTE]
245+
> Under `testRender` all children are mocked
245246
>
246247
> We consider tests built around `testRender` to be unit tests (as opposed to integration tests)
247248
> because they do not actually run any child workflows or workers.
@@ -342,7 +343,7 @@ class TodoNavigationWorkflowTest {
342343

343344
TodoNavigationWorkflow
344345
.testRender(
345-
props = TodoProps(name = "Ada"),
346+
props = TodoProps(username = "Ada"),
346347
// Start from the list step to validate selecting a todo.
347348
initialState = State(
348349
todos = todos,
@@ -384,7 +385,7 @@ class TodoNavigationWorkflowTest {
384385

385386
TodoNavigationWorkflow
386387
.testRender(
387-
props = TodoProps(name = "Ada"),
388+
props = TodoProps(username = "Ada"),
388389
// Start from the edit step so we can simulate saving.
389390
initialState = State(
390391
todos = todos,
@@ -463,7 +464,7 @@ class TodoNavigationWorkflowTest {
463464
The `RenderTester` allows easy "mocking" of child workflows and workers.
464465
However, this means that we are not exercising the full infrastructure
465466
(even though we could get a fairly high confidence from the tests).
466-
ometimes, it may be worth putting together integration tests that test a full tree of Workflows.
467+
Sometimes, it may be worth putting together integration tests that test a full tree of Workflows.
467468
This lets us test integration with the non-workflow world as well,
468469
such as external reactive data sources that your workflows might be observing via Workers.
469470

@@ -481,12 +482,12 @@ the same runtime that `renderWorkflowIn` uses.
481482
When you create an Android app using Workflow,
482483
you will probably use `renderWorkflowIn`,
483484
which starts a runtime to host your workflows in an androidx ViewModel.
484-
Under the hood,this method is an overload of lower-level `renderWorkflowIn` function
485+
Under the hood, this method is an overload of lower-level `renderWorkflowIn` function
485486
that runs the workflow runtime in a coroutine and exposes a `StateFlow` of renderings.
486487
When writing integration tests for workflows,
487488
you can use this core function directly (maybe with a library like [Turbine](https://github.com/cashapp/turbine)),
488489
or you can use `workflow-testing`'s `WorkflowTester`.
489-
The `WorkflowTester` starts a workflow and lets you request renderingsand outputs manually
490+
The `WorkflowTester` starts a workflow and lets you request renderings and outputs manually
490491
so you can write tests that interact with the runtime from the outside.
491492

492493
This will be a properly opaque test,

0 commit comments

Comments
 (0)