diff options
73 files changed, 1677 insertions, 127 deletions
@@ -86,4 +86,7 @@ gradle-app.setting # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 # gradle/wrapper/gradle-wrapper.properties -!lib/*.jar
\ No newline at end of file +!lib/*.jar + +local.properties +android.local.properties
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 3826f563..634de1d7 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -20,10 +20,6 @@ </profile> </annotationProcessing> <bytecodeTargetLevel> - <module name="__main" target="1.8" /> - <module name="__test" target="1.8" /> - <module name="all_main" target="1.8" /> - <module name="all_test" target="1.8" /> <module name="android-gradle-plugin_main" target="1.6" /> <module name="android-gradle-plugin_test" target="1.6" /> <module name="ant_main" target="1.5" /> @@ -34,15 +30,10 @@ <module name="cli_test" target="1.5" /> <module name="core_main" target="1.5" /> <module name="core_test" target="1.5" /> - <module name="dokka-android-gradle-plugin_main" target="1.6" /> - <module name="dokka-android-gradle-plugin_test" target="1.6" /> - <module name="dokka-gradle-plugin_main" target="1.6" /> - <module name="dokka-gradle-plugin_test" target="1.6" /> - <module name="dokka-maven-plugin" target="1.5" /> - <module name="farjar_main" target="1.8" /> - <module name="farjar_test" target="1.8" /> <module name="fatjar_main" target="1.8" /> <module name="fatjar_test" target="1.8" /> + <module name="gradle-integration-tests_main" target="1.8" /> + <module name="gradle-integration-tests_test" target="1.8" /> <module name="gradle-plugin_main" target="1.6" /> <module name="gradle-plugin_test" target="1.6" /> <module name="integration_main" target="1.8" /> @@ -50,8 +41,6 @@ <module name="maven-plugin" target="1.5" /> <module name="maven-plugin_main" target="1.8" /> <module name="maven-plugin_test" target="1.8" /> - <module name="runners_main" target="1.8" /> - <module name="runners_test" target="1.8" /> </bytecodeTargetLevel> </component> </project>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index eaa3a486..7e6aaef5 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -21,6 +21,9 @@ <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar.iml" group="runners/fatjar" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_main.iml" group="runners/fatjar" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_test.iml" group="runners/fatjar" /> + <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests.iml" group="runners/gradle-integration-tests" /> + <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_main.iml" group="runners/gradle-integration-tests" /> + <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_test.iml" group="runners/gradle-integration-tests" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin.iml" group="runners/gradle-plugin" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_main.iml" group="runners/gradle-plugin" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_test.iml" group="runners/gradle-plugin" /> diff --git a/.idea/runConfigurations/All_tests.xml b/.idea/runConfigurations/All_tests.xml new file mode 100644 index 00000000..d0d60ec9 --- /dev/null +++ b/.idea/runConfigurations/All_tests.xml @@ -0,0 +1,7 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="All tests" type="CompoundRunConfigurationType" factoryName="Compound Run Configuration"> + <toRun type="JUnit" name="Core tests" /> + <toRun type="JUnit" name="Gradle integration tests" /> + <method /> + </configuration> +</component>
\ No newline at end of file diff --git a/.idea/runConfigurations/Core_tests.xml b/.idea/runConfigurations/Core_tests.xml new file mode 100644 index 00000000..6f76e23f --- /dev/null +++ b/.idea/runConfigurations/Core_tests.xml @@ -0,0 +1,26 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="Core tests" type="JUnit" factoryName="JUnit"> + <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" /> + <module name="core_test" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> + <option name="ALTERNATIVE_JRE_PATH" /> + <option name="PACKAGE_NAME" /> + <option name="MAIN_CLASS_NAME" value="" /> + <option name="METHOD_NAME" value="" /> + <option name="TEST_OBJECT" value="directory" /> + <option name="VM_PARAMETERS" value="" /> + <option name="PARAMETERS" value="" /> + <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/core/" /> + <option name="ENV_VARIABLES" /> + <option name="PASS_PARENT_ENVS" value="true" /> + <option name="TEST_SEARCH_SCOPE"> + <value defaultName="singleModule" /> + </option> + <envs /> + <dir value="$PROJECT_DIR$/core/src/test/kotlin" /> + <patterns> + <pattern testClass="org.jetbrains.dokka.gradle.*" /> + </patterns> + <method /> + </configuration> +</component>
\ No newline at end of file diff --git a/.idea/runConfigurations/Gradle_integration_tests.xml b/.idea/runConfigurations/Gradle_integration_tests.xml new file mode 100644 index 00000000..20af8f96 --- /dev/null +++ b/.idea/runConfigurations/Gradle_integration_tests.xml @@ -0,0 +1,26 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="Gradle integration tests" type="JUnit" factoryName="JUnit"> + <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" /> + <module name="gradle-integration-tests_test" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> + <option name="ALTERNATIVE_JRE_PATH" /> + <option name="PACKAGE_NAME" /> + <option name="MAIN_CLASS_NAME" value="" /> + <option name="METHOD_NAME" value="" /> + <option name="TEST_OBJECT" value="pattern" /> + <option name="VM_PARAMETERS" value="" /> + <option name="PARAMETERS" value="" /> + <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/runners/gradle-integration-tests" /> + <option name="ENV_VARIABLES" /> + <option name="PASS_PARENT_ENVS" value="true" /> + <option name="TEST_SEARCH_SCOPE"> + <value defaultName="singleModule" /> + </option> + <envs /> + <dir value="$PROJECT_DIR$/core/src/test/kotlin" /> + <patterns> + <pattern testClass="org.jetbrains.dokka.gradle.*" /> + </patterns> + <method /> + </configuration> +</component>
\ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bb730356..8e2efd2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
\ No newline at end of file diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt b/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt new file mode 100644 index 00000000..3c9bf156 --- /dev/null +++ b/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt @@ -0,0 +1,70 @@ +package org.jetbrains.dokka + +import kotlin.reflect.* +import kotlin.reflect.jvm.isAccessible + +object ReflectDsl { + + class CallOrPropAccess(private val receiver: Any?, + private val clz: KClass<*>, + private val selector: String) { + + @Suppress("UNCHECKED_CAST") + operator fun <T : Any?> invoke(vararg a: Any?): T { + return func!!.call(receiver, *a) as T + } + + operator fun get(s: String): CallOrPropAccess { + return v<Any?>()!![s] + } + + val func: KFunction<*>? by lazy { clz.memberFunctions.find { it.name == selector } } + val prop: KProperty<*>? by lazy { clz.memberProperties.find { it.name == selector } } + + fun takeIfIsFunc(): CallOrPropAccess? = if (func != null) this else null + + fun takeIfIsProp(): CallOrPropAccess? = if (prop != null) this else null + + @Suppress("UNCHECKED_CAST") + fun <T : Any?> v(): T { + val prop = prop!! + return try { + prop.getter.apply { isAccessible = true }.call(receiver) as T + } catch (e: KotlinNullPointerException) { + // Hack around kotlin-reflect bug KT-18480 + val jclass = clz.java + val customGetterName = prop.getter.name + val getterName = if (customGetterName.startsWith("<")) "get" + prop.name.capitalize() else customGetterName + val getter = jclass.getDeclaredMethod(getterName) + getter.isAccessible = true + + getter.invoke(receiver) as T + + } + } + + @Suppress("UNCHECKED_CAST") + fun v(x: Any?) { + (prop as KMutableProperty).setter.apply { isAccessible = true }.call(receiver, x) + } + + + } + + operator fun Any.get(s: String): CallOrPropAccess { + val clz = this.javaClass.kotlin + return CallOrPropAccess(this, clz, s) + } + + operator fun Any.get(s: String, clz: Class<*>): CallOrPropAccess { + val kclz = clz.kotlin + return CallOrPropAccess(this, kclz, s) + } + + operator fun Any.get(s: String, clz: KClass<*>): CallOrPropAccess { + return CallOrPropAccess(this, clz, s) + } + + inline infix fun Any.isInstance(clz: Class<*>?): Boolean = clz != null && clz.isAssignableFrom(this.javaClass) + inline infix fun Any.isNotInstance(clz: Class<*>?): Boolean = !(this isInstance clz) +}
\ No newline at end of file diff --git a/runners/android-gradle-plugin/build.gradle b/runners/android-gradle-plugin/build.gradle index 01b9d3f0..a1747619 100644 --- a/runners/android-gradle-plugin/build.gradle +++ b/runners/android-gradle-plugin/build.gradle @@ -23,11 +23,10 @@ dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' shadow project(path: ':runners:gradle-plugin', configuration: 'shadow') + compileOnly project(':integration') provided gradleApi() provided localGroovy() - - provided 'com.android.tools.build:gradle:2.3.0' } task sourceJar(type: Jar) { diff --git a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt index 5db2ad2f..f392f1ab 100644 --- a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt +++ b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt @@ -1,13 +1,10 @@ package org.jetbrains.dokka.gradle -import com.android.build.gradle.* -import com.android.build.gradle.internal.VariantManager import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.Input +import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder import java.io.File -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.memberProperties open class DokkaAndroidPlugin : Plugin<Project> { override fun apply(project: Project) { @@ -19,50 +16,15 @@ open class DokkaAndroidPlugin : Plugin<Project> { } } -open class DokkaAndroidTask : DokkaTask() { - override val sdkProvider: SdkProvider? = AndroidSdkProvider(project) -} - -private class AndroidSdkProvider(private val project: Project) : SdkProvider { - private val ext: BaseExtension? by lazy { - project.extensions.findByType(LibraryExtension::class.java) - ?: project.extensions.findByType(AppExtension::class.java) - ?: project.extensions.findByType(TestExtension::class.java) - } +private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build() - private val isAndroidProject: Boolean get() = ext != null +open class DokkaAndroidTask : DokkaTask() { - private val variantManager: VariantManager? by lazy { - val plugin = (project.plugins.findPlugin("android") - ?: project.plugins.findPlugin("android-library") - ?: project.plugins.findPlugin("com.android.test") - ?: throw Exception("Android plugin not found, please use dokka-android with android or android-library plugin.")) as BasePlugin - plugin.javaClass.kotlin.memberProperties - .find { it.name == "variantManager" } - ?.apply { isAccessible = true } - ?.let { it.get(plugin) as VariantManager } - ?: plugin.variantManager - } + @Input var noAndroidSdkLink: Boolean = false - private val allVariantsClassPath by lazy { - try { - variantManager?.variantDataList?.flatMap { it.variantConfiguration.compileClasspath }!! - } catch(e: Exception) { - throw Exception("Unsupported version of android build tools, could not access variant manager.", e) + init { + project.afterEvaluate { + if (!noAndroidSdkLink) externalDocumentationLinks.add(ANDROID_REFERENCE_URL) } } - - override val name: String = "android" - - override val isValid: Boolean - get() = isAndroidProject - - override val classpath: List<File> - get() = ext?.bootClasspath.orEmpty() + allVariantsClassPath - - override val sourceDirs: Set<File>? - get() { - val sourceSet = ext?.sourceSets?.findByName(SourceSet.MAIN_SOURCE_SET_NAME) - return sourceSet?.java?.srcDirs - } } diff --git a/runners/build.gradle b/runners/build.gradle index e171800b..f1d2873c 100644 --- a/runners/build.gradle +++ b/runners/build.gradle @@ -6,7 +6,7 @@ configure([project("ant"), project("cli"), project("fatjar"), project("maven-plu } } -configure([project("gradle-plugin"), project("android-gradle-plugin")]) { +configure([project("gradle-plugin"), project("android-gradle-plugin"), project("gradle-integration-tests")]) { buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_for_gradle_version" diff --git a/runners/gradle-integration-tests/build.gradle b/runners/gradle-integration-tests/build.gradle new file mode 100644 index 00000000..179b6455 --- /dev/null +++ b/runners/gradle-integration-tests/build.gradle @@ -0,0 +1,45 @@ + + +apply plugin: 'kotlin' + + +configurations { + dokkaPlugin + dokkaAndroidPlugin + dokkaFatJar +} + +dependencies { + + testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: kotlin_for_gradle_version + testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_for_gradle_version + testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-test', version: kotlin_for_gradle_version + + dokkaPlugin project(path: ':runners:gradle-plugin', configuration: 'shadow') + dokkaAndroidPlugin project(path: ':runners:android-gradle-plugin', configuration: 'shadow') + dokkaFatJar project(path: ":runners:fatjar", configuration: 'shadow') + + testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile gradleTestKit() +} + + + +task createClasspathManifest { + def outputDir = file("$buildDir/$name") + + inputs.files(configurations.dokkaPlugin + configurations.dokkaAndroidPlugin + configurations.dokkaFatJar) + outputs.dir outputDir + + doLast { + outputDir.mkdirs() + file("$outputDir/dokka-plugin-classpath.txt").text = configurations.dokkaPlugin.join("\n") + file("$outputDir/android-dokka-plugin-classpath.txt").text = configurations.dokkaAndroidPlugin.join("\n") + file("$outputDir/fatjar.txt").text = configurations.dokkaFatJar.join("\n") + } +} + + +createClasspathManifest.mustRunAfter project(":runners:fatjar").shadowJar +testClasses.dependsOn project(":runners:fatjar").shadowJar +testClasses.dependsOn createClasspathManifest
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java new file mode 100644 index 00000000..cbb1cc3c --- /dev/null +++ b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java @@ -0,0 +1,39 @@ + +package com.intellij.rt.execution.junit; + +import junit.framework.ComparisonFailure; + +public class FileComparisonFailure extends ComparisonFailure implements KnownException { + private final String myExpected; + private final String myActual; + private final String myFilePath; + private final String myActualFilePath; + + public FileComparisonFailure(String message, String expected, String actual, String filePath) { + this(message, expected, actual, filePath, (String)null); + } + + public FileComparisonFailure(String message, String expected, String actual, String expectedFilePath, String actualFilePath) { + super(message, expected, actual); + this.myExpected = expected; + this.myActual = actual; + this.myFilePath = expectedFilePath; + this.myActualFilePath = actualFilePath; + } + + public String getFilePath() { + return this.myFilePath; + } + + public String getActualFilePath() { + return this.myActualFilePath; + } + + public String getExpected() { + return this.myExpected; + } + + public String getActual() { + return this.myActual; + } +} diff --git a/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java new file mode 100644 index 00000000..c24653ea --- /dev/null +++ b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java @@ -0,0 +1,6 @@ + +package com.intellij.rt.execution.junit; + +interface KnownException { + +} diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt new file mode 100644 index 00000000..255138a9 --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt @@ -0,0 +1,108 @@ +package org.jetbrains.dokka.gradle + + +import com.intellij.rt.execution.junit.FileComparisonFailure +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths + + +val testDataFolder = Paths.get("testData") + +val pluginClasspathData = Paths.get("build", "createClasspathManifest", "dokka-plugin-classpath.txt") +val androidPluginClasspathData = pluginClasspathData.resolveSibling("android-dokka-plugin-classpath.txt") + +val dokkaFatJarPathData = pluginClasspathData.resolveSibling("fatjar.txt") + +val androidLocalProperties = testDataFolder.resolve("android.local.properties").let { if (Files.exists(it)) it else null } + +abstract class AbstractDokkaGradleTest { + @get:Rule val testProjectDir = TemporaryFolder() + + open val pluginClasspath: List<File> = pluginClasspathData.toFile().readLines().map { File(it) } + + fun checkOutputStructure(expected: String, actualSubpath: String) { + val expectedPath = testDataFolder.resolve(expected) + val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize() + + assertEqualsIgnoringSeparators(expectedPath.toFile(), buildString { + actualPath.toFile().writeStructure(this, File(actualPath.toFile(), ".")) + }) + } + + fun checkNoErrorClasses(actualSubpath: String, extension: String = "html", errorClassMarker: String = "ERROR CLASS") { + val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize() + var checked = 0 + Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach { + val text = it.toFile().readText() + + val noErrorClasses = text.replace(errorClassMarker, "?!") + + if (noErrorClasses != text) { + throw FileComparisonFailure("", noErrorClasses, text, null) + } + + checked++ + } + println("$checked files checked for error classes") + } + + fun checkNoUnresolvedLinks(actualSubpath: String, extension: String = "html", marker: Regex = "[\"']#[\"']".toRegex()) { + val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize() + var checked = 0 + Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach { + val text = it.toFile().readText() + + val noErrorClasses = text.replace(marker, "?!") + + if (noErrorClasses != text) { + throw FileComparisonFailure("", noErrorClasses, text, null) + } + + checked++ + } + println("$checked files checked for unresolved links") + } + + fun checkExternalLink(actualSubpath: String, linkBody: String, fullLink: String, extension: String = "html") { + val match = "!!match!!" + val notMatch = "!!not-match!!" + + val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize() + var checked = 0 + var totalEntries = 0 + Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach { + val text = it.toFile().readText() + + val textWithoutMatches = text.replace(fullLink, match) + + val textWithoutNonMatches = textWithoutMatches.replace(linkBody, notMatch) + + if (textWithoutNonMatches != textWithoutMatches) { + + val expected = textWithoutNonMatches.replace(notMatch, fullLink).replace(match, fullLink) + val actual = textWithoutMatches.replace(match, fullLink) + + throw FileComparisonFailure("", expected, actual, null) + } + if (text != textWithoutMatches) + totalEntries++ + + checked++ + } + println("$checked files checked for valid external links '$linkBody', found $totalEntries links") + } + + fun configure(gradleVersion: String = "3.5", kotlinVersion: String = "1.1.2", arguments: Array<String>): GradleRunner { + val fatjar = dokkaFatJarPathData.toFile().readText() + + return GradleRunner.create().withProjectDir(testProjectDir.root) + .withArguments("-Pdokka_fatjar=$fatjar", "-Ptest_kotlin_version=$kotlinVersion", *arguments) + .withPluginClasspath(pluginClasspath) + .withGradleVersion(gradleVersion) + .withDebug(true) + } +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt new file mode 100644 index 00000000..de22a980 --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt @@ -0,0 +1,66 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test +import java.io.File +import java.nio.file.Files +import kotlin.test.assertEquals + +class AndroidAppTest : AbstractDokkaGradleTest() { + override val pluginClasspath: List<File> = androidPluginClasspathData.toFile().readLines().map { File(it) } + + fun prepareTestData(testDataRootPath: String) { + val testDataRoot = testDataFolder.resolve(testDataRootPath) + val tmpRoot = testProjectDir.root.toPath() + + testDataRoot.resolve("app").copy(tmpRoot.resolve("app")) + testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle")) + testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle")) + + androidLocalProperties?.copy(tmpRoot.resolve("local.properties")) + } + + + data class AndroidPluginParams(val pluginVersion: String, val buildToolsVersion: String, val compileSdk: Int) { + fun asArguments(): List<String> = listOf( + "-Pabt_plugin_version=$pluginVersion", + "-Pabt_version=$buildToolsVersion", + "-Psdk_version=$compileSdk" + ) + } + + + private fun doTest(gradleVersion: String, kotlinVersion: String, androidPluginParams: AndroidPluginParams) { + prepareTestData("androidApp") + + val result = configure(gradleVersion, kotlinVersion, + arguments = arrayOf("dokka", "--stacktrace") + androidPluginParams.asArguments()) + .build() + + println(result.output) + + assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokka")?.outcome) + + val docsOutput = "app/build/dokka" + + checkOutputStructure("androidApp/fileTree.txt", docsOutput) + + checkNoErrorClasses(docsOutput) + checkNoUnresolvedLinks(docsOutput) + + checkExternalLink(docsOutput, "<span class=\"identifier\">Activity</span>", + """<a href="https://developer.android.com/reference/android/app/Activity.html"><span class="identifier">Activity</span></a>""") + } + + @Test fun `test kotlin 1_1_2-5 and gradle 4_0 and abt 3_0_0-alpha3`() { + doTest("4.0", "1.1.2-5", AndroidPluginParams("3.0.0-alpha3", "25.0.2", 25)) + } + + @Test fun `test kotlin 1_1_2 and gradle 3_5 and abt 2_3_0`() { + doTest("3.5", "1.1.2", AndroidPluginParams("2.3.0", "25.0.0", 24)) + } + + @Test fun `test kotlin 1_0_7 and gradle 2_14_1 and abt 2_2_3`() { + doTest("2.14.1", "1.0.7", AndroidPluginParams("2.2.3", "25.0.0", 24)) + } +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt new file mode 100644 index 00000000..aee0e14c --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt @@ -0,0 +1,58 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.testkit.runner.TaskOutcome +import org.jetbrains.dokka.gradle.AndroidAppTest.AndroidPluginParams +import org.junit.Test +import java.io.File +import kotlin.test.assertEquals + +class AndroidMultiFlavourAppTest : AbstractDokkaGradleTest() { + override val pluginClasspath: List<File> = androidPluginClasspathData.toFile().readLines().map { File(it) } + + fun prepareTestData(testDataRootPath: String) { + val testDataRoot = testDataFolder.resolve(testDataRootPath) + val tmpRoot = testProjectDir.root.toPath() + + testDataRoot.resolve("app").copy(tmpRoot.resolve("app")) + testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle")) + testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle")) + + androidLocalProperties?.copy(tmpRoot.resolve("local.properties")) + } + + private fun doTest(gradleVersion: String, kotlinVersion: String, androidPluginParams: AndroidPluginParams) { + prepareTestData("androidMultiFlavourApp") + + val result = configure(gradleVersion, kotlinVersion, + arguments = arrayOf("dokka", "dokkaFullFlavourOnly", "--stacktrace") + androidPluginParams.asArguments()) + .build() + + println(result.output) + + assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokka")?.outcome) + assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokkaFullFlavourOnly")?.outcome) + + val docsOutput = "app/build/dokka" + + checkOutputStructure("androidMultiFlavourApp/fileTree.txt", docsOutput) + + checkNoErrorClasses(docsOutput) + checkNoUnresolvedLinks(docsOutput) + + checkExternalLink(docsOutput, "<span class=\"identifier\">Activity</span>", + """<a href="https://developer.android.com/reference/android/app/Activity.html"><span class="identifier">Activity</span></a>""") + } + + @Test fun `test kotlin 1_1_2-5 and gradle 4_0 and abt 3_0_0-alpha3`() { + doTest("4.0", "1.1.2-5", AndroidPluginParams("3.0.0-alpha3", "25.0.2", 25)) + } + + @Test fun `test kotlin 1_1_2 and gradle 3_5 and abt 2_3_0`() { + doTest("3.5", "1.1.2", AndroidPluginParams("2.3.0", "25.0.0", 24)) + } + + @Test fun `test kotlin 1_0_7 and gradle 2_14_1 and abt 2_2_3`() { + doTest("2.14.1", "1.0.7", AndroidPluginParams("2.2.3", "25.0.0", 24)) + } + +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt new file mode 100644 index 00000000..f9801c82 --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt @@ -0,0 +1,51 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test +import kotlin.test.assertEquals + +class BasicTest : AbstractDokkaGradleTest() { + + fun prepareTestData(testDataRootPath: String) { + val testDataRoot = testDataFolder.resolve(testDataRootPath) + val tmpRoot = testProjectDir.root.toPath() + + testDataRoot.resolve("src").copy(tmpRoot.resolve("src")) + testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle")) + testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle")) + } + + private fun doTest(gradleVersion: String, kotlinVersion: String) { + + prepareTestData("basic") + + val result = configure(gradleVersion, kotlinVersion, arguments = arrayOf("dokka", "--stacktrace")).build() + + println(result.output) + + assertEquals(TaskOutcome.SUCCESS, result.task(":dokka")?.outcome) + + val docsOutput = "build/dokka" + + checkOutputStructure("basic/fileTree.txt", docsOutput) + + checkNoErrorClasses(docsOutput) + checkNoUnresolvedLinks(docsOutput) + + checkExternalLink(docsOutput, "<span class=\"identifier\">String</span>", + """<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html"><span class="identifier">String</span></a>""") + } + + @Test fun `test kotlin 1_1_2 and gradle 3_5`() { + doTest("3.5", "1.1.2") + } + + @Test fun `test kotlin 1_0_7 and gradle 2_14_1`() { + doTest("2.14.1", "1.0.7") + } + + @Test fun `test kotlin 1_1_2 and gradle 4_0`() { + doTest("4.0", "1.1.2") + } + +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt new file mode 100644 index 00000000..13c7c37e --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt @@ -0,0 +1,54 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test +import kotlin.test.assertEquals + +class MultiProjectSingleOutTest : AbstractDokkaGradleTest() { + + fun prepareTestData(testDataRootPath: String) { + val testDataRoot = testDataFolder.resolve(testDataRootPath) + val tmpRoot = testProjectDir.root.toPath() + + testDataRoot.apply { + resolve("build.gradle").copy(tmpRoot.resolve("build.gradle")) + resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle")) + resolve("subA").copy(tmpRoot.resolve("subA")) + resolve("subB").copy(tmpRoot.resolve("subB")) + } + } + + private fun doTest(gradleVersion: String, kotlinVersion: String) { + + prepareTestData("multiProjectSingleOut") + + val result = configure(gradleVersion, kotlinVersion, arguments = arrayOf("dokka", "--stacktrace")).build() + + println(result.output) + + assertEquals(TaskOutcome.SUCCESS, result.task(":dokka")?.outcome) + + val docsOutput = "build/dokka" + + checkOutputStructure("multiProjectSingleOut/fileTree.txt", docsOutput) + + checkNoErrorClasses(docsOutput) + checkNoUnresolvedLinks(docsOutput) + + checkExternalLink(docsOutput, "<span class=\"identifier\">String</span>", + """<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html"><span class="identifier">String</span></a>""") + } + + @Test fun `test kotlin 1_1_2 and gradle 3_5`() { + doTest("3.5", "1.1.2") + } + + @Test fun `test kotlin 1_0_7 and gradle 2_14_1`() { + doTest("2.14.1", "1.0.7") + } + + @Test fun `test kotlin 1_1_2 and gradle 4_0`() { + doTest("4.0", "1.1.2") + } + +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt new file mode 100644 index 00000000..d44459b1 --- /dev/null +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt @@ -0,0 +1,59 @@ +package org.jetbrains.dokka.gradle + +import com.intellij.rt.execution.junit.FileComparisonFailure +import java.io.File +import java.io.IOException +import java.nio.file.FileVisitResult +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.SimpleFileVisitor +import java.nio.file.attribute.BasicFileAttributes + + +fun File.writeStructure(builder: StringBuilder, relativeTo: File = this, spaces: Int = 0) { + builder.append(" ".repeat(spaces)) + val out = if (this != relativeTo) this.relativeTo(relativeTo) else this + + builder.append(out) + if (this.isDirectory) { + builder.appendln("/") + this.listFiles().sortedBy { it.name }.forEach { it.writeStructure(builder, this, spaces + 4) } + } else { + builder.appendln() + } +} + +fun assertEqualsIgnoringSeparators(expectedFile: File, output: String) { + if (!expectedFile.exists()) expectedFile.createNewFile() + val expectedText = expectedFile.readText().replace("\r\n", "\n") + val actualText = output.replace("\r\n", "\n") + + if (expectedText != actualText) + throw FileComparisonFailure("", expectedText, actualText, expectedFile.canonicalPath) +} + +class CopyFileVisitor(private var sourcePath: Path?, private val targetPath: Path) : SimpleFileVisitor<Path>() { + + @Throws(IOException::class) + override fun preVisitDirectory(dir: Path, + attrs: BasicFileAttributes): FileVisitResult { + if (sourcePath == null) { + sourcePath = dir + } else { + Files.createDirectories(targetPath.resolve(sourcePath?.relativize(dir))) + } + return FileVisitResult.CONTINUE + } + + @Throws(IOException::class) + override fun visitFile(file: Path, + attrs: BasicFileAttributes): FileVisitResult { + Files.copy(file, targetPath.resolve(sourcePath?.relativize(file))) + return FileVisitResult.CONTINUE + } +} + +fun Path.copy(to: Path) { + Files.walkFileTree(this, CopyFileVisitor(this, to)) +} + diff --git a/runners/gradle-integration-tests/testData/androidApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle new file mode 100644 index 00000000..1555de9f --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle @@ -0,0 +1,50 @@ +buildscript { + repositories { + jcenter() + mavenLocal() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version" + } +} + +plugins { + id 'org.jetbrains.dokka-android' +} + + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'org.jetbrains.dokka-android' + +android { + compileSdkVersion Integer.parseInt(sdk_version) + buildToolsVersion abt_version + + defaultConfig { + applicationId "org.example.kotlin.mixed" + minSdkVersion 14 + targetSdkVersion Integer.parseInt(sdk_version) + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt') + } + } + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$test_kotlin_version" +} + + +dokka { + dokkaFatJar = new File(dokka_fatjar) +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..b4e1a892 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.example.kotlin.mixed" > + + <application + android:allowBackup="true" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" + android:theme="@style/AppTheme" > + + <activity + android:name=".JavaActivity" + android:label="@string/title_activity_main_activity1" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name=".KotlinActivity" + android:label="@string/title_activity_main_activity2" /> + + </application> + +</manifest> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java b/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java new file mode 100644 index 00000000..3668c594 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java @@ -0,0 +1,34 @@ +package org.example.kotlin.mixed; + +import android.content.Intent; +import android.os.Bundle; +import android.app.Activity; +import android.view.Menu; +import android.view.View; +import android.widget.Button; + +public class JavaActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Button next = (Button) findViewById(R.id.Button01); + next.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + Intent myIntent = new Intent(view.getContext(), KotlinActivity.class); + startActivityForResult(myIntent, 0); + } + }); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + +} diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt b/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt new file mode 100644 index 00000000..ca2f27b0 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt @@ -0,0 +1,28 @@ +package org.example.kotlin.mixed + +import android.content.Intent +import android.os.Bundle +import android.app.Activity +import android.view.Menu +import android.widget.Button + +class KotlinActivity : Activity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main2) + + val next = findViewById(R.id.Button02) as Button + next.setOnClickListener { + val intent: Intent = Intent() + setResult(RESULT_OK, intent) + finish() + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + menuInflater.inflate(R.menu.main_activity2, menu) + return true + } +} diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..96a442e5 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..359047df --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..71c6d760 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..ede57c39 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,24 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".MainActivity"> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Activity 1" /> + + <Button android:text="Next" + android:id="@+id/Button01" + android:layout_width="250px" + android:textSize="18px" + android:layout_height="55px"> + </Button> + +</LinearLayout> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml new file mode 100644 index 00000000..d707536a --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml @@ -0,0 +1,24 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".MainActivity"> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Activity 2" /> + + <Button android:text="Next" + android:id="@+id/Button02" + android:layout_width="250px" + android:textSize="18px" + android:layout_height="55px"> + </Button> + +</LinearLayout> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml new file mode 100644 index 00000000..f3b10b6c --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/action_settings" + android:title="@string/action_settings" + android:orderInCategory="100" + android:showAsAction="never" /> +</menu> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml new file mode 100644 index 00000000..f3b10b6c --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/action_settings" + android:title="@string/action_settings" + android:orderInCategory="100" + android:showAsAction="never" /> +</menu> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml new file mode 100644 index 00000000..47c82246 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ +<resources> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> +</resources> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..d8f08bc2 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name">AndroidSample</string> + <string name="action_settings">Settings</string> + <string name="hello_world">Hello world!</string> + <string name="title_activity_main_activity1">JavaActivity</string> + <string name="title_activity_main_activity2">KotlinActivity</string> + +</resources> diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..6ce89c7b --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ +<resources> + + <!-- + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Light"> + <!-- + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + +</resources> diff --git a/runners/gradle-integration-tests/testData/androidApp/build.gradle b/runners/gradle-integration-tests/testData/androidApp/build.gradle new file mode 100644 index 00000000..59477b52 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + mavenCentral() + jcenter() + maven { url 'https://maven.google.com' } + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } + dependencies { + classpath "com.android.tools.build:gradle:$abt_plugin_version" + } +} + +allprojects { + repositories { + mavenCentral() + jcenter() + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } +} diff --git a/runners/gradle-integration-tests/testData/androidApp/fileTree.txt b/runners/gradle-integration-tests/testData/androidApp/fileTree.txt new file mode 100644 index 00000000..3827b69e --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/fileTree.txt @@ -0,0 +1,19 @@ +/ + app/ + alltypes/ + index.html + index-outline.html + index.html + org.example.kotlin.mixed/ + -java-activity/ + -init-.html + index.html + on-create-options-menu.html + -kotlin-activity/ + -init-.html + index.html + on-create-options-menu.html + on-create.html + index.html + package-list + style.css diff --git a/runners/gradle-integration-tests/testData/androidApp/settings.gradle b/runners/gradle-integration-tests/testData/androidApp/settings.gradle new file mode 100644 index 00000000..1feb2867 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidApp/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = "androidApp" + +include ':app'
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle new file mode 100644 index 00000000..ee68ba6d --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle @@ -0,0 +1,75 @@ +buildscript { + repositories { + jcenter() + mavenLocal() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version" + } +} + +plugins { + id 'org.jetbrains.dokka-android' +} + + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'org.jetbrains.dokka-android' + +android { + compileSdkVersion Integer.parseInt(sdk_version) + buildToolsVersion abt_version + + defaultConfig { + applicationId "org.example.kotlin.mixed" + minSdkVersion 14 + targetSdkVersion Integer.parseInt(sdk_version) + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt') + } + } + + flavorDimensions "mode" + productFlavors { + free { + dimension "mode" + applicationIdSuffix ".free" + versionNameSuffix "-free" + } + full { + dimension "mode" + applicationIdSuffix ".full" + versionNameSuffix "-full" + } + } + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + free.java.srcDirs += 'src/free/kotlin' + } +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$test_kotlin_version" +} + + +dokka { + outputDirectory = "$buildDir/dokka/all" + dokkaFatJar = new File(dokka_fatjar) +} + +task dokkaFullFlavourOnly(type: org.jetbrains.dokka.gradle.DokkaAndroidTask) { + kotlinTasks { + ["compileFullReleaseKotlin"] + } + dokkaFatJar = new File(dokka_fatjar) + outputDirectory = "$buildDir/dokka/fullOnly" + moduleName = "full" +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml new file mode 100644 index 00000000..3ecbcd3a --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml @@ -0,0 +1,9 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application> + <activity + android:name="org.example.kotlin.mixed.free.AdActivity" + android:label="@string/title_activity_ad" + android:theme="@style/AppTheme"></activity> + </application> +</manifest> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt new file mode 100644 index 00000000..b0b980fd --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt @@ -0,0 +1,14 @@ +package org.example.kotlin.mixed.free + +import android.os.Bundle +import android.app.Activity +import org.example.kotlin.mixed.R + +class AdActivity : Activity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_ad) + } + +} diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml new file mode 100644 index 00000000..e6443d05 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml @@ -0,0 +1,24 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".free.AdActivity"> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Advertisment" /> + + <Button android:text="Next" + android:id="@+id/Button02" + android:layout_width="250px" + android:textSize="18px" + android:layout_height="55px"> + </Button> + +</LinearLayout> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml new file mode 100644 index 00000000..bbdf2d06 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="title_activity_ad">AdActivity</string> +</resources> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..b4e1a892 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.example.kotlin.mixed" > + + <application + android:allowBackup="true" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" + android:theme="@style/AppTheme" > + + <activity + android:name=".JavaActivity" + android:label="@string/title_activity_main_activity1" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name=".KotlinActivity" + android:label="@string/title_activity_main_activity2" /> + + </application> + +</manifest> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java new file mode 100644 index 00000000..3668c594 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java @@ -0,0 +1,34 @@ +package org.example.kotlin.mixed; + +import android.content.Intent; +import android.os.Bundle; +import android.app.Activity; +import android.view.Menu; +import android.view.View; +import android.widget.Button; + +public class JavaActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Button next = (Button) findViewById(R.id.Button01); + next.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + Intent myIntent = new Intent(view.getContext(), KotlinActivity.class); + startActivityForResult(myIntent, 0); + } + }); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + +} diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt new file mode 100644 index 00000000..ca2f27b0 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt @@ -0,0 +1,28 @@ +package org.example.kotlin.mixed + +import android.content.Intent +import android.os.Bundle +import android.app.Activity +import android.view.Menu +import android.widget.Button + +class KotlinActivity : Activity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main2) + + val next = findViewById(R.id.Button02) as Button + next.setOnClickListener { + val intent: Intent = Intent() + setResult(RESULT_OK, intent) + finish() + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + menuInflater.inflate(R.menu.main_activity2, menu) + return true + } +} diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..96a442e5 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..359047df --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..71c6d760 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..ede57c39 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,24 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".MainActivity"> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Activity 1" /> + + <Button android:text="Next" + android:id="@+id/Button01" + android:layout_width="250px" + android:textSize="18px" + android:layout_height="55px"> + </Button> + +</LinearLayout> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml new file mode 100644 index 00000000..d707536a --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml @@ -0,0 +1,24 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".MainActivity"> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Activity 2" /> + + <Button android:text="Next" + android:id="@+id/Button02" + android:layout_width="250px" + android:textSize="18px" + android:layout_height="55px"> + </Button> + +</LinearLayout> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml new file mode 100644 index 00000000..f3b10b6c --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/action_settings" + android:title="@string/action_settings" + android:orderInCategory="100" + android:showAsAction="never" /> +</menu> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml new file mode 100644 index 00000000..f3b10b6c --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/action_settings" + android:title="@string/action_settings" + android:orderInCategory="100" + android:showAsAction="never" /> +</menu> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml new file mode 100644 index 00000000..47c82246 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ +<resources> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> +</resources> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..d8f08bc2 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name">AndroidSample</string> + <string name="action_settings">Settings</string> + <string name="hello_world">Hello world!</string> + <string name="title_activity_main_activity1">JavaActivity</string> + <string name="title_activity_main_activity2">KotlinActivity</string> + +</resources> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..6ce89c7b --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ +<resources> + + <!-- + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Light"> + <!-- + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + +</resources> diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle new file mode 100644 index 00000000..59477b52 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + mavenCentral() + jcenter() + maven { url 'https://maven.google.com' } + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } + dependencies { + classpath "com.android.tools.build:gradle:$abt_plugin_version" + } +} + +allprojects { + repositories { + mavenCentral() + jcenter() + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } +} diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt new file mode 100644 index 00000000..5e969d8b --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt @@ -0,0 +1,45 @@ +/ + all/ + app/ + alltypes/ + index.html + index-outline.html + index.html + org.example.kotlin.mixed/ + -java-activity/ + -init-.html + index.html + on-create-options-menu.html + -kotlin-activity/ + -init-.html + index.html + on-create-options-menu.html + on-create.html + index.html + org.example.kotlin.mixed.free/ + -ad-activity/ + -init-.html + index.html + on-create.html + index.html + package-list + style.css + fullOnly/ + full/ + alltypes/ + index.html + index-outline.html + index.html + org.example.kotlin.mixed/ + -java-activity/ + -init-.html + index.html + on-create-options-menu.html + -kotlin-activity/ + -init-.html + index.html + on-create-options-menu.html + on-create.html + index.html + package-list + style.css diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle new file mode 100644 index 00000000..1feb2867 --- /dev/null +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = "androidApp" + +include ':app'
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/basic/build.gradle b/runners/gradle-integration-tests/testData/basic/build.gradle new file mode 100644 index 00000000..bc20e1cf --- /dev/null +++ b/runners/gradle-integration-tests/testData/basic/build.gradle @@ -0,0 +1,39 @@ +buildscript { + repositories { + mavenCentral() + jcenter() + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version" + } +} + +plugins { + id 'org.jetbrains.dokka' +} + +apply plugin: 'kotlin' +apply plugin: 'org.jetbrains.dokka' + +repositories { + mavenCentral() + jcenter() + maven { + url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" + } + maven { + url "https://dl.bintray.com/kotlin/kotlin-dev" + } +} + +dependencies { + compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version + compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version +} + + +dokka { + dokkaFatJar = new File(dokka_fatjar) +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/basic/fileTree.txt b/runners/gradle-integration-tests/testData/basic/fileTree.txt new file mode 100644 index 00000000..1a483d4e --- /dev/null +++ b/runners/gradle-integration-tests/testData/basic/fileTree.txt @@ -0,0 +1,30 @@ +/ + basic/ + alltypes/ + index.html + demo/ + -a/ + -init-.html + index.html + p.html + -greeter/ + -init-.html + greet.html + index.html + name.html + -some-interface.html + -some-sub-type/ + -init-.html + index.html + -some-type/ + -init-.html + index.html + constructor.html + index.html + main.html + str.html + x.html + index-outline.html + index.html + package-list + style.css diff --git a/runners/gradle-integration-tests/testData/basic/settings.gradle b/runners/gradle-integration-tests/testData/basic/settings.gradle new file mode 100644 index 00000000..c36a146c --- /dev/null +++ b/runners/gradle-integration-tests/testData/basic/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "basic"
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt b/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt new file mode 100644 index 00000000..7492e2a8 --- /dev/null +++ b/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt @@ -0,0 +1,41 @@ +package demo + +/** + * This class supports greeting people by name. + * + * @property name The name of the person to be greeted. + */ +class Greeter(val name: String) { + + /** + * Prints the greeting to the standard output. + */ + fun greet() { + println("Hello $name!") + } +} + +fun main(args: Array<String>) { + Greeter(args[0]).greet() +} + +val str = "Hello! ".repeat(4) +val x: (a: String, b: Int) -> Int = { a, b -> 0 } + +interface SomeInterface +private class SomeImpl : SomeInterface + +fun SomeInterface.constructor(): SomeInterface { + return SomeImpl() +} + +open class SomeType +class SomeSubType : SomeType() + +fun SomeType.constructor(): SomeType { + return SomeSubType() +} + + +annotation class A(val p: String) + diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle new file mode 100644 index 00000000..68d93e30 --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle @@ -0,0 +1,32 @@ +plugins { + id 'org.jetbrains.dokka' +} + +subprojects { + buildscript { + repositories { + mavenCentral() + jcenter() + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version" + } + } + repositories { + mavenCentral() + jcenter() + maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } + maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + } +} + +apply plugin: 'org.jetbrains.dokka' + +dokka { + kotlinTasks { + [":subA:compileKotlin", ":subB:compileKotlin"] + } + dokkaFatJar = new File(dokka_fatjar) +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt new file mode 100644 index 00000000..5624fca6 --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt @@ -0,0 +1,33 @@ +/ + multi-project-root/ + alltypes/ + index.html + index-outline.html + index.html + package-list + s1/ + -my-class/ + -init-.html + index.html + otherworks.html + -super/ + -init-.html + bar.html + foo.html + index.html + index.html + some-cool-thing.html + s2/ + -cooler/ + -init-.html + a.html + coolest.html + index.html + my-class.html + -superful/ + -init-.html + bar.html + index.html + index.html + main.html + style.css diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle new file mode 100644 index 00000000..283cc526 --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = "multiProjectRoot" + +include 'subA', 'subB'
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle new file mode 100644 index 00000000..0600411e --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle @@ -0,0 +1,6 @@ +apply plugin: 'kotlin' + +dependencies { + compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version + compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version +} diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt new file mode 100644 index 00000000..126d7f3e --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt @@ -0,0 +1,31 @@ +package s1 + +/** + * Coolest one + */ +fun someCoolThing(s: String) = s.repeat(2) + +/** + * Just a class + */ +class MyClass { + /** + * Ultimate answer to all questions + */ + fun otherworks(): Int = 42 +} + +/** + * Just a SUPER class + */ +open class Super { + /** + * Same as [MyClass.otherworks] + */ + fun foo(i: Int = 21) = i * 2 + + /** + * magic + */ + open fun bar() = foo() +}
\ No newline at end of file diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle new file mode 100644 index 00000000..7b8ff9f3 --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle @@ -0,0 +1,7 @@ +apply plugin: 'kotlin' + +dependencies { + compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version + compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version + compile project(":subA") +} diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt new file mode 100644 index 00000000..8a87590a --- /dev/null +++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt @@ -0,0 +1,31 @@ +package s2 + +import s1.Super +import s1.MyClass +import s1.someCoolThing + +/** + * Just an entry-point + */ +fun main(args: Array<String>) { + +} + +/** + * Take a glass of hot water + */ +class Cooler { + val myClass = MyClass() + val a = myClass.otherworks() + val coolest = someCoolThing() +} + +/** + * Powerful + */ +class Superful : Super() { + /** + * Overriden magic + */ + override fun bar() = foo(20) * 2 +}
\ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index 61c83de4..fd4053ee 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -4,15 +4,14 @@ import groovy.lang.Closure import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.Task import org.gradle.api.file.FileCollection import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.* import org.gradle.api.tasks.Optional -import org.jetbrains.dokka.DokkaBootstrap -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.SerializeOnlyDokkaConfiguration -import org.jetbrains.dokka.automagicTypedProxy +import org.jetbrains.dokka.* +import org.jetbrains.dokka.ReflectDsl.isNotInstance import org.jetbrains.dokka.gradle.ClassloaderContainer.fatJarClassLoader import org.jetbrains.dokka.gradle.DokkaVersion.version import ru.yole.jkid.JsonExclude @@ -22,6 +21,7 @@ import java.io.InputStream import java.io.Serializable import java.net.URLClassLoader import java.util.* +import java.util.concurrent.Callable import java.util.function.BiConsumer open class DokkaPlugin : Plugin<Project> { @@ -52,9 +52,24 @@ object ClassloaderContainer { } open class DokkaTask : DefaultTask() { + + fun defaultKotlinTasks() = with(ReflectDsl) { + val abstractKotlinCompileClz = try { + project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (cnfe: ClassNotFoundException) { + logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") + return@with emptyList<Task>() + } + + return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } + } + init { group = JavaBasePlugin.DOCUMENTATION_GROUP description = "Generates dokka documentation for Kotlin" + + @Suppress("LeakingThis") + dependsOn(Callable { kotlinTasks.flatMap { it.dependsOn } }) } @Input @@ -62,8 +77,13 @@ open class DokkaTask : DefaultTask() { @Input var outputFormat: String = "html" var outputDirectory: String = "" - @Input - var processConfigurations: List<Any?> = arrayListOf("compile") + + + @Deprecated("Going to be removed in 0.9.16, use classpath + sourceDirs instead if kotlinTasks is not suitable for you") + @Input var processConfigurations: List<Any?> = emptyList() + + @Input var classpath: List<File> = arrayListOf() + @Input var includes: List<Any?> = arrayListOf() @Input @@ -92,7 +112,16 @@ open class DokkaTask : DefaultTask() { @Optional @Input var cacheRoot: String? = null - protected open val sdkProvider: SdkProvider? = null + @get:Input + internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } + + + private var kotlinTasksConfigurator: () -> List<Any?>? = { defaultKotlinTasks() } + private val kotlinTasks: List<Task> by lazy { extractKotlinCompileTasks() } + + fun kotlinTasks(closure: Closure<Any?>) { + kotlinTasksConfigurator = { closure.call() as? List<Any?> } + } fun linkMapping(closure: Closure<Any?>) { val mapping = LinkMapping() @@ -151,6 +180,56 @@ open class DokkaTask : DefaultTask() { } } + internal data class ClasspathAndSourceRoots(val classpath: List<File>, val sourceRoots: List<File>) : Serializable + + private fun extractKotlinCompileTasks(): List<Task> { + val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() + val (paths, other) = inputList.partition { it is String } + + val taskContainer = project.tasks + + val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } + + other + .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } + + tasksByPath + .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } + + + return (tasksByPath + other) as List<Task> + } + + private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { + + val allTasks = kotlinTasks + + val allClasspath = mutableSetOf<File>() + val allSourceRoots = mutableSetOf<File>() + + allTasks.forEach { + + logger.debug("Dokka found AbstractKotlinCompile task: $it") + with(ReflectDsl) { + val taskSourceRoots: List<File> = it["sourceRootsContainer"]["sourceRoots"].v() + + val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! + + val taskClasspath: Iterable<File> = + (it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() ?: + it["getClasspath", abstractKotlinCompileClz]()) + + allClasspath += taskClasspath.filter { it.exists() } + allSourceRoots += taskSourceRoots.filter { it.exists() } + } + } + + return ClasspathAndSourceRoots(allClasspath.toList(), allSourceRoots.toList()) + } + + private fun Iterable<File>.toSourceRoots(): List<SourceRoot> = this.filter { it.exists() }.map { SourceRoot().apply { path = it.path } } @TaskAction fun generate() { @@ -159,22 +238,18 @@ open class DokkaTask : DefaultTask() { try { loadFatJar() - val project = project - val sdkProvider = sdkProvider - val sourceRoots = collectSourceRoots() - val allConfigurations = project.configurations + val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - val classpath = - if (sdkProvider != null && sdkProvider.isValid) sdkProvider.classpath else emptyList<File>() + - processConfigurations - .map { allConfigurations?.getByName(it.toString()) ?: throw IllegalArgumentException("No configuration $it found") } - .flatMap { it } + val project = project + val sourceRoots = collectSourceRoots() + tasksSourceRoots.toSourceRoots() if (sourceRoots.isEmpty()) { logger.warn("No source directories found: skipping dokka generation") return } + val fullClasspath = collectClasspathFromOldSources() + tasksClasspath + classpath + val bootstrapClass = fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") val bootstrapInstance = bootstrapClass.constructors.first().newInstance() @@ -183,7 +258,7 @@ open class DokkaTask : DefaultTask() { val configuration = SerializeOnlyDokkaConfiguration( moduleName, - classpath.map { it.absolutePath }, + fullClasspath.map { it.absolutePath }, sourceRoots, samples.filterNotNull().map { project.file(it).absolutePath }, includes.filterNotNull().map { project.file(it).absolutePath }, @@ -222,28 +297,40 @@ open class DokkaTask : DefaultTask() { } } - fun collectSourceRoots(): List<SourceRoot> { - val provider = sdkProvider + private fun collectClasspathFromOldSources(): List<File> { + + val allConfigurations = project.configurations + + val fromConfigurations = + processConfigurations.map { + allConfigurations?.getByName(it.toString()) ?: throw IllegalArgumentException("No configuration $it found") + }.flatten() + + return fromConfigurations + } + + private fun collectSourceRoots(): List<SourceRoot> { val sourceDirs = if (sourceDirs.any()) { logger.info("Dokka: Taking source directories provided by the user") sourceDirs.toSet() - } else if (provider != null && provider.isValid) { - logger.info("Dokka: Taking source directories from ${provider.name} sdk provider") - provider.sourceDirs - } else { + } else if (kotlinTasks.isEmpty()) { logger.info("Dokka: Taking source directories from default java plugin") val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java) val sourceSets = javaPluginConvention.sourceSets?.findByName(SourceSet.MAIN_SOURCE_SET_NAME) sourceSets?.allSource?.srcDirs + } else { + emptySet() } - return sourceRoots + (sourceDirs?.filter { it.exists() }?.map { SourceRoot().apply { path = it.path } } ?: emptyList()) + return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) } - @InputFiles + @SkipWhenEmpty + @InputFiles fun getInputFiles(): FileCollection = - project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) + + project.files(kotlinCompileBasedClasspathAndSourceRoots.sourceRoots.map { project.fileTree(File(it.path)) }) + + project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) + project.files(includes) + project.files(samples.map { project.fileTree(it) }) @@ -252,6 +339,13 @@ open class DokkaTask : DefaultTask() { companion object { const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" + const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" + + private fun getAbstractKotlinCompileFor(task: Task) = try { + task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (e: ClassNotFoundException) { + null + } } } @@ -262,6 +356,10 @@ class SourceRoot : DokkaConfiguration.SourceRoot { } override var platforms: List<String> = arrayListOf() + + override fun toString(): String { + return "${platforms.joinToString()}::$path" + } } open class LinkMapping : Serializable, DokkaConfiguration.SourceLinkDefinition { @@ -315,36 +413,3 @@ class PackageOptions : DokkaConfiguration.PackageOptions { override var reportUndocumented: Boolean = true override var skipDeprecated: Boolean = false } -/** - * A provider for SDKs that can be used if a project uses classes that live outside the JDK or uses a - * different method to determine the source directories. - * - * For example an Android library project configures its sources through the Android extension instead - * of the basic java convention. Also it has its custom classes located in the SDK installation directory. - */ -interface SdkProvider { - /** - * The name of this provider. Only used for logging purposes. - */ - val name: String - - /** - * Checks whether this provider has everything it needs to provide the source directories. - */ - val isValid: Boolean - - /** - * Provides additional classpath files where Dokka should search for external classes. - * The file list is injected **after** JDK Jars and **before** project dependencies. - * - * This is only called if [isValid] returns `true`. - */ - val classpath: List<File> - - /** - * Provides a list of directories where Dokka should search for source files. - * - * This is only called if [isValid] returns `true`. - */ - val sourceDirs: Set<File>? -} diff --git a/runners/maven-plugin/build.gradle b/runners/maven-plugin/build.gradle index 3f80ba4a..e1a3af1a 100644 --- a/runners/maven-plugin/build.gradle +++ b/runners/maven-plugin/build.gradle @@ -25,7 +25,7 @@ dependencies { shadow "org.apache.maven.plugin-tools:maven-plugin-annotations:$maven_plugin_tools_version" } -task generatePom << { +task ("generatePom") doLast { final pomTemplate = new File(projectDir, "pom.tpl.xml") final pom = new File(buildDir, "pom.xml") pom.text = pomTemplate.text.replace("<version>dokka_version</version>", "<version>$dokka_version</version>") @@ -43,7 +43,6 @@ task helpMojo(type: CrossPlatformExec) { commandLine mvn, '-e', '-B', 'org.apache.maven.plugins:maven-plugin-plugin:helpmojo' } - helpMojo.dependsOn generatePom sourceSets.main.java.srcDir("$buildDir/generated-sources/plugin") compileJava.dependsOn helpMojo diff --git a/runners/maven-plugin/pom.tpl.xml b/runners/maven-plugin/pom.tpl.xml index 3b5afd74..c5883c6a 100644 --- a/runners/maven-plugin/pom.tpl.xml +++ b/runners/maven-plugin/pom.tpl.xml @@ -21,6 +21,6 @@ </plugin> </plugins> <directory>./</directory> - <outputDirectory>classes/main</outputDirectory> + <outputDirectory>./classes/java/main</outputDirectory> </build> </project> diff --git a/settings.gradle b/settings.gradle index 9da9e303..4dcfd255 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,9 @@ -include 'core', 'runners:fatjar', 'runners:ant', 'runners:cli', 'runners:maven-plugin', 'runners:gradle-plugin', 'runners:android-gradle-plugin', 'integration' +include 'core', + 'integration', + 'runners:fatjar', + 'runners:ant', + 'runners:cli', + 'runners:maven-plugin', + 'runners:gradle-plugin', + 'runners:android-gradle-plugin', + 'runners:gradle-integration-tests' |