Skip to content

Commit 934eea4

Browse files
committed
Add tests for swift-script
1 parent 9baf376 commit 934eea4

File tree

9 files changed

+194
-1
lines changed

9 files changed

+194
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
let arguments = CommandLine.arguments.dropFirst()
2+
print(arguments.map{"\"\($0)\""}.joined(separator: " "))
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"dependencies" : [
3+
4+
],
5+
"sourceFile" : "\/Users\/yr.chen\/Developer\/GSoC\/swift-package-manager\/Fixtures\/Scripts\/EchoArguments\/EchoArguments.swift"
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@package(name: "CwdDump", path: "cwd-dump")
2+
import CwdDump
3+
4+
CwdDump.main()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"dependencies" : [
3+
{
4+
"package" : {
5+
"raw" : "name:\"CwdDump\",path:\"\/Users\/yr.chen\/Developer\/GSoC\/swift-package-manager\/Fixtures\/Scripts\/EchoCWD\/cwd-dump\"",
6+
"path" : "\/Users\/yr.chen\/Developer\/GSoC\/swift-package-manager\/Fixtures\/Scripts\/EchoCWD\/cwd-dump",
7+
"name" : "CwdDump"
8+
},
9+
"modules" : [
10+
"CwdDump"
11+
]
12+
}
13+
],
14+
"sourceFile" : "\/Users\/yr.chen\/Developer\/GSoC\/swift-package-manager\/Fixtures\/Scripts\/EchoCWD\/EchoCWD.swift"
15+
}
16+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// swift-tools-version:5.5
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "CwdDump",
8+
products: [
9+
// Products define the executables and libraries a package produces, and make them visible to other packages.
10+
.library(
11+
name: "CwdDump",
12+
targets: ["CwdDump"])
13+
],
14+
targets: [
15+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
16+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
17+
.target(name: "CwdDump")
18+
]
19+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Foundation
2+
3+
public struct CwdDump {
4+
public static func main() {
5+
print(FileManager().currentDirectoryPath)
6+
}
7+
}

