blob: 0384bf739655c59a02cd95b7a7459acde36b4289 [file] [log] [blame]
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03001/*
2 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +03005package kotlinx.coroutines.experimental.tools
6
7import org.junit.*
Roman Elizarov53c00282018-08-22 11:00:10 +03008import org.junit.runner.*
9import org.junit.runners.*
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030010import java.io.*
Roman Elizarov53c00282018-08-22 11:00:10 +030011import java.util.*
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030012import java.util.jar.*
Roman Elizarov53c00282018-08-22 11:00:10 +030013import kotlin.collections.ArrayList
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030014
Roman Elizarov53c00282018-08-22 11:00:10 +030015@RunWith(Parameterized::class)
16class PublicApiTest(
17 private val rootDir: String,
18 private val moduleName: String
19) {
20 companion object {
21 private val apiProps = ClassLoader.getSystemClassLoader()
22 .getResource("api.properties").openStream().use { Properties().apply { load(it) } }
23 private val nonPublicPackages = apiProps.getProperty("packages.internal")!!.split(" ")
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030024
Roman Elizarov53c00282018-08-22 11:00:10 +030025 @Parameterized.Parameters(name = "{1}")
26 @JvmStatic
27 fun modules(): List<Array<Any>> {
28 val moduleRoots = apiProps.getProperty("module.roots").split(" ")
29 val moduleMarker = apiProps.getProperty("module.marker")!!
30 val moduleIgnore = apiProps.getProperty("module.ignore")!!.split(" ").toSet()
31 val modules = ArrayList<Array<Any>>()
32 for (rootDir in moduleRoots) {
33 File("../$rootDir").listFiles( FileFilter { it.isDirectory })?.forEach { dir ->
34 if (dir.name !in moduleIgnore && File(dir, moduleMarker).exists()) {
35 modules += arrayOf<Any>(rootDir, dir.name)
36 }
37 }
38 }
39 return modules
40 }
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030041 }
42
43 @Test
Roman Elizarov53c00282018-08-22 11:00:10 +030044 fun testApi() {
45 val libsDir = File("../$rootDir/$moduleName/build/libs").absoluteFile.normalize()
46 val jarFile = getJarPath(libsDir)
47 val kotlinJvmMappingsFiles = listOf(libsDir.resolve("../visibilities.json"))
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030048 val visibilities =
49 kotlinJvmMappingsFiles
Roman Elizarov53c00282018-08-22 11:00:10 +030050 .map { readKotlinVisibilities(it) }
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030051 .reduce { m1, m2 -> m1 + m2 }
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030052 val api = getBinaryAPI(JarFile(jarFile), visibilities).filterOutNonPublic(nonPublicPackages)
Roman Elizarov53c00282018-08-22 11:00:10 +030053 api.dumpAndCompareWith(File("reference-public-api").resolve("$moduleName.txt"))
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030054 }
55
Roman Elizarov53c00282018-08-22 11:00:10 +030056 private fun getJarPath(libsDir: File): File {
57 val regex = Regex("$moduleName-.+\\.jar")
58 val files = (libsDir.listFiles() ?: throw Exception("Cannot list files in $libsDir"))
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030059 .filter { it.name.let {
60 it matches regex
61 && !it.endsWith("-sources.jar")
62 && !it.endsWith("-javadoc.jar")
63 && !it.endsWith("-tests.jar")} }
Roman Elizarov53c00282018-08-22 11:00:10 +030064 return files.singleOrNull() ?: throw Exception("No single file matching $regex in $libsDir:\n${files.joinToString("\n")}")
Vsevolod Tolstopyatov74bcc922018-05-03 20:07:54 +030065 }
66}