Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missed clean FlakySafeSemanticsBehaviorInterceptor when removing flakySafely intrceptors inside FlakySafeInterceptorScalpel #646

Open
VladislavSumin opened this issue Jun 3, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@VladislavSumin
Copy link
Collaborator

Missed clean FlakySafeSemanticsBehaviorInterceptor when removing flakySafely intrceptors inside FlakySafeInterceptorScalpel

temp solution to local fix:

Fix
import com.kaspersky.components.composesupport.config.ComposeConfig
import com.kaspersky.components.composesupport.config.ComposeInterceptorsInjector
import com.kaspersky.components.composesupport.interceptors.behavior.impl.flakysafety.FlakySafeSemanticsBehaviorInterceptor
import com.kaspersky.kaspresso.flakysafety.FlakySafetyProviderGlobalImpl
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.core.testcontext.BaseTestContext
import com.kaspersky.kaspresso.testcases.core.testcontext.TestContext
import io.mockk.every
import io.mockk.spyk

/**
* Магия рефлексии вперемешку с рантайм моками и всякой грязью, если вы читаете эти строки, то лучше
* закройте этот файл и забудьте, что когда-либо заходили сюда.
*
* Если вы все еще хотите продолжить, то в начале найлейте себе бокальчик пива и забейте кальян ибо дальше
* вас ждет ад.
*
* АСТАНАВИТЕСЬ, не надо!
*
* @param kaspressoBuilder - надо.
*/
internal fun TestContext<Unit>.fixFlakySafety(kaspressoBuilder: Kaspresso.Builder) {

  val fakeBuilder = ComposeConfig.Builder.default(
      kaspressoBuilder = kaspressoBuilder,
      lateComposeCustomize = {}
  )

  val context = this
  val flakySafetyProvider = context.flakySafetyProvider
  val originalScalpel = flakySafetyProvider.flakySafeInterceptorScalpel


  val flakySafeInterceptorScalpelClass = this::class.java.classLoader!!
      .loadClass("com.kaspersky.kaspresso.flakysafety.scalpel.FlakySafeInterceptorScalpel")

  val scalpelSwitcherField = flakySafeInterceptorScalpelClass.getDeclaredField("scalpelSwitcher")
  scalpelSwitcherField.isAccessible = true
  val scalpelSwitcher = scalpelSwitcherField.get(originalScalpel)!!
  val scalpelSwitcherSpy = spyk(scalpelSwitcher)
  scalpelSwitcherField.set(originalScalpel, scalpelSwitcherSpy)

  val originalCalAttemptRestoreScalp = scalpelSwitcher::class.java.getDeclaredMethod(
      "attemptRestoreScalp",
      this.javaClass.classLoader!!.loadClass("kotlin.jvm.functions.Function0")!!,
  )
  originalCalAttemptRestoreScalp.isAccessible = true

  every { scalpelSwitcherSpy["attemptRestoreScalp"](any<() -> Unit>()) } answers {
      originalCalAttemptRestoreScalp.invoke(scalpelSwitcher, {
          println("QWQWQW: set default interceptors")
          ComposeInterceptorsInjector.injectKaspressoInKakaoCompose(
              fakeBuilder.semanticsBehaviorInterceptors,
              fakeBuilder.semanticsWatcherInterceptors,
          )
          // Если вы дочитали до сюда, то вот вам прикольная штука из скобок=)
          (args[0]!! as () -> Unit)()
      })
      Unit
  }

  val scalpelSpy = spyk(originalScalpel)
  flakySafetyProvider.flakySafeInterceptorScalpel = scalpelSpy

  every { scalpelSpy["scalpKakaoInterceptors"]() } answers {
      println("QWQWQW: set cleanered interceptors")
      ComposeInterceptorsInjector.injectKaspressoInKakaoCompose(
          fakeBuilder.semanticsBehaviorInterceptors.filter {
              it !is FlakySafeSemanticsBehaviorInterceptor
          },
          fakeBuilder.semanticsWatcherInterceptors,
      )
      callOriginal()
  }
}

/**
* Достает [FlakySafetyProviderGlobalImpl] из [BaseTestContext] через рефлексию
*/
private val BaseTestContext.flakySafetyProvider: FlakySafetyProviderGlobalImpl
  get() {
      val safetyDelegateField = BaseTestContext::class.java.getDeclaredField("\$\$delegate_0")
      safetyDelegateField.isAccessible = true
      return safetyDelegateField.get(this) as FlakySafetyProviderGlobalImpl
  }

private var FlakySafetyProviderGlobalImpl.flakySafeInterceptorScalpel: Any
  get() {
      val flakySafeInterceptorScalpelField = this::class.java.getDeclaredField("flakySafeInterceptorScalpel")
      flakySafeInterceptorScalpelField.isAccessible = true
      return flakySafeInterceptorScalpelField.get(this)!!
  }
  set(value) {
      val flakySafeInterceptorScalpelField = this::class.java.getDeclaredField("flakySafeInterceptorScalpel")
      flakySafeInterceptorScalpelField.isAccessible = true
      flakySafeInterceptorScalpelField.set(this, value)
  }

@VladislavSumin VladislavSumin added the bug Something isn't working label Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant