mirror of
https://github.com/mayokunadeniyi/Instant-Weather.git
synced 2025-08-06 15:00:23 +08:00

* chore: manage dependencies with buildSrc * chore: setup firebase crashlytics, analytics * chore: convert build scripts to kotlin dsl * chore: convert build scripts to kotlin dsl * chore: remove kotlin android extensions, enable viewbinding * feat: use bottom sheet in search fragmenrt, format forecast dates * chore: fix build config issues * refactor: update .gitignore * refactor: update .gitignore * ci: update actions workflow * refactor: fix failing tests * chore: fix build config issues * ci: update actions workflow
97 lines
3.1 KiB
Kotlin
97 lines
3.1 KiB
Kotlin
package com.mayokunadeniyi.instantweather.utils
|
|
|
|
import android.view.View
|
|
import androidx.databinding.DataBindingUtil
|
|
import androidx.databinding.ViewDataBinding
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.fragment.app.FragmentActivity
|
|
import androidx.fragment.app.testing.FragmentScenario
|
|
import androidx.test.core.app.ActivityScenario
|
|
import androidx.test.espresso.IdlingResource
|
|
import java.util.*
|
|
|
|
/**
|
|
* Created by Mayokun Adeniyi on 25/07/2020.
|
|
*/
|
|
|
|
class DataBindingIdlingResource : IdlingResource {
|
|
// List of registered callbacks
|
|
private val idlingCallbacks = mutableListOf<IdlingResource.ResourceCallback>()
|
|
// Give it a unique id to work around an Espresso bug where you cannot register/unregister
|
|
// an idling resource with the same name.
|
|
private val id = UUID.randomUUID().toString()
|
|
// Holds whether isIdle was called and the result was false. We track this to avoid calling
|
|
// onTransitionToIdle callbacks if Espresso never thought we were idle in the first place.
|
|
private var wasNotIdle = false
|
|
|
|
lateinit var activity: FragmentActivity
|
|
|
|
override fun getName() = "DataBinding $id"
|
|
|
|
override fun isIdleNow(): Boolean {
|
|
val idle = !getBindings().any { it.hasPendingBindings() }
|
|
@Suppress("LiftReturnOrAssignment")
|
|
if (idle) {
|
|
if (wasNotIdle) {
|
|
// Notify observers to avoid Espresso race detector.
|
|
idlingCallbacks.forEach { it.onTransitionToIdle() }
|
|
}
|
|
wasNotIdle = false
|
|
} else {
|
|
wasNotIdle = true
|
|
// Check next frame.
|
|
activity.findViewById<View>(android.R.id.content).postDelayed(
|
|
{
|
|
isIdleNow
|
|
},
|
|
16
|
|
)
|
|
}
|
|
return idle
|
|
}
|
|
|
|
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback) {
|
|
idlingCallbacks.add(callback)
|
|
}
|
|
|
|
/**
|
|
* Find all binding classes in all currently available fragments.
|
|
*/
|
|
private fun getBindings(): List<ViewDataBinding> {
|
|
val fragments = (activity as? FragmentActivity)
|
|
?.supportFragmentManager
|
|
?.fragments
|
|
|
|
val bindings =
|
|
fragments?.mapNotNull {
|
|
it.view?.getBinding()
|
|
} ?: emptyList()
|
|
val childrenBindings = fragments?.flatMap { it.childFragmentManager.fragments }
|
|
?.mapNotNull { it.view?.getBinding() } ?: emptyList()
|
|
|
|
return bindings + childrenBindings
|
|
}
|
|
}
|
|
|
|
private fun View.getBinding(): ViewDataBinding? = DataBindingUtil.getBinding(this)
|
|
|
|
/**
|
|
* Sets the activity from an [ActivityScenario] to be used from [DataBindingIdlingResource].
|
|
*/
|
|
fun DataBindingIdlingResource.monitorActivity(
|
|
activityScenario: ActivityScenario<out FragmentActivity>
|
|
) {
|
|
activityScenario.onActivity {
|
|
this.activity = it
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the fragment from a [FragmentScenario] to be used from [DataBindingIdlingResource].
|
|
*/
|
|
fun DataBindingIdlingResource.monitorFragment(fragmentScenario: FragmentScenario<out Fragment>) {
|
|
fragmentScenario.onFragment {
|
|
this.activity = it.requireActivity()
|
|
}
|
|
}
|