|
1 | 1 | package com.squareup.workflow1.ui.container
|
2 | 2 |
|
3 | 3 | import android.content.Context
|
4 |
| -import android.view.View |
| 4 | +import android.os.Parcel |
| 5 | +import android.os.Parcelable |
| 6 | +import android.text.Editable |
| 7 | +import android.util.SparseArray |
| 8 | +import android.widget.EditText |
5 | 9 | import androidx.activity.ComponentActivity
|
6 | 10 | import androidx.test.ext.junit.rules.ActivityScenarioRule
|
7 | 11 | import com.google.common.truth.Truth
|
@@ -29,10 +33,67 @@ internal class BackStackContainerTest {
|
29 | 33 | override val compatibilityKey = name
|
30 | 34 | override val viewFactory: ScreenViewFactory<Rendering>
|
31 | 35 | get() = ScreenViewFactory.fromCode<Rendering> { _, initialRendering, context, _ ->
|
32 |
| - ScreenViewHolder(initialRendering, View(context)) { _, _ -> /* Noop */ } |
| 36 | + ScreenViewHolder( |
| 37 | + initialRendering, |
| 38 | + EditText(context).apply { |
| 39 | + // Must have an id to participate in view persistence. |
| 40 | + id = 65 |
| 41 | + } |
| 42 | + ) { _, _ -> /* Noop */ } |
33 | 43 | }
|
34 | 44 | }
|
35 | 45 |
|
| 46 | + @Test fun savedStateParcelingWorks() { |
| 47 | + scenario.onActivity { activity -> |
| 48 | + val originalView = VisibleBackStackContainer(activity).apply { |
| 49 | + // Must have an id to participate in view persistence. |
| 50 | + id = 42 |
| 51 | + } |
| 52 | + val holder1 = ScreenViewHolder<BackStackScreen<*>>(EMPTY, originalView) { r, e -> |
| 53 | + originalView.update(r, e) |
| 54 | + } |
| 55 | + |
| 56 | + // Show "able". |
| 57 | + holder1.show(BackStackScreen(Rendering("able")), EMPTY) |
| 58 | + // Type "first" into the rendered EditText. |
| 59 | + (originalView.getChildAt(0) as EditText).text = "first".toEditable() |
| 60 | + // Push "baker" on top of "able". |
| 61 | + holder1.show(BackStackScreen(Rendering("able"), Rendering("baker")), EMPTY) |
| 62 | + // Type "second" into the replacement rendered EditText. |
| 63 | + (originalView.getChildAt(0) as EditText).text = "second".toEditable() |
| 64 | + |
| 65 | + // Save the view state to a ByteArray and read it out again, exercising all of |
| 66 | + // the Parcel machinery. |
| 67 | + val savedArray = SparseArray<Parcelable>() |
| 68 | + originalView.saveHierarchyState(savedArray) |
| 69 | + val bytes = Parcel.obtain().let { parcel -> |
| 70 | + parcel.writeSparseArray(savedArray) |
| 71 | + parcel.marshall().also { parcel.recycle() } |
| 72 | + } |
| 73 | + val restoredArray = Parcel.obtain().let { parcel -> |
| 74 | + parcel.unmarshall(bytes, 0, bytes.size) |
| 75 | + parcel.setDataPosition(0) |
| 76 | + parcel.readSparseArray<Parcelable>(this::class.java.classLoader)!!.also { parcel.recycle() } |
| 77 | + } |
| 78 | + |
| 79 | + // Create a new BackStackContainer with the same id as the original |
| 80 | + val restoredView = VisibleBackStackContainer(activity).apply { id = 42 } |
| 81 | + val restoredHolder = ScreenViewHolder<BackStackScreen<*>>(EMPTY, restoredView) { r, e -> |
| 82 | + restoredView.update(r, e) |
| 83 | + } |
| 84 | + // Have it render the same able > baker back stack that we last showed in the original. |
| 85 | + restoredHolder.show(BackStackScreen(Rendering("able"), Rendering("baker")), EMPTY) |
| 86 | + // Restore the view hierarchy. |
| 87 | + restoredView.restoreHierarchyState(restoredArray) |
| 88 | + // Android took care of restoring the text that was last shown. |
| 89 | + assertThat((restoredView.getChildAt(0) as EditText).text.toString()).isEqualTo("second") |
| 90 | + // Pop back to able. |
| 91 | + restoredHolder.show(BackStackScreen(Rendering("able")), EMPTY) |
| 92 | + // BackStackContainer restored the text we had typed on that. |
| 93 | + assertThat((restoredView.getChildAt(0) as EditText).text.toString()).isEqualTo("first") |
| 94 | + } |
| 95 | + } |
| 96 | + |
36 | 97 | @Test fun firstScreenIsRendered() {
|
37 | 98 | scenario.onActivity { activity ->
|
38 | 99 | val view = VisibleBackStackContainer(activity)
|
@@ -116,3 +177,7 @@ internal class BackStackContainerTest {
|
116 | 177 | }
|
117 | 178 | }
|
118 | 179 | }
|
| 180 | + |
| 181 | +private fun String.toEditable(): Editable { |
| 182 | + return Editable.Factory.getInstance().newEditable(this) |
| 183 | +} |
0 commit comments