migueldeicaza / SwiftGodot

New Godot bindings for Swift
https://migueldeicaza.github.io/SwiftGodotDocs/tutorials/swiftgodot-tutorials/
MIT License
1.06k stars 64 forks source link

SwiftGodotTestability can't be used to test user extensions #424

Open tishin opened 5 months ago

tishin commented 5 months ago

Given a simple package description with an extension target depending on SwiftGodot and a test target depending on SwiftGodotTestability:

// swift-tools-version: 5.10

import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms: [.macOS(.v13)],
    products: [
        .library(name: "MyLibrary", type: .dynamic, targets: ["MyLibrary"])
    ],
    dependencies: [
        .package(url: "https://github.com/migueldeicaza/SwiftGodot", branch: "main"),
    ],
    targets: [
        .target(
            name: "MyLibrary",
            dependencies: [
                .product(name: "SwiftGodot", package: "SwiftGodot"),
            ]),
        .testTarget(
            name: "MyLibraryTests",
            dependencies: [
                "MyLibrary",
                .product(name: "SwiftGodotTestability", package: "SwiftGodot"),
            ]),
    ]
)

Running tests throws an error: Swift package target 'SwiftGodot' is linked as a static library by 'MyLibraryTests' and 'SwiftGodot', but cannot be built dynamically because there is a package product with the same name.

SwiftGodot is linked dynamically to the extension target MyLibrary, but it's linked statically to SwiftGodotTestability, which is linked statically to MyLibraryTests. Marking SwiftGodotTestability as a dynamic product does not solve the issue, because SwiftGodot target would still be linked statically to SwiftGodotTestability, still causing a mismatch with its dynamic product counterpart.

tishin commented 5 months ago

It's possible now to run tests by changing MyLibrary's depependency to SwiftGodotStatic:

.target(
    name: "MyLibrary",
    dependencies: [
-        .product(name: "SwiftGodot", package: "SwiftGodot"),
+        .product(name: "SwiftGodotStatic", package: "SwiftGodot"),
    ]),

It's a bit counterintuitive, and if you want to keep SwiftGodot dynamic, you'd have to switch between the two to run tests. But since it's not possible to link internal package target dynamically, the only option to make dynamic SwiftGodot product testable is to split the package into multiple package description files and make SwiftGodotTestability dependant on the dynamic SwiftGodot product instead of the internal target. And I'm not sure if it's reasonable.