All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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,
    )
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy