Skip to content

Commit 06d1225

Browse files
committed
Add TestSupport module for test specific deps
This removes the use of Utilities.swift symlinks and adds a tests specific library which all tests can depend on
1 parent aba094d commit 06d1225

30 files changed

+208
-140
lines changed

Package.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ let package = Package(
4848
/** Source control operations */
4949
name: "SourceControl",
5050
dependencies: ["Basic", "Utility"]),
51+
Target(
52+
/** Test support library */
53+
name: "TestSupport",
54+
dependencies: ["Basic", "Utility", "POSIX"]),
5155

5256
// MARK: Project Model
5357

@@ -107,9 +111,27 @@ let package = Package(
107111

108112
// MARK: Additional Test Dependencies
109113

114+
Target(
115+
name: "BuildTests",
116+
dependencies: ["Build", "TestSupport"]),
117+
Target(
118+
name: "CommandsTests",
119+
dependencies: ["Commands", "TestSupport"]),
110120
Target(
111121
name: "FunctionalTests",
112-
dependencies: ["Basic", "Utility", "PackageModel"]),
122+
dependencies: ["Basic", "Utility", "PackageModel", "TestSupport"]),
123+
Target(
124+
name: "GetTests",
125+
dependencies: ["Get", "TestSupport"]),
126+
Target(
127+
name: "PackageLoadingTests",
128+
dependencies: ["PackageLoading", "TestSupport"]),
129+
Target(
130+
name: "SourceControlTests",
131+
dependencies: ["SourceControl", "TestSupport"]),
132+
Target(
133+
name: "UtilityTests",
134+
dependencies: ["Utility", "TestSupport"]),
113135
])
114136

