Select the asserter based on test framework presence in classpath
Simplify asserter lookup: enumerate all AsserterContributors when the file class with lookupAsserter function is initialized. It's assumed that AsserterContributor initialization should be fast. #KT-21154 Fixed
This commit is contained in:
@@ -3,21 +3,25 @@ package kotlin.test.junit
|
||||
import org.junit.*
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
* Provides [JUnitAsserter] if `org.junit.Assert` is found in the classpath.
|
||||
*/
|
||||
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
|
||||
return if (hasJUnitInClassPath) JUnitAsserter else null
|
||||
}
|
||||
|
||||
if (className.startsWith("org.junit.") || className.startsWith("junit.")) {
|
||||
return JUnitAsserter
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
private val hasJUnitInClassPath = try {
|
||||
Class.forName("org.junit.Assert")
|
||||
true
|
||||
} catch (_: ClassNotFoundException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `kotlin.test` assertions by delegating them to `org.junit.Assert` class.
|
||||
*/
|
||||
object JUnitAsserter : Asserter {
|
||||
override fun assertEquals(message: String?, expected: Any?, actual: Any?) {
|
||||
Assert.assertEquals(message, expected, actual)
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
package kotlin.test.junit.tests
|
||||
|
||||
import org.junit.*
|
||||
import org.junit.Assert
|
||||
import kotlin.test.*
|
||||
import java.util.concurrent.*
|
||||
import kotlin.test.junit.JUnitAsserter
|
||||
|
||||
class JUnitContributorTest {
|
||||
@Test
|
||||
fun smokeTest() {
|
||||
Assert.assertEquals("JUnitAsserter", asserter.`class`.simpleName)
|
||||
assertSame(JUnitAsserter, kotlin.test.asserter)
|
||||
Assert.assertEquals(JUnitAsserter::class.java.simpleName, kotlin.test.asserter.javaClass.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)
|
||||
fun parallelThreadGetsTheSameAsserter() {
|
||||
val q = ArrayBlockingQueue<Any>(1)
|
||||
|
||||
Thread {
|
||||
q.put(asserter)
|
||||
}.start()
|
||||
|
||||
Assert.assertEquals("DefaultAsserter", q.take().`class`.simpleName)
|
||||
assertSame(kotlin.test.asserter, q.take())
|
||||
}
|
||||
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
private val asserter: java.lang.Object
|
||||
get() = Class.forName("kotlin.test.AssertionsKt").getMethod("getAsserter").invoke(null) as java.lang.Object
|
||||
}
|
||||
|
||||
@@ -1,48 +1,15 @@
|
||||
package kotlin.test
|
||||
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.*
|
||||
import java.util.concurrent.locks.*
|
||||
import kotlin.concurrent.withLock
|
||||
import java.util.ServiceLoader
|
||||
|
||||
private val inited = AtomicBoolean()
|
||||
private val lock = ReentrantLock()
|
||||
private val contributors = ArrayList<AsserterContributor>()
|
||||
|
||||
internal actual fun lookupAsserter(): Asserter = lookup()
|
||||
private val contributors = ServiceLoader.load(AsserterContributor::class.java).toList()
|
||||
|
||||
private val defaultAsserter = DefaultAsserter()
|
||||
|
||||
internal fun lookup(): Asserter {
|
||||
initContributorsIfNeeded()
|
||||
|
||||
internal actual fun lookupAsserter(): Asserter {
|
||||
for (contributor in contributors) {
|
||||
val asserter = contributor.contribute()
|
||||
if (asserter != null) {
|
||||
return asserter
|
||||
}
|
||||
if (asserter != null) return asserter
|
||||
}
|
||||
|
||||
return defaultAsserter
|
||||
}
|
||||
|
||||
private fun initContributors() {
|
||||
contributors.clear()
|
||||
val loader = ServiceLoader.load(AsserterContributor::class.java)
|
||||
|
||||
for (contributor in loader) {
|
||||
if (contributor != null) {
|
||||
contributors.add(contributor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initContributorsIfNeeded() {
|
||||
if (!inited.get()) {
|
||||
lock.withLock {
|
||||
if (inited.compareAndSet(false, true)) {
|
||||
initContributors()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,25 @@ package kotlin.test.testng
|
||||
import org.testng.*
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
* Provides [TestNGAsserter] if `org.testng.Assert` is found in the classpath.
|
||||
*/
|
||||
class TestNGContributor : AsserterContributor {
|
||||
override fun contribute(): Asserter? {
|
||||
for (stackFrame in currentStackTrace()) {
|
||||
val className = stackFrame.className
|
||||
return if (hasTestNGInClassPath) TestNGAsserter else null
|
||||
}
|
||||
|
||||
if (className.startsWith("org.testng.") || className.startsWith("testng.")) {
|
||||
return TestNGAsserter
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
private val hasTestNGInClassPath = try {
|
||||
Class.forName("org.testng.Assert")
|
||||
true
|
||||
} catch (_: ClassNotFoundException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `kotlin.test` assertions by delegating them to `org.testng.Assert` class.
|
||||
*/
|
||||
object TestNGAsserter : Asserter {
|
||||
override fun assertEquals(message: String?, expected: Any?, actual: Any?) {
|
||||
Assert.assertEquals(expected, actual, message)
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
package kotlin.test.testng.tests
|
||||
|
||||
import org.testng.annotations.*
|
||||
import org.testng.*
|
||||
import org.testng.Assert
|
||||
import kotlin.test.*
|
||||
import java.util.concurrent.*
|
||||
import kotlin.test.testng.TestNGAsserter
|
||||
|
||||
class TestNGContributorTest {
|
||||
|
||||
@Test
|
||||
fun smokeTest() {
|
||||
Assert.assertEquals("TestNGAsserter", kotlin.test.asserter.javaClass.simpleName)
|
||||
assertSame(TestNGAsserter, asserter)
|
||||
Assert.assertEquals(TestNGAsserter::class.java.simpleName, kotlin.test.asserter.javaClass.simpleName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should fail to contribute if it was run outside of testng`() {
|
||||
fun parallelThreadGetsTheSameAsserter() {
|
||||
val q = ArrayBlockingQueue<Any>(1)
|
||||
|
||||
Thread {
|
||||
q.put(kotlin.test.asserter)
|
||||
q.put(asserter)
|
||||
}.start()
|
||||
|
||||
Assert.assertEquals("DefaultAsserter", q.take().javaClass.simpleName)
|
||||
assertSame(asserter, q.take())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user