From aea8670c12758ee753fe3c14b710372e99cd20bb Mon Sep 17 00:00:00 2001 From: Dmitrii Krasnov Date: Thu, 13 Apr 2023 15:40:48 +0200 Subject: [PATCH] migrated NativeLibraryDslIT and NativeLibraryDslWithCocoapodsIT to junit 5 and gradle TestKit #KT-51553 --- .../jetbrains/kotlin/gradle/BaseGradleIT.kt | 5 - .../kotlin/gradle/native/GeneralNativeIT.kt | 7 +- .../native/NativeDownloadAndPlatformLibsIT.kt | 9 +- .../gradle/native/NativeLibraryDslIT.kt | 132 +++++------ .../native/NativeLibraryDslWithCocoapodsIT.kt | 210 +++++++++--------- .../kotlin/gradle/testbase/fileAssertions.kt | 33 ++- .../gradle/testbase/nativeTestHelpers.kt | 11 + .../gradle/testbase/outputAssertions.kt | 56 +++++ .../kotlin/gradle/testbase/tasksAssertions.kt | 68 +++++- 9 files changed, 336 insertions(+), 195 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt index 1c23cdf0281..df4ce3f1827 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt @@ -725,11 +725,6 @@ abstract class BaseGradleIT { } } - fun CompiledProject.assertTasksRegisteredAndNotRealized(vararg tasks: String) { - assertTasksRegistered(*tasks) - assertTasksNotRealized(*tasks) - } - fun CompiledProject.assertTasksSkipped(vararg tasks: String) { for (task in tasks) { assertContains("Skipping task '$task'") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/GeneralNativeIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/GeneralNativeIT.kt index 0e8403fafe4..73ab19f1cb5 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/GeneralNativeIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/GeneralNativeIT.kt @@ -1224,11 +1224,6 @@ class GeneralNativeIT : BaseGradleIT() { */ fun CompiledProject.getOutputForTask(taskPath: String): String = getOutputForTask(taskPath, output) - fun CompiledProject.extractNativeCommandLineArguments(taskPath: String? = null, toolName: NativeToolKind): List = - extractNativeToolSettings(taskPath?.let { getOutputForTask(taskPath) } ?: output, - toolName, - NativeToolSettingsKind.COMMAND_LINE_ARGUMENTS).toList() - fun CompiledProject.extractNativeCustomEnvironment(taskPath: String? = null, toolName: NativeToolKind): Map = extractNativeToolSettings(taskPath?.let { getOutputForTask(taskPath) } ?: output, toolName, @@ -1241,7 +1236,7 @@ class GeneralNativeIT : BaseGradleIT() { vararg taskPaths: String, toolName: NativeToolKind = NativeToolKind.KONANC, check: (List) -> Unit - ) = taskPaths.forEach { taskPath -> check(extractNativeCommandLineArguments(taskPath, toolName)) } + ) = taskPaths.forEach { taskPath -> check(extractNativeCompilerCommandLineArguments(getOutputForTask(taskPath), toolName)) } fun CompiledProject.withNativeCustomEnvironment( vararg taskPaths: String, diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeDownloadAndPlatformLibsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeDownloadAndPlatformLibsIT.kt index a613c1c2597..861fb07dd56 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeDownloadAndPlatformLibsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeDownloadAndPlatformLibsIT.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.gradle.native import org.jetbrains.kotlin.gradle.* import org.jetbrains.kotlin.gradle.embedProject import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.containsSequentially -import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.extractNativeCommandLineArguments import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.withNativeCommandLineArguments import org.jetbrains.kotlin.gradle.testbase.NativeToolKind +import org.jetbrains.kotlin.gradle.testbase.extractNativeCompilerCommandLineArguments import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader @@ -187,7 +187,12 @@ class NativeDownloadAndPlatformLibsIT : BaseGradleIT() { // Check that user can change generation mode used by the cinterop tool. buildWithLightDist("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") { assertSuccessful() - assertTrue(extractNativeCommandLineArguments(toolName = NativeToolKind.GENERATE_PLATFORM_LIBRARIES).containsSequentially("-mode", "metadata")) + assertTrue( + extractNativeCompilerCommandLineArguments( + taskOutput = output, + toolName = NativeToolKind.GENERATE_PLATFORM_LIBRARIES + ).containsSequentially("-mode", "metadata") + ) } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt index cd7cca395ce..aca458a5693 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt @@ -1,72 +1,62 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.gradle.native -import org.jetbrains.kotlin.gradle.BaseGradleIT -import org.jetbrains.kotlin.gradle.GradleVersionRequired -import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.withNativeCommandLineArguments -import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl -import org.jetbrains.kotlin.konan.target.HostManager -import org.junit.Assume -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertTrue -import kotlin.test.Test +import org.gradle.api.logging.LogLevel +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.condition.EnabledOnOs +import org.junit.jupiter.api.condition.OS +import kotlin.io.path.appendText -class NativeLibraryDslIT : BaseGradleIT() { - override val defaultGradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT +@DisplayName("Tests for K/N library dsl builds") +@NativeGradlePluginTests +class NativeLibraryDslIT : KGPBaseTest() { - @Test - fun `check registered gradle tasks`() { - with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { - build(":shared:tasks") { - assertSuccessful() - assertTasksRegistered( - ":shared:assembleMyfatframeFatFramework", - ":shared:assembleMyframeFrameworkIosArm64", - ":shared:assembleMylibSharedLibraryLinuxX64", - ":shared:assembleMyslibSharedLibraryLinuxX64", - ":shared:assembleSharedXCFramework" - ) - assertTasksNotRegistered( - ":shared:assembleMyslibReleaseSharedLibraryLinuxX64" - ) - } - build(":lib:tasks") { - assertSuccessful() - assertTasksRegistered( - ":lib:assembleGroofatframeFatFramework", - ":lib:assembleGrooframeFrameworkIosArm64", - ":lib:assembleGroolibSharedLibraryIosX64", - ":lib:assembleLibXCFramework" - ) - } + @DisplayName("K/N project with custom registered gradle tasks") + @GradleTest + fun shouldSharedAndLibRegisteredTasks(gradleVersion: GradleVersion) { + nativeProject("new-kn-library-dsl", gradleVersion) { + buildAndAssertAllTasks( + "shared:assembleMyfatframeFatFramework", + "shared:assembleMyframeFrameworkIosArm64", + "shared:assembleMylibSharedLibraryLinuxX64", + "shared:assembleMyslibSharedLibraryLinuxX64", + "shared:assembleSharedXCFramework", + "lib:assembleGroofatframeFatFramework", + "lib:assembleGrooframeFrameworkIosArm64", + "lib:assembleGroolibSharedLibraryIosX64", + "lib:assembleLibXCFramework", + notRegisteredTasks = listOf("shared:assembleMyslibReleaseSharedLibraryLinuxX64") + ) } } - @Test - fun `link shared library from two gradle modules`() { - with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { + @DisplayName("Link shared libraries from two gradle modules") + @GradleTest + fun shouldLinkSharedLibrariesFromTwoModules(gradleVersion: GradleVersion) { + nativeProject("new-kn-library-dsl", gradleVersion) { build(":shared:assembleMyslibDebugSharedLibraryLinuxX64") { - assertSuccessful() assertTasksExecuted( ":lib:compileKotlinLinuxX64", ":shared:compileKotlinLinuxX64", ":shared:assembleMyslibDebugSharedLibraryLinuxX64" ) - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmyslib.so") - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmyslib_api.h") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmyslib.so") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmyslib_api.h") } } } - @Test - fun `link shared library from single gradle module`() { - with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { - build(":shared:assembleMylibDebugSharedLibraryLinuxX64") { - assertSuccessful() + @DisplayName("Link shared library from single gradle module") + @GradleTest + fun shouldLinkSharedLibrariesFromSingleModule(gradleVersion: GradleVersion) { + nativeProject("new-kn-library-dsl", gradleVersion) { + build(":shared:assembleMylibDebugSharedLibraryLinuxX64", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) { assertTasksExecuted( ":shared:compileKotlinLinuxX64", ":shared:assembleMylibDebugSharedLibraryLinuxX64" @@ -74,23 +64,22 @@ class NativeLibraryDslIT : BaseGradleIT() { assertTasksNotExecuted( ":lib:compileKotlinLinuxX64" ) - withNativeCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { - assertFalse(it.contains("-Xfoo=bar")) - assertFalse(it.contains("-Xbaz=qux")) - assertTrue(it.contains("-Xmen=pool")) + assertNativeTasksCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { + assertCommandLineArgumentsDoNotContain("-Xfoo=bar", "-Xbaz=qux", commandLineArguments = it) + assertCommandLineArgumentsContain("-Xmen=pool", commandLineArguments = it) } - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmylib.so") - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") } } } - @Test - fun `link shared library from single gradle module with additional link args`() { - with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { - gradleProperties().appendText("\nkotlin.native.linkArgs=-Xfoo=bar -Xbaz=qux") - build(":shared:assembleMylibDebugSharedLibraryLinuxX64") { - assertSuccessful() + @DisplayName("Links shared library from single gradle module with additional link args") + @GradleTest + fun shouldLinkSharedLibrariesFromSingleModuleWithAdditionalLinkArgs(gradleVersion: GradleVersion) { + nativeProject("new-kn-library-dsl", gradleVersion) { + gradleProperties.appendText("\nkotlin.native.linkArgs=-Xfoo=bar -Xbaz=qux") + build(":shared:assembleMylibDebugSharedLibraryLinuxX64", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) { assertTasksExecuted( ":shared:compileKotlinLinuxX64", ":shared:assembleMylibDebugSharedLibraryLinuxX64" @@ -98,23 +87,21 @@ class NativeLibraryDslIT : BaseGradleIT() { assertTasksNotExecuted( ":lib:compileKotlinLinuxX64" ) - withNativeCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { - assertTrue(it.contains("-Xfoo=bar")) - assertTrue(it.contains("-Xbaz=qux")) - assertTrue(it.contains("-Xmen=pool")) + assertNativeTasksCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { + assertCommandLineArgumentsContain("-Xfoo=bar", "-Xbaz=qux", "-Xmen=pool", commandLineArguments = it) } - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmylib.so") - assertFileExists("/shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so") + assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") } } } - @Test - fun `link release XCFramework from two gradle modules`() { - Assume.assumeTrue(HostManager.hostIsMac) - with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { + @EnabledOnOs(OS.MAC) + @DisplayName("Links release XCFramework from two gradle modules") + @GradleTest + fun shouldLinkXCFrameworkFromTwoModules(gradleVersion: GradleVersion) { + nativeProject("new-kn-library-dsl", gradleVersion) { build(":shared:assembleSharedReleaseXCFramework") { - assertSuccessful() assertTasksExecuted( ":shared:compileKotlinIosX64", ":shared:compileKotlinIosArm64", @@ -127,8 +114,9 @@ class NativeLibraryDslIT : BaseGradleIT() { assertTasksNotExecuted( ":shared:assembleSharedDebugXCFramework" ) - assertFileExists("/shared/build/out/xcframework/release/shared.xcframework") + assertDirectoryInProjectExists("shared/build/out/xcframework/release/shared.xcframework") } } } + } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslWithCocoapodsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslWithCocoapodsIT.kt index 3a5011952ce..ab3097e2442 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslWithCocoapodsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslWithCocoapodsIT.kt @@ -1,162 +1,173 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.gradle.native -import org.jetbrains.kotlin.gradle.BaseGradleIT -import org.jetbrains.kotlin.gradle.GradleVersionRequired -import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl -import org.jetbrains.kotlin.konan.target.HostManager -import org.junit.Assume -import org.junit.BeforeClass -import kotlin.test.Test -import kotlin.test.assertEquals +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.condition.EnabledOnOs +import org.junit.jupiter.api.condition.OS +import kotlin.io.path.appendText -class NativeLibraryDslWithCocoapodsIT : BaseGradleIT() { +@EnabledOnOs(OS.MAC) +@DisplayName("Tests for K/N with cocoapods") +@NativeGradlePluginTests +class NativeLibraryDslWithCocoapodsIT : KGPBaseTest() { - companion object { - @BeforeClass - @JvmStatic - fun assumeMacHost() { - Assume.assumeTrue(HostManager.hostIsMac) + @DisplayName("Registers shared tasks") + @GradleTest + fun shouldCheckGradleRegisteredTasks(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { + buildAndAssertAllTasks( + "shared:generateMylibStaticLibraryLinuxX64Podspec", + "shared:generateMyslibSharedLibraryLinuxX64Podspec", + "shared:generateMyframeFrameworkIosArm64Podspec", + "shared:generateMyfatframeFatFrameworkPodspec", + "shared:generateSharedXCFrameworkPodspec", + "lib:generateGrooframeFrameworkIosArm64Podspec", + "lib:generateGrooxcframeXCFrameworkPodspec", + "shared:generateMyframewihtoutpodspecFrameworkIosArm64Podspec", + "lib:generateGrooxcframewithoutpodspecXCFrameworkPodspec" + ) } } - override val defaultGradleVersion = GradleVersionRequired.FOR_MPP_SUPPORT - - @Test - fun `check registered gradle tasks`() { - project { - build(":shared:tasks") { - assertSuccessful() - assertTasksRegistered( - ":shared:generateMylibStaticLibraryLinuxX64Podspec", - ":shared:generateMyslibSharedLibraryLinuxX64Podspec", - ":shared:generateMyframeFrameworkIosArm64Podspec", - ":shared:generateMyfatframeFatFrameworkPodspec", - ":shared:generateSharedXCFrameworkPodspec", - ":lib:generateGrooframeFrameworkIosArm64Podspec", - ":lib:generateGrooxcframeXCFrameworkPodspec", - ":shared:generateMyframewihtoutpodspecFrameworkIosArm64Podspec", - ":lib:generateGrooxcframewithoutpodspecXCFrameworkPodspec", + @DisplayName("Generates podspec when assembling static lib for Linux X64") + @GradleTest + fun shouldGeneratePodspecWithStaticLibForLinuxX64(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { + build(":shared:assembleMylibStaticLibraryLinuxX64") { + assertTasksExecuted(":shared:generateMylibStaticLibraryLinuxX64Podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/mylib.podspec"), + projectPath.resolve("shared/build/out/static/mylib.podspec"), ) } } } - @Test - fun `generate podspec when assembling static lib`() { - project { - build(":shared:assembleMylibStaticLibraryLinuxX64") { - assertSuccessful() - assertTasksExecuted(":shared:generateMylibStaticLibraryLinuxX64Podspec") - assertFilesContentEqual("podspecs/mylib.podspec", "/shared/build/out/static/mylib.podspec") - } - } - } - - @Test - fun `generate podspec when assembling shared lib`() { - project { + @DisplayName("Generates podspec when assembling shared lib for Linux X64") + @GradleTest + fun shouldGeneratePodspecWithSharedLibForLinuxX64(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleMyslibSharedLibraryLinuxX64") { - assertSuccessful() assertTasksExecuted(":shared:generateMyslibSharedLibraryLinuxX64Podspec") - assertFilesContentEqual("podspecs/myslib.podspec", "/shared/build/out/dynamic/myslib.podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/myslib.podspec"), + projectPath.resolve("shared/build/out/dynamic/myslib.podspec") + ) } } } - @Test - fun `not generate podspec when withPodspec is empty`() { - project { + @DisplayName("Does not generate podspec with empty withPodspec for Linux X64") + @GradleTest + fun shouldNotGeneratePodspecWithoutPodspecForLinuxX64(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleMyslibwithoutpodspecSharedLibraryLinuxX64") { - assertSuccessful() assertTasksSkipped(":shared:generateMyslibwithoutpodspecSharedLibraryLinuxX64Podspec") - assertContains("Skipping task ':shared:generateMyslibwithoutpodspecSharedLibraryLinuxX64Podspec' because there are no podspec attributes defined") + assertOutputContains("Skipping task ':shared:generateMyslibwithoutpodspecSharedLibraryLinuxX64Podspec' because there are no podspec attributes defined") } } } - @Test - fun `generate podspec when assembling framework`() { - project { + @DisplayName("Generates podspec when assembling framework for Ios Arm 64") + @GradleTest + fun shouldGeneratePodspecWithFrameworkIosArm64(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleMyframeFrameworkIosArm64") { - assertSuccessful() assertTasksExecuted(":shared:generateMyframeFrameworkIosArm64Podspec") - assertFilesContentEqual("podspecs/myframe.podspec", "/shared/build/out/framework/myframe.podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/myframe.podspec"), + projectPath.resolve("shared/build/out/framework/myframe.podspec") + ) } } } - @Test - fun `not generate podspec when there is no withPodspec`() { - project { + @DisplayName("Does not generate podspec with empty withPodspec for Ios Arm 64") + @GradleTest + fun shouldNotGeneratePodspecWithoutPodspecForIosArm64(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleMyframewihtoutpodspecFrameworkIosArm64") { - assertSuccessful() assertTasksSkipped(":shared:generateMyframewihtoutpodspecFrameworkIosArm64Podspec") + assertOutputContains("Skipping task ':shared:generateMyframewihtoutpodspecFrameworkIosArm64Podspec' because there are no podspec attributes defined") } } } - @Test - fun `generate podspec when assembling fat framework`() { - project { + @DisplayName("Generates podspec when assembling fat framework") + @GradleTest + fun shouldGeneratePodspecWithFatFramework(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleMyfatframeFatFramework") { - assertSuccessful() assertTasksExecuted(":shared:generateMyfatframeFatFrameworkPodspec") - assertFilesContentEqual("podspecs/myfatframe.podspec", "/shared/build/out/fatframework/myfatframe.podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/myfatframe.podspec"), + projectPath.resolve("shared/build/out/fatframework/myfatframe.podspec") + ) } } } - @Test - fun `generate podspec when assembling xcframework`() { - project { + @DisplayName("Generates podspec when assembling xcframework") + @GradleTest + fun shouldGeneratePodspecWithXCFramework(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":shared:assembleSharedXCFramework") { - assertSuccessful() assertTasksExecuted(":shared:generateSharedXCFrameworkPodspec") - assertFilesContentEqual("podspecs/shared.podspec", "/shared/build/out/xcframework/shared.podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/shared.podspec"), + projectPath.resolve("shared/build/out/xcframework/shared.podspec") + ) } } } - @Test - fun `generate podspec when assembling xcframework from groovy`() { - project { + @DisplayName("Generates podspec when assembling xcframework from groovy") + @GradleTest + fun shouldGeneratePodspecWithXCFrameworkFromGroovy(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":lib:assembleGrooframeFrameworkIosArm64") { - assertSuccessful() assertTasksExecuted(":lib:generateGrooframeFrameworkIosArm64Podspec") - assertFilesContentEqual("podspecs/grooframe.podspec", "/lib/build/out/framework/grooframe.podspec") + assertFilesContentEquals( + projectPath.resolve("podspecs/grooframe.podspec"), + projectPath.resolve("lib/build/out/framework/grooframe.podspec") + ) } } } - @Test - fun `not generate podspec from groovy when withPodspec is empty`() { - project { + @DisplayName("Does not generate podspec with empty withPodspec from groovy") + @GradleTest + fun shouldNotGeneratePodspecWithEmptyPodspecFromGrooby(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":lib:assembleGrooxcframeXCFramework") { - assertSuccessful() assertTasksSkipped(":lib:generateGrooxcframeXCFrameworkPodspec") } } } - @Test - fun `not generate podspec from groovy when there is no withPodspec`() { - project { + @DisplayName("Does not generate podspec from groovy when there is no withPodspec") + @GradleTest + fun shouldNotGeneratePodspecFromGroovyWithoutPodspec(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { build(":lib:assembleGrooxcframewithoutpodspecXCFramework") { - assertSuccessful() assertTasksSkipped(":lib:generateGrooxcframewithoutpodspecXCFrameworkPodspec") } } } - @Test - fun `generate podspecs when several frameworks have with the same name`() { - project { - projectDir.resolve("shared/build.gradle.kts").appendText(""" + @DisplayName("Generates podspecs when several frameworks with the same name") + @GradleTest + fun shouldGeneratePodspecsWhenSeveralFrameworksWithTheSameName(gradleVersion: GradleVersion) { + buildNewKnLibraryDslCocoapodsProjectWithTasks(gradleVersion) { + subProject("shared").buildGradleKts.appendText( + //language=kotlin + """ kotlinArtifacts { Native.Library { target = linuxX64 @@ -164,22 +175,17 @@ class NativeLibraryDslWithCocoapodsIT : BaseGradleIT() { withPodspec {} } } - """.trimIndent()) + """.trimIndent() + ) - build(":shared:assembleSharedXCFramework") { - assertSuccessful() - } + build(":shared:assembleSharedXCFramework") } } - private fun project(block: Project.() -> Unit) { - transformProjectWithPluginsDsl("new-kn-library-dsl-cocoapods").block() + private fun buildNewKnLibraryDslCocoapodsProjectWithTasks( + gradleVersion: GradleVersion, + buildBlock: TestProject.() -> Unit + ) { + nativeProject("new-kn-library-dsl-cocoapods", gradleVersion, test = buildBlock) } - - private fun CompiledProject.assertFilesContentEqual(expected: String, actual: String) { - assertFileExists(expected) - assertFileExists(actual) - assertEquals(fileInWorkingDir(expected).readText(), fileInWorkingDir(actual).readText()) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt index 40e2c5e73ce..dc6083ff614 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt @@ -11,14 +11,16 @@ import java.nio.file.Files import java.nio.file.Path import kotlin.io.path.exists import kotlin.io.path.isDirectory +import kotlin.io.path.readLines import kotlin.io.path.readText +import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.asserter /** * Asserts file under [file] path exists and is a regular file. */ -fun GradleProject.assertFileExists( +fun assertFileExists( file: Path ) { assert(Files.exists(file)) { @@ -39,7 +41,7 @@ fun GradleProject.assertFileInProjectExists( assertFileExists(projectPath.resolve(pathToFile)) } -fun GradleProject.assertFileExistsInTree( +fun assertFileExistsInTree( pathToTreeRoot: Path, fileName: String ) { @@ -54,6 +56,7 @@ fun GradleProject.assertFileExistsInTree( "File $fileName does not exists in $pathToTreeRoot!" } } + /** * Asserts file under [pathToFile] relative to the test project does not exist. */ @@ -63,7 +66,7 @@ fun GradleProject.assertFileInProjectNotExists( assertFileNotExists(projectPath.resolve(pathToFile)) } -fun GradleProject.assertFileNotExists( +fun assertFileNotExists( pathToFile: Path ) { assert(!Files.exists(pathToFile)) { @@ -71,7 +74,7 @@ fun GradleProject.assertFileNotExists( } } -fun GradleProject.assertFileNotExistsInTree( +fun assertFileNotExistsInTree( pathToTreeRoot: Path, fileName: String ) { @@ -108,7 +111,7 @@ fun GradleProject.assertDirectoryExists( dirPath: Path ) = assertDirectoriesExist(dirPath) -fun GradleProject.assertDirectoriesExist( +fun assertDirectoriesExist( vararg dirPaths: Path ) { val (exist, notExist) = dirPaths.partition { it.exists() } @@ -151,7 +154,7 @@ fun GradleProject.assertFileInProjectDoesNotContain( /** * Asserts file under [file] exists and contains all the lines from [expectedText] */ -fun GradleProject.assertFileContains( +fun assertFileContains( file: Path, vararg expectedText: String ) { @@ -173,7 +176,7 @@ fun GradleProject.assertFileContains( /** * Asserts file under [file] exists and does not contain any line from [unexpectedText] */ -fun GradleProject.assertFileDoesNotContain( +fun assertFileDoesNotContain( file: Path, vararg unexpectedText: String ) { @@ -214,6 +217,22 @@ fun assertContainsFiles(expected: Iterable, actual: Iterable, messag }, actualSet.containsAll(expectedSet)) } +/** + * Asserts that the content of two files is equal. + * @param expected The path to the expected file. + * @param actual The path to the actual file. + * @throws AssertionError if the contents of the two files are not equal. + */ +fun assertFilesContentEquals(expected: Path, actual: Path) { + assertFileExists(expected) + assertFileExists(actual) + assertContentEquals( + expected.readLines().asSequence(), + actual.readLines().asSequence(), + "Files content not equal" + ) +} + class GradleVariantAssertions( val variantJson: JsonObject ) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/nativeTestHelpers.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/nativeTestHelpers.kt index cc9069971c4..2383d533024 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/nativeTestHelpers.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/nativeTestHelpers.kt @@ -22,6 +22,17 @@ val DEFAULT_CURRENT_PLATFORM_TARGET_NAME_POSTFIX = HostManager.host.presetName.l fun extractNativeCompilerClasspath(taskOutput: String, toolName: NativeToolKind): List = extractNativeToolSettings(taskOutput, toolName, NativeToolSettingsKind.COMPILER_CLASSPATH).toList() +/** + * Extracts command line arguments of given task's output + * + * @param taskOutput debug level output of the task + * @param toolName compiler type + * + * @return list of command line arguments + */ +fun extractNativeCompilerCommandLineArguments(taskOutput: String, toolName: NativeToolKind): List = + extractNativeToolSettings(taskOutput, toolName, NativeToolSettingsKind.COMMAND_LINE_ARGUMENTS).toList() + enum class NativeToolKind(val title: String) { KONANC("konanc"), GENERATE_PLATFORM_LIBRARIES("generatePlatformLibraries"), diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt index 23e6b3075b1..d9109518d11 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle.testbase +import org.gradle.api.logging.LogLevel import org.gradle.api.logging.configuration.WarningMode import org.gradle.testkit.runner.BuildResult @@ -252,3 +253,58 @@ fun BuildResult.assertCompilerArgument( "$taskPath task compiler arguments don't contain $expectedArgument. Actual content: $compilerArguments" } } + +/** + * Asserts command line arguments of the given K/N compiler for given tasks' paths + * + * Note: Log level of output must be set to [LogLevel.DEBUG]. + * + * @param tasksPaths tasks' paths, for which command line arguments should be checked with give assertions + * @param toolName name of build tool + * @param assertions assertions, with will be applied to each command line arguments of each given task + */ +fun BuildResult.assertNativeTasksCommandLineArguments( + vararg tasksPaths: String, + toolName: NativeToolKind = NativeToolKind.KONANC, + assertions: (List) -> Unit +) = tasksPaths.forEach { taskPath -> + assertions(extractNativeCompilerCommandLineArguments(getOutputForTask(taskPath), toolName)) +} + +/** + * Asserts that the given list of command line arguments does not contain any of the expected arguments. + * + * @param expectedArgs the list of expected arguments + * @param commandLineArguments the list of actual command line arguments + * @throws AssertionError if any of the expected arguments are found in the actual arguments list + */ +fun BuildResult.assertCommandLineArgumentsDoNotContain( + vararg expectedArgs: String, + commandLineArguments: List +) { + expectedArgs.forEach { + assert(!commandLineArguments.contains(it)) { + printBuildOutput() + "There is unexpected ${it} in actual command line arguments are: ${commandLineArguments}" + } + } +} + +/** + * Asserts that the given list of command line arguments contains all the expected arguments. + * + * @param expectedArgs the list of expected arguments + * @param commandLineArguments the list of actual command line arguments + * @throws AssertionError if any of the expected arguments are missing from the actual arguments list + */ +fun BuildResult.assertCommandLineArgumentsContain( + vararg expectedArgs: String, + commandLineArguments: List +) { + expectedArgs.forEach { + assert(commandLineArguments.contains(it)) { + printBuildOutput() + "There is no ${it} in actual command line arguments are: ${commandLineArguments}" + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tasksAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tasksAssertions.kt index 96e8a593863..421bc5a8a81 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tasksAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tasksAssertions.kt @@ -41,6 +41,18 @@ fun BuildResult.assertTasksExecuted(vararg tasks: String) { } } +/** + * Asserts given [tasks] have not been executed. + */ +fun BuildResult.assertTasksNotExecuted(vararg tasks: String) { + tasks.forEach { + assert(!this.tasks.contains(task(it))) { + printBuildOutput() + "Task $it was executed and finished with state: ${task(it)?.outcome}" + } + } +} + /** * Asserts given [tasks] have 'SUCCESS' execution state. */ @@ -129,7 +141,7 @@ fun BuildResult.assertTasksPackedToCache(vararg tasks: String) { * * Note: Log level of output must be set to [LogLevel.DEBUG]. * - * @param tasksPaths names of the tasks, which classpath should be checked with give assertions + * @param tasksPaths tasks' paths, for which classpath should be checked with give assertions * @param toolName name of build tool * @param assertions assertions, with will be applied to each classpath of each given task */ @@ -138,3 +150,57 @@ fun BuildResult.assertNativeTasksClasspath( toolName: NativeToolKind = NativeToolKind.KONANC, assertions: (List) -> Unit ) = tasksPaths.forEach { taskPath -> assertions(extractNativeCompilerClasspath(getOutputForTask(taskPath), toolName)) } + +/** + * Builds test project with 'tasks --all' arguments and then + * asserts that [registeredTasks] of the given tasks have been registered + * and tasks from the [notRegisteredTasks] list have not been registered. + * + * @param registeredTasks The names of the tasks that should have been registered, + * it could contain task paths as well, but without the first semicolon. + * @param notRegisteredTasks An optional list of task names that should not have been registered, + * it could contain task paths as well, but without the first semicolon. + * @throws AssertionError if any of the registered tasks do not match the expected task names, + * or if any of the not-registered tasks were actually registered. + */ +fun TestProject.buildAndAssertAllTasks( + vararg registeredTasks: String, + notRegisteredTasks: List = emptyList() +) { + build("tasks", "--all") { + val allRegisteredTasks = getAllTasksFromTheOutput() + registeredTasks.forEach { + assert(allRegisteredTasks.contains(it)) { + printBuildOutput() + "Expected $it task is not registered in all tasks." + } + } + notRegisteredTasks.forEach { + assert(!allRegisteredTasks.contains(it)) { + printBuildOutput() + "$it task should not be registered in all tasks." + } + } + } +} + +/** + * Method parses the output of a 'tasks --all' build + * and returns a list of all the tasks mentioned in it. + * + * @return A list of all the tasks mentioned in the build 'tasks -all' output + * @throws IllegalStateException if the build output could not be parsed. + */ +private fun BuildResult.getAllTasksFromTheOutput(): List { + + val taskPattern = Regex("^([:\\w]+) - (.*)$") + val tasks = mutableListOf() + + output.lines().forEach { line -> + if (line.matches(taskPattern)) { + tasks.add(taskPattern.find(line)!!.groupValues[1]) + } + } + + return tasks +} \ No newline at end of file