-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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 specific assertion helpers #1001
Changes from 24 commits
2d6ca09
451930e
b5279aa
7c9102c
43c956e
d995cde
bc0c5e3
05f037a
e580a04
1a0bce3
ee5db7d
514318c
869d4eb
c638df6
6bf57fa
9a76a15
b3ab661
893adba
efebdd8
0cc09cb
78a62bb
2007a89
b0bfc63
99b7569
0fa5c98
e226327
6fdbf08
a726c91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,16 @@ are `static` methods in the `{Assertions}` class. | |
include::{testDir}/example/AssertionsDemo.java[tags=user_guide] | ||
---- | ||
|
||
Junit Jupiter also comes with a few assertion methods that lend themselves well to being | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
used in https://kotlinlang.org/[Kotlin]. All JUnit Jupiter Kotlin assertions are top-level | ||
functions in the `org.junit.jupiter.api` package. | ||
|
||
// TODO: Change to using kotlin language highlighting after switch to rouge syntax highlighter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the status of switching to the rouge syntax highlighter? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still blocked by asciidoctor/asciidoctor#1040. |
||
[source,java,indent=0] | ||
---- | ||
include::{kotlinTestDir}/example/AssertionsDemoKotlin.kt[tags=user_guide] | ||
---- | ||
|
||
[[writing-tests-assertions-third-party]] | ||
==== Third-party Assertion Libraries | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,23 +143,3 @@ private static String greeting() { | |
} | ||
// end::user_guide[] | ||
// @formatter:on | ||
|
||
class Person { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't access this class in |
||
|
||
private final String firstName; | ||
private final String lastName; | ||
|
||
Person(String firstName, String lastName) { | ||
this.firstName = firstName; | ||
this.lastName = lastName; | ||
} | ||
|
||
String getFirstName() { | ||
return firstName; | ||
} | ||
|
||
String getLastName() { | ||
return lastName; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright 2015-2017 the original author or authors. | ||
* | ||
* All rights reserved. This program and the accompanying materials are | ||
* made available under the terms of the Eclipse Public License v2.0 which | ||
* accompanies this distribution and is available at | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
package example | ||
|
||
// tag::user_guide[] | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.assertAll | ||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Assertions.assertTrue | ||
import org.junit.jupiter.api.assertThrows | ||
|
||
class AssertionsDemoKotlin { | ||
|
||
// end::user_guide[] | ||
val person = Person("John", "Doe") | ||
val people = setOf(person, Person("James", "Doe")) | ||
|
||
// tag::user_guide[] | ||
@Test | ||
fun `grouped assertions`() { | ||
assertAll("person", | ||
{ assertEquals("John", person.firstName) }, | ||
{ assertEquals("Doe", person.lastName) } | ||
) | ||
} | ||
|
||
@Test | ||
fun `exception testing`() { | ||
val exception = assertThrows<IllegalArgumentException> ("Should throw an exception") { | ||
throw IllegalArgumentException("a message") | ||
} | ||
assertEquals("a message", exception.message) | ||
} | ||
|
||
@Test | ||
fun `assertions from a stream`() { | ||
assertAll( | ||
"people with name starting with J", | ||
people | ||
.stream() | ||
.map { | ||
// This mapping returns Stream<() -> Unit> | ||
{ assertTrue(it.firstName.startsWith("J")) } | ||
} | ||
) | ||
} | ||
} | ||
// end::user_guide[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright 2015-2017 the original author or authors. | ||
* | ||
* All rights reserved. This program and the accompanying materials are | ||
* made available under the terms of the Eclipse Public License v2.0 which | ||
* accompanies this distribution and is available at | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
package example | ||
|
||
data class Person(val firstName: String, val lastName: String) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,32 @@ | ||
dependencies { | ||
api("org.opentest4j:opentest4j:${ota4jVersion}") | ||
api(project(':junit-platform-commons')) | ||
api(project(":junit-platform-commons")) | ||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib") | ||
} | ||
|
||
jar { | ||
manifest { | ||
attributes( | ||
'Automatic-Module-Name': 'org.junit.jupiter.api' | ||
'Automatic-Module-Name': 'org.junit.jupiter.api' | ||
) | ||
} | ||
} | ||
|
||
configurations { | ||
apiElements { | ||
/* | ||
* Needed to configure kotlin to work correctly with the "java-library" plugin. | ||
* See: | ||
* https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_known_issues | ||
* https://youtrack.jetbrains.com/issue/KT-18497 | ||
*/ | ||
outgoing | ||
.variants | ||
.getByName("classes") | ||
.artifact( | ||
"file" : compileKotlin.destinationDir, | ||
"type" : "java-classes-directory", | ||
"builtBy" : compileKotlin | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The compiler will generate a class called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's fine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool! |
||
* Copyright 2015-2017 the original author or authors. | ||
* | ||
* All rights reserved. This program and the accompanying materials are | ||
* made available under the terms of the Eclipse Public License v2.0 which | ||
* accompanies this distribution and is available at | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though this file is called This will require some monkeying with spotless due to this issue: Does the team mind that the kotlin compiler just generates a class and uses its own naming convention? If not then I don't need to worry about the spotless bug. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this naming convention likely to change in the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, it shouldn't. |
||
@file:API(status = EXPERIMENTAL, since = "5.1") | ||
package org.junit.jupiter.api | ||
|
||
import org.apiguardian.api.API | ||
import org.apiguardian.api.API.Status.EXPERIMENTAL | ||
import org.junit.jupiter.api.function.Executable | ||
import java.util.function.Supplier | ||
import java.util.stream.Stream | ||
|
||
/** | ||
* [Stream] of functions to be executed. | ||
*/ | ||
internal typealias ExecutableStream = Stream<() -> Unit> | ||
internal fun ExecutableStream.convert() = map { Executable(it) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make these private? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Effectively they are. I can make them private if you wish though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I was able to make them private. |
||
|
||
/** | ||
* @see Assertions.assertAll | ||
*/ | ||
fun assertAll(executables: ExecutableStream) = | ||
Assertions.assertAll(executables.convert()) | ||
|
||
/** | ||
* @see Assertions.assertAll | ||
*/ | ||
fun assertAll(heading: String?, executables: ExecutableStream) = | ||
Assertions.assertAll(heading, executables.convert()) | ||
|
||
/** | ||
* @see Assertions.assertAll | ||
*/ | ||
fun assertAll(vararg executables: () -> Unit) = | ||
assertAll(executables.toList().stream()) | ||
|
||
/** | ||
* @see Assertions.assertAll | ||
*/ | ||
fun assertAll(heading: String?, vararg executables: () -> Unit) = | ||
assertAll(heading, executables.toList().stream()) | ||
|
||
/** | ||
* Example usage: | ||
* ```kotlin | ||
* val exception = assertThrows<IllegalArgumentException> { | ||
* throw IllegalArgumentException("Talk to a duck") | ||
* } | ||
* assertEquals("Talk to a duck", exception.message) | ||
* ``` | ||
* @see Assertions.assertThrows | ||
*/ | ||
inline fun <reified T : Throwable> assertThrows(noinline executable: () -> Unit): T = | ||
Assertions.assertThrows(T::class.java, Executable(executable)) | ||
|
||
/** | ||
* Example usage: | ||
* ```kotlin | ||
* val exception = assertThrows<IllegalArgumentException>("Should throw an Exception") { | ||
* throw IllegalArgumentException("Talk to a duck") | ||
* } | ||
* assertEquals("Talk to a duck", exception.message) | ||
* ``` | ||
* @see Assertions.assertThrows | ||
*/ | ||
inline fun <reified T : Throwable> assertThrows(message: String, noinline executable: () -> Unit): T = | ||
assertThrows({ message }, executable) | ||
|
||
/** | ||
* Example usage: | ||
* ```kotlin | ||
* val exception = assertThrows<IllegalArgumentException>({ "Should throw an Exception" }) { | ||
* throw IllegalArgumentException("Talk to a duck") | ||
* } | ||
* assertEquals("Talk to a duck", exception.message) | ||
* ``` | ||
* @see Assertions.assertThrows | ||
*/ | ||
inline fun <reified T : Throwable> assertThrows(noinline message: () -> String, noinline executable: () -> Unit): T = | ||
Assertions.assertThrows(T::class.java, Executable(executable), Supplier { | ||
/* | ||
* This is a hacky workaround due to a bug in how the JDK 9 JavaDoc code generator interacts with the | ||
* generated Kotlin Bytecode. | ||
* https://youtrack.jetbrains.com/issue/KT-20025 | ||
*/ | ||
message() | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ktlint is the only kotlin linter that exists at present. I use it for all of my projects and it's pretty nice.
If you want to have it use tabs instead of spaces for indentation it can be configured using an
.editorconfig
file in the root directory of the project.