Add kotlin.test library

This commit is contained in:
Sergey Mashkov
2015-11-24 15:17:42 +03:00
parent dd36ef5712
commit 1867abbbe7
27 changed files with 1526 additions and 0 deletions
@@ -25,6 +25,12 @@
<artifactId>kotlin-js-library-example</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.jvm</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!-- testing -->
<dependency>
@@ -20,6 +20,12 @@
<artifactId>kotlin-js-library</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.jvm</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!-- testing -->
<dependency>
+90
View File
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test.js</artifactId>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-test-resources</phase>
<configuration>
<includeScope>test</includeScope>
<includeTypes>jar</includeTypes>
<outputDirectory>${project.basedir}/target/test-js</outputDirectory>
<includes>*.js</includes>
<excludes>*.meta.js</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<executions>
<execution>
<id>install node and npm</id>
<!--<phase>generate-test-resources</phase>-->
<phase>none</phase>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
</configuration>
</execution>
<execution>
<id>npm install</id>
<!--<phase>generate-test-resources</phase>-->
<phase>none</phase>
<goals>
<goal>npm</goal>
</goals>
<!-- Optional configuration which provides for running any npm command -->
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>javascript tests</id>
<goals>
<goal>karma</goal>
</goals>
<!-- disable js tests -->
<phase>none</phase>
<configuration>
<karmaConfPath>${project.basedir}/src/test/karma/karma.conf.js</karmaConfPath>
</configuration>
</execution>
</executions>
<configuration>
<nodeVersion>v0.12.7</nodeVersion>
<npmVersion>2.14.4</npmVersion>
<workingDirectory>${project.basedir}/src/test/karma</workingDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module.exports = function (config) {
config.set({
frameworks: ['qunit'],
reporters: ['progress', 'junit'],
files: [
'../../../target/test-js/kotlin.js',
'../../../target/test-js/*.js',
'../../../target/classes/*.js'
],
exclude: [],
port: 9876,
runnerPort: 9100,
colors: true,
autoWatch: false,
browsers: [
'PhantomJS'
],
captureTimeout: 5000,
//singleRun: false,
singleRun: true,
reportSlowerThan: 500,
junitReporter: {
outputFile: '../../../target/reports/test-results.xml',
suite: ''
},
preprocessors: {
'**/*.js': ['sourcemap']
}
}
)
};
@@ -0,0 +1,14 @@
{
"name": "karma-tests",
"version": "0.0.0",
"devDependencies": {
"karma": "*",
"qunitjs": "*",
"karma-qunit": "*",
"karma-junit-reporter": "~0.2",
"karma-sourcemap-loader": "~0.3",
"karma-teamcity-reporter": "*",
"karma-phantomjs-launcher": "*",
"phantomjs": "1.9.13"
}
}
+107
View File
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test.jvm</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>(4,5)</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.shared</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-js-library</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/assembly/sources.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<forceCreation>true</forceCreation>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<archive>
<forced />
<manifestEntries>
<Built-By>${user.name}</Built-By>
<Implementation-Vendor>JetBrains s.r.o.</Implementation-Vendor>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>${project.basedir}/src/main/kotlin</dir>
<dir>${project.basedir}/src/main/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>${project.basedir}/src/test/kotlin</dir>
<dir>${project.basedir}/src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,46 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>sources</id>
<formats>
<format>jar</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>../shared/src/main/kotlin</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>../shared/src/main/kotlin.jvm</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>src/main/kotlin</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
</fileSets>
</assembly>
@@ -0,0 +1,41 @@
package kotlin.test.junit
import org.junit.*
import kotlin.test.*
class JUnitContributor : AsserterContributor {
override fun contribute(): Asserter? {
for (stackFrame in currentStackTrace()) {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
val className = stackFrame.className as java.lang.String
if (className.startsWith("org.junit.") || className.startsWith("junit.")) {
return JUnitAsserter
}
}
return null
}
}
object JUnitAsserter : Asserter {
override fun assertEquals(message : String?, expected : Any?, actual : Any?) {
Assert.assertEquals(message, expected, actual)
}
override fun assertNotEquals(message : String?, illegal : Any?, actual : Any?) {
Assert.assertNotEquals(message, illegal, actual)
}
override fun assertNotNull(message : String?, actual : Any?) {
Assert.assertNotNull(message ?: "actual value is null", actual)
}
override fun assertNull(message : String?, actual : Any?) {
Assert.assertNull(message ?: "actual value is not null", actual)
}
override fun fail(message : String?) {
Assert.fail(message)
}
}
@@ -0,0 +1 @@
kotlin.test.junit.JUnitContributor
@@ -0,0 +1,27 @@
package kotlinx.testing.tests
import org.junit.*
import java.util.concurrent.*
class JUnitContributorTest {
@Test
fun smokeTest() {
Assert.assertEquals("JUnitAsserter", asserter.`class`.simpleName)
}
@Test
fun `should fail to contribute if it was run outside of junit`() {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
val q = ArrayBlockingQueue<java.lang.Object>(1)
Thread {
q.put(asserter)
}.start()
Assert.assertEquals("DefaultAsserter", q.take().`class`.simpleName)
}
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
private val asserter: java.lang.Object
get() = Class.forName("kotlin.test.TestAssertionsKt").getMethod("getAsserter").invoke(null) as java.lang.Object
}
+114
View File
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-project</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>kotlin.test</artifactId>
<packaging>pom</packaging>
<modules>
<module>shared</module>
<module>jvm</module>
<!--<module>js</module>--> <!-- TODO enable back when js build fixed -->
</modules>
<developers>
<developer>
<name>Sergey Mashkov</name>
<organization>JetBrains s.r.o.</organization>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
<properties>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-js-library</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${project.version}</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<forkCount>2C</forkCount>
<reuseForks>true</reuseForks>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>0.0.26</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>kotlin-jvm</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>kotlin-js</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
</project>
+148
View File
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test.shared</artifactId>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/assembly/sources.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>kotlin-js</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-js-library
</artifactId> <!-- TODO including this causes compilation to fail due to resolution ambiguity -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>test-compile-js</id>
<phase>test-compile</phase>
<goals>
<goal>test-js</goal>
</goals>
<configuration>
<sourceDirs>
<dir>${project.basedir}/src/test/kotlin</dir>
<dir>${project.basedir}/src/test/kotlin.js</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>js-compile</id>
<phase>compile</phase>
<goals>
<goal>js</goal>
</goals>
<configuration>
<outputFile>${project.build.outputDirectory}/${project.artifactId}.js</outputFile>
<sourceDirs>
<dir>${project.basedir}/src/main/kotlin</dir>
<dir>${project.basedir}/src/main/kotlin.js</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>kotlin-jvm</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-runtime</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>${project.basedir}/src/main/kotlin</dir>
<dir>${project.basedir}/src/main/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>${project.basedir}/src/test/kotlin</dir>
<dir>${project.basedir}/src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -0,0 +1,46 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>sources</id>
<formats>
<format>jar</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>src/main/kotlin</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>src/main/kotlin.jvm</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
<fileSet>
<filtered>true</filtered>
<lineEnding>unix</lineEnding>
<directory>src/main/kotlin.js</directory>
<outputDirectory/>
<includes>
<include>**/*.kt</include>
</includes>
</fileSet>
</fileSets>
</assembly>
@@ -0,0 +1,53 @@
package kotlin.test
import java.util.*
import java.util.concurrent.atomic.*
import java.util.concurrent.locks.*
private val inited = AtomicBoolean()
private val lock = ReentrantLock()
private val contributors = ArrayList<AsserterContributor>()
internal fun lookup(): Asserter {
initContributorsIfNeeded()
for (contributor in contributors) {
val asserter = contributor.contribute()
if (asserter != null) {
return asserter
}
}
return DefaultAsserter()
}
private fun initContributors() {
contributors.clear()
@Suppress("DEPRECATION")
val loader = ServiceLoader.load(AsserterContributor::class.javaClass)
for (contributor in loader) {
if (contributor != null) {
contributors.add(contributor)
}
}
}
private fun initContributorsIfNeeded() {
if (!inited.get()) {
lock.withLock {
if (inited.compareAndSet(false, true)) {
initContributors()
}
}
}
}
private inline fun Lock.withLock(block: () -> Unit) {
lockInterruptibly()
try {
block()
} finally {
unlock()
}
}
@@ -0,0 +1,68 @@
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("TestAssertionsKt")
package kotlin.test
import kotlin.jvm.internal.*
import kotlin.reflect.*
@Deprecated("Use assertFailsWith instead.", ReplaceWith("assertFailsWith(exceptionClass, block)"), kotlin.DeprecationLevel.ERROR)
fun <T : Throwable> failsWith(exceptionClass: Class<T>, block: () -> Any): T = assertFailsWith(exceptionClass, { block() })
/** Asserts that a [block] fails with a specific exception being thrown. */
fun <T : Throwable> assertFailsWith(exceptionClass: Class<T>, block: () -> Unit): T = assertFailsWith(exceptionClass, null, block)
/** Asserts that a [block] fails with a specific exception being thrown. */
fun <T : Throwable> assertFailsWith(exceptionClass: Class<T>, message: String?, block: () -> Unit): T {
try {
block()
} catch (e: Throwable) {
if (exceptionClass.isInstance(e)) {
@Suppress("UNCHECKED_CAST")
return e as T
}
asserter.fail((message?.let { "$it. " } ?: "") + "Expected an exception of type $exceptionClass to be thrown, but was $e")
throw e
}
val msg = message?.let { "$it. " } ?: ""
asserter.fail(msg + "Expected an exception of type $exceptionClass to be thrown, but was completed successfully.")
throw IllegalStateException(msg + "Should have failed.")
}
/** Asserts that a [block] fails with a specific exception of type [exceptionClass] being thrown. */
@Suppress("DEPRECATION")
fun <T : Throwable> assertFailsWith(exceptionClass: KClass<T>, message: String? = null, block: () -> Unit): T = assertFailsWith(exceptionClass.javaClass, message, block)
/** Asserts that a [block] fails with a specific exception of type [T] being thrown.
* Since inline method doesn't allow to trace where it was invoked, it is required to pass a [message] to distinguish this method call from others.
*/
@Suppress("DEPRECATION")
inline fun <reified T : Throwable> assertFailsWith(message: String, noinline block: () -> Unit): T = assertFailsWith(T::class.javaClass, message, block)
/**
* Comments out a [block] of test code until it is implemented while keeping a link to the code
* to implement in your unit test output
*/
inline fun todo(@Suppress("UNUSED_PARAMETER") block: () -> Unit) {
System.out.println("TODO at " + currentStackTrace()[1])
}
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE")
inline fun currentStackTrace() = (java.lang.Exception() as java.lang.Throwable).stackTrace
/**
* The active implementation of [Asserter]. An implementation of [Asserter] can be provided
* using the [Java service loader](http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html) mechanism.
*/
val asserter: Asserter
get() = lookup()
/**
* Returns a Java [Class] instance corresponding to the given [KClass] instance.
*/
@Suppress("UNCHECKED_CAST")
@Intrinsic("kotlin.KClass.java.property")
@Deprecated("This is for internal use only", ReplaceWith("this.java"), kotlin.DeprecationLevel.WARNING)
val <T : Any> KClass<T>.javaClass: Class<T>
get() = (this as ClassBasedDeclarationContainer).jClass as Class<T>
@@ -0,0 +1,10 @@
package kotlin.internal
/**
* The value of this type parameter should be mentioned in input types (argument types, receiver type or expected type).
*/
@Target(AnnotationTarget.TYPE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
internal annotation class OnlyInputTypes
@@ -0,0 +1,25 @@
package kotlin.jvm
/**
* Specifies the name for the Java class or method
* which is generated from this element.
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/java-interop.html#handling-signature-clashes-with-platformname)
* for more information.
* @property name the name of the element.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FILE)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
public annotation class JvmName(public val name: String)
/**
* Instructs the Kotlin compiler to generate a multifile class with top-level functions and properties declared in this file as one of its parts.
* Name of the corresponding multifile class is provided by the [JvmName] annotation.
*/
@Target(AnnotationTarget.FILE)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
public annotation class JvmMultifileClass
@@ -0,0 +1,133 @@
package kotlin.test
import java.util.*
class CollectionAssertionSession<E, C: Iterable<E>>(val collection: C)
inline fun <E, C: Iterable<E>> assert(collection: C, block: CollectionAssertionSession<E, C>.() -> Unit) {
CollectionAssertionSession(collection).block()
}
fun <C: Collection<*>> CollectionAssertionSession<*, C>.sizeShouldBe(expectedSize: Int, message: String? = null) {
assertEquals(expectedSize, collection.size, message ?: "collection should have size $expectedSize but it is ${collection.size}")
}
fun <T> CollectionAssertionSession<T, *>.elementAtShouldBe(position: Int, expected: T, message: String? = null) {
assertEquals(expected, collection.elementAt(position), message ?: "element at $position should be $expected")
}
fun <T, C: Iterable<T>> CollectionAssertionSession<T, C>.elementAtShouldComply(position: Int, message: String? = null, predicate: (T) -> Boolean) {
assertTrue(message) { predicate(collection.elementAt(position)) }
}
fun <T> CollectionAssertionSession<T, *>.lastElementShouldBe(expected: T, message: String? = null) {
assertEquals(expected, collection.last(), message ?: "the last element should be $expected")
}
fun <T> CollectionAssertionSession<T, *>.containsAll(vararg elements: T) {
for (e in elements) {
assertTrue(message = "Element $e is missing in the collection") { e in collection }
}
}
fun <T, C: Iterable<T>> CollectionAssertionSession<T, C>.shouldBe(expectedElements: Iterable<T>, message: String? = null) {
val actual = collection.iterator()
val expected = expectedElements.iterator()
while (actual.hasNext() && expected.hasNext()) {
assertEquals(expected.next(), actual.next(), message)
}
if (actual.hasNext()) {
fail("Actual collection is longer than expected. Extra elements are: ${actual.remaining()}")
}
if (expected.hasNext()) {
fail("Actual collection is shorter than expected. Missing elements are: ${expected.remaining()}")
}
}
fun <T, C: Set<T>> CollectionAssertionSession<T, C>.shouldBeSet(other: Set<T>, message: String? = null) {
for (e in other) {
if (e !in collection) {
fail(message ?: "Element $e in not in the collection $collection")
}
}
for (e in collection) {
if (e !in other) {
fail(message ?: "Element $e is not expected")
}
}
}
fun <T, C: Set<T>> CollectionAssertionSession<T, C>.shouldBeSet(vararg other: T) {
val otherSet = HashSet<T>()
for (e in other) {
otherSet.add(e)
}
shouldBeSet(otherSet)
}
private operator fun <T> Iterable<T>.contains(e: T): Boolean {
if (this is Set<T>) {
return contains(e)
}
for (it in this) {
if (it == e) {
return true
}
}
return false
}
private fun <T> Iterable<T>.last(): T {
if (this is List<T>) {
if (this.isEmpty()) {
throw NoSuchElementException()
}
return this[size - 1]
}
val it = iterator()
var result: T = iterator().next()
while (it.hasNext()) {
result = it.next()
}
return result
}
private fun <T> Iterable<T>.elementAt(position: Int): T {
if (position < 0) {
throw IllegalArgumentException("position shouldn't be negative: $position")
}
if (this is List<T>) {
return this[position]
}
val iterator = iterator()
var idx = 0
do {
if (!iterator.hasNext()) {
throw IndexOutOfBoundsException("index $position is out of the collection bounds [0; $idx)")
}
val result = iterator.next()
if (idx == position) {
return result
}
idx++
} while (true)
throw IllegalStateException()
}
private fun <T> Iterator<T>.remaining(): List<T> {
val result = ArrayList<T>()
while (hasNext()) {
result.add(next())
}
return result
}
@@ -0,0 +1,14 @@
package kotlin.test
/**
* Default [Asserter] implementation to avoid dependency on JUnit or TestNG.
*/
class DefaultAsserter() : Asserter {
override fun fail(message: String?) {
if (message == null)
throw AssertionError()
else
throw AssertionError(message)
}
}
@@ -0,0 +1,187 @@
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("TestAssertionsKt")
/**
* A number of helper methods for writing unit tests.
*/
package kotlin.test
import kotlin.internal.*
/** Asserts that the given [block] returns `false`. */
@Deprecated("Use assertFalse instead.", ReplaceWith("assertFalse(message, block)"), kotlin.DeprecationLevel.ERROR)
fun assertNot(message: String, block: () -> Boolean): Unit = assertFalse(message, block)
/** Asserts that the given [block] returns `false`. */
@Deprecated("Use assertFalse instead.", ReplaceWith("assertFalse(null, block)"), kotlin.DeprecationLevel.ERROR)
fun assertNot(block: () -> Boolean): Unit = assertFalse(block = block)
/** Asserts that the given [block] returns `true`. */
fun assertTrue(message: String? = null, block: () -> Boolean): Unit = assertTrue(block(), message)
/** Asserts that the expression is `true` with an optional [message]. */
fun assertTrue(actual: Boolean, message: String? = null) {
return asserter.assertTrue(message ?: "Expected value to be true.", actual)
}
/** Asserts that the given [block] returns `false`. */
fun assertFalse(message: String? = null, block: () -> Boolean): Unit = assertFalse(block(), message)
/** Asserts that the expression is `false` with an optional [message]. */
fun assertFalse(actual: Boolean, message: String? = null) {
return asserter.assertTrue(message ?: "Expected value to be false.", !actual)
}
/** Asserts that the [expected] value is equal to the [actual] value, with an optional [message]. */
fun <@OnlyInputTypes T> assertEquals(expected: T, actual: T, message: String? = null) {
asserter.assertEquals(message, expected, actual)
}
/** Asserts that the [actual] value is not equal to the illegal value, with an optional [message]. */
fun <@OnlyInputTypes T> assertNotEquals(illegal: T, actual: T, message: String? = null) {
asserter.assertNotEquals(message, illegal, actual)
}
/** Asserts that the [actual] value is not `null`, with an optional [message]. */
fun <T : Any> assertNotNull(actual: T?, message: String? = null): T {
asserter.assertNotNull(message, actual)
return actual!!
}
/** Asserts that the [actual] value is not `null`, with an optional [message] and a function [block] to process the not-null value. */
fun <T : Any, R> assertNotNull(actual: T?, message: String? = null, block: (T) -> R) {
asserter.assertNotNull(message, actual)
if (actual != null) {
block(actual)
}
}
/** Asserts that the [actual] value is `null`, with an optional [message]. */
fun assertNull(actual: Any?, message: String? = null) {
asserter.assertNull(message, actual)
}
/** Marks a test as having failed if this point in the execution path is reached, with an optional [message]. */
fun fail(message: String? = null) {
asserter.fail(message)
}
/** Asserts that given function [block] returns the given [expected] value. */
fun <@OnlyInputTypes T> expect(expected: T, block: () -> T) {
assertEquals(expected, block())
}
/** Asserts that given function [block] returns the given [expected] value and use the given [message] if it fails. */
fun <@OnlyInputTypes T> expect(expected: T, message: String?, block: () -> T) {
assertEquals(expected, block(), message)
}
@Deprecated("Use assertFails instead.", ReplaceWith("assertFails(block)"), kotlin.DeprecationLevel.ERROR)
fun fails(block: () -> Unit): Throwable? = assertFails(block)
/** Asserts that given function [block] fails by throwing an exception. */
fun assertFails(block: () -> Unit): Throwable? {
var thrown: Throwable? = null
try {
block()
} catch (e: Throwable) {
thrown = e
}
if (thrown == null)
asserter.fail("Expected an exception to be thrown")
return thrown
}
/**
* Abstracts the logic for performing assertions. Specific implementations of [Asserter] can use JUnit
* or TestNG assertion facilities.
*/
interface Asserter {
/**
* Fails the current test with the specified message.
*
* @param message the message to report.
*/
fun fail(message: String?): Unit
/**
* Asserts that the specified value is `true`.
*
* @param lazyMessage the function to return a message to report if the assertion fails.
*/
fun assertTrue(lazyMessage: () -> String?, actual: Boolean): Unit {
if (!actual) {
fail(lazyMessage())
}
}
/**
* Asserts that the specified value is `true`.
*
* @param message the message to report if the assertion fails.
*/
fun assertTrue(message: String?, actual: Boolean): Unit {
assertTrue({ message }, actual)
}
/**
* Asserts that the specified values are equal.
*
* @param message the message to report if the assertion fails.
*/
fun assertEquals(message: String?, expected: Any?, actual: Any?): Unit {
assertTrue({ (message?.let { "$it. " } ?: "") + "Expected <$expected>, actual <$actual>." }, actual == expected)
}
/**
* Asserts that the specified values are not equal.
*
* @param message the message to report if the assertion fails.
*/
fun assertNotEquals(message: String?, illegal: Any?, actual: Any?): Unit {
assertTrue({ (message?.let { "$it. " } ?: "") + "Illegal value: <$actual>." }, actual != illegal)
}
/**
* Asserts that the specified value is `null`.
*
* @param message the message to report if the assertion fails.
*/
fun assertNull(message: String?, actual: Any?): Unit {
assertTrue({ (message?.let { "$it. " } ?: "") + "Expected value to be null, but was: <$actual>." }, actual == null)
}
/**
* Asserts that the specified value is not `null`.
*
* @param message the message to report if the assertion fails.
*/
fun assertNotNull(message: String?, actual: Any?): Unit {
assertTrue({ (message?.let { "$it. " } ?: "") + "Expected value to be not null." }, actual != null)
}
}
/**
* Checks applicability and provides Asserter instance
*/
interface AsserterContributor {
/**
* Provides [Asserter] instance or `null` depends on the current context.
*
* @return asserter instance or null if it is not applicable now
*/
fun contribute(): Asserter?
}
internal fun <T, R> T.let(block: (T) -> R): R = block(this)
internal fun <T> Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T? {
for (e in this) {
if (predicate(e)) {
return e
}
}
return null
}
@@ -0,0 +1,39 @@
package kotlinx.testing.tests
import kotlin.test.*
import org.junit.*
class BasicAssertionsJVMTest {
@Test
fun testFailsWith() {
assertFailsWith(IllegalArgumentException::class) {
throw IllegalArgumentException()
}
}
@Test(expected = AssertionError::class)
fun testFailsWithFails() {
assertFailsWith(IllegalArgumentException::class) {
throw IllegalStateException()
}
}
@Test
fun testFailsWithMessage() {
assertFailsWith<IllegalArgumentException>("") {
throw IllegalArgumentException()
}
}
@Test
fun testToDo() {
todo {
fail("Shouldn't pass here")
}
}
@Test
fun testCurrentStackTrace() {
assertEquals("BasicAssertionsJVMTest.kt", currentStackTrace()[0].fileName)
}
}
@@ -0,0 +1,131 @@
package kotlin.test.tests
import org.junit.*
import kotlin.test.*
class BasicAssertionsTest {
@Test
fun testAssertEquals() {
assertEquals(1, 1)
}
@Test
fun testAssertEqualsString() {
assertEquals("a", "a")
}
@Test(expected = AssertionError::class)
fun testAssertEqualsFails() {
assertEquals(1, 2)
}
@Test
fun testAssertTrue() {
assertTrue(true)
}
@Test
fun testAssertTrueWithLambda() {
assertTrue { true }
}
@Test(expected = AssertionError::class)
fun testAssertTrueFails() {
assertTrue(false)
}
@Test(expected = AssertionError::class)
fun testAssertTrueWithLambdaFails() {
assertTrue { false }
}
@Test
fun testAssertFalse() {
assertFalse(false)
}
@Test
fun testAssertFalseLambda() {
assertFalse { false }
}
@Test(expected = AssertionError::class)
fun testAssertFalseFails() {
assertFalse(true)
}
@Test(expected = AssertionError::class)
fun testAssertFalseWithLambdaFails() {
assertFalse { true }
}
@Test
fun testAssertFails() {
assertFails { throw IllegalStateException() }
}
@Test(expected = AssertionError::class)
fun testAssertFailsFails() {
assertFails { }
Assert.fail("Shouldn't pass here")
}
@Test
fun testAssertNotEquals() {
assertNotEquals(1, 2)
}
@Test(expected = AssertionError::class)
fun testAssertNotEqualsFails() {
assertNotEquals(1, 1)
}
@Test
fun testAssertNotNull() {
assertNotNull(true)
}
@Test(expected = AssertionError::class)
fun testAssertNotNullFails() {
assertNotNull(null)
}
@Test
fun testAssertNotNullLambda() {
assertNotNull("") { assertEquals("", it) }
}
@Test(expected = AssertionError::class)
fun testAssertNotNullLambdaFails() {
assertNotNull(null) {
@Suppress("UNREACHABLE_CODE")
assertNotNull(it)
}
}
@Test
fun testAssertNull() {
assertNull(null)
}
@Test(expected = AssertionError::class)
fun testAssertNullFails() {
assertNull(true)
}
@Test(expected = AssertionError::class)
fun testFail() {
fail("should fail")
}
@Test
fun testExpect() {
expect(1) { 1 }
}
@Test(expected = AssertionError::class)
fun testExpectFails() {
expect(1) { 2 }
}
}
@@ -0,0 +1,136 @@
package kotlin.test.tests
import org.junit.*
import java.util.*
import kotlin.test.*
class CollectionAssertionTest {
@Test
fun testList() {
assert(listOf(1, 2, 3)) {
sizeShouldBe(3)
elementAtShouldBe(0, 1)
elementAtShouldComply(0) { it > 0 }
lastElementShouldBe(3)
containsAll(1, 2)
shouldBe(listOf(1, 2, 3))
}
}
@Test
fun testSet() {
assert(setOf(1, 2, 3)) {
sizeShouldBe(3)
elementAtShouldBe(0, 1)
elementAtShouldComply(0) { it > 0 }
lastElementShouldBe(3)
containsAll(1, 2)
shouldBeSet(setOf(1, 2, 3))
}
}
@Test(expected = AssertionError::class)
fun testSizeShouldBeFails() {
assert(listOf(1, 2, 3)) {
sizeShouldBe(1)
}
}
@Test(expected = AssertionError::class)
fun testElementAtShouldBeFail() {
assert(listOf(1, 2, 3)) {
elementAtShouldBe(0, 0)
}
}
@Test(expected = AssertionError::class)
fun testElementAtShouldComplyFail() {
assert(listOf(1, 2, 3)) {
elementAtShouldComply(0) { it < 0 }
}
}
@Test(expected = AssertionError::class)
fun testLastElementFail() {
assert(listOf(1, 2, 3)) {
lastElementShouldBe(0)
}
}
@Test(expected = NoSuchElementException::class)
fun testLastElementOnEmptyFail() {
assert(listOf<Int>()) {
lastElementShouldBe(0)
}
}
@Test(expected = AssertionError::class)
fun testContainsAll() {
assert(listOf(1, 2, 3)) {
containsAll(1, 8)
}
}
@Test(expected = AssertionError::class)
fun testContainsAllWithSet() {
assert(setOf(1, 2, 3)) {
containsAll(1, 8)
}
}
@Test
fun testShouldBeLess() {
try {
assert(listOf(1, 2, 3)) {
shouldBe(listOf(1, 2, 3, 4))
}
Assert.fail("It shouldn't pass here")
} catch (e: AssertionError) {
assertTrue { "[4]" in e.message!! }
assertTrue { "shorter" in e.message!! }
}
}
@Test
fun testShouldBeLonger() {
try {
assert(listOf(1, 2, 3)) {
shouldBe(listOf(1, 2))
}
Assert.fail("It shouldn't pass here")
} catch (e: AssertionError) {
assertTrue { "[3]" in e.message!! }
assertTrue { "longer" in e.message!! }
}
}
@Test(expected = AssertionError::class)
fun testShouldBeSetExtra() {
assert(setOf(1, 2, 3)) {
shouldBeSet(setOf(1, 2))
}
}
@Test
fun testShouldBeSetExact() {
assert(setOf(1, 2, 3)) {
shouldBeSet(setOf(1, 2, 3))
}
}
@Test
fun testShouldBeSetExactVararg() {
assert(setOf(1, 2, 3)) {
shouldBeSet(1, 2, 3)
}
}
@Test(expected = AssertionError::class)
fun testShouldBeSetMissing() {
assert(setOf(1, 2, 3)) {
shouldBeSet(setOf(1, 2, 3, 4))
}
}
}
@@ -0,0 +1,24 @@
package kotlin.test.tests
import java.util.*
internal fun <T> listOf(vararg elements: T): List<T> {
val result = ArrayList<T>(elements.size)
for (e in elements) {
result.add(e)
}
return result
}
internal fun <T> setOf(vararg elements: T): Set<T> {
val result = HashSet<T>(elements.size)
for (e in elements) {
result.add(e)
}
return result
}
internal operator fun String.contains(sub: String) = (this as java.lang.String).contains(sub)
+2
View File
@@ -97,6 +97,8 @@
<module>tools/kotlin-js-tests</module>
<module>tools/kotlin-js-tests-junit</module>
<module>kotlin.test</module>
<module>examples/kotlin-java-example</module>
<module>examples/js-example</module>
<module>examples/kotlin-js-library-example</module>
+6
View File
@@ -19,6 +19,12 @@
<artifactId>kotlin-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.jvm</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -21,6 +21,11 @@
<artifactId>kotlin-stdlib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.jvm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-js-tests</artifactId>