Add kotlin.test library
This commit is contained in:
@@ -25,6 +25,12 @@
|
|||||||
<artifactId>kotlin-js-library-example</artifactId>
|
<artifactId>kotlin-js-library-example</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin.test.jvm</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
<artifactId>kotlin-js-library</artifactId>
|
<artifactId>kotlin-js-library</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin.test.jvm</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -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
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+131
@@ -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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
+136
@@ -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)
|
||||||
|
|
||||||
@@ -97,6 +97,8 @@
|
|||||||
<module>tools/kotlin-js-tests</module>
|
<module>tools/kotlin-js-tests</module>
|
||||||
<module>tools/kotlin-js-tests-junit</module>
|
<module>tools/kotlin-js-tests-junit</module>
|
||||||
|
|
||||||
|
<module>kotlin.test</module>
|
||||||
|
|
||||||
<module>examples/kotlin-java-example</module>
|
<module>examples/kotlin-java-example</module>
|
||||||
<module>examples/js-example</module>
|
<module>examples/js-example</module>
|
||||||
<module>examples/kotlin-js-library-example</module>
|
<module>examples/kotlin-js-library-example</module>
|
||||||
|
|||||||
@@ -19,6 +19,12 @@
|
|||||||
<artifactId>kotlin-runtime</artifactId>
|
<artifactId>kotlin-runtime</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin.test.jvm</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
<artifactId>kotlin-stdlib</artifactId>
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin.test.jvm</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-js-tests</artifactId>
|
<artifactId>kotlin-js-tests</artifactId>
|
||||||
|
|||||||
Reference in New Issue
Block a user