Sources/SPMTestSupport/SwiftPMProduct.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public enum SwiftPMProduct: Product {
1717
case SwiftPackage
1818
case SwiftTest
1919
case SwiftRun
20+
case SwiftScript
2021
case XCTestHelper
2122

2223
/// Executable name.
@@ -30,6 +31,8 @@ public enum SwiftPMProduct: Product {
3031
return RelativePath("swift-test")
3132
case .SwiftRun:
3233
return RelativePath("swift-run")
34+
case .SwiftScript:
35+
return RelativePath("swift-script")
3336
case .XCTestHelper:
3437
return RelativePath("swiftpm-xctest-helper")
3538
}

Sources/SPMTestSupport/misc.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,23 @@ public func fixture(
6262
return
6363
}
6464

65-
// The fixture contains either a checkout or just a Git directory.
65+
// The fixture contains either a checkout, a script or just a Git directory.
6666
if localFileSystem.isFile(fixtureDir.appending(component: "Package.swift")) {
6767
// It's a single package, so copy the whole directory as-is.
6868
let dstDir = tmpDirPath.appending(component: copyName)
6969
try systemQuietly("cp", "-R", "-H", fixtureDir.pathString, dstDir.pathString)
7070

7171
// Invoke the block, passing it the path of the copied fixture.
7272
try body(dstDir)
73+
} else if localFileSystem.isFile(fixtureDir.appending(component: "PackageSyntax.txt")) {
74+
// It's a directory with scripts, so copy the whole directory as-is.
75+
let dstDir = tmpDirPath.appending(component: copyName)
76+
try systemQuietly("cp", "-R", "-H", fixtureDir.pathString, dstDir.pathString)
77+
78+
// Mock package-syntax-parser output with PackageSyntax.txt
79+
try withPackageSyntax(from: dstDir.appending(component: "PackageSyntax.txt")) {
80+
try body(dstDir)
81+
}
7382
} else {
7483
// Copy each of the package directories and construct a git repo in it.
7584
for fileName in try localFileSystem.getDirectoryContents(fixtureDir).sorted() {
@@ -249,3 +258,19 @@ public func loadPackageGraph(
249258
createREPLProduct: createREPLProduct
250259
)
251260
}
261+
262+
private func withPackageSyntax(from file: AbsolutePath, _ body: () throws -> Void) throws -> Void {
263+
var pathSuffix = ""
264+
if let PATH = ProcessEnv.path {
265+
pathSuffix += ":" + PATH
266+
}
267+
try withTemporaryDirectory { path in
268+
let parser = path.appending(component: "package-syntax-parser")
269+
try localFileSystem.writeFileContents(parser) {
270+
$0.write("cat \(file.toJSON())\n")
271+
$0.flush()
272+
}
273+
try localFileSystem.chmod(.executable, path: parser)
274+
try withCustomEnv(["PATH": path.pathString + pathSuffix], body: body)
275+
}
276+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import XCTest
12+
13+
import SPMTestSupport
14+
import Commands
15+
import TSCBasic
16+
17+
final class ScriptToolTests: XCTestCase {
18+
private func execute(_ args: [String]) throws -> (stdout: String, stderr: String) {
19+
return try SwiftPMProduct.SwiftScript.execute(args)
20+
}
21+
22+
private func build(_ args: String...) throws -> (stdout: String, stderr: String) {
23+
return try execute(["build"] + args)
24+
}
25+
26+
private func run(_ args: String...) throws -> (stdout: String, stderr: String) {
27+
return try execute(["run"] + args)
28+
}
29+
30+
func testUsage() throws {
31+
let stdout = try execute(["-help"]).stdout
32+
XCTAssert(stdout.contains("USAGE: swift script <subcommand>"), "got stdout:\n" + stdout)
33+
}
34+
35+
func testSeeAlso() throws {
36+
let stdout = try execute(["--help"]).stdout
37+
XCTAssert(stdout.contains("SEE ALSO: swift build, swift run, swift package, swift test"), "got stdout:\n" + stdout)
38+
}
39+
40+
func testVersion() throws {
41+
let stdout = try execute(["--version"]).stdout
42+
XCTAssert(stdout.contains("Swift Package Manager"), "got stdout:\n" + stdout)
43+
}
44+
45+
func testWrongScriptPath() throws {
46+
try withTemporaryDirectory { path in
47+
let pathString = path.appending(component: "EchoArguments").pathString
48+
do {
49+
_ = try run(pathString)
50+
XCTFail("Unexpected success")
51+
} catch SwiftPMProductError.executionFailure(_, _, let stderr) {
52+
XCTExpectFailure() // FIXME: Seems an implementation bug of TSC?
53+
XCTAssertEqual(stderr, "error: \(pathString) doesn't exist\n")
54+
}
55+
}
56+
}
57+
58+
func testArgumentPassing() throws {
59+
fixture(name: "Scripts/EchoArguments") { path in
60+
let result = try run(path.appending(component: "EchoArguments.swift").pathString,
61+
"1", "--hello", "world")
62+
63+
// We only expect tool's output on the stdout stream.
64+
XCTAssertEqual(result.stdout.trimmingCharacters(in: .whitespacesAndNewlines),
65+
#""1" "--hello" "world""#)
66+
67+
// swift-build-tool output should go to stderr.
68+
XCTAssertMatch(result.stderr, .contains("Using cache: EchoArguments-"))
69+
XCTAssertMatch(result.stderr, .contains("Compiling"))
70+
XCTAssertMatch(result.stderr, .contains("Linking"))
71+
}
72+
}
73+
74+
func testCurrentWorkingDirectoryWithLocalDependency() throws {
75+
fixture(name: "Scripts/EchoCWD") { path in
76+
let result = try run(path.appending(component: "EchoCWD.swift").pathString)
77+
78+
XCTAssertEqual(result.stdout.trimmingCharacters(in: .whitespacesAndNewlines),
79+
localFileSystem.currentWorkingDirectory?.pathString)
80+
}
81+
}
82+
83+
func testPrebuild() throws {
84+
fixture(name: "Scripts/EchoArguments") { path in
85+
let result = try build(path.appending(component: "EchoArguments.swift").pathString)
86+
87+
// swift-build-tool output should go to stderr.
88+
XCTAssertMatch(result.stderr, .contains("Using cache: EchoArguments-"))
89+
XCTAssertMatch(result.stderr, .contains("Compiling"))
90+
XCTAssertMatch(result.stderr, .contains("Linking"))
91+
}
92+
}
93+
94+
func testQuietMode() throws {
95+
fixture(name: "Scripts/EchoArguments") { path in
96+
let result = try run(path.appending(component: "EchoArguments.swift").pathString, "--quiet",
97+
"1", "--hello", "world")
98+
99+
// We only expect tool's output on the stdout stream.
100+
XCTAssertEqual(result.stdout.trimmingCharacters(in: .whitespacesAndNewlines),
101+
#""1" "--hello" "world""#)
102+
103+
// swift-build-tool output should be muted.
104+
XCTAssertNoMatch(result.stderr, .contains("Using cache: EchoArguments-"))
105+
XCTAssertNoMatch(result.stderr, .contains("Compiling"))
106+
XCTAssertNoMatch(result.stderr, .contains("Linking"))
107+
}
108+
}
109+
110+
// TODO: Tests for other swift-script tools
111+
}

0 commit comments

Comments
 (0)