Skip to content

Commit 0c952a4

Browse files
committed
Migrate AutoCompleteTextViewFactory to compose
1 parent 6f0ce2c commit 0c952a4

File tree

4 files changed

+369
-46
lines changed

4 files changed

+369
-46
lines changed
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google LLC
2+
* Copyright 2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,13 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.android.fhir.datacapture.views.factories
17+
package com.google.android.fhir.datacapture.test.views
1818

1919
import android.view.View
2020
import android.widget.AutoCompleteTextView
2121
import android.widget.FrameLayout
2222
import android.widget.TextView
23-
import androidx.test.espresso.Espresso.onView
23+
import androidx.test.espresso.Espresso
2424
import androidx.test.espresso.action.ViewActions
2525
import androidx.test.espresso.assertion.ViewAssertions
2626
import androidx.test.espresso.matcher.RootMatchers
@@ -32,9 +32,11 @@ import com.google.android.fhir.datacapture.test.TestActivity
3232
import com.google.android.fhir.datacapture.test.utilities.delayMainThread
3333
import com.google.android.fhir.datacapture.validation.NotValidated
3434
import com.google.android.fhir.datacapture.views.QuestionnaireViewItem
35+
import com.google.android.fhir.datacapture.views.factories.AutoCompleteViewHolderFactory
36+
import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolder
3537
import com.google.android.material.chip.ChipGroup
3638
import com.google.android.material.textfield.MaterialAutoCompleteTextView
37-
import com.google.common.truth.Truth.assertThat
39+
import com.google.common.truth.Truth
3840
import org.hl7.fhir.r4.model.Coding
3941
import org.hl7.fhir.r4.model.Questionnaire
4042
import org.hl7.fhir.r4.model.QuestionnaireResponse
@@ -69,8 +71,9 @@ class AutoCompleteViewHolderFactoryEspressoTest {
6971
)
7072
runOnUI { viewHolder.bind(questionnaireViewItem) }
7173

