Coverage Summary for Class: BaseUIIntegrationTest (ru.eda.plgn.bizgen.plugin.base)

Class Method, % Branch, % Line, % Instruction, %
BaseUIIntegrationTest 0% (0/9) 0% (0/8) 0% (0/31) 0% (0/244)
BaseUIIntegrationTest$1$1$1 0% (0/2) 0% (0/7) 0% (0/38)
BaseUIIntegrationTest$_init_$lambda$0$$inlined$bindSingleton$default$1 0% (0/1)
Total 0% (0/12) 0% (0/8) 0% (0/38) 0% (0/282)


 package ru.eda.plgn.bizgen.plugin.base
 
 import com.intellij.driver.client.Driver
 import com.intellij.driver.sdk.waitForIndicators
 import com.intellij.ide.starter.ci.CIServer
 import com.intellij.ide.starter.ci.NoCIServer
 import com.intellij.ide.starter.di.di
 import com.intellij.ide.starter.driver.engine.runIdeWithDriver
 import com.intellij.ide.starter.ide.IDETestContext
 import com.intellij.ide.starter.ide.IdeProductProvider
 import com.intellij.ide.starter.models.IDEStartResult
 import com.intellij.ide.starter.models.TestCase
 import com.intellij.ide.starter.project.LocalProjectInfo
 import com.intellij.ide.starter.runner.Starter
 import org.junit.jupiter.api.Tag
 import org.junit.jupiter.api.condition.EnabledIfSystemProperty
 import org.junit.jupiter.api.fail
 import org.kodein.di.DI
 import org.kodein.di.bindSingleton
 import java.nio.file.Files
 import java.nio.file.Path
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.minutes
 
 /**
  * Маркерная аннотация для интеграционных тестов плагина.
  *
  * Совмещает два механизма фильтрации:
  * - [Tag] `"integrationTests"` — для будущей тег-фильтрации на gradle-уровне.
  * - [EnabledIfSystemProperty] `runIntegrationTests=true` — для запуска из IDE через VM options
  *
  * @author Dmitry_Emelyanenko
  */
 @Tag("integrationTests")
 @Retention(value = AnnotationRetention.RUNTIME)
 @Target(allowedTargets = [AnnotationTarget.CLASS])
 @EnabledIfSystemProperty(named = "runIntegrationTests", matches = "true")
 annotation class IntegrationTest
 
 /**
  * Базовый класс интеграционных тестов плагина.
  *
  * Содержит общую инфраструктуру JetBrains Integration Test Framework (Starter + Driver):
  * - настройку [CIServer] через Kodein DI (перехват failures → [fail]);
  * - фабрику [IDETestContext] [newContextWithPlugin] с установкой собранного архива плагина;
  * - резолвер пути к архиву плагина [resolvePluginArchivePath] (system property → fallback на `build/distributions/`).
  *
  * Конкретные тесты наследуются от этого класса и содержат только `@Test`-методы с бизнес-логикой.
  *
  * @author Dmitry_Emelyanenko
  */
 @IntegrationTest
 abstract class BaseUIIntegrationTest {
 
   /**
    * Версия IntelliJ IDEA для тестирования — fallback при ручном запуске из IDE без gradle.
    *
    * При запуске через gradle-задачу `integrationTest` фактическая версия берётся из system property `bizgen.test.ide.version`
    * (пробрасывается из `ideaVersion` в `ru-bizgen-plugin/build.gradle.kts` — та же версия, под которую собирается плагин), см.
    * [resolveTestIdeVersion].
    *
    * Значение по умолчанию `"2026.1"` совпадает с версией сборки плагина (`version=1.12.261` → `ideaVersion="2026.1"`), чтобы ручной запуск
    * шёл на той же версии. Наследники могут переопределить для запуска на другой версии.
    */
   protected open val ideVersion: String = "2026.1"
 
   init {
     di = DI {
       extend(di)
       bindSingleton<CIServer>(overrides = true) {
         object : CIServer by NoCIServer {
           override fun reportTestFailure(
             testName: String,
             message: String,
             details: String,
             linkToLogs: String?,
           ) {
             System.err.println("=== CIServer.reportTestFailure ===")
             System.err.println("testName = $testName")
             System.err.println("message = $message")
             System.err.println("details = $details")
             System.err.println("linkToLogs = $linkToLogs")
             fail { "$testName fails: $message.\n$details" }
           }
         }
       }
     }
   }
 
   protected fun runIdea(testName: String, projectDir: Path, runTimeout: Duration = 2.minutes, block: Driver.() -> Unit): IDEStartResult {
     return newContextWithPlugin(testName, projectDir)
       .runIdeWithDriver(runTimeout = runTimeout)
       .useDriverAndCloseIde {
         waitForIndicators(1.minutes)
         block()
       }
   }
 
   /**
    * Создаёт [IDETestContext] с установленным плагином для теста [testName].
    *
    * Продукт: IntelliJ IDEA **Ultimate** ([IdeProductProvider.IU]).
    *
    * Версия берётся из [resolveTestIdeVersion] — совпадает с версией, под которую собирается плагин (`ideaVersion` в
    * `ru-bizgen-plugin/build.gradle.kts`). IU 2026.1 используется вместо IC, т.к. IC 2026.1 не опубликована в products-releases API (см.
    * KDoc [ideVersion]).
    *
    * @param testName имя тест-кейса (используется Starter'ом для логирования/артефактов)
    * @param projectDir директория проекта, открываемого в тестовой IDE
    * @return настроенный контекст с установленным плагином
    */
   private fun newContextWithPlugin(testName: String, projectDir: Path): IDETestContext {
     val context = Starter.newContext(
       testName = testName,
       TestCase(IdeProductProvider.IU, projectInfo = LocalProjectInfo(projectDir)).withVersion(resolveTestIdeVersion()),
     )
     context.pluginConfigurator.installPluginFromPath(resolvePluginArchivePath())
     return context
   }
 
   /**
    * Резолвинг версии IntelliJ IDEA IC для тестирования.
    *
    * Приоритет:
    * 1. System property `bizgen.test.ide.version` (выставляется gradle-задачей `integrationTest` из `ideaVersion` в
    *    `ru-bizgen-plugin/build.gradle.kts` — та же версия, под которую собирается плагин).
    * 2. Поле [ideVersion] — fallback для ручного запуска из IDE без gradle.
    *
    * @return версия IDE для тестирования
    */
   private fun resolveTestIdeVersion(): String = System.getProperty("bizgen.test.ide.version") ?: ideVersion
 
   /**
    * Резолвинг пути к архиву плагина для установки в тестовую IDE.
    *
    * Приоритет:
    * 1. System property `path.to.build.plugin` (выставляется gradle-задачей `integrationTest`, см.
    *    `ru-bizgen-plugin/build.gradle.kts:96-99`).
    * 2. Последний по версии `ru-bizgen-*.zip` в `build/distributions/` — для запуска из IDE после ручного выполнения
    *    `:ru-bizgen-plugin:buildPlugin` без необходимости править VM options.
    *
    * @return путь к архиву плагина
    */
   private fun resolvePluginArchivePath(): Path {
     System.getProperty("path.to.build.plugin")?.let { return Path.of(it) }
 
     val distDir = Path.of("build/distributions")
     if (!Files.isDirectory(distDir)) {
       fail { "System property 'path.to.build.plugin' is not set and $distDir not found. Run ':ru-bizgen-plugin:buildPlugin' first." }
     }
 
     val pluginZips = Files.list(distDir).use { stream ->
       stream
         .filter { it.fileName.toString().matches(Regex("""ru-bizgen-\d+\.\d+\.\d+\.zip""")) }
         .sorted(Comparator.reverseOrder())
         .toList()
     }
 
     return pluginZips.firstOrNull()
       ?: fail { "No ru-bizgen-*.zip in $distDir. Run ':ru-bizgen-plugin:buildPlugin' first." }
   }
 }