115137

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 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 func XCTest.XCTFail
12+
13+
import Basic
14+
import POSIX
15+
import Utility
16+
17+
#if os(macOS)
18+
import class Foundation.Bundle
19+
#endif
20+
21+
/// Defines the executables used by SwiftPM.
22+
/// Contains path to the currently built executable and
23+
/// helper method to execute them.
24+
public enum SwiftPMProduct {
25+
case SwiftBuild
26+
case SwiftPackage
27+
case SwiftTest
28+
case XCTestHelper
29+
30+
/// Path to currently built binary.
31+
var path: AbsolutePath {
32+
#if os(macOS)
33+
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
34+
return AbsolutePath(bundle.bundlePath).parentDirectory.appending(self.exec)
35+
}
36+
fatalError()
37+
#else
38+
return AbsolutePath(CommandLine.arguments.first!, relativeTo: currentWorkingDirectory).parentDirectory.appending(self.exec)
39+
#endif
40+
}
41+
42+
/// Executable name.
43+
var exec: RelativePath {
44+
switch self {
45+
case .SwiftBuild:
46+
return RelativePath("swift-build")
47+
case .SwiftPackage:
48+
return RelativePath("swift-package")
49+
case .SwiftTest:
50+
return RelativePath("swift-test")
51+
case .XCTestHelper:
52+
return RelativePath("swiftpm-xctest-helper")
53+
}
54+
}
55+
56+
/// Executes the product with specified arguments.
57+
///
58+
/// - Parameters:
59+
/// - args: The arguments to pass.
60+
/// - env: Enviroment variables to pass. Enviroment will never be inherited.
61+
/// - chdir: Adds argument `--chdir <path>` if not nil.
62+
/// - printIfError: Print the output on non-zero exit.
63+
///
64+
/// - Returns: The output of the process.
65+
public func execute(_ args: [String], chdir: AbsolutePath? = nil, env: [String: String] = [:], printIfError: Bool = false) throws -> String {
66+
var out = ""
67+
var completeArgs = [path.asString]
68+
if let chdir = chdir {
69+
completeArgs += ["--chdir", chdir.asString]
70+
}
71+
completeArgs += args
72+
do {
73+
try POSIX.popen(completeArgs, redirectStandardError: true, environment: env) {
74+
out += $0
75+
}
76+
return out
77+
} catch {
78+
if printIfError {
79+
print("**** FAILURE EXECUTING SUBPROCESS ****")
80+
print("command: " + completeArgs.map{ $0.shellEscaped() }.joined(separator: " "))
81+
print("SWIFT_EXEC:", env["SWIFT_EXEC"] ?? "nil")
82+
print("output:", out)
83+
}
84+
throw error
85+
}
86+
}
87+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 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 func XCTest.XCTFail
12+
13+
import Basic
14+
import POSIX
15+
import Utility
16+
17+
#if os(macOS)
18+
import class Foundation.Bundle
19+
#endif
20+
21+
public func XCTAssertBuilds(_ path: AbsolutePath, configurations: Set<Configuration> = [.Debug, .Release], file: StaticString = #file, line: UInt = #line, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) {
22+
for conf in configurations {
23+
do {
24+
print(" Building \(conf)")
25+
_ = try executeSwiftBuild(path, configuration: conf, printIfError: true, Xcc: Xcc, Xld: Xld, Xswiftc: Xswiftc, env: env)
26+
} catch {
27+
XCTFail("`swift build -c \(conf)' failed:\n\n\(error)\n", file: file, line: line)
28+
}
29+
}
30+
}
31+
32+
public func XCTAssertSwiftTest(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line, env: [String: String] = [:]) {
33+
do {
34+
_ = try SwiftPMProduct.SwiftTest.execute([], chdir: path, env: env, printIfError: true)
35+
} catch {
36+
XCTFail("`swift test' failed:\n\n\(error)\n", file: file, line: line)
37+
}
38+
}
39+
40+
public func XCTAssertBuildFails(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) {
41+
do {
42+
_ = try executeSwiftBuild(path, Xcc: Xcc, Xld: Xld, Xswiftc: Xswiftc)
43+
44+
XCTFail("`swift build' succeeded but should have failed", file: file, line: line)
45+
46+
} catch POSIX.Error.exitStatus(let status, _) where status == 1{
47+
// noop
48+
} catch {
49+
XCTFail("`swift build' failed in an unexpected manner")
50+
}
51+
}
52+
53+
public func XCTAssertFileExists(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
54+
if !isFile(path) {
55+
XCTFail("Expected file doesn’t exist: \(path.asString)", file: file, line: line)
56+
}
57+
}
58+
59+
public func XCTAssertDirectoryExists(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
60+
if !isDirectory(path) {
61+
XCTFail("Expected directory doesn’t exist: \(path.asString)", file: file, line: line)
62+
}
63+
}
64+
65+
public func XCTAssertNoSuchPath(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
66+
if exists(path) {
67+
XCTFail("path exists but should not: \(path.asString)", file: file, line: line)
68+
}
69+
}

Tests/FunctionalTests/Utilities.swift renamed to Sources/TestSupport/misc.swift

Lines changed: 8 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import class Foundation.Bundle
2020

2121

