0

I am using IntelliJ and Maven, have downloaded the Kotest plugin, and I have added the dependencies to pom.xml (kotest-runner-junit5-jvm, kotest-assertions-core-jvm, kotest-property-jvm, all version 5.5.0).

The following basic example is working:

class MyFirstTestClass : FunSpec({
    test("my first test") {
        1 + 2 shouldBe 3
    }
})

But I cannot make another example work, the PythagTriple:

import io.kotest.core.spec.style.FunSpec
import io.kotest.core.spec.style.StringSpec
import io.kotest.data.forAll
import io.kotest.matchers.shouldBe

data class PythagoreanTriple(
    val a: Int,
    val b: Int,
    val c: Int
)

class MyTests : FunSpec({
    context("Pythagorean triples tests") {
        forAll(
            PythagoreanTriple(3, 4, 5),
            PythagoreanTriple(6, 8, 10),
            PythagoreanTriple(8, 15, 17),
            PythagoreanTriple(7, 24, 25)
        ) { (a, b, c) ->
            isPythagoreanTriple(a, b, c) shouldBe true
        }
    }
})

fun isPythagoreanTriple(a: Int, b: Int, c: Int): Boolean = a * a + b * b == c * c

I could find two variants of this example, one using forAll, the other using withData. Both do not work.

There seem to be two problems:

(1)

Kotlin: None of the following functions can be called with the arguments supplied: 
public suspend fun <A> forAll(vararg rows: Row1<TypeVariable(A)>, testfn: suspend (TypeVariable(A)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B> forAll(vararg rows: Row2<TypeVariable(A), TypeVariable(B)>, testfn: suspend (TypeVariable(A), TypeVariable(B)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C> forAll(vararg rows: Row3<TypeVariable(A), TypeVariable(B), TypeVariable(C)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D> forAll(vararg rows: Row4<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D, E> forAll(vararg rows: Row5<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D, E, F> forAll(vararg rows: Row6<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D, E, F, G> forAll(vararg rows: Row7<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D, E, F, G, H> forAll(vararg rows: Row8<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G), TypeVariable(H)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G), TypeVariable(H)) -> Unit): Unit defined in io.kotest.data
public suspend fun <A, B, C, D, E, F, G, H, I> forAll(vararg rows: Row9<TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G), TypeVariable(H), TypeVariable(I)>, testfn: suspend (TypeVariable(A), TypeVariable(B), TypeVariable(C), TypeVariable(D), TypeVariable(E), TypeVariable(F), TypeVariable(G), TypeVariable(H), TypeVariable(I)) -> Unit): Unit defined in io.kotest.data

Using withData just leads to Unresolved reference: withData, and I haven't found an import.

(2)

Kotlin: Cannot infer a type for this parameter. Please specify it explicitly.

This seems to refer to the following:

        { **(a, b, c)** ->
            isPythagoreanTriple(a, b, c) shouldBe true
        }

These must be some basic problems I was unable to solve, given I am a newbie. Any help would be very much appreciated.

LeoColman
  • 6,950
  • 7
  • 34
  • 63
Daniel
  • 1
  • 1

1 Answers1

0

There are 3 mistakes making your test not work:

  1. Your test setup does not contain a test, but only a context. This can simply be solved by changing the context into a test.
  2. You should not use your own data type for the forAll-rows, but as the message in (1) suggests, the different variants of forAll are defined for data types Row1, Row2, Row3, and so on. Each of them can be created with row(...). (There is one row function for each arity from 1 to 14.)
  3. The variants of forEach do not specify a function with one RowX parameter, but a function with X parameters of types that are the parameter types of RowX. Therefore, it is not correct that the parameters a, b, c are surrounded by parentheses - which is a notation for destructuring one parameter into its components.

Altogether your test works when you change it in the following way:

class PythagoreanTripleTest : FunSpec({
    test("Pythagorean triples tests") {
        forAll(
            row(3, 4, 5),
            row(6, 8, 10),
            row(8, 15, 17),
            row(7, 24, 25)
        ) { a, b, c ->
            isPythagoreanTriple(a, b, c) shouldBe true
        }
    }
})
Karsten Gabriel
  • 3,115
  • 6
  • 19