72-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(ViewActions.typeText("Coding 1"))
73-
assertThat(
74+
Espresso.onView(ViewMatchers.withId(R.id.autoCompleteTextView))
75+
.perform(ViewActions.typeText("Coding 1"))
76+
Truth.assertThat(
7477
viewHolder.itemView
7578
.findViewById<MaterialAutoCompleteTextView>(R.id.autoCompleteTextView)
7679
.adapter
@@ -91,22 +94,23 @@ class AutoCompleteViewHolderFactoryEspressoTest {
9194
)
9295
runOnUI { viewHolder.bind(questionnaireViewItem) }
9396

94-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(ViewActions.typeText("Coding 3"))
97+
Espresso.onView(ViewMatchers.withId(R.id.autoCompleteTextView))
98+
.perform(ViewActions.typeText("Coding 3"))
9599
runOnUI {
96100
viewHolder.itemView
97101
.findViewById<AutoCompleteTextView>(R.id.autoCompleteTextView)
98102
.showDropDown()
99103
}
100-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(delayMainThread())
101-
onView(ViewMatchers.withText("Coding 3"))
104+
Espresso.onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(delayMainThread())
105+
Espresso.onView(ViewMatchers.withText("Coding 3"))
102106
.inRoot(RootMatchers.isPlatformPopup())
103107
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
104108
.perform(ViewActions.click())
105-
assertThat(
109+
Truth.assertThat(
106110
viewHolder.itemView.findViewById<TextView>(R.id.autoCompleteTextView).text.toString(),
107111
)
108112
.isEmpty()
109-
assertThat(answerHolder!!.map { it.valueCoding.display })
113+
Truth.assertThat(answerHolder!!.map { it.valueCoding.display })
110114
.containsExactly("Coding 1", "Coding 5", "Coding 3")
111115
}
112116

@@ -121,7 +125,7 @@ class AutoCompleteViewHolderFactoryEspressoTest {
121125
)
122126
runOnUI { viewHolder.bind(questionnaireViewItem) }
123127

124-
assertThat(viewHolder.itemView.findViewById<ChipGroup>(R.id.chipContainer).childCount)
128+
Truth.assertThat(viewHolder.itemView.findViewById<ChipGroup>(R.id.chipContainer).childCount)
125129
.isEqualTo(2)
126130
}
127131

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Google LLC
2+
* Copyright 2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,42 +14,60 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.android.fhir.datacapture.views.factories
17+
package com.google.android.fhir.datacapture.test.views
1818

1919
import android.view.View
2020
import android.widget.FrameLayout
2121
import android.widget.TextView
22-
import androidx.appcompat.app.AppCompatActivity
22+
import androidx.compose.ui.test.junit4.createEmptyComposeRule
23+
import androidx.compose.ui.test.onRoot
24+
import androidx.compose.ui.test.printToLog
2325
import androidx.core.view.get
26+
import androidx.test.ext.junit.rules.ActivityScenarioRule
27+
import androidx.test.ext.junit.runners.AndroidJUnit4
28+
import androidx.test.platform.app.InstrumentationRegistry
2429
import com.google.android.fhir.datacapture.R
2530
import com.google.android.fhir.datacapture.extensions.displayString
2631
import com.google.android.fhir.datacapture.extensions.identifierString
32+
import com.google.android.fhir.datacapture.test.TestActivity
2733
import com.google.android.fhir.datacapture.validation.Invalid
2834
import com.google.android.fhir.datacapture.validation.NotValidated
2935
import com.google.android.fhir.datacapture.validation.Valid
3036
import com.google.android.fhir.datacapture.views.QuestionTextConfiguration
3137
import com.google.android.fhir.datacapture.views.QuestionnaireViewItem
38+
import com.google.android.fhir.datacapture.views.factories.AutoCompleteViewHolderFactory
39+
import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolder
3240
import com.google.android.material.chip.Chip
3341
import com.google.android.material.chip.ChipGroup
3442
import com.google.android.material.textfield.TextInputLayout
3543
import com.google.common.truth.Truth.assertThat
3644
import org.hl7.fhir.r4.model.Coding
3745
import org.hl7.fhir.r4.model.Questionnaire
3846
import org.hl7.fhir.r4.model.QuestionnaireResponse
47+
import org.junit.Before
48+
import org.junit.Rule
3949
import org.junit.Test
4050
import org.junit.runner.RunWith
41-
import org.robolectric.Robolectric
42-
import org.robolectric.RobolectricTestRunner
4351

44-
@RunWith(RobolectricTestRunner::class)
52+
@RunWith(AndroidJUnit4::class)
4553
class AutoCompleteViewHolderFactoryTest {
46-
private val parent =
47-
FrameLayout(
48-
Robolectric.buildActivity(AppCompatActivity::class.java).create().get().apply {
49-
setTheme(com.google.android.material.R.style.Theme_Material3_DayNight)
50-
},
51-
)
52-
private val viewHolder = AutoCompleteViewHolderFactory.create(parent)
54+
@get:Rule
55+
val activityScenarioRule: ActivityScenarioRule<TestActivity> =
56+
ActivityScenarioRule(TestActivity::class.java)
57+
58+
@get:Rule val composeTestRule = createEmptyComposeRule()
59+
60+
private lateinit var viewHolder: QuestionnaireItemViewHolder
61+
62+
@Before
63+
fun setUp() {
64+
activityScenarioRule.scenario.onActivity { activity ->
65+
viewHolder = AutoCompleteViewHolderFactory.create(FrameLayout(activity))
66+
activity.setContentView(viewHolder.itemView)
67+
}
68+
69+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
70+
}
5371

5472
@Test
5573
fun shouldSetQuestionHeader() {
@@ -62,6 +80,9 @@ class AutoCompleteViewHolderFactoryTest {
6280
),
6381
)
6482

83+
// Synchronize
84+
composeTestRule.waitForIdle()
85+
6586
assertThat(viewHolder.itemView.findViewById<TextView>(R.id.question).text.toString())
6687
.isEqualTo("Question")
6788
}
@@ -80,6 +101,7 @@ class AutoCompleteViewHolderFactoryTest {
80101
.setValue(Coding().setCode("test2-code").setDisplay("Test2 Code")),
81102
)
82103
}
104+
83105
viewHolder.bind(
84106
QuestionnaireViewItem(
85107
questionnaireItem,
@@ -88,7 +110,7 @@ class AutoCompleteViewHolderFactoryTest {
88110
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
89111
value =
90112
questionnaireItem.answerOption
91-
.first { it.value.displayString(parent.context) == "Test1 Code" }
113+
.first { it.value.displayString(viewHolder.itemView.context) == "Test1 Code" }
92114
.valueCoding
93115
},
94116
)
@@ -98,6 +120,7 @@ class AutoCompleteViewHolderFactoryTest {
98120
),
99121
)
100122

123+
composeTestRule.onRoot().printToLog("shouldHaveSingleAnswerChip")
101124
assertThat(viewHolder.itemView.findViewById<ChipGroup>(R.id.chipContainer).childCount)
102125
.isEqualTo(1)
103126
}
@@ -132,14 +155,18 @@ class AutoCompleteViewHolderFactoryTest {
132155
addAnswer(
133156
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
134157
value =
135-
answers.first { it.value.displayString(parent.context) == "Test1 Code" }.valueCoding
158+
answers
159+
.first { it.value.displayString(viewHolder.itemView.context) == "Test1 Code" }
160+
.valueCoding
136161
},
137162
)
138163

139164
addAnswer(
140165
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
141166
value =
142-
answers.first { it.value.displayString(parent.context) == "Test2 Code" }.valueCoding
167+
answers
168+
.first { it.value.displayString(viewHolder.itemView.context) == "Test2 Code" }
169+
.valueCoding
143170
},
144171
)
145172
},
@@ -198,7 +225,7 @@ class AutoCompleteViewHolderFactoryTest {
198225
value =
199226
answers
200227
.first {
201-
it.value.identifierString(parent.context) ==
228+
it.value.identifierString(viewHolder.itemView.context) ==
202229
"http://answers/test-codes1.0|test2-code"
203230
}
204231
.valueCoding
@@ -245,7 +272,9 @@ class AutoCompleteViewHolderFactoryTest {
245272
addAnswer(
246273
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
247274
value =
248-
answers.first { it.value.displayString(parent.context) == "Test1 Code" }.valueCoding
275+
answers
276+
.first { it.value.displayString(viewHolder.itemView.context) == "Test1 Code" }
277+
.valueCoding
249278
},
250279
)
251280
},
@@ -338,7 +367,7 @@ class AutoCompleteViewHolderFactoryTest {
338367
}
339368

340369
@Test
341-
fun `hides error textview in the header`() {
370+
fun hidesErrorTextviewInTheHeader() {
342371
viewHolder.bind(
343372
QuestionnaireViewItem(
344373
Questionnaire.QuestionnaireItemComponent(),
@@ -353,7 +382,7 @@ class AutoCompleteViewHolderFactoryTest {
353382
}
354383

355384
@Test
356-
fun `show asterisk`() {
385+
fun showAsterisk() {
357386
viewHolder.bind(
358387
QuestionnaireViewItem(
359388
Questionnaire.QuestionnaireItemComponent().apply {
@@ -372,7 +401,7 @@ class AutoCompleteViewHolderFactoryTest {
372401
}
373402

374403
@Test
375-
fun `hide asterisk`() {
404+
fun hideAsterisk() {
376405
viewHolder.bind(
377406
QuestionnaireViewItem(
378407
Questionnaire.QuestionnaireItemComponent().apply {
@@ -391,7 +420,7 @@ class AutoCompleteViewHolderFactoryTest {
391420
}
392421

393422
@Test
394-
fun `shows required text`() {
423+
fun showsRequiredText() {
395424
viewHolder.bind(
396425
QuestionnaireViewItem(
397426
Questionnaire.QuestionnaireItemComponent().apply { required = true },
@@ -409,7 +438,7 @@ class AutoCompleteViewHolderFactoryTest {
409438
}
410439

411440
@Test
412-
fun `hide required text`() {
441+
fun hideRequiredText() {
413442
viewHolder.bind(
414443
QuestionnaireViewItem(
415444
Questionnaire.QuestionnaireItemComponent().apply { required = true },
@@ -429,7 +458,7 @@ class AutoCompleteViewHolderFactoryTest {
429458
}
430459

431460
@Test
432-
fun `shows optional text`() {
461+
fun `showsOptionalText`() {
433462
viewHolder.bind(
434463
QuestionnaireViewItem(
435464
Questionnaire.QuestionnaireItemComponent().apply { text = "Question" },
@@ -447,7 +476,7 @@ class AutoCompleteViewHolderFactoryTest {
447476
}
448477

449478
@Test
450-
fun `hide optional text`() {
479+
fun `hideOptionalText`() {
451480
viewHolder.bind(
452481
QuestionnaireViewItem(
453482
Questionnaire.QuestionnaireItemComponent().apply { text = "Question" },

0 commit comments

Comments
 (0)