Skip to content

Commit

Permalink
Supports sub types (fixes #57)
Browse files Browse the repository at this point in the history
  • Loading branch information
SalomonBrys committed May 6, 2023
1 parent 087f9a0 commit 3995979
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,14 @@ public class MocKMPProcessor(

private class Error(message: String, val node: KSNode) : Exception(message)

override fun process(resolver: Resolver): List<KSAnnotated> {
override fun process(resolver: Resolver): List<KSAnnotated> =
try {
return privateProcess(resolver)
privateProcess(resolver)
} catch (e: Error) {
logger.error("MocKMP: ${e.message}", e.node)
if (throwErrors) throw e
return emptyList()
emptyList()
}
}

private fun KSNode.asString(): String = when (this) {
is KSValueParameter -> {
Expand All @@ -84,6 +83,32 @@ public class MocKMPProcessor(
val references = HashSet<KSNode>()
}

private fun KSType.toFunName(): String {
val prefix = buildString {
var pDecl = declaration.parentDeclaration
while (pDecl != null) {
append(pDecl.simpleName.asString())
append("_")
pDecl = pDecl.parentDeclaration
}
}
return prefix +
if (arguments.isEmpty()) declaration.simpleName.asString()
else "${declaration.simpleName.asString()}X${arguments.joinToString("_") { it.type!!.resolve().toFunName() } }X"
}

private fun KSDeclaration.toMockName(): String {
val prefix = buildString {
var pDecl = parentDeclaration
while (pDecl != null) {
append(pDecl.simpleName.asString())
append("_")
pDecl = pDecl.parentDeclaration
}
}
return "Mock" + prefix + simpleName.asString()
}

private fun privateProcess(resolver: Resolver): List<KSAnnotated> {
val toInject = HashMap<KSClassDeclaration, ArrayList<Pair<String, KSPropertyDeclaration>>>()
val toMock = HashMap<KSClassDeclaration, ToProcess>()
Expand Down Expand Up @@ -183,7 +208,7 @@ public class MocKMPProcessor(
}

toMock.forEach { (vItf, process) ->
val mockClassName = "Mock${vItf.simpleName.asString()}"
val mockClassName = vItf.toMockName()
val gFile = FileSpec.builder(vItf.packageName.asString(), mockClassName)
val gCls = TypeSpec.classBuilder(mockClassName)
.addSuperinterface(
Expand Down Expand Up @@ -267,10 +292,6 @@ public class MocKMPProcessor(
gFile.build().writeTo(codeGenerator, Dependencies(true, *process.files.toTypedArray()))
}

fun KSType.toFunName(): String =
if (arguments.isEmpty()) declaration.simpleName.asString()
else "${declaration.simpleName.asString()}X${arguments.joinToString("_") { it.type!!.resolve().toFunName() } }X"

toFake.forEach { (vType, process) ->
val vCls = vType.declaration as KSClassDeclaration
val filesDeps = HashSet(process.files)
Expand Down Expand Up @@ -367,7 +388,7 @@ public class MocKMPProcessor(
gFun.addStatement(
"this.%N = %T(%N)",
vProp.simpleName.asString(),
ClassName(vPropTypeDecl.packageName.asString(), "Mock${vPropTypeDecl.simpleName.asString()}"),
ClassName(vPropTypeDecl.packageName.asString(), vPropTypeDecl.toMockName()),
"mocker"
)
}
Expand Down
34 changes: 22 additions & 12 deletions tests/tests-junit4/src/commonMain/kotlin/data/Data.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ package data

import kotlinx.datetime.Instant

data class SubData<T>(
val data: T,
val int: Int
)

enum class Direction { LEFT, RIGHT }

data class SomeDirection(
val dir: Direction
)
val dir: Direction,
val data: SubData
) {
data class SubData(
val nDir: Direction?,
)
}

typealias NamesMap<K> = Map<K, Set<String>>

data class Data(
val sub1: SubData<String>,
val sub2: SubData<Int>,
val sub3: SubData<Map<String, Set<String>>>,
val gen1: GenData<String>,
val gen2: GenData<Int>,
val gen3: GenData<Map<String, Set<String>>>,
val sub: SubData,
val nullDir: SomeDirection?,
val dir1: SomeDirection,
val dir2: SomeDirection,
Expand All @@ -32,6 +33,15 @@ data class Data(
val map: NamesMap<Int>,
val hashMap: HashMap<String, Long>,
val linkedHashMap: LinkedHashMap<String, Long>,
) {
data class SubData(
val nStr: String?,
)
}

data class GenData<T>(
val data: T,
val int: Int
)

class Arrays(
Expand All @@ -41,6 +51,6 @@ class Arrays(

class Funs(
val cb: (String) -> Unit,
val data: () -> SubData<String>,
val combo: (String) -> SubData<String>
val data: () -> GenData<String>,
val combo: (String) -> GenData<String>
)
8 changes: 8 additions & 0 deletions tests/tests-junit4/src/commonMain/kotlin/foo/Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ interface Foo<out T : Any> {

@ExperimentalTest
fun experimentalMethod()

interface Sub {
fun doOp()
}
}

typealias BarCB = (String) -> Int
Expand All @@ -56,6 +60,10 @@ interface Bar : Foo<Bar> {
fun taCallback(cb: BarCB)
fun suspendCallback(cb: suspend (String) -> Int)
fun <T: Comparable<T>> order(c: Iterable<T>) : List<T>

interface Sub {
fun doOp()
}
}

abstract class Abs(val i: Int)
Expand Down
42 changes: 32 additions & 10 deletions tests/tests-junit4/src/commonTest/kotlin/tests/InjectionTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package tests

import data.*
import foo.Bar
import foo.Foo
import foo.MockBar
import kotlinx.datetime.Instant
import org.kodein.mock.Fake
import org.kodein.mock.Mock
import org.kodein.mock.tests.TestsWithMocks
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.*

class InjectionTests : TestsWithMocks() {

Expand All @@ -28,6 +27,12 @@ class InjectionTests : TestsWithMocks() {
@Mock
lateinit var callback: (Boolean, Int) -> String

@Mock
lateinit var s1: Foo.Sub

@Mock
lateinit var s2: Bar.Sub

val control by withMocks { Control(bar, data) }

override fun setUpMocks() = injectMocks(mocker)
Expand All @@ -41,12 +46,13 @@ class InjectionTests : TestsWithMocks() {
fun testFakeData() {
assertEquals(
Data(
SubData("", 0),
SubData(0, 0),
SubData(emptyMap(), 0),
GenData("", 0),
GenData(0, 0),
GenData(emptyMap(), 0),
Data.SubData(null),
null,
SomeDirection(Direction.LEFT),
SomeDirection(Direction.LEFT),
SomeDirection(Direction.LEFT, SomeDirection.SubData(null)),
SomeDirection(Direction.LEFT, SomeDirection.SubData(null)),
Instant.fromEpochSeconds(0),
emptyList(),
ArrayList(),
Expand Down Expand Up @@ -85,7 +91,23 @@ class InjectionTests : TestsWithMocks() {
@Test
fun testFakeFunctions() {
funs.cb("foo")
assertEquals(SubData("", 0), funs.data())
assertEquals(SubData("", 0), funs.combo("foo"))
assertEquals(GenData("", 0), funs.data())
assertEquals(GenData("", 0), funs.combo("foo"))
}

@Test
fun testSameName() {
var r1 = false
var r2 = false
every { s1.doOp() } runs { r1 = true }
every { s2.doOp() } runs { r2 = true }
assertFalse(r1 || r2)
s1.doOp()
verify { s1.doOp() }
assertTrue(r1)
assertFalse(r2)
s2.doOp()
verify { s2.doOp() }
assertTrue(r2)
}
}

0 comments on commit 3995979

Please sign in to comment.