summaryrefslogtreecommitdiff
path: root/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTestBase.kt
blob: 728ee72d59b4c90a267ff38462dbd0152526ad0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package org.jetbrains.kotlin.jps.build

import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.ThrowableRunnable
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.idea.test.runAll
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.config.KotlinFacetSettings
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import org.jetbrains.kotlin.platform.js.JsPlatforms
import java.io.File
import java.nio.file.Paths

abstract class KotlinJpsBuildTestBase : AbstractKotlinJpsBuildTestCase() {
    protected lateinit var originalProjectDir: File
    protected val expectedOutputFile: File
        get() = File(originalProjectDir, "expected-output.txt")

    override fun setUp() {
        super.setUp()
        val currentTestMethod = this::class.members.firstOrNull { it.name == "test" + getTestName(false) }
        val workingDirFromAnnotation = currentTestMethod?.annotations?.filterIsInstance<WorkingDir>()?.firstOrNull()?.name
        val projDirPath = Paths.get(
            TEST_DATA_PATH,
            "general",
            workingDirFromAnnotation ?: getTestName(false)
        )
        originalProjectDir = projDirPath.toFile()
        workDir = copyTestDataToTmpDir(originalProjectDir)
        orCreateProjectDir
    }

    protected open fun copyTestDataToTmpDir(testDataDir: File): File {
        assert(testDataDir.exists()) { "Cannot find source folder " + testDataDir.absolutePath }
        val tmpDir = FileUtil.createTempDirectory("kjbtb-jps-build", null)
        FileUtil.copyDir(testDataDir, tmpDir)
        return tmpDir
    }

    override fun tearDown() {
        runAll(
            ThrowableRunnable { workDir.deleteRecursively() },
            ThrowableRunnable { super.tearDown() }
        )
    }

    override fun doGetProjectDir(): File = workDir

    annotation class WorkingDir(val name: String)

    enum class LibraryDependency {
        NONE,
        JVM_MOCK_RUNTIME,
        JVM_FULL_RUNTIME,
        JS_STDLIB_WITHOUT_FACET,
        JS_STDLIB,
    }

    protected fun initProject(libraryDependency: LibraryDependency = LibraryDependency.NONE) {
        addJdk(JDK_NAME)
        loadProject(workDir.absolutePath + File.separator + PROJECT_NAME + ".ipr")

        when (libraryDependency) {
            LibraryDependency.NONE -> Unit
            LibraryDependency.JVM_MOCK_RUNTIME -> addKotlinMockRuntimeDependency()
            LibraryDependency.JVM_FULL_RUNTIME -> addKotlinStdlibDependency()
            LibraryDependency.JS_STDLIB_WITHOUT_FACET -> addKotlinJavaScriptStdlibDependency()
            LibraryDependency.JS_STDLIB -> {
                addKotlinJavaScriptStdlibDependency()
                setupKotlinJSFacet()
            }
        }
    }

    protected fun setupKotlinJSFacet() {
        myProject.modules.forEach {
            val facet = KotlinFacetSettings()
            facet.compilerArguments = K2JSCompilerArguments()
            facet.targetPlatform = JsPlatforms.defaultJsPlatform

            it.container.setChild(
                JpsKotlinFacetModuleExtension.KIND,
                JpsKotlinFacetModuleExtension(facet)
            )
        }
    }

    companion object {
        const val JDK_NAME = "IDEA_JDK"
        const val PROJECT_NAME = "kotlinProject"

        @JvmStatic
        protected fun assertFilesExistInOutput(module: JpsModule, vararg relativePaths: String) {
            for (path in relativePaths) {
                val outputFile = findFileInOutputDir(module, path)
                assertTrue(
                    "Output not written: " + outputFile.absolutePath + "\n Directory contents: \n" + dirContents(
                        outputFile.parentFile
                    ), outputFile.exists()
                )
            }
        }

        @JvmStatic
        protected fun findFileInOutputDir(module: JpsModule, relativePath: String): File {
            val outputUrl = JpsJavaExtensionService.getInstance().getOutputUrl(module, false)
            assertNotNull(outputUrl)
            val outputDir = File(JpsPathUtil.urlToPath(outputUrl))
            return File(outputDir, relativePath)
        }

        @JvmStatic
        protected fun assertFilesNotExistInOutput(module: JpsModule, vararg relativePaths: String) {
            val outputUrl = JpsJavaExtensionService.getInstance().getOutputUrl(module, false)
            assertNotNull(outputUrl)
            val outputDir = File(JpsPathUtil.urlToPath(outputUrl))
            for (path in relativePaths) {
                val outputFile = File(outputDir, path)
                assertFalse("Output directory \"" + outputFile.absolutePath + "\" contains \"" + path + "\"", outputFile.exists())
            }
        }

        private fun dirContents(dir: File): String {
            val files = dir.listFiles() ?: return "<not found>"
            val builder = StringBuilder()
            for (file in files) {
                builder.append(" * ").append(file.name).append("\n")
            }
            return builder.toString()
        }
    }
}