1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Basics
import PackageModel
import SPMTestSupport
import XCTest
final class ResourcesTests: XCTestCase {
func testSimpleResources() async throws {
try await fixture(name: "Resources/Simple") { fixturePath in
var executables = ["SwiftyResource"]
// Objective-C module requires macOS
#if os(macOS)
executables.append("SeaResource")
executables.append("CPPResource")
#endif
for execName in executables {
let (output, _) = try await executeSwiftRun(fixturePath, execName)
XCTAssertTrue(output.contains("foo"), output)
}
}
}
func testLocalizedResources() async throws {
try await fixture(name: "Resources/Localized") { fixturePath in
try await executeSwiftBuild(fixturePath)
let exec = AbsolutePath(".build/debug/exe", relativeTo: fixturePath)
// Note: <rdar://problem/59738569> Source from LANG and -AppleLanguages on command line for Linux resources
let output = try await AsyncProcess.checkNonZeroExit(args: exec.pathString, "-AppleLanguages", "(en_US)")
XCTAssertEqual(output, """
¡Hola Mundo!
Hallo Welt!
Bonjour le monde !
""")
}
}
func testResourcesInMixedClangPackage() async throws {
#if !os(macOS)
// Running swift-test fixtures on linux is not yet possible.
try XCTSkipIf(true, "test is only supported on macOS")
#endif
try await fixture(name: "Resources/Simple") { fixturePath in
await XCTAssertBuilds(fixturePath, extraArgs: ["--target", "MixedClangResource"])
}
}
func testMovedBinaryResources() async throws {
try await fixture(name: "Resources/Moved") { fixturePath in
var executables = ["SwiftyResource"]
// Objective-C module requires macOS
#if os(macOS)
executables.append("SeaResource")
#endif
let binPath = try AbsolutePath(validating:
await executeSwiftBuild(fixturePath, configuration: .Release, extraArgs: ["--show-bin-path"]).stdout
.trimmingCharacters(in: .whitespacesAndNewlines)
)
for execName in executables {
_ = try await executeSwiftBuild(fixturePath, configuration: .Release, extraArgs: ["--product", execName])
try await withTemporaryDirectory(prefix: execName) { tmpDirPath in
defer {
// Unblock and remove the tmp dir on deinit.
try? localFileSystem.chmod(.userWritable, path: tmpDirPath, options: [.recursive])
try? localFileSystem.removeFileTree(tmpDirPath)
}
let destBinPath = tmpDirPath.appending(component: execName)
// Move the binary
try localFileSystem.move(from: binPath.appending(component: execName), to: destBinPath)
// Move the resources
try localFileSystem
.getDirectoryContents(binPath)
.filter { $0.contains(execName) && $0.hasSuffix(".bundle") || $0.hasSuffix(".resources") }
.forEach { try localFileSystem.move(from: binPath.appending(component: $0), to: tmpDirPath.appending(component: $0)) }
// Run the binary
let output = try await AsyncProcess.checkNonZeroExit(args: destBinPath.pathString)
XCTAssertTrue(output.contains("foo"))
}
}
}
}
func testSwiftResourceAccessorDoesNotCauseInconsistentImportWarning() async throws {
try await fixture(name: "Resources/FoundationlessClient/UtilsWithFoundationPkg") { fixturePath in
await XCTAssertBuilds(
fixturePath,
Xswiftc: ["-warnings-as-errors"]
)
}
}
func testResourceBundleInClangPackageWhenRunningSwiftTest() async throws {
#if !os(macOS)
// Running swift-test fixtures on linux is not yet possible.
try XCTSkipIf(true, "test is only supported on macOS")
#endif
try await fixture(name: "Resources/Simple") { fixturePath in
await XCTAssertSwiftTest(fixturePath, extraArgs: ["--filter", "ClangResourceTests"])
}
}
func testResourcesEmbeddedInCode() async throws {
try await fixture(name: "Resources/EmbedInCodeSimple") { fixturePath in
let execPath = fixturePath.appending(components: ".build", "debug", "EmbedInCodeSimple")
try await executeSwiftBuild(fixturePath)
let result = try await AsyncProcess.checkNonZeroExit(args: execPath.pathString)
XCTAssertEqual(result, "hello world\n\n")
let resourcePath = fixturePath.appending(
components: "Sources", "EmbedInCodeSimple", "best.txt")
// Check incremental builds
for i in 0..<2 {
let content = "Hi there \(i)!"
// Update the resource file.
try localFileSystem.writeFileContents(resourcePath, string: content)
try await executeSwiftBuild(fixturePath)
// Run the executable again.
let result2 = try await AsyncProcess.checkNonZeroExit(args: execPath.pathString)
XCTAssertEqual(result2, "\(content)\n")
}
}
}
func testResourcesOutsideOfTargetCanBeIncluded() async throws {
try UserToolchain.default.skipUnlessAtLeastSwift6()
try await testWithTemporaryDirectory { tmpPath in
let packageDir = tmpPath.appending(components: "MyPackage")
let manifestFile = packageDir.appending("Package.swift")
try localFileSystem.createDirectory(manifestFile.parentDirectory, recursive: true)
try localFileSystem.writeFileContents(
manifestFile,
string: """
// swift-tools-version: 6.0
import PackageDescription
let package = Package(name: "MyPackage",
targets: [
.executableTarget(
name: "exec",
resources: [.copy("../resources")]
)
])
""")
let targetSourceFile = packageDir.appending(components: "Sources", "exec", "main.swift")
try localFileSystem.createDirectory(targetSourceFile.parentDirectory, recursive: true)
try localFileSystem.writeFileContents(targetSourceFile, string: """
import Foundation
print(Bundle.module.resourcePath ?? "<empty>")
""")
let resource = packageDir.appending(components: "Sources", "resources", "best.txt")
try localFileSystem.createDirectory(resource.parentDirectory, recursive: true)
try localFileSystem.writeFileContents(resource, string: "best")
let (_, stderr) = try await executeSwiftBuild(packageDir, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"])
// Filter some unrelated output that could show up on stderr.
let filteredStderr = stderr.components(separatedBy: "\n").filter { !$0.contains("[logging]") }.joined(separator: "\n")
XCTAssertEqual(filteredStderr, "", "unexpectedly received error output: \(stderr)")
let builtProductsDir = packageDir.appending(components: [".build", "debug"])
// On Apple platforms, it's going to be `.bundle` and elsewhere `.resources`.
let potentialResourceBundleName = try XCTUnwrap(localFileSystem.getDirectoryContents(builtProductsDir).filter { $0.hasPrefix("MyPackage_exec.") }.first)
let resourcePath = builtProductsDir.appending(components: [potentialResourceBundleName, "resources", "best.txt"])
XCTAssertTrue(localFileSystem.exists(resourcePath), "resource file wasn't copied by the build")
let contents = try String(contentsOfFile: resourcePath.pathString)
XCTAssertEqual(contents, "best", "unexpected resource contents: \(contents)")
}
}
}
|