Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-12912] Fix crash in test targets with Bundle.module in 5.3 #2905

Merged
merged 1 commit into from
Sep 17, 2020
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
76 changes: 76 additions & 0 deletions IntegrationTests/Tests/IntegrationTests/BasicTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,80 @@ final class BasicTests: XCTestCase {
}
}
}

func testSwiftTestWithResources() throws {
try withTemporaryDirectory { dir in
let toolDir = dir.appending(component: "swiftTestResources")
try localFileSystem.createDirectory(toolDir)
try localFileSystem.writeFileContents(
toolDir.appending(component: "Package.swift"),
bytes: ByteString(encodingAsUTF8: """
// swift-tools-version:5.3
import PackageDescription

let package = Package(
name: "AwesomeResources",
targets: [
.target(name: "AwesomeResources", resources: [.copy("hello.txt")]),
.testTarget(name: "AwesomeResourcesTest", dependencies: ["AwesomeResources"], resources: [.copy("world.txt")])
]
)
""")
)
try localFileSystem.createDirectory(toolDir.appending(component: "Sources"))
try localFileSystem.createDirectory(toolDir.appending(components: "Sources", "AwesomeResources"))
try localFileSystem.writeFileContents(
toolDir.appending(components: "Sources", "AwesomeResources", "AwesomeResource.swift"),
bytes: ByteString(encodingAsUTF8: """
import Foundation

public struct AwesomeResource {
public init() {}
public let hello = try! String(contentsOf: Bundle.module.url(forResource: "hello", withExtension: "txt")!)
}

""")
)

try localFileSystem.writeFileContents(
toolDir.appending(components: "Sources", "AwesomeResources", "hello.txt"),
bytes: ByteString(encodingAsUTF8: "hello")
)

try localFileSystem.createDirectory(toolDir.appending(component: "Tests"))
try localFileSystem.createDirectory(toolDir.appending(components: "Tests", "AwesomeResourcesTest"))

try localFileSystem.writeFileContents(
toolDir.appending(components: "Tests", "AwesomeResourcesTest", "world.txt"),
bytes: ByteString(encodingAsUTF8: "world")
)

try localFileSystem.writeFileContents(
toolDir.appending(components: "Tests", "AwesomeResourcesTest", "MyTests.swift"),
bytes: ByteString(encodingAsUTF8: """
import XCTest
import Foundation
import AwesomeResources

final class MyTests: XCTestCase {
func testFoo() {
XCTAssertTrue(AwesomeResource().hello == "hello")
}
func testBar() {
let world = try! String(contentsOf: Bundle.module.url(forResource: "world", withExtension: "txt")!)
XCTAssertTrue(world == "world")
}
}
"""))

let testOutput = try sh(swiftTest, "--package-path", toolDir, "--filter", "MyTests.*").stderr

// Check the test log.
XCTAssertContents(testOutput) { checker in
checker.check(.contains("Test Suite 'MyTests' started"))
checker.check(.contains("Test Suite 'MyTests' passed"))
checker.check(.contains("Executed 2 tests, with 0 failures"))
}
}
}
}
14 changes: 8 additions & 6 deletions Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -578,19 +578,21 @@ public final class SwiftTargetBuildDescription {
// Do nothing if we're not generating a bundle.
guard let bundlePath = self.bundlePath else { return }

// Compute the basename of the bundle.
let bundleBasename = bundlePath.basename

let stream = BufferedOutputByteStream()
stream <<< """
import class Foundation.Bundle

extension Foundation.Bundle {
static var module: Bundle = {
let bundlePath = Bundle.main.bundlePath + "/" + "\(bundleBasename)"
guard let bundle = Bundle(path: bundlePath) else {
fatalError("could not load resource bundle: \\(bundlePath)")
let mainPath = Bundle.main.bundlePath + "/" + "\(bundlePath.basename)"
let buildPath = "\(bundlePath.pathString)"

let preferredBundle = Bundle(path: mainPath)

guard let bundle = preferredBundle != nil ? preferredBundle : Bundle(path: buildPath) else {
fatalError("could not load resource bundle: from \\(mainPath) or \\(buildPath)")
}

return bundle
}()
}
Expand Down