2222
/// Test-helper function that runs a block of code on a copy of a test fixture package. The copy is made into a temporary directory, and the block is given a path to that directory. The block is permitted to modify the copy. The temporary copy is deleted after the block returns. The fixture name may contain `/` characters, which are treated as path separators, exactly as if the name were a relative path.
23-
func fixture(name: String, tags: [String] = [], file: StaticString = #file, line: UInt = #line, body: @noescape(AbsolutePath) throws -> Void) {
23+
public func fixture(name: String, tags: [String] = [], file: StaticString = #file, line: UInt = #line, body: @noescape(AbsolutePath) throws -> Void) {
2424
do {
2525
// Make a suitable test directory name from the fixture subpath.
2626
let fixtureSubpath = RelativePath(name)
@@ -83,7 +83,7 @@ func fixture(name: String, tags: [String] = [], file: StaticString = #file, line
8383
}
8484

8585
/// Test-helper function that creates a new Git repository in a directory. The new repository will contain exactly one empty file, and if a tag name is provided, a tag with that name will be created.
86-
func initGitRepo(_ dir: AbsolutePath, tag: String? = nil, file: StaticString = #file, line: UInt = #line) {
86+
public func initGitRepo(_ dir: AbsolutePath, tag: String? = nil, file: StaticString = #file, line: UInt = #line) {
8787
do {
8888
let file = dir.appending(component: "file.swift")
8989
try systemQuietly(["touch", file.asString])
@@ -101,89 +101,19 @@ func initGitRepo(_ dir: AbsolutePath, tag: String? = nil, file: StaticString = #
101101
}
102102
}
103103

104-
func tagGitRepo(_ dir: AbsolutePath, tag: String) throws {
104+
public func tagGitRepo(_ dir: AbsolutePath, tag: String) throws {
105105
try systemQuietly([Git.tool, "-C", dir.asString, "tag", tag])
106106
}
107107

108-
enum Configuration {
108+
public enum Configuration {
109109
case Debug
110110
case Release
111111
}
112112

113113
private var globalSymbolInMainBinary = 0
114114

115-
/// Defines the executables used by SwiftPM.
116-
/// Contains path to the currently built executable and
117-
/// helper method to execute them.
118-
enum SwiftPMProduct {
119-
case SwiftBuild
120-
case SwiftPackage
121-
case SwiftTest
122-
case XCTestHelper
123-
124-
/// Path to currently built binary.
125-
var path: AbsolutePath {
126-
#if os(macOS)
127-
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
128-
return AbsolutePath(bundle.bundlePath).parentDirectory.appending(self.exec)
129-
}
130-
fatalError()
131-
#else
132-
return AbsolutePath(CommandLine.arguments.first!, relativeTo: currentWorkingDirectory).parentDirectory.appending(self.exec)
133-
#endif
134-
}
135-
136-
/// Executable name.
137-
var exec: RelativePath {
138-
switch self {
139-
case .SwiftBuild:
140-
return RelativePath("swift-build")
141-
case .SwiftPackage:
142-
return RelativePath("swift-package")
143-
case .SwiftTest:
144-
return RelativePath("swift-test")
145-
case .XCTestHelper:
146-
return RelativePath("swiftpm-xctest-helper")
147-
}
148-
}
149-
}
150-
151-
extension SwiftPMProduct {
152-
/// Executes the product with specified arguments.
153-
///
154-
/// - Parameters:
155-
/// - args: The arguments to pass.
156-
/// - env: Enviroment variables to pass. Enviroment will never be inherited.
157-
/// - chdir: Adds argument `--chdir <path>` if not nil.
158-
/// - printIfError: Print the output on non-zero exit.
159-
///
160-
/// - Returns: The output of the process.
161-
func execute(_ args: [String], chdir: AbsolutePath? = nil, env: [String: String] = [:], printIfError: Bool = false) throws -> String {
162-
var out = ""
163-
var completeArgs = [path.asString]
164-
if let chdir = chdir {
165-
completeArgs += ["--chdir", chdir.asString]
166-
}
167-
completeArgs += args
168-
do {
169-
try POSIX.popen(completeArgs, redirectStandardError: true, environment: env) {
170-
out += $0
171-
}
172-
return out
173-
} catch {
174-
if printIfError {
175-
print("**** FAILURE EXECUTING SUBPROCESS ****")
176-
print("command: " + completeArgs.map{ $0.shellEscaped() }.joined(separator: " "))
177-
print("SWIFT_EXEC:", env["SWIFT_EXEC"] ?? "nil")
178-
print("output:", out)
179-
}
180-
throw error
181-
}
182-
}
183-
}
184-
185115
@discardableResult
186-
func executeSwiftBuild(_ chdir: AbsolutePath, configuration: Configuration = .Debug, printIfError: Bool = false, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) throws -> String {
116+
public func executeSwiftBuild(_ chdir: AbsolutePath, configuration: Configuration = .Debug, printIfError: Bool = false, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) throws -> String {
187117
var args = ["--configuration"]
188118
switch configuration {
189119
case .Debug:
@@ -205,7 +135,7 @@ func executeSwiftBuild(_ chdir: AbsolutePath, configuration: Configuration = .De
205135
}
206136

207137
/// Test helper utility for executing a block with a temporary directory.
208-
func mktmpdir(function: StaticString = #function, file: StaticString = #file, line: UInt = #line, body: @noescape(AbsolutePath) throws -> Void) {
138+
public func mktmpdir(function: StaticString = #function, file: StaticString = #file, line: UInt = #line, body: @noescape(AbsolutePath) throws -> Void) {
209139
do {
210140
let tmpDir = try TemporaryDirectory(prefix: "spm-tests-\(function)", removeTreeOnDeinit: true)
211141
try body(tmpDir.path)
@@ -214,63 +144,13 @@ func mktmpdir(function: StaticString = #function, file: StaticString = #file, li
214144
}
215145
}
216146

217-
func XCTAssertBuilds(_ path: AbsolutePath, configurations: Set<Configuration> = [.Debug, .Release], file: StaticString = #file, line: UInt = #line, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) {
218-
for conf in configurations {
219-
do {
220-
print(" Building \(conf)")
221-
_ = try executeSwiftBuild(path, configuration: conf, printIfError: true, Xcc: Xcc, Xld: Xld, Xswiftc: Xswiftc, env: env)
222-
} catch {
223-
XCTFail("`swift build -c \(conf)' failed:\n\n\(error)\n", file: file, line: line)
224-
}
225-
}
226-
}
227-
228-
func XCTAssertSwiftTest(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line, env: [String: String] = [:]) {
229-
do {
230-
_ = try SwiftPMProduct.SwiftTest.execute([], chdir: path, env: env, printIfError: true)
231-
} catch {
232-
XCTFail("`swift test' failed:\n\n\(error)\n", file: file, line: line)
233-
}
234-
}
235-
236-
func XCTAssertBuildFails(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line, Xcc: [String] = [], Xld: [String] = [], Xswiftc: [String] = [], env: [String: String] = [:]) {
237-
do {
238-
_ = try executeSwiftBuild(path, Xcc: Xcc, Xld: Xld, Xswiftc: Xswiftc)
239-
240-
XCTFail("`swift build' succeeded but should have failed", file: file, line: line)
241-
242-
} catch POSIX.Error.exitStatus(let status, _) where status == 1{
243-
// noop
244-
} catch {
245-
XCTFail("`swift build' failed in an unexpected manner")
246-
}
247-
}
248-
249-
func XCTAssertFileExists(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
250-
if !isFile(path) {
251-
XCTFail("Expected file doesn’t exist: \(path.asString)", file: file, line: line)
252-
}
253-
}
254-
255-
func XCTAssertDirectoryExists(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
256-
if !isDirectory(path) {
257-
XCTFail("Expected directory doesn’t exist: \(path.asString)", file: file, line: line)
258-
}
259-
}
260-
261-
func XCTAssertNoSuchPath(_ path: AbsolutePath, file: StaticString = #file, line: UInt = #line) {
262-
if exists(path) {
263-
XCTFail("path exists but should not: \(path.asString)", file: file, line: line)
264-
}
265-
}
266-
267-
func systemQuietly(_ args: [String]) throws {
147+
public func systemQuietly(_ args: [String]) throws {
268148
// Discard the output, by default.
269149
//
270150
// FIXME: Find a better default behavior here.
271151
let _ = try POSIX.popen(args, redirectStandardError: true)
272152
}
273153

274-
func systemQuietly(_ args: String...) throws {
154+
public func systemQuietly(_ args: String...) throws {
275155
try systemQuietly(args)
276156
}

Tests/BuildTests/PackageVersionDataTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import XCTest
1212

13+
import TestSupport
1314
import Basic
1415
import PackageModel
1516
import PackageDescription

Tests/BuildTests/Utilities.swift

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)