I suppose that would be OK if I were only calling my Kotlin code from Java. But I'm not, I'm calling from Kotlin, and JUnit can't test idomatic usage. Plus, btw - have I mentioned lately that I hate java? That's why I'm using Kotlin.
So far, Kotlin's been doing a good job of insulating me from java, and I'd like to keep it that way. So I've written a unit test framework before - I can write one in Kotlin. In fact, I just did, it doesn't take long.
~ here is an example of usage:
fun main(args: Array<String>) {
var k1 = 0
var k2 = 0
var k3 = 0
TestIt("this is the test suite")
.beforeEach {
k1 += 1
}.afterEach {
k2 += 1
}.onDone {
k3 = k1 + k2
}.run {
it("this is the test") {
it.equals(1, 1)
}
it("this is another test") {
it.equals("fred", 1)
}
}
}
And, here is the TestIt code, the thing about kotlin is that it's so easy and succinct. The entire framework fits in on file, and is about 80 lines of code.
class TestIt(name:String) {
private var name = name
private var beforeProc = {}
private var afterProc = {}
private var doneProc = {}
private val tests:MutableList = mutableListOf()
data class Test(val name:String, val proc:(assert) -> Unit) {}
object assert {
var result = false
var actual:Any? = null
var expected:Any? = null
fun equals(actual:Any, expected:Any):Boolean {
if (actual.equals(expected)) {
this.result = true
} else {
this.result = false
this.actual = actual
this.expected = expected
}
return this.result
}
}
fun beforeEach(proc:() -> Unit):TestIt {
beforeProc = proc
return this
}
fun afterEach(proc:() -> Unit):TestIt {
afterProc = proc
return this
}
fun onDone(proc:() -> Unit):TestIt {
doneProc = proc
return this
}
fun run(main:(func:(name:String, proc:(assert) -> Unit) -> Unit) -> Unit) {
val fail = "\u001b[31m" /* VT100 RED */
val pass = "\u001b[32m" /* VT100 GREEN */
val reset = "\u001b[0m" /* VT100 RESET */
var passed = 0
var failed = 0
main {name:String, proc:(assert) -> Unit ->
val ignore = tests.add(Test(name, proc))
}
println("\t$name\n---------------------------------")
for (test in tests) {
assert.result = true
beforeProc()
test.proc(assert)
afterProc()
if (assert.result) {
passed++
println("${pass}PASS${reset} <=> ${test.name}")
} else {
failed++
println("${fail}FAIL${reset} <=> ${test.name}")
println(" expected ${fail}[${reset}${assert.expected}${fail}]${reset}")
println(" actual ${fail}[${reset}${assert.actual}${fail}]${reset}")
}
}
doneProc()
println("---------------------------------")
println(" <====> Pass: $passed")
println(" <====> Fail: $failed\n\n")
}
}
No comments:
Post a Comment