-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow unit test targets to import and link executable targets (#3316)
* Add a fast way to look up the package in which a particular target or product is defined. * Allow SwiftTargetDescription, ClangTargetDescription, and ProductDescription to know the tools version of the package in which they are defined. This allows compiler flags and other semantically significant changes to be conditionalized on the tools version. In the cases where tools versions are synthesized, they get the tools version of the package defining the product or target for which they are being synthesized. The fallback for anything that cannot be determined at all is always `.vNext`, which is the same as has been the case until now. * Allow unit tests to import and link any main modules of executables that are implemented in Swift. This uses a new Swift compiler flag to set the name of the entry point when emitting object code, and then uses linker flags to rename the main executable module's entry point back to `_main` again when actually linking the executable. This is guarded by a tools version check, since packages written this way won't be testable on older toolchains. Also, this is currently only done on Darwin and Linux. A supplemental PR will generate a small stub containing code that implements `main` to call the per-module `<module>_main` function, which will be linked into the executable.
- Loading branch information
1 parent
4ba446b
commit 037a616
Showing
13 changed files
with
293 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// swift-tools-version: 999.0 | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "TestableExe", | ||
targets: [ | ||
.target( | ||
name: "TestableExe1" | ||
), | ||
.target( | ||
name: "TestableExe2" | ||
), | ||
.target( | ||
name: "TestableExe3" | ||
), | ||
.testTarget( | ||
name: "TestableExeTests", | ||
dependencies: [ | ||
"TestableExe1", | ||
"TestableExe2", | ||
"TestableExe3", | ||
] | ||
), | ||
] | ||
) |
5 changes: 5 additions & 0 deletions
5
Fixtures/Miscellaneous/TestableExe/Sources/TestableExe1/main.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
public func GetGreeting1() -> String { | ||
return "Hello, world" | ||
} | ||
|
||
print("\(GetGreeting1())!") |
5 changes: 5 additions & 0 deletions
5
Fixtures/Miscellaneous/TestableExe/Sources/TestableExe2/main.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
public func GetGreeting2() -> String { | ||
return "Hello, planet" | ||
} | ||
|
||
print("\(GetGreeting2())!") |
1 change: 1 addition & 0 deletions
1
Fixtures/Miscellaneous/TestableExe/Sources/TestableExe3/include/TestableExe3.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
const char * GetGreeting3(); |
10 changes: 10 additions & 0 deletions
10
Fixtures/Miscellaneous/TestableExe/Sources/TestableExe3/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <stdio.h> | ||
#include "include/TestableExe3.h" | ||
|
||
const char * GetGreeting3() { | ||
return "Hello, universe"; | ||
} | ||
|
||
int main() { | ||
printf("%s!\n", GetGreeting3()); | ||
} |
73 changes: 73 additions & 0 deletions
73
Fixtures/Miscellaneous/TestableExe/Tests/TestableExeTests/TestableExeTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import XCTest | ||
import TestableExe1 | ||
import TestableExe2 | ||
// import TestableExe3 | ||
import class Foundation.Bundle | ||
|
||
final class TestableExeTests: XCTestCase { | ||
func testExample() throws { | ||
// This is an example of a functional test case. | ||
// Use XCTAssert and related functions to verify your tests produce the correct | ||
// results. | ||
|
||
print(GetGreeting1()) | ||
XCTAssertEqual(GetGreeting1(), "Hello, world") | ||
print(GetGreeting2()) | ||
XCTAssertEqual(GetGreeting2(), "Hello, planet") | ||
// XCTAssertEqual(String(cString: GetGreeting3()), "Hello, universe") | ||
|
||
// Some of the APIs that we use below are available in macOS 10.13 and above. | ||
guard #available(macOS 10.13, *) else { | ||
return | ||
} | ||
|
||
var execPath = productsDirectory.appendingPathComponent("TestableExe1") | ||
var process = Process() | ||
process.executableURL = execPath | ||
var pipe = Pipe() | ||
process.standardOutput = pipe | ||
try process.run() | ||
process.waitUntilExit() | ||
var data = pipe.fileHandleForReading.readDataToEndOfFile() | ||
var output = String(data: data, encoding: .utf8) | ||
XCTAssertEqual(output, "Hello, world!\n") | ||
|
||
execPath = productsDirectory.appendingPathComponent("TestableExe2") | ||
process = Process() | ||
process.executableURL = execPath | ||
pipe = Pipe() | ||
process.standardOutput = pipe | ||
try process.run() | ||
process.waitUntilExit() | ||
data = pipe.fileHandleForReading.readDataToEndOfFile() | ||
output = String(data: data, encoding: .utf8) | ||
XCTAssertEqual(output, "Hello, planet!\n") | ||
|
||
execPath = productsDirectory.appendingPathComponent("TestableExe3") | ||
process = Process() | ||
process.executableURL = execPath | ||
pipe = Pipe() | ||
process.standardOutput = pipe | ||
try process.run() | ||
process.waitUntilExit() | ||
data = pipe.fileHandleForReading.readDataToEndOfFile() | ||
output = String(data: data, encoding: .utf8) | ||
XCTAssertEqual(output, "Hello, universe!\n") | ||
} | ||
|
||
/// Returns path to the built products directory. | ||
var productsDirectory: URL { | ||
#if os(macOS) | ||
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") { | ||
return bundle.bundleURL.deletingLastPathComponent() | ||
} | ||
fatalError("couldn't find the products directory") | ||
#else | ||
return Bundle.main.bundleURL | ||
#endif | ||
} | ||
|
||
static var allTests = [ | ||
("testExample", testExample), | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.