Skip to content

Commit 4ef241b

Browse files
committed
test: fix EmptyFragmentActivity memory leaks
Issue 21168 Assisted-by: Claude Opus 4.8 - all
1 parent 66c74f1 commit 4ef241b

3 files changed

Lines changed: 43 additions & 42 deletions

File tree

AnkiDroid/src/test/java/com/ichi2/anki/browser/FindAndReplaceDialogFragmentTest.kt

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -89,38 +89,39 @@ class FindAndReplaceDialogFragmentTest : RobolectricTest() {
8989
runTest {
9090
val note = createFindReplaceTestNote("A", "kart", "kilogram")
9191
val file = IdsFile(targetContext.cacheDir, listOf(note.id))
92-
val scenario =
93-
FragmentScenario.launch(
92+
FragmentScenario
93+
.launch(
9494
fragmentClass = FindAndReplaceDialogFragment::class.java,
9595
fragmentArgs = bundleOf(FindAndReplaceDialogFragment.ARG_IDS to file),
9696
themeResId = R.style.Theme_Light,
97-
)
98-
scenario.onFragment { fragment ->
99-
advanceUntilIdle()
100-
onView(withId(R.id.only_selected_notes_check_box))
101-
.inRoot(isDialog())
102-
.check(matches(isEnabled()))
103-
onView(withId(R.id.only_selected_notes_check_box))
104-
.inRoot(isDialog())
105-
.check(matches(isChecked()))
106-
// 2 default field options + 2 fields from the only note selected
107-
val allTargets =
108-
targetContext.getDefaultTargets() + listOf("Afield0", "Afield1")
109-
assertThat(fragment.adapter.items, equalTo(allTargets))
110-
}
111-
scenario.recreate()
112-
scenario.onFragment { fragment ->
113-
advanceUntilIdle()
114-
onView(withId(R.id.only_selected_notes_check_box))
115-
.inRoot(isDialog())
116-
.check(matches(isEnabled()))
117-
onView(withId(R.id.only_selected_notes_check_box))
118-
.inRoot(isDialog())
119-
.check(matches(isChecked()))
120-
// check that the target list from before the recreate call wasn't reset
121-
val allTargets = targetContext.getDefaultTargets() + listOf("Afield0", "Afield1")
122-
assertThat(fragment.adapter.items, equalTo(allTargets))
123-
}
97+
).use { scenario ->
98+
scenario.onFragment { fragment ->
99+
advanceUntilIdle()
100+
onView(withId(R.id.only_selected_notes_check_box))
101+
.inRoot(isDialog())
102+
.check(matches(isEnabled()))
103+
onView(withId(R.id.only_selected_notes_check_box))
104+
.inRoot(isDialog())
105+
.check(matches(isChecked()))
106+
// 2 default field options + 2 fields from the only note selected
107+
val allTargets =
108+
targetContext.getDefaultTargets() + listOf("Afield0", "Afield1")
109+
assertThat(fragment.adapter.items, equalTo(allTargets))
110+
}
111+
scenario.recreate()
112+
scenario.onFragment { fragment ->
113+
advanceUntilIdle()
114+
onView(withId(R.id.only_selected_notes_check_box))
115+
.inRoot(isDialog())
116+
.check(matches(isEnabled()))
117+
onView(withId(R.id.only_selected_notes_check_box))
118+
.inRoot(isDialog())
119+
.check(matches(isChecked()))
120+
// check that the target list from before the recreate call wasn't reset
121+
val allTargets = targetContext.getDefaultTargets() + listOf("Afield0", "Afield1")
122+
assertThat(fragment.adapter.items, equalTo(allTargets))
123+
}
124+
}
124125
}
125126

126127
private fun onFindReplaceFragment(
@@ -133,7 +134,7 @@ class FindAndReplaceDialogFragmentTest : RobolectricTest() {
133134
fragmentClass = FindAndReplaceDialogFragment::class.java,
134135
fragmentArgs = bundleOf(FindAndReplaceDialogFragment.ARG_IDS to file),
135136
themeResId = R.style.Theme_Light,
136-
).onFragment { fragment -> fragment.action() }
137+
).use { scenario -> scenario.onFragment { fragment -> fragment.action() } }
137138
}
138139

139140
/**

AnkiDroid/src/test/java/com/ichi2/anki/export/ExportDialogFragmentTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ import org.junit.runner.RunWith
3636
class ExportDialogFragmentTest : RobolectricTest() {
3737
@Test
3838
fun `collection export options are initialized correctly`() {
39-
launchFragment<ExportDialogFragment>(
40-
themeResId = R.style.Theme_Light,
41-
).onFragment {
39+
onExportDialog {
4240
// Select export type as anki collection package.
4341
onView(withId(R.id.export_type_selector)).inRoot(isDialog()).perform(click())
4442
onData(containsString(TR.exportingAnkiCollectionPackage()))
@@ -62,9 +60,7 @@ class ExportDialogFragmentTest : RobolectricTest() {
6260

6361
@Test
6462
fun `apkg export options are initialized correctly`() {
65-
launchFragment<ExportDialogFragment>(
66-
themeResId = R.style.Theme_Light,
67-
).onFragment {
63+
onExportDialog {
6864
// Select export type as anki deck package.
6965
onView(withId(R.id.export_type_selector)).inRoot(isDialog()).perform(click())
7066
onData(containsString(TR.exportingAnkiDeckPackage()))
@@ -100,9 +96,7 @@ class ExportDialogFragmentTest : RobolectricTest() {
10096

10197
@Test
10298
fun `Legacy export checkbox(default false) is shown only for collection and apkg`() {
103-
launchFragment<ExportDialogFragment>(
104-
themeResId = R.style.Theme_Light,
105-
).onFragment {
99+
onExportDialog {
106100
// check legacy checkboxes status for collection export
107101
onView(withId(R.id.export_type_selector)).inRoot(isDialog()).perform(click())
108102
onData(containsString(TR.exportingAnkiCollectionPackage()))
@@ -158,4 +152,10 @@ class ExportDialogFragmentTest : RobolectricTest() {
158152
.check(matches(not(isDisplayed())))
159153
}
160154
}
155+
156+
/** Launches [ExportDialogFragment] and executes [action] on the fragment. */
157+
private fun onExportDialog(action: ExportDialogFragment.() -> Unit) =
158+
launchFragment<ExportDialogFragment>(
159+
themeResId = R.style.Theme_Light,
160+
).use { scenario -> scenario.onFragment { action(it) } }
161161
}

AnkiDroid/src/test/java/com/ichi2/anki/scheduling/SetDueDateDialogTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ class SetDueDateDialogTest : RobolectricTest() {
152152
fragmentArgs = dialog.arguments,
153153
) {
154154
return@launchFragment dialog
155-
}.apply {
156-
moveToState(Lifecycle.State.RESUMED)
155+
}.use { scenario ->
156+
scenario.moveToState(Lifecycle.State.RESUMED)
157157
advanceRobolectricLooper()
158-
this.onFragment {
158+
scenario.onFragment {
159159
action(it)
160160
}
161161
}

0 commit comments

Comments
 (0)