diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/TypeCheckSwiftExportGoldenData.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/TypeCheckSwiftExportGoldenData.java new file mode 100644 index 00000000000..306c83a61ec --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/TypeCheckSwiftExportGoldenData.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010-2024 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.konan.test.blackbox; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("native/swift/swift-export-standalone/testData") +@TestDataPath("$PROJECT_ROOT") +public class TypeCheckSwiftExportGoldenData extends SwiftTypeCheckBaseTest { + @Test + public void testAllFilesPresentInTestData() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/no_package") + @TestDataPath("$PROJECT_ROOT") + public class No_package { + @Test + public void testAllFilesPresentInNo_package() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/no_package"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/no_package/golden_result") + @TestDataPath("$PROJECT_ROOT") + public class Golden_result { + @Test + public void testAllFilesPresentInGolden_result() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/no_package/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Test + @TestMetadata("result.swift") + public void testResult() throws Exception { + runTest("native/swift/swift-export-standalone/testData/no_package/golden_result/result.swift"); + } + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/no_package/input_root") + @TestDataPath("$PROJECT_ROOT") + public class Input_root { + @Test + public void testAllFilesPresentInInput_root() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/no_package/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + } + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/simple") + @TestDataPath("$PROJECT_ROOT") + public class Simple { + @Test + public void testAllFilesPresentInSimple() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/simple/golden_result") + @TestDataPath("$PROJECT_ROOT") + public class Golden_result { + @Test + public void testAllFilesPresentInGolden_result() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Test + @TestMetadata("result.swift") + public void testResult() throws Exception { + runTest("native/swift/swift-export-standalone/testData/simple/golden_result/result.swift"); + } + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/simple/input_root") + @TestDataPath("$PROJECT_ROOT") + public class Input_root { + @Test + public void testAllFilesPresentInInput_root() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + } + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/variables") + @TestDataPath("$PROJECT_ROOT") + public class Variables { + @Test + public void testAllFilesPresentInVariables() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/variables"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/variables/golden_result") + @TestDataPath("$PROJECT_ROOT") + public class Golden_result { + @Test + public void testAllFilesPresentInGolden_result() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/variables/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + + @Test + @TestMetadata("result.swift") + public void testResult() throws Exception { + runTest("native/swift/swift-export-standalone/testData/variables/golden_result/result.swift"); + } + } + + @Nested + @TestMetadata("native/swift/swift-export-standalone/testData/variables/input_root") + @TestDataPath("$PROJECT_ROOT") + public class Input_root { + @Test + public void testAllFilesPresentInInput_root() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/variables/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true); + } + } + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt index a7a405db9fe..45de31bb8db 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt @@ -488,6 +488,17 @@ fun main() { model("CExport", pattern = "^([^_](.+))$", recursive = false) } } + // Swift Export + testGroup( + "native/native.tests/tests-gen/", + "native/swift/swift-export-standalone/testData" + ) { + testClass( + suiteTestClassName = "TypeCheckSwiftExportGoldenData" + ) { + model("", extension = "swift", recursive = true) + } + } } } diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/SwiftTypeCheckBaseTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/SwiftTypeCheckBaseTest.kt new file mode 100644 index 00000000000..6d67111c4b1 --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/SwiftTypeCheckBaseTest.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2024 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.konan.test.blackbox + +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.konan.target.AppleConfigurables +import org.jetbrains.kotlin.konan.target.withOSVersion +import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.invokeSwiftC +import org.jetbrains.kotlin.konan.test.blackbox.support.settings.configurables +import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assumptions +import java.io.File + + +abstract class SwiftTypeCheckBaseTest : AbstractNativeSimpleTest() { + /** + This test is the simplest possible solutions for task KT-65559 + + One reading this test could find themselves confused, with following questions: + 1/ what does it do + 2/ why it is placed in native-test infra + 3/ what actually we do test + + This comment wil try to answer all those questions. + + What we are trying to achieve: + There is a SwiftExport artefact, and we have some integration tests for it. + But our integration tests check only one thing - that our current implementation generates expected source files. + But we do not compile that resulted files, as that actions requires macOS agents with swift installed, + and we want to keep our day2day tests as quick as possible. + + So, we have construct this test - it will take golden data that we are expecting to receive from SwiftExport, + and verify with swift compiler that we expect valid code. This way we have separated tests that verify code generation + from tests that verify code validity. That separation may not be desired, but that separation allows us to keep tests for + code generation fast and TeamCity agent agnostic. + + We do plan to refactor this, and extract infra for running swiftc and xcode into separate module, that will be shared + between SwiftExport, ObjectiveCExport, Kotlin/Native and KGP tests. But currently - the following solution is the simplest one. + */ + fun runTest( + swiftFilePath: String, + ) { + Assumptions.assumeTrue(targets.hostTarget.family.isAppleFamily && targets.testTarget.family.isAppleFamily) + + val swiftFile = File(swiftFilePath) + val cHeader = swiftFile.withReplacedExtensionOrNull("swift", "h") + ?: throw IllegalArgumentException("SwiftTypeCheckBaseTest input should have .h counterpart") + + val configs = testRunSettings.configurables as AppleConfigurables + val swiftTarget = configs.targetTriple.withOSVersion(configs.osVersionMin).toString() + + val args = listOf( + "-typecheck", swiftFile.absolutePath, + "-import-objc-header", cHeader.absolutePath, + "-sdk", configs.absoluteTargetSysRoot, "-target", swiftTarget + ) + + val (exitCode, swiftcOutput, _, _) = + invokeSwiftC(testRunSettings, args) + + assertEquals(ExitCode.OK, exitCode, "swift type checked resulted in: $swiftcOutput") + } +}