1 package com.google.devtools.ksp.test 2 3 import org.gradle.testkit.runner.GradleRunner 4 import org.jetbrains.kotlin.cli.common.ExitCode 5 import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler 6 import org.junit.Assert 7 import org.junit.Rule 8 import org.junit.Test 9 import java.io.ByteArrayOutputStream 10 import java.io.File 11 import java.io.PrintStream 12 import java.net.URLClassLoader 13 14 data class CompileResult(val exitCode: ExitCode, val output: String) 15 16 class KSPCmdLineOptionsIT { 17 @Rule 18 @JvmField 19 val project: TemporaryTestProject = TemporaryTestProject("cmd-options") 20 runCmdCompilernull21 private fun runCmdCompiler(pluginOptions: List<String>): CompileResult { 22 val gradleRunner = GradleRunner.create().withProjectDir(project.root) 23 gradleRunner.withArguments("clean", ":processors:build").build() 24 val processorJar = File(project.root, "processors/build/libs/processors-1.0-SNAPSHOT.jar") 25 val classLoader = URLClassLoader(arrayOf(processorJar.toURI().toURL()), javaClass.classLoader) 26 val compiler = classLoader.loadClass(K2JVMCompiler::class.java.name).newInstance() as K2JVMCompiler 27 val repoPath = "../build/repos/test/com/google/devtools/ksp/" 28 val kspPluginId = "com.google.devtools.ksp.symbol-processing" 29 val kspPluginJar = File("$repoPath/symbol-processing-cmdline/2.0.255-SNAPSHOT").listFiles()!!.filter { 30 it.name.matches(Regex(".*-\\d.jar")) 31 }.maxByOrNull { it.lastModified() }!! 32 val kspApiJar = File("$repoPath/symbol-processing-api/2.0.255-SNAPSHOT").listFiles()!!.filter { 33 it.name.matches(Regex(".*-\\d.jar")) 34 }.maxByOrNull { it.lastModified() }!! 35 val compilerArgs = mutableListOf( 36 "-no-stdlib", 37 "-Xplugin=${kspPluginJar.absolutePath}", 38 "-Xplugin=${kspApiJar.absolutePath}", 39 "-P", "plugin:$kspPluginId:apclasspath=${processorJar.absolutePath}", 40 "-P", "plugin:$kspPluginId:projectBaseDir=${project.root}/build", 41 "-P", "plugin:$kspPluginId:classOutputDir=${project.root}/build", 42 "-P", "plugin:$kspPluginId:javaOutputDir=${project.root}/build/out", 43 "-P", "plugin:$kspPluginId:kotlinOutputDir=${project.root}/build/out", 44 "-P", "plugin:$kspPluginId:resourceOutputDir=${project.root}/build/out", 45 "-P", "plugin:$kspPluginId:kspOutputDir=${project.root}/build/out", 46 "-P", "plugin:$kspPluginId:cachesDir=${project.root}/build/out", 47 "-P", "plugin:$kspPluginId:incremental=false", 48 "-d", "${project.root}/build/out" 49 ) 50 pluginOptions.forEach { 51 compilerArgs.add("-P") 52 compilerArgs.add("plugin:$kspPluginId:$it") 53 } 54 compilerArgs.add(File(project.root, "workload/src/main/kotlin/com/example/A.kt").absolutePath) 55 val outStream = ByteArrayOutputStream() 56 val exitCode = compiler.exec(PrintStream(outStream), *compilerArgs.toTypedArray()) 57 return CompileResult(exitCode, outStream.toString()) 58 } 59 60 @Test testWithCompilationOnErrornull61 fun testWithCompilationOnError() { 62 val result = runCmdCompiler(listOf("apoption=error=true", "withCompilation=true")) 63 val errors = result.output.lines().filter { it.startsWith("error: [ksp]") } 64 val exitCode = result.exitCode 65 Assert.assertTrue(exitCode == ExitCode.COMPILATION_ERROR) 66 Assert.assertTrue( 67 errors.any { 68 it.startsWith("error: [ksp] java.lang.IllegalStateException: Error on request") 69 } 70 ) 71 } 72 73 @Test testWithCompilationOnErrorOknull74 fun testWithCompilationOnErrorOk() { 75 val result = runCmdCompiler(listOf("apoption=error=true", "returnOkOnError=true", "withCompilation=true")) 76 val errors = result.output.lines().filter { it.startsWith("error: [ksp]") } 77 val exitCode = result.exitCode 78 Assert.assertTrue(exitCode == ExitCode.OK) 79 Assert.assertTrue( 80 errors.any { 81 it.startsWith("error: [ksp] java.lang.IllegalStateException: Error on request") 82 } 83 ) 84 } 85 } 86