Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions Sources/SkipSyntax/Kotlin/KotlinUnitTestTransformer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ final class KotlinUnitTestTransformer: KotlinTransformer {
/// Types annotated with `@Suite` in Swift source.
private var swiftTestingSuites: [Source.FilePath: Set<String>] = [:]

static let testRunnerAnnotation: String? = nil // was: "@org.junit.runner.RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class)"

func gather(from syntaxTree: SyntaxTree) {
var testFunctions: Set<String> = []
var suiteTypes: Set<String> = []
Expand Down Expand Up @@ -88,11 +86,7 @@ final class KotlinUnitTestTransformer: KotlinTransformer {
} else {
functionDeclaration.annotations += ["@Test"]
}
if let testRunnerAnnotation = Self.testRunnerAnnotation {
if !owningClass.annotations.contains(testRunnerAnnotation) {
owningClass.annotations += [testRunnerAnnotation]
}
}
owningClass.addTestRunnerAnnotation()
// For Swift Testing @Suite types that don't extend XCTestCase,
// make them implement the XCTestCase interface for assertion access
if isSwiftTesting && !isXCTest {
Expand Down Expand Up @@ -141,9 +135,7 @@ final class KotlinUnitTestTransformer: KotlinTransformer {
let classDeclaration = KotlinClassDeclaration(name: className, signature: .named(className, []), declarationType: .classDeclaration)
classDeclaration.modifiers = Modifiers(isFinal: true)
classDeclaration.inherits = [.named("XCTestCase", [])]
if let testRunnerAnnotation = Self.testRunnerAnnotation {
classDeclaration.annotations = [testRunnerAnnotation]
}
classDeclaration.addTestRunnerAnnotation()
classDeclaration.extras = functionDeclaration.extras

// Move the function into the class
Expand Down Expand Up @@ -215,3 +207,23 @@ final class KotlinUnitTestTransformer: KotlinTransformer {
return infos.contains { $0.inherits.contains { $0.isNamed("XCTestCase", moduleName: "XCTest", generics: []) } }
}
}

extension KotlinClassDeclaration {
/// A default annotation to add to generated test cases, which is required by Robolectric to correcly mock various Android API
///
/// Failure to include this will result in errors like:
/// ```
/// java.lang.RuntimeException: Method parse in android.net.Uri not mocked.
/// ```
/// See also: https://developer.android.com/training/testing/local-tests#mocking-dependencies
static let testRunnerAnnotation: String? = "@org.junit.runner.RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class)"

func addTestRunnerAnnotation() {
if let testRunnerAnnotation = Self.testRunnerAnnotation {
// only add the annotation of the class itself has not already specified an annotation
if !self.annotations.contains(where: { $0.hasPrefix("@org.junit.runner.RunWith(") || $0.hasPrefix("@RunWith(") }) {
self.annotations += [testRunnerAnnotation]
}
}
}
}
27 changes: 15 additions & 12 deletions Tests/SkipSyntaxTests/TransformerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// SPDX-License-Identifier: AGPL-3.0-only

import XCTest
@testable import SkipSyntax

let testRunnerAnnotation: String = KotlinClassDeclaration.testRunnerAnnotation?.appending("\n") ?? ""

final class TransformerTests: XCTestCase {
func testUnitTestTransformer() async throws {
Expand All @@ -22,7 +25,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal open class TestCase: XCTestCase {
\(testRunnerAnnotation)internal open class TestCase: XCTestCase {
@Test
internal open fun testSomeTest() = Unit

Expand Down Expand Up @@ -52,7 +55,7 @@ final class TransformerTests: XCTestCase {

import skip.unit.*

internal open class TestCase: XCTestCase {
\(testRunnerAnnotation)internal open class TestCase: XCTestCase {

@OptIn(ExperimentalCoroutinesApi::class)
@Test
Expand Down Expand Up @@ -86,7 +89,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class MyTests: XCTestCase {
\(testRunnerAnnotation)internal class MyTests: XCTestCase {
@Test
internal fun addition(): Unit = expectEqual(1 + 1, 2)
}
Expand All @@ -106,7 +109,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class MyTests: XCTestCase {
\(testRunnerAnnotation)internal class MyTests: XCTestCase {
@Test
internal fun boolCheck() {
val x = true
Expand All @@ -128,7 +131,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class MyTests: XCTestCase {
\(testRunnerAnnotation)internal class MyTests: XCTestCase {
@Test
internal fun inequality(): Unit = expectNotEqual(1, 2)
}
Expand All @@ -148,7 +151,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class MyTests: XCTestCase {
\(testRunnerAnnotation)internal class MyTests: XCTestCase {
@Test
internal fun unwrap() {
val x: Int? = 42
Expand Down Expand Up @@ -178,7 +181,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class MathTests: XCTestCase {
\(testRunnerAnnotation)internal class MathTests: XCTestCase {
@Test
internal fun addition(): Unit = expectEqual(2 + 2, 4)

Expand All @@ -205,7 +208,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class CompTests: XCTestCase {
\(testRunnerAnnotation)internal class CompTests: XCTestCase {
@Test
internal fun comparisons() {
expectGreaterThan(5, 3)
Expand All @@ -227,7 +230,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class AdditionTests: XCTestCase {
\(testRunnerAnnotation)internal class AdditionTests: XCTestCase {
@Test
internal fun addition(): Unit = expectEqual(1 + 2, 3)
}
Expand All @@ -252,12 +255,12 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class AdditionTests: XCTestCase {
\(testRunnerAnnotation)internal class AdditionTests: XCTestCase {
@Test
internal fun addition(): Unit = expectEqual(1 + 1, 2)
}

internal class SubtractionTests: XCTestCase {
\(testRunnerAnnotation)internal class SubtractionTests: XCTestCase {
@Test
internal fun subtraction(): Unit = expectEqual(5 - 3, 2)
}
Expand All @@ -277,7 +280,7 @@ final class TransformerTests: XCTestCase {
""", kotlin: """
import skip.unit.*

internal class BoolCheckTests: XCTestCase {
\(testRunnerAnnotation)internal class BoolCheckTests: XCTestCase {
@Test
internal fun boolCheck() {
val x = true
Expand Down
2 changes: 1 addition & 1 deletion Tests/SkipSyntaxTests/XCTestCaseAdditions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ extension XCTestCase {
].compactMap({ $0 })

do {
let result = try await Process.checkNonZeroExit(arguments: args, environment: env, loggingHandler: { msg in
let result = try await Process.checkNonZeroExit(arguments: args, environmentBlock: .init(env), loggingHandler: { msg in
print("kotlinc> " + msg)
})

Expand Down
Loading