Java edition
Kotlin
Kotlin support is experimental: it’s proved on mutastic’s own Kotlin samples, and not yet on enough real projects to promise it.
mutastic reads class files, so a Kotlin project runs as a Java one does: the same command, the same operators and the same cards. This page is only what’s different.
Kotlin Multiplatform
Section titled “Kotlin Multiplatform”A Kotlin Multiplatform module runs through its JVM target, jvm() or jvm("desktop"): mutastic
mutates the target’s code, common code included, and runs the target’s tests (jvmTest,
desktopTest). With one JVM target that’s the module’s suite; with more, --suite names one
(--suite=desktopTest). A file named for where it runs, Board.common.kt or Board.desktop.kt, is
shown as itself, though kotlinc names its class Board_commonKt.
The Gradle plugin works the same way: id("io.mutastic") beside kotlin("multiplatform") gives the
module mutasticRun and the other tasks, which run the JVM target’s tests, and suite = "desktopTest"
in mutastic { } names one where there are several.
What kotlinc writes is left alone
Section titled “What kotlinc writes is left alone”kotlinc writes code that isn’t in your source. A mutant of it would ask for a test of code you didn’t
write, so mutastic skips it as generated:, on what the class file shows (@kotlin.Metadata, and
kotlinc’s own calls and shapes), never on a name alone:
- its null checks on parameters, and the name each reports;
- a data class’s
copy,componentNandequals; - a
lateinit’s getter and the check that it’s been set; - a coroutine’s state machine: where to resume, saving locals across a suspension, and the comparison
with
COROUTINE_SUSPENDED; - code copied in from an inline function in a library, such as the loop in
filter.
x!! and x as String are yours, so their checks stay: without one, a null carries on where you said
it shouldn’t. x!!.size is the exception, skipped as equivalent:, as reading the value throws the same
NullPointerException.
Inline functions
Section titled “Inline functions”kotlinc copies an inline function’s body into each call, and numbers the copy’s lines past the end of the file. mutastic reads the map kotlinc keeps of where each copy came from, so a mutant in your own inline function is on that function’s line, in its file, and a test of the call catches it.
The function’s own body is skipped, as nothing runs it, unless Java calls it. One that only tests call is skipped too, and that’s a blind spot: what’s copied into a test isn’t changed, so nothing shows whether the tests would notice.
Jetpack Compose
Section titled “Jetpack Compose”The Compose compiler rewrites every @Composable function: it passes in a Composer, starts and ends
groups, works out $changed and $default masks to skip a call whose arguments haven’t changed, and
writes trace and source information around your code. remember reads and writes the Composer’s
cache. mutastic skips all of that as generated:, told by what the class file shows: a function that
takes a Composer and then its masks, the runtime’s own calls, and what works on the masks or on what
the runtime answered. The keys of groups, and the stand-ins a call passes for an argument left to its
default, are skipped too.
What you wrote in a composable keeps its mutants, as in any function: a when choosing what to show, an
if in a lambda, a call to Text (removing it removes something from the screen). Tests that drive the
UI, with runComposeUiTest or a desktop test rule, reach that code like any other test, and so do plain
unit tests of a state holder.
A lambda that returns nothing gives back Unit in the class file, which no caller reads, so a change of
that Unit is skipped too.
Suggested tests
Section titled “Suggested tests”For a Kotlin class, a suggested test is written in Kotlin, for the class’s Kotlin test class: fun
with no void, a top-level function called by its name (plusOne(1)), a constructor with no new, an
extension called on its receiver (1.doubled()) and a property read as one (Counter(2).twice). A
call that can’t be sure to compile gets no suggestion: a generic function or class, one renamed with
@JvmName, an object’s or companion’s member, or a test class written in Java.
See Suggested tests for how the call and its inputs are found.
Operators for Kotlin
Section titled “Operators for Kotlin”kotlin/empty-return, in the plugins mutastic ships, makes a method returning a range or a sequence
return an empty one: see Kotlin’s empty returns.