raniejade/kspec

Introduce lambda constructor parameter to shorten specification.

Opened this issue · 1 comments

Here is a small sample that introduces an intermediate class that shortens specification classes. We lose flexibility a bit (no way to change the runner via @RunWith) and it also clashes the name with the Spec interface. This was inspired by spekframework/spek#71.

import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import io.polymorphicpanda.kspec.KSpec
import io.polymorphicpanda.kspec.describe
import io.polymorphicpanda.kspec.it
import io.polymorphicpanda.kspec.junit.JUnitKSpecRunner
import org.junit.runner.RunWith

@RunWith(JUnitKSpecRunner::class)
open class Spec(private val definition: Spec.() -> Unit) : KSpec() {
    override fun spec() {
        definition()
    }
}

class ExampleSpec : Spec({
    describe("a group") {
        it("example") {
            assertThat(2 + 3, equalTo(5))
        }
    }
})

It does shorten it a bit but looks weird if you do shared examples like:

class CalculatorSpec: Specks({
    describe(Calculator::class) {
        itBehavesLike(calculator())
    } }) {
    companion object {
        fun calculator() = sharedExample<Calculator> {
            describe("add") {
                it("1 + 1 = 2") {
                    assertThat(subject.add(1, 1), equalTo(2))
                }
            }

            describe("minus") {
                it("1 - 1 = 0") {
                    assertThat(subject.minus(1, 1), equalTo(0))
                }
            }

            describe("multiply") {
                it("1 * 2 = 2") {
                    assertThat(subject.multiply(1, 2), equalTo(2))
                }
            }

            describe("divide") {
                it("10 / 5 = 2") {
                    assertThat(subject.divide(10, 5), equalTo(2))
                }
            }
        }
    }
}

Declaring it somewhere else would fix it. #17 added support for filtering based on tags (another new feature) which can be configured by overriding KSpec.configure. This will add to the weirdness again.

class TestSpec: KSpec() {
    override fun configure(config: KSpecConfig) {
        ...
    }

   ...
}

Personally I still prefer the current approach, instance properties and methods might come in handy in the future.