Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Kotlin publishing and testing examples #3589

Merged
merged 2 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Kotlin publishing and testing examples
  • Loading branch information
0xnm committed Sep 22, 2024
commit 3ed9dfc6e5c5910db608ff059339694d03011c97
34 changes: 34 additions & 0 deletions example/kotlinlib/publishing/2-publish-module/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._, publish._

object foo extends KotlinModule with PublishModule {

def mainClass = Some("foo.FooKt")

def kotlinVersion = "1.9.24"

def publishVersion = "0.0.1"

def pomSettings = PomSettings(
description = "Hello",
organization = "com.lihaoyi",
url = "https://github.com/lihaoyi/example",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("lihaoyi", "example"),
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)
}

// This is an example `KotlinModule` with added publishing capabilities via
// `PublishModule`. This requires that you define an additional
// `publishVersion` and `pomSettings` with the relevant metadata, and provides
// the `.publishLocal` and `publishSigned` tasks for publishing locally to the
// machine or to the central maven repository

/** Usage

> mill foo.publishLocal
Publishing Artifact(com.lihaoyi,foo,0.0.1) to ivy repo...

*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package foo

fun main(args: Array<String>) = println("Hello World")
9 changes: 9 additions & 0 deletions example/kotlinlib/testing/1-test-suite/bar/src/bar/Bar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package bar

open class Bar {

fun hello(): String = "Hello World"

}

fun main(args: Array<String>) = println(Bar().hello())
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bar

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldStartWith
import io.kotest.matchers.string.shouldEndWith
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

class BarTests : FunSpec({

test("hello") {
val result = Bar().hello()
result shouldStartWith "Hello"
}

test("world") {
val result = Bar().hello()
result shouldEndWith "World"
}

test("mockito") {
val mockBar = mock<Bar>()

whenever(mockBar.hello()) doReturn "Hello Mockito World"

val result = mockBar.hello()

result shouldBe "Hello Mockito World"
verify(mockBar).hello()
}
})
44 changes: 44 additions & 0 deletions example/kotlinlib/testing/1-test-suite/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//// SNIPPET:BUILD1
package build
import mill._, kotlinlib._

object foo extends KotlinModule {

def mainClass = Some("foo.FooKt")

def kotlinVersion = "1.9.24"

object test extends KotlinModuleTests {
def testFramework = "com.github.sbt.junit.jupiter.api.JupiterFramework"
def ivyDeps = Agg(
ivy"com.github.sbt.junit:jupiter-interface:0.11.4",
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1",
ivy"org.mockito.kotlin:mockito-kotlin:5.4.0"
)

// This is needed because of the "mockito-kotlin"
def kotlincOptions = super.kotlincOptions() ++ Seq("-jvm-target", "11")
}
}
// This build defines a single module with a test suite, configured to use
// "JUnit" + "Kotest" as the testing framework, along with Mockito. Test suites are themselves
// ``KotlinModule``s, nested within the enclosing module,
//// SNIPPET:BUILD2

object bar extends KotlinModule {

def mainClass = Some("bar.BarKt")

def kotlinVersion = "1.9.24"

object test extends KotlinModuleTests with TestModule.Junit5 {
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1",
ivy"org.mockito.kotlin:mockito-kotlin:5.4.0"
)

// This is needed because of the "mockito-kotlin"
def kotlincOptions = super.kotlincOptions() ++ Seq("-jvm-target", "11")
}
}

9 changes: 9 additions & 0 deletions example/kotlinlib/testing/1-test-suite/foo/src/foo/Foo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package foo

open class Foo {

fun hello(): String = "Hello World"

}

fun main(args: Array<String>) = println(Foo().hello())
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package foo

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldStartWith
import io.kotest.matchers.string.shouldEndWith
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

class FooTests : FunSpec({

test("hello") {
val result = Foo().hello()
result shouldStartWith "Hello"
}

test("world") {
val result = Foo().hello()
result shouldEndWith "World"
}

test("mockito") {
val mockFoo = mock<Foo>()

whenever(mockFoo.hello()) doReturn "Hello Mockito World"

val result = mockFoo.hello()

result shouldBe "Hello Mockito World"
verify(mockFoo).hello()
}
})
5 changes: 5 additions & 0 deletions example/kotlinlib/testing/2-test-deps/baz/src/baz/Baz.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package baz

object Baz {
const val VALUE = 123
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package baz

object BazTestUtils {

fun bazAssertEquals(x: Any, y: Any) {
println("Using BazTestUtils.bazAssertEquals")
if (x != y) {
throw AssertionError("Expected $y, but got $x")
}
}
}
12 changes: 12 additions & 0 deletions example/kotlinlib/testing/2-test-deps/baz/test/src/baz/BazTests.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package baz

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import com.google.common.math.IntMath

class BazTests : FunSpec({

test("simple") {
BazTestUtils.bazAssertEquals(Baz.VALUE, IntMath.mean(122, 124))
}
})
30 changes: 30 additions & 0 deletions example/kotlinlib/testing/2-test-deps/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._

object qux extends KotlinModule {

def kotlinVersion = "1.9.24"

def moduleDeps = Seq(baz)

object test extends KotlinModuleTests with TestModule.Junit5 {
def moduleDeps = super.moduleDeps ++ Seq(baz.test)
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1",
ivy"com.google.guava:guava:33.3.0-jre"
)
}
}

object baz extends KotlinModule {

def kotlinVersion = "1.9.24"

object test extends KotlinModuleTests with TestModule.Junit5 {
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1",
ivy"com.google.guava:guava:33.3.0-jre"
)
}
}
5 changes: 5 additions & 0 deletions example/kotlinlib/testing/2-test-deps/qux/src/qux/Qux.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package qux

object Qux {
const val VALUE = "xyz"
}
12 changes: 12 additions & 0 deletions example/kotlinlib/testing/2-test-deps/qux/test/src/qux/QuxTests.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package qux

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import com.google.common.base.Ascii

class QuxTests : FunSpec({

test("simple") {
baz.BazTestUtils.bazAssertEquals(Ascii.toLowerCase("XYZ"), Qux.VALUE)
}
})
21 changes: 21 additions & 0 deletions example/kotlinlib/testing/3-integration-suite/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//// SNIPPET:BUILD3
package build
import mill._, kotlinlib._
object qux extends KotlinModule {

def kotlinVersion = "1.9.24"

object test extends KotlinModuleTests with TestModule.Junit5 {
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1"
)
}
object integration extends KotlinModuleTests with TestModule.Junit5 {
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1"
)
}
}

// The integration suite is just another regular test module within the parent KotlinModule
// (This example also demonstrates using Junit 5 instead of Junit 4)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package qux

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

class QuxIntegrationTests : FunSpec({

test("helloworld") {
val result = Qux.hello()
result shouldBe "Hello World"
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package qux

object Qux {
fun main(args: Array<String>) = println(hello())

fun hello(): String = "Hello World"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package qux

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldStartWith
import io.kotest.matchers.string.shouldEndWith

class QuxTests : FunSpec({

test("hello") {
val result = Qux.hello()
result shouldStartWith "Hello"
}

test("world") {
val result = Qux.hello()
result shouldEndWith "World"
}
})
12 changes: 12 additions & 0 deletions example/package.mill
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ object `package` extends RootModule with Module {
object builds extends Cross[ExampleCrossModuleKotlin](build.listIn(millSourcePath / "builds"))
object linting extends Cross[ExampleCrossModuleKotlin](build.listIn(millSourcePath / "linting"))
object module extends Cross[ExampleCrossModuleKotlin](build.listIn(millSourcePath / "module"))
object publishing extends Cross[ExampleCrossModuleKotlin](build.listIn(millSourcePath / "publishing"))
object testing extends Cross[ExampleCrossModuleKotlin](build.listIn(millSourcePath / "testing"))
}
object scalalib extends Module {
object basic extends Cross[ExampleCrossModule](build.listIn(millSourcePath / "basic"))
Expand Down Expand Up @@ -77,6 +79,16 @@ object `package` extends RootModule with Module {
.replace("bar.BarTests.escaping", "bar.BarTestsescaping")
case "4-builtin-commands" => line.replace("compile.dest/zinc", "compile.dest/kotlin.analysis.dummy")
case "5-resources" => line.replace("FooTests.simple", "FooTestssimple")
case "1-test-suite" => line
.replace("mill bar.test bar.BarTests.hello", "kotest_filter_tests='hello' kotest_filter_specs='bar.BarTests' ./mill bar.test")
.replace("FooTests.hello", "FooTestshello")
.replace("FooTests.world", "FooTestsworld")
.replace("BarTests.hello", "BarTestshello")
.replace("BarTests.world", "BarTestsworld")
.replace("compiling 1 ... source...", "Compiling 1 ... source...")
case "2-test-deps" => line
.replace("qux.QuxTests.simple", "qux.QuxTestssimple")
.replace("baz.BazTests.simple", "baz.BazTestssimple")
case _ => line
}
}
Expand Down
Loading