Skip to content

Commit b4cee44

Browse files
committed
Add rudimentary script support
1 parent bd0b90e commit b4cee44

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.tschuchort.compiletesting
2+
3+
4+
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
5+
import org.jetbrains.kotlin.name.Name
6+
import java.net.URLClassLoader
7+
8+
fun KotlinCompilation.Result.runCompiledScript(
9+
fileName: String,
10+
args: List<String> = emptyList(),
11+
classLoader: ClassLoader? = Thread.currentThread().contextClassLoader
12+
) {
13+
fun String.removeKotlinFileSuffix() = removeSuffix(".kt").removeSuffix(".kts")
14+
15+
val scriptClassName = Name.identifier(
16+
PackagePartClassUtils.getFilePartShortName(fileName.removeKotlinFileSuffix())
17+
).identifier.removeSuffix("Kt")
18+
19+
val scriptClassLoader = URLClassLoader(arrayOf(outputDirectory.toURI().toURL()), classLoader)
20+
21+
val scriptClass = try {
22+
scriptClassLoader.loadClass(scriptClassName)
23+
} catch (e: ClassNotFoundException) {
24+
throw IllegalArgumentException("Could not load script class for given filename $fileName", e)
25+
}
26+
27+
scriptClass.getConstructor(Array<String>::class.java).newInstance(args.toTypedArray())
28+
}
29+

src/main/kotlin/com/tschuchort/compiletesting/Utils.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.tschuchort.compiletesting
22

3-
import java.io.File
4-
import java.io.IOException
3+
import okio.Buffer
4+
import java.io.*
55
import java.net.URL
66
import java.net.URLClassLoader
7+
import java.nio.charset.Charset
78
import java.nio.file.*
89
import java.nio.file.attribute.BasicFileAttributes
910
import javax.lang.model.SourceVersion
@@ -83,4 +84,17 @@ internal inline fun <T> withSystemProperties(properties: Map<String, String>, f:
8384
System.setProperty(key, value)
8485
}
8586
}
87+
}
88+
89+
internal inline fun <R> withSystemOut(stream: PrintStream, crossinline f: () -> R): R {
90+
System.setOut(stream)
91+
val ret = f()
92+
System.setOut(PrintStream(FileOutputStream(FileDescriptor.out)))
93+
return ret
94+
}
95+
96+
internal inline fun <R> captureSystemOut(crossinline f: () -> R): Pair<R, String> {
97+
val systemOutBuffer = Buffer()
98+
val ret = withSystemOut(PrintStream(systemOutBuffer.outputStream()), f)
99+
return Pair(ret, systemOutBuffer.readString(Charset.defaultCharset()))
86100
}

src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package com.tschuchort.compiletesting
22

33
import org.assertj.core.api.Assertions.assertThat
44
import com.tschuchort.compiletesting.KotlinCompilation.ExitCode
5+
import okio.Buffer
56
import org.assertj.core.api.Assertions.fail
67
import org.junit.Rule
78
import org.junit.Test
89
import org.junit.rules.TemporaryFolder
9-
import java.io.File
10+
import java.io.FileDescriptor
11+
import java.io.FileOutputStream
12+
import java.io.PrintStream
1013
import javax.annotation.processing.AbstractProcessor
1114
import javax.annotation.processing.RoundEnvironment
1215
import javax.lang.model.element.TypeElement
@@ -588,6 +591,42 @@ class KotlinCompilationTests {
588591
assertClassLoadable(result, "${KotlinTestProcessor.GENERATED_PACKAGE}.${KotlinTestProcessor.GENERATED_JAVA_CLASS_NAME}")
589592
}
590593

594+
@Test
595+
fun `Can execute Kotlinscript`() {
596+
val kSource = SourceFile.new("Kscript.kts", """
597+
println("hello script")
598+
""".trimIndent())
599+
600+
val result = defaultCompilerConfig().apply {
601+
sources = listOf(kSource)
602+
}.compile()
603+
604+
val (ret, sysOut) = captureSystemOut {
605+
result.runCompiledScript("Kscript")
606+
}
607+
608+
assertThat(sysOut).contains("hello script")
609+
}
610+
611+
@Test
612+
fun `Kotlinscript receives command line arguments`() {
613+
val kSource = SourceFile.new("Kscript.kts", """
614+
println(args[0] + " " + args[1])
615+
""".trimIndent())
616+
617+
val result = defaultCompilerConfig().apply {
618+
sources = listOf(kSource)
619+
}.compile()
620+
621+
assertThat(result.exitCode).isEqualTo(ExitCode.OK)
622+
623+
val (_, sysOut) = captureSystemOut {
624+
result.runCompiledScript("Kscript", args = listOf("arg0", "arg1"))
625+
}
626+
627+
assertThat(sysOut).contains("arg0 arg1")
628+
}
629+
591630
private fun defaultCompilerConfig(): KotlinCompilation {
592631
return KotlinCompilation().apply {
593632
workingDir = temporaryFolder.root

0 commit comments

Comments
 (0)