commonMain.com.episode6.mockspresso2.internal.MxoInstanceBuilder.kt Maven / Gradle / Ivy
package com.episode6.mockspresso2.internal
import com.episode6.mockspresso2.DependencyAlreadyMappedError
import com.episode6.mockspresso2.MockspressoInstance
import com.episode6.mockspresso2.api.Dependencies
import com.episode6.mockspresso2.api.DynamicObjectMaker
import com.episode6.mockspresso2.api.FallbackObjectMaker
import com.episode6.mockspresso2.api.RealObjectMaker
import com.episode6.mockspresso2.defaultFallbackObjectMaker
import com.episode6.mockspresso2.defaultRealObjectMaker
import com.episode6.mockspresso2.internal.util.DependencyCacheBuilder
import com.episode6.mockspresso2.internal.util.RealObjectRequestsList
import com.episode6.mockspresso2.reflect.DependencyKey
import com.episode6.mockspresso2.reflect.TypeToken
internal class MxoInstanceBuilder(private val parent: Lazy? = null) {
private var realMaker: RealObjectMaker? = null
private var fallbackMaker: FallbackObjectMaker? = null
private val dynamicMakers: MutableList = mutableListOf()
private val dependencies = DependencyCacheBuilder()
private val realObjectRequests = RealObjectRequestsList()
private val setupCallbacks: MutableList<(MockspressoInstance) -> Unit> = mutableListOf()
private val teardownCallbacks: MutableList<() -> Unit> = mutableListOf()
fun onSetup(cmd: (MockspressoInstance) -> Unit) {
setupCallbacks += cmd
}
fun onTearDown(cmd: () -> Unit) {
teardownCallbacks += cmd
}
fun realObjectMaker(realMaker: RealObjectMaker) {
this.realMaker = realMaker
}
fun addDynamicMaker(dynamicMaker: DynamicObjectMaker) {
dynamicMakers += dynamicMaker
}
fun fallbackObjectMaker(fallbackMaker: FallbackObjectMaker) {
this.fallbackMaker = fallbackMaker
}
fun dependencyOf(key: DependencyKey, provider: Dependencies.() -> T) {
key.assertNotMapped()
dependencies.put(key, provider)
}
fun realObject(
key: DependencyKey,
implementationToken: TypeToken,
interceptor: (IMPL) -> BIND = { it }
) {
key.assertNotMapped()
realObjectRequests.put(key, implementationToken, interceptor)
}
private fun DependencyKey<*>.assertNotMapped() {
if (dependencies.containsKey(this) || realObjectRequests.containsKey(this)) {
throw DependencyAlreadyMappedError(this)
}
}
fun build() = parent?.value.let { parent ->
MxoInstance(
parent = parent,
realMaker = realMaker ?: parent?.realMaker ?: defaultRealObjectMaker(),
fallbackMaker = fallbackMaker ?: parent?.fallbackMaker ?: defaultFallbackObjectMaker(),
dynamicMakers = dynamicMakers,
setupCallbacks = setupCallbacks,
teardownCallbacks = teardownCallbacks,
dependenciesBuilder = dependencies,
realObjectRequests = realObjectRequests,
)
}
}