Skip to content

Commit 3cd208e

Browse files
authored
Add multi-group clear API (#70)
1 parent e9bd1b5 commit 3cd208e

5 files changed

Lines changed: 86 additions & 3 deletions

File tree

app/src/test/java/com/trendyol/medusa/DestinationListenerTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,48 @@ class DestinationListenerTest {
281281
}
282282
}
283283

284+
@Test
285+
fun `given fragments from multiple groups, when clearGroups is called, then matching groups are removed atomically`() {
286+
val testObserver = TestObserver<Fragment>()
287+
launchActivity<MainActivity>().use { scenario ->
288+
scenario.moveToState(Lifecycle.State.RESUMED)
289+
scenario.onActivity { activity ->
290+
activity.multipleStackNavigator.observeDestinationChanges(activity, testObserver)
291+
activity.doAndExecuteFragmentTransactions {
292+
start(FragmentGenerator.generateNewFragment())
293+
start(FragmentGenerator.generateNewFragment(), "group-1")
294+
start(FragmentGenerator.generateNewFragment(), "group-2")
295+
start(FragmentGenerator.generateNewFragment(), "group-1")
296+
start(FragmentGenerator.generateNewFragment(), "group-3")
297+
}
298+
activity.doAndExecuteFragmentTransactions {
299+
clearGroups("group-1", "group-3")
300+
}
301+
302+
Assert.assertEquals(
303+
"fragment 6",
304+
testObserver.getLastFragmentName(indexFromLast = 1)
305+
)
306+
Assert.assertEquals(
307+
"fragment 4",
308+
testObserver.getLastFragmentName(indexFromLast = 0)
309+
)
310+
}
311+
}
312+
}
313+
314+
@Test(expected = IllegalArgumentException::class)
315+
fun `given default group, when clearGroups is called, then exception is thrown`() {
316+
launchActivity<MainActivity>().use { scenario ->
317+
scenario.moveToState(Lifecycle.State.RESUMED)
318+
scenario.onActivity { activity ->
319+
activity.doAndExecuteFragmentTransactions {
320+
clearGroups("group-name", "")
321+
}
322+
}
323+
}
324+
}
325+
284326
/**
285327
* Gets the fragment name at a specific index from the last observed fragment.
286328
* Useful for testing fragment navigation sequences.

medusa/src/main/java/com/trendyol/medusalib/navigator/FragmentStackState.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ data class FragmentStackState constructor(
7373
}
7474

7575
fun popItems(groupName: String): List<StackItem> {
76+
return popItems(setOf(groupName))
77+
}
78+
79+
fun popItems(groupNames: Set<String>): List<StackItem> {
7680
val currentTabIndex = getSelectedTabIndex()
7781
val currentTabStack = fragmentTagStack.get(getSelectedTabIndex())
7882

@@ -83,7 +87,7 @@ data class FragmentStackState constructor(
8387

8488
for (i in 1 until currentTabStack.size) {
8589
val stackItem = currentTabStack[i]
86-
if (groupName == stackItem.groupName) {
90+
if (groupNames.contains(stackItem.groupName)) {
8791
deletedStackItems.add(stackItem)
8892
} else {
8993
updatedTabStack.push(stackItem)

medusa/src/main/java/com/trendyol/medusalib/navigator/MultipleStackNavigator.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,17 @@ open class MultipleStackNavigator(
206206
}
207207

208208
override fun clearGroup(fragmentGroupName: String) {
209-
if (fragmentGroupName == DEFAULT_GROUP_NAME) {
209+
clearGroups(fragmentGroupName)
210+
}
211+
212+
override fun clearGroups(vararg fragmentGroupNames: String) {
213+
if (fragmentGroupNames.any { it == DEFAULT_GROUP_NAME }) {
210214
throw IllegalArgumentException("Fragment group name can not be empty.")
211215
}
212216
val upperFragmentTag = fragmentStackState.peekItemFromSelectedTab()?.fragmentTag
213217

214218
val poppedFragmentTags = fragmentStackState
215-
.popItems(fragmentGroupName)
219+
.popItems(fragmentGroupNames.toSet())
216220
.map { it.fragmentTag }
217221

218222
if (poppedFragmentTags.isNotEmpty()) {

medusa/src/main/java/com/trendyol/medusalib/navigator/Navigator.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ interface Navigator {
163163
*/
164164
fun clearGroup(fragmentGroupName: String)
165165

166+
/**
167+
* Clears all fragments with any of the given group names in the
168+
* current tab in a single transaction. This method aims to clear all
169+
* related/steps fragments from tab atomically.
170+
*/
171+
fun clearGroups(vararg fragmentGroupNames: String)
172+
166173
/**
167174
* Checks if stack has only root
168175
* @param tabIndex

medusa/src/test/java/com/trendyol/medusalib/navigator/FragmentStackStateTest.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,30 @@ class FragmentStackStateTest {
2828

2929
Truth.assertThat(stackState.fragmentTagStack).containsExactlyElementsIn(emptyStack)
3030
}
31+
32+
@Test
33+
fun `popItems removes all items matching given group names from selected tab`() {
34+
val stackState = buildFragmentStackState(
35+
buildTabStack(0),
36+
buildStack(
37+
StackItem("ROOT"),
38+
StackItem("TAG1", "GROUP_1"),
39+
StackItem("TAG2", "GROUP_2"),
40+
StackItem("TAG3", "GROUP_1"),
41+
StackItem("TAG4", "GROUP_3"),
42+
),
43+
)
44+
45+
val actualPoppedItems = stackState.popItems(setOf("GROUP_1", "GROUP_3"))
46+
47+
Truth.assertThat(actualPoppedItems).containsExactly(
48+
StackItem("TAG1", "GROUP_1"),
49+
StackItem("TAG3", "GROUP_1"),
50+
StackItem("TAG4", "GROUP_3"),
51+
).inOrder()
52+
Truth.assertThat(stackState.fragmentTagStack[0]).containsExactly(
53+
StackItem("ROOT"),
54+
StackItem("TAG2", "GROUP_2"),
55+
).inOrder()
56+
}
3157
}

0 commit comments

Comments
 (0)