diff --git a/build-logic/src/main/kotlin/dfbuild.kotlinJvmCommon.gradle.kts b/build-logic/src/main/kotlin/dfbuild.kotlinJvmCommon.gradle.kts index e670be80ec..0e0544bf69 100644 --- a/build-logic/src/main/kotlin/dfbuild.kotlinJvmCommon.gradle.kts +++ b/build-logic/src/main/kotlin/dfbuild.kotlinJvmCommon.gradle.kts @@ -23,3 +23,7 @@ artifacts { builtBy(tasks.jar) } } + +dependencies { + testImplementation(project(":common-test-utils")) +} diff --git a/common-test-utils/README.md b/common-test-utils/README.md new file mode 100644 index 0000000000..6056bedf98 --- /dev/null +++ b/common-test-utils/README.md @@ -0,0 +1,3 @@ +## :common-test-utils + +This internal module contains shared test utilities. diff --git a/common-test-utils/build.gradle.kts b/common-test-utils/build.gradle.kts new file mode 100644 index 0000000000..659d97dbee --- /dev/null +++ b/common-test-utils/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + with(conventions.plugins.dfbuild) { + alias(kotlinJvm11) + } +} + +group = "org.jetbrains.kotlinx" + +dependencies { + api(projects.core) + + api(libs.kotestAssertions) { + exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8") + } + implementation(libs.kotlin.stdlib) + implementation(libs.kotlin.reflect) +} diff --git a/common-test-utils/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DebugUtils.kt b/common-test-utils/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DebugUtils.kt new file mode 100644 index 0000000000..452a0d2d03 --- /dev/null +++ b/common-test-utils/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DebugUtils.kt @@ -0,0 +1,45 @@ +package org.jetbrains.kotlinx.dataframe + +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.shouldBeInstanceOf +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.print +import org.jetbrains.kotlinx.dataframe.api.schema +import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup +import org.jetbrains.kotlinx.dataframe.columns.FrameColumn +import org.jetbrains.kotlinx.dataframe.io.renderToString +import kotlin.reflect.typeOf + +public fun > T.toDebugString(rowsLimit: Int = 20): String = + """ + ${renderToString(borders = true, title = true, columnTypes = true, valueLimit = -1, rowsLimit = rowsLimit)} + + ${schema()} + """.trimIndent() + +/** + * Prints dataframe to console with borders, title, column types and schema + */ +public fun > T.alsoDebug(println: String? = null, rowsLimit: Int = 20): T = + apply { + println?.let { println(it) } + print(borders = true, title = true, columnTypes = true, valueLimit = -1, rowsLimit = rowsLimit) + schema().print() + } + +public fun DataFrame<*>.shouldHaveColumnGroup(name: String, block: (ColumnGroup<*>) -> Unit = { }): ColumnGroup<*> = + getColumnOrNull(name).shouldBeInstanceOf>(block) + +public fun DataFrame<*>.shouldHaveFrameColumn(name: String, block: (FrameColumn<*>) -> Unit = { }): FrameColumn<*> = + getColumnOrNull(name).shouldBeInstanceOf>(block) + +public inline fun DataFrame<*>.shouldHaveColumn( + name: String, + block: (DataColumn) -> Unit = { }, +): DataColumn { + val shouldBeInstanceOf = getColumnOrNull(name).shouldBeInstanceOf>() + shouldBeInstanceOf.type() shouldBe typeOf() + val cast = shouldBeInstanceOf.cast() + block(cast) + return cast +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8c8d095df1..17e84351e5 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -69,6 +69,7 @@ dependencies { testImplementation(libs.kotestAssertions) { exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8") } + // kotest shouldBe forcefully escapes newlines when content is identical except additional newlines // which makes diff very hard to perceive. CodeGenerationTests.kt suffers from it a lot. using assertEquals there for working diff. testImplementation(kotlin("test")) diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/Utils.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/Utils.kt index 0f884a042f..f5bdc4e1b8 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/Utils.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/Utils.kt @@ -1,53 +1,10 @@ package org.jetbrains.kotlinx.dataframe -import io.kotest.matchers.shouldBe -import io.kotest.matchers.types.shouldBeInstanceOf -import org.jetbrains.kotlinx.dataframe.api.cast -import org.jetbrains.kotlinx.dataframe.api.print -import org.jetbrains.kotlinx.dataframe.api.schema -import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup -import org.jetbrains.kotlinx.dataframe.columns.FrameColumn -import org.jetbrains.kotlinx.dataframe.io.renderToString import org.jetbrains.kotlinx.dataframe.types.UtilTests import java.net.URL -import kotlin.reflect.typeOf fun testResource(resourcePath: String): URL = UtilTests::class.java.classLoader.getResource(resourcePath)!! fun testCsv(csvName: String) = testResource("$csvName.csv") fun testJson(jsonName: String) = testResource("$jsonName.json") - -fun > T.toDebugString(rowsLimit: Int = 20) = - """ - ${renderToString(borders = true, title = true, columnTypes = true, valueLimit = -1, rowsLimit = rowsLimit)} - - ${schema()} - """.trimIndent() - -/** - * Prints dataframe to console with borders, title, column types and schema - */ -fun > T.alsoDebug(println: String? = null, rowsLimit: Int = 20): T = - apply { - println?.let { println(it) } - print(borders = true, title = true, columnTypes = true, valueLimit = -1, rowsLimit = rowsLimit) - schema().print() - } - -fun DataFrame<*>.shouldHaveColumnGroup(name: String, block: (ColumnGroup<*>) -> Unit = { }): ColumnGroup<*> = - getColumnOrNull(name).shouldBeInstanceOf>(block) - -fun DataFrame<*>.shouldHaveFrameColumn(name: String, block: (FrameColumn<*>) -> Unit = { }): FrameColumn<*> = - getColumnOrNull(name).shouldBeInstanceOf>(block) - -inline fun DataFrame<*>.shouldHaveColumn( - name: String, - block: (DataColumn) -> Unit = { }, -): DataColumn { - val shouldBeInstanceOf = getColumnOrNull(name).shouldBeInstanceOf>() - shouldBeInstanceOf.type() shouldBe typeOf() - val cast = shouldBeInstanceOf.cast() - block(cast) - return cast -} diff --git a/dataframe-json/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/JsonTests.kt b/dataframe-json/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/JsonTests.kt index 6716f0a7b8..073f77f529 100644 --- a/dataframe-json/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/JsonTests.kt +++ b/dataframe-json/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/JsonTests.kt @@ -21,6 +21,7 @@ import org.intellij.lang.annotations.Language import org.jetbrains.kotlinx.dataframe.AnyFrame import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.alsoDebug import org.jetbrains.kotlinx.dataframe.api.FormattedFrame import org.jetbrains.kotlinx.dataframe.api.JsonPath import org.jetbrains.kotlinx.dataframe.api.allNulls @@ -34,7 +35,6 @@ import org.jetbrains.kotlinx.dataframe.api.format import org.jetbrains.kotlinx.dataframe.api.getColumnGroup import org.jetbrains.kotlinx.dataframe.api.getColumns import org.jetbrains.kotlinx.dataframe.api.getFrameColumn -import org.jetbrains.kotlinx.dataframe.api.print import org.jetbrains.kotlinx.dataframe.api.schema import org.jetbrains.kotlinx.dataframe.api.toFloat import org.jetbrains.kotlinx.dataframe.api.toMap @@ -1221,16 +1221,6 @@ fun parseJsonStr(jsonStr: String): JsonObject = Json.parseToJsonElement(jsonStr) fun testJson(jsonName: String) = testResource("$jsonName.json") -/** - * Prints dataframe to console with borders, title, column types and schema - */ -fun > T.alsoDebug(println: String? = null, rowsLimit: Int = 20): T = - apply { - println?.let { println(it) } - print(borders = true, title = true, columnTypes = true, valueLimit = -1, rowsLimit = rowsLimit) - schema().print() - } - internal val nothingType: KType = typeOf>().arguments.first().type!! internal val nullableNothingType: KType = typeOf>().arguments.first().type!! diff --git a/settings.gradle.kts b/settings.gradle.kts index 1ac37404eb..b09b2ec6e5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,3 +28,4 @@ include("dataframe-geo-jupyter") include("dataframe-openapi-generator") include("core") include("dataframe-compiler-plugin-core") +include("common-test-utils")