Skip to content

Commit 5c50b7f

Browse files
committed
2 parents 86b3167 + 0e83440 commit 5c50b7f

File tree

4 files changed

+79
-52
lines changed

4 files changed

+79
-52
lines changed

Package.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,19 @@ let package = Package(
101101
dependencies: ["Commands"]),
102102
Target(
103103
/** Shim tool to find test names on OS X */
104-
name: "swiftpm-xctest-helper"),
104+
name: "swiftpm-xctest-helper",
105+
dependencies: []),
106+
Target(
107+
/** FIXME: The Basic tests currently have a layering violation and a dependency on Utility for infrastructure. */
108+
name: "BasicTests",
109+
dependencies: ["Basic", "Utility"]),
110+
Target(
111+
name: "FunctionalTests",
112+
dependencies: ["Basic", "Utility", "PackageModel"]),
113+
Target(
114+
/** FIXME: Turns out PackageLoadingTests violate encapsulation :( */
115+
name: "PackageLoadingTests",
116+
dependencies: ["Get", "PackageLoading"]),
105117
])
106118

107119

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ public struct PackageBuilder {
214214
} else {
215215
testModules = []
216216
}
217+
try fillDependencies(modules: modules + testModules)
217218
let products = try constructProducts(modules, testModules: testModules)
218219
return Package(manifest: manifest, path: packagePath, modules: modules, testModules: testModules, products: products)
219220
}
@@ -344,6 +345,12 @@ public struct PackageBuilder {
344345
}
345346
}
346347

348+
return modules
349+
}
350+
351+
/// Fills the module dependencies delcared via targets in manifest.
352+
private func fillDependencies(modules: [Module]) throws {
353+
347354
// Create a map of modules indexed by name.
348355
var modulesByName = [String: Module]()
349356
for module in modules {
@@ -382,7 +389,15 @@ public struct PackageBuilder {
382389
throw ModuleError.modulesNotFound(missingModuleNames)
383390
}
384391

385-
return modules
392+
// Normally, test modules are only dependent upon modules with
393+
// the same basename. For example, a test module in
394+
// 'Root/Tests/FooTests' is dependent upon 'Root/Sources/Foo'.
395+
// Only do this if there is no explict dependency declared in manifest.
396+
for module in modules where module.isTest && module.dependencies.isEmpty {
397+
if let baseModule = modulesByName[module.basename] {
398+
module.dependencies = [baseModule]
399+
}
400+
}
386401
}
387402

388403
/// Private function that checks whether a module name is valid. This method doesn't return anything, but rather, if there's a problem, it throws an error describing what the problem is.
@@ -504,57 +519,8 @@ public struct PackageBuilder {
504519
}
505520

506521
// Create the test modules
507-
let testModules = try directoryContents(testsPath).filter(shouldConsiderDirectory).flatMap { dir in
522+
return try directoryContents(testsPath).filter(shouldConsiderDirectory).flatMap { dir in
508523
return [try createModule(dir, name: dir.basename, isTest: true)]
509524
}
510-
511-
// Populate the test module dependencies.
512-
for case let testModule as SwiftModule in testModules {
513-
// FIXME: This is very inefficient, we want a map on the modules.
514-
if testModule.basename == "Basic" {
515-
// FIXME: The Basic tests currently have a layering
516-
// violation and a dependency on Utility for infrastructure.
517-
testModule.dependencies = modules.filter{
518-
switch $0.name {
519-
case "Basic", "Utility":
520-
return true
521-
default:
522-
return false
523-
}
524-
}
525-
} else if testModule.basename == "Functional" {
526-
// FIXME: swiftpm's own Functional tests module does not
527-
// follow the normal rules--there is no corresponding
528-
// 'Sources/Functional' module to depend upon. For the
529-
// time being, assume test modules named 'Functional'
530-
// depend upon 'Utility', and hope that no users define
531-
// test modules named 'Functional'.
532-
testModule.dependencies = modules.filter{
533-
switch $0.name {
534-
case "Basic", "Utility", "PackageModel":
535-
return true
536-
default:
537-
return false
538-
}
539-
}
540-
} else if testModule.basename == "PackageLoading" {
541-
// FIXME: Turns out PackageLoadingTests violate encapsulation :(
542-
testModule.dependencies = modules.filter{
543-
switch $0.name {
544-
case "Get", "PackageLoading":
545-
return true
546-
default:
547-
return false
548-
}
549-
}
550-
} else {
551-
// Normally, test modules are only dependent upon modules with
552-
// the same basename. For example, a test module in
553-
// 'Root/Tests/Foo' is dependent upon 'Root/Sources/Foo'.
554-
testModule.dependencies = modules.filter{ $0.name == testModule.basename }
555-
}
556-
}
557-
558-
return testModules
559525
}
560526
}

Tests/PackageLoadingTests/ConventionTests.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,51 @@ class ConventionTests: XCTestCase {
509509
}
510510
}
511511

512+
func testTestTargetDependencies() throws {
513+
var fs = InMemoryFileSystem()
514+
try fs.createEmptyFiles("/Sources/Foo/source.swift",
515+
"/Sources/Bar/source.swift",
516+
"/Tests/FooTests/source.swift"
517+
)
518+
519+
let package = PackageDescription.Package(name: "pkg", targets: [Target(name: "FooTests", dependencies: ["Bar"])])
520+
PackageBuilderTester(package, in: fs) { result in
521+
result.checkModule("Foo") { moduleResult in
522+
moduleResult.check(c99name: "Foo", type: .library, isTest: false)
523+
moduleResult.checkSources(root: "/Sources/Foo", paths: "source.swift")
524+
}
525+
526+
result.checkModule("Bar") { moduleResult in
527+
moduleResult.check(c99name: "Bar", type: .library, isTest: false)
528+
moduleResult.checkSources(root: "/Sources/Bar", paths: "source.swift")
529+
}
530+
531+
result.checkModule("FooTests") { moduleResult in
532+
moduleResult.check(c99name: "FooTests", type: .library, isTest: true)
533+
moduleResult.checkSources(root: "/Tests/FooTests", paths: "source.swift")
534+
moduleResult.check(dependencies: ["Bar"])
535+
moduleResult.check(recursiveDependencies: ["Bar"])
536+
}
537+
}
538+
}
539+
540+
func testInvalidTestTargets() throws {
541+
// Test module in Sources/
542+
var fs = InMemoryFileSystem()
543+
try fs.createEmptyFiles("/Sources/FooTests/source.swift")
544+
PackageBuilderTester("TestsInSources", in: fs) { result in
545+
result.checkDiagnostic("the module at Sources/FooTests has an invalid name (\'FooTests\'): the name of a non-test module has a ‘Tests’ suffix fix: rename the module at ‘Sources/FooTests’ to not have a ‘Tests’ suffix")
546+
}
547+
548+
// Normal module in Tests/
549+
fs = InMemoryFileSystem()
550+
try fs.createEmptyFiles("/Sources/main.swift",
551+
"/Tests/Foo/source.swift")
552+
PackageBuilderTester("TestsInSources", in: fs) { result in
553+
result.checkDiagnostic("the module at Tests/Foo has an invalid name (\'Foo\'): the name of a test module has no ‘Tests’ suffix fix: rename the module at ‘Tests/Foo’ to have a ‘Tests’ suffix")
554+
}
555+
}
556+
512557
func testManifestTargetDeclErrors() throws {
513558
// Reference a target which doesn't exist.
514559
var fs = InMemoryFileSystem()

Utilities/bootstrap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ def parse_manifest():
306306
return Target(name, deps)
307307
targets = list(map(convert, pattern.finditer(manifest_data)))
308308

309+
# Remove the targets which should be ignored in stage 1.
310+
targets = [target for target in targets if target.name not in g_ignored_targets]
311+
309312
# substitute strings for Target objects
310313
for target in targets:
311314
def convert(targetName):
@@ -337,6 +340,7 @@ def parse_manifest():
337340
# Hard-coded target definition.
338341
g_project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
339342
g_source_root = os.path.join(g_project_root, "Sources")
343+
g_ignored_targets = ["swiftpm-xctest-helper", "BasicTests", "FunctionalTests", "PackageLoadingTests"]
340344
targets = parse_manifest()
341345
target_map = dict((t.name, t) for t in targets)
342346

0 commit comments

Comments
 (0)