From 8e2c3718784a881c260343a3fe4abb5c8fb3e931 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Tue, 1 Apr 2025 18:52:18 -0400 Subject: [PATCH 1/3] Remove expicit .dynamic for SkipAndroidBridge product --- Package.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index e099e01..69c6351 100644 --- a/Package.swift +++ b/Package.swift @@ -6,14 +6,14 @@ let package = Package( defaultLocalization: "en", platforms: [.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)], products: [ - .library(name: "SkipAndroidBridge", type: .dynamic, targets: ["SkipAndroidBridge"]), + .library(name: "SkipAndroidBridge", targets: ["SkipAndroidBridge"]), .library(name: "SkipAndroidBridgeSamples", type: .dynamic, targets: ["SkipAndroidBridgeSamples"]), ], dependencies: [ .package(url: "https://source.skip.tools/skip.git", from: "1.2.34"), .package(url: "https://source.skip.tools/skip-foundation.git", from: "1.3.1"), - .package(url: "https://source.skip.tools/swift-jni.git", "0.0.0"..<"2.0.0"), - .package(url: "https://source.skip.tools/skip-bridge.git", "0.0.0"..<"2.0.0"), + //.package(url: "https://source.skip.tools/skip-bridge.git", "0.0.0"..<"2.0.0"), + .package(url: "https://source.skip.tools/skip-bridge.git", branch: "no-dynamic"), .package(url: "https://source.skip.tools/swift-android-native.git", "0.0.0"..<"2.0.0") ], targets: [ From ab8e5fed08edf06a8079f69cf4c0741dfa7585f2 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Tue, 1 Apr 2025 19:15:33 -0400 Subject: [PATCH 2/3] Remove explicit SwiftJNI dependency --- Package.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Package.swift b/Package.swift index 69c6351..f31b86f 100644 --- a/Package.swift +++ b/Package.swift @@ -19,7 +19,6 @@ let package = Package( targets: [ .target(name: "SkipAndroidBridge", dependencies: [ .product(name: "SkipBridge", package: "skip-bridge"), - .product(name: "SwiftJNI", package: "swift-jni"), .product(name: "SkipFoundation", package: "skip-foundation"), .product(name: "AndroidNative", package: "swift-android-native", condition: .when(platforms: [.android])), ], plugins: [.plugin(name: "skipstone", package: "skip")]), From 5bb061401b04df7b74918cd1c6d5425417f2ece0 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Tue, 1 Apr 2025 20:24:26 -0400 Subject: [PATCH 3/3] Move AndroidBridgeTests.swift to SkipAndroidBridgeSamplesTests --- Package.swift | 5 -- .../SkipAndroidBridgeSamplesTests.swift | 28 +++++++++++ .../AndroidBridgeTests.swift | 50 ------------------- Tests/SkipAndroidBridgeTests/Skip/skip.yml | 8 --- .../SkipAndroidBridgeTests/XCSkipTests.swift | 30 ----------- 5 files changed, 28 insertions(+), 93 deletions(-) delete mode 100644 Tests/SkipAndroidBridgeTests/AndroidBridgeTests.swift delete mode 100644 Tests/SkipAndroidBridgeTests/Skip/skip.yml delete mode 100644 Tests/SkipAndroidBridgeTests/XCSkipTests.swift diff --git a/Package.swift b/Package.swift index f31b86f..703c859 100644 --- a/Package.swift +++ b/Package.swift @@ -23,11 +23,6 @@ let package = Package( .product(name: "AndroidNative", package: "swift-android-native", condition: .when(platforms: [.android])), ], plugins: [.plugin(name: "skipstone", package: "skip")]), - .testTarget(name: "SkipAndroidBridgeTests", dependencies: [ - "SkipAndroidBridge", - .product(name: "SkipTest", package: "skip"), - ], plugins: [.plugin(name: "skipstone", package: "skip")]), - .target(name: "SkipAndroidBridgeSamples", dependencies: [ "SkipAndroidBridge", ], resources: [.process("Resources")], plugins: [.plugin(name: "skipstone", package: "skip")]), diff --git a/Tests/SkipAndroidBridgeSamplesTests/SkipAndroidBridgeSamplesTests.swift b/Tests/SkipAndroidBridgeSamplesTests/SkipAndroidBridgeSamplesTests.swift index daeb1f4..9741f15 100644 --- a/Tests/SkipAndroidBridgeSamplesTests/SkipAndroidBridgeSamplesTests.swift +++ b/Tests/SkipAndroidBridgeSamplesTests/SkipAndroidBridgeSamplesTests.swift @@ -19,6 +19,34 @@ final class SkipAndroidBridgeSamplesTests: XCTestCase { #endif } + func testAndroidBridge() throws { + #if SKIP + let context = ProcessInfo.processInfo.androidContext + XCTAssertNotNil(context, "ProcessInfo.processInfo.androidContext was nil") + + let filesDir = URL(fileURLWithPath: context.getFilesDir().getAbsolutePath(), isDirectory: true) + let cacheDir = URL(fileURLWithPath: context.getCacheDir().getAbsolutePath(), isDirectory: true) + + if isRobolectric { + // Robolectric's files folder is tough to predict (e.g. /var/folders/zl/wkdjv4s1271fbm6w0plzknkh0000gn/T/robolectric-AndroidBridgeTests_testAndroidBridge_SkipAndroidBridge_debugUnitTest10131350412654065418/skip.android.bridge.samples.test-dataDir/files) + XCTAssertTrue(filesDir.path.hasSuffix("/files"), "unexpected filesDir.path: \(filesDir.path)") + XCTAssertTrue(cacheDir.path.hasSuffix("/cache"), "unexpected cacheDir.path: \(cacheDir.path)") + } else { + // …but Android is predictably the app's "files" and "cache" directories + XCTAssertEqual("/data/user/0/skip.android.bridge.samples.test/files", filesDir.path) + XCTAssertEqual("/data/user/0/skip.android.bridge.samples.test/cache", cacheDir.path) + } + + // make sure we can read and write to the filesDir + try "ABC".write(to: filesDir.appendingPathComponent("test.txt"), atomically: true, encoding: .utf8) + try "XYZ".write(to: cacheDir.appendingPathComponent("test.txt"), atomically: true, encoding: .utf8) + + try AndroidBridgeBootstrap.initAndroidBridge(filesDir: filesDir.path, cacheDir: cacheDir.path) + #else + throw XCTSkip("testAndroidBridge only works from SKIP") + #endif + } + func testSimpleConstants() { XCTAssertEqual(swiftStringConstant, "s") } diff --git a/Tests/SkipAndroidBridgeTests/AndroidBridgeTests.swift b/Tests/SkipAndroidBridgeTests/AndroidBridgeTests.swift deleted file mode 100644 index 58bb010..0000000 --- a/Tests/SkipAndroidBridgeTests/AndroidBridgeTests.swift +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2024–2025 Skip -// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception -import XCTest -#if canImport(OSLog) -import OSLog -#endif -import Foundation -import SkipBridge -@testable import SkipAndroidBridge - -#if canImport(OSLog) -let logger: Logger = Logger(subsystem: "skip.android.bridge", category: "AndroidBridgeTests") -#endif - -@available(macOS 13, *) -final class AndroidBridgeTests: XCTestCase { - override func setUp() { - #if SKIP - loadPeerLibrary(packageName: "skip-android-bridge", moduleName: "SkipAndroidBridge") - #endif - } - - func testAndroidBridge() throws { - #if SKIP - let context = ProcessInfo.processInfo.androidContext - XCTAssertNotNil(context, "ProcessInfo.processInfo.androidContext was nil") - - let filesDir = URL(fileURLWithPath: context.getFilesDir().getAbsolutePath(), isDirectory: true) - let cacheDir = URL(fileURLWithPath: context.getCacheDir().getAbsolutePath(), isDirectory: true) - - if isRobolectric { - // Robolectric's files folder is tough to predict (e.g. /var/folders/zl/wkdjv4s1271fbm6w0plzknkh0000gn/T/robolectric-AndroidBridgeTests_testAndroidBridge_SkipAndroidBridge_debugUnitTest10131350412654065418/skip.android.bridge.test-dataDir/files) - XCTAssertTrue(filesDir.path.hasSuffix("/files"), "unexpected filesDir.path: \(filesDir.path)") - XCTAssertTrue(cacheDir.path.hasSuffix("/cache"), "unexpected cacheDir.path: \(cacheDir.path)") - } else { - // …but Android is predictably the app's "files" and "cache" directories - XCTAssertEqual("/data/user/0/skip.android.bridge.test/files", filesDir.path) - XCTAssertEqual("/data/user/0/skip.android.bridge.test/cache", cacheDir.path) - } - - // make sure we can read and write to the filesDir - try "ABC".write(to: filesDir.appendingPathComponent("test.txt"), atomically: true, encoding: .utf8) - try "XYZ".write(to: cacheDir.appendingPathComponent("test.txt"), atomically: true, encoding: .utf8) - - try AndroidBridgeBootstrap.initAndroidBridge(filesDir: filesDir.path, cacheDir: cacheDir.path) - #else - throw XCTSkip("testAndroidBridge only works from SKIP") - #endif - } -} diff --git a/Tests/SkipAndroidBridgeTests/Skip/skip.yml b/Tests/SkipAndroidBridgeTests/Skip/skip.yml deleted file mode 100644 index b6e8347..0000000 --- a/Tests/SkipAndroidBridgeTests/Skip/skip.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Configuration file for https://skip.tools project -# -# Kotlin dependencies and Gradle build options for this module can be configured here -#build: -# contents: -# - block: 'dependencies' -# contents: -# - 'implementation("androidx.compose.runtime:runtime")' diff --git a/Tests/SkipAndroidBridgeTests/XCSkipTests.swift b/Tests/SkipAndroidBridgeTests/XCSkipTests.swift deleted file mode 100644 index 45ef89e..0000000 --- a/Tests/SkipAndroidBridgeTests/XCSkipTests.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024–2025 Skip -// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception -import Foundation -#if os(macOS) // Skip transpiled tests only run on macOS targets -import SkipTest - -/// This test case will run the transpiled tests for the Skip module. -@available(macOS 13, macCatalyst 16, *) -final class XCSkipTests: XCTestCase, XCGradleHarness { - public func testSkipModule() async throws { - // Run the transpiled JUnit tests for the current test module. - // These tests will be executed locally using Robolectric. - // Connected device or emulator tests can be run by setting the - // `ANDROID_SERIAL` environment variable to an `adb devices` - // ID in the scheme's Run settings. - // - // Note that it isn't currently possible to filter the tests to run. - try await runGradleTests() - } -} -#endif - -/// True when running in a transpiled Java runtime environment -let isJava = ProcessInfo.processInfo.environment["java.io.tmpdir"] != nil -/// True when running within an Android environment (either an emulator or device) -let isAndroid = isJava && ProcessInfo.processInfo.environment["ANDROID_ROOT"] != nil -/// True is the transpiled code is currently running in the local Robolectric test environment -let isRobolectric = isJava && !isAndroid -/// True if the system's `Int` type is 32-bit. -let is32BitInteger = Int64(Int.max) == Int64(Int32.max)