Skip to content

Commit

Permalink
Use ActivityViewModelContext for activity scope (#676)
Browse files Browse the repository at this point in the history
* Use ActivityViewModelContext for activity scope

* Update MavericksComposeExtensions.kt

* Add tests
  • Loading branch information
apramana authored Jul 20, 2023
1 parent 115c8c3 commit 210b92a
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ inline fun <reified VM : MavericksViewModel<S>, reified S : MavericksState> mave
val view = LocalView.current

val viewModelContext = remember(scope, activity, viewModelStoreOwner, savedStateRegistry) {
val parentFragment = scope as? Fragment ?: findFragmentFromView(view)
val parentFragment = when (scope) {
is Fragment -> scope
is ComponentActivity -> null
else -> findFragmentFromView(view)
}

if (parentFragment != null) {
val args = argsFactory?.invoke() ?: parentFragment.arguments?.get(Mavericks.KEY_ARG)
Expand Down
7 changes: 7 additions & 0 deletions mvrx-compose/src/test/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
tools:ignore="GoogleAppIndexingWarning"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:allowBackup="false">
<activity android:name="com.airbnb.mvrx.compose.LifecycleOwnerScopeTestActivity" android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.airbnb.mvrx.compose.FragmentArgsTestActivity" android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.airbnb.mvrx.compose

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentContainerView
import com.airbnb.mvrx.Mavericks
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class LifecycleOwnerScopeTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<LifecycleOwnerScopeTestActivity>()

@Before
fun setUp() {
Mavericks.initialize(composeTestRule.activity)
}

@Test
fun `activity_viewModel and activity_activityScopedViewModel are the same`() {
assertNotNull(composeTestRule.activity.viewModel)
assertNotNull(composeTestRule.activity.activityScopedViewModel)
assert(composeTestRule.activity.viewModel === composeTestRule.activity.activityScopedViewModel)
}

@Test
fun `fragment_viewModel and fragment_activityScopedViewModel are different`() {
assertNotNull(composeTestRule.activity.fragment.viewModel)
assertNotNull(composeTestRule.activity.fragment.activityScopedViewModel)
assert(composeTestRule.activity.fragment.viewModel !== composeTestRule.activity.fragment.activityScopedViewModel)
}

@Test
fun `activity_viewModel and fragment_activityScopedViewModel are the same`() {
assertNotNull(composeTestRule.activity.viewModel)
assertNotNull(composeTestRule.activity.fragment.activityScopedViewModel)
assert(composeTestRule.activity.viewModel === composeTestRule.activity.fragment.activityScopedViewModel)
}

@Test
fun `fragment_viewModel and activity_activityScopedViewModel are different`() {
assertNotNull(composeTestRule.activity.fragment.viewModel)
assertNotNull(composeTestRule.activity.activityScopedViewModel)
assert(composeTestRule.activity.fragment.viewModel !== composeTestRule.activity.activityScopedViewModel)
}
}

class LifecycleOwnerScopeTestActivity : AppCompatActivity() {
lateinit var fragment: LifecycleOwnerScopeTestFragment
lateinit var viewModel: CounterViewModel
lateinit var activityScopedViewModel: CounterViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val fragmentId = 123
val fragmentContainerView = FragmentContainerView(this).apply {
id = fragmentId
}
val composeView = ComposeView(this).apply {
setContent {
this@LifecycleOwnerScopeTestActivity.viewModel = mavericksViewModel<CounterViewModel, CounterState>()
this@LifecycleOwnerScopeTestActivity.activityScopedViewModel = mavericksActivityViewModel<CounterViewModel, CounterState>()
}
}

setContentView(
LinearLayout(this).apply {
addView(fragmentContainerView)
addView(composeView)
}
)

fragment = LifecycleOwnerScopeTestFragment()

supportFragmentManager.beginTransaction()
.add(
fragmentId,
fragment
)
.commit()
}
}

class LifecycleOwnerScopeTestFragment : Fragment() {
lateinit var viewModel: CounterViewModel
lateinit var activityScopedViewModel: CounterViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return ComposeView(requireContext()).apply {
setContent {
this@LifecycleOwnerScopeTestFragment.viewModel = mavericksViewModel<CounterViewModel, CounterState>()
this@LifecycleOwnerScopeTestFragment.activityScopedViewModel = mavericksActivityViewModel<CounterViewModel, CounterState>()
}
}
}
}

0 comments on commit 210b92a

Please sign in to comment.