Skip to content

Tests: Migrate BuildSystemDelegateTests to Swift Testing and augment #9013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.build
.test
.index-build
DerivedData
/.previous-build
Expand Down
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ let package = Package(
name: "_InternalTestSupport",
dependencies: [
"Basics",
"DriverSupport",
"PackageFingerprint",
"PackageGraph",
"PackageLoading",
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageModel/Toolchain+SupportedFeatures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public enum SwiftCompilerFeature {
}

extension Toolchain {
public var supportesSupportedFeatures: Bool {
public var supportsSupportedFeatures: Bool {
guard let features = try? swiftCompilerSupportedFeatures else {
return false
}
Expand Down
25 changes: 25 additions & 0 deletions Sources/_InternalTestSupport/BuildConfiguration+Helpers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 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 enum PackageModel.BuildConfiguration

extension BuildConfiguration {

public var buildFor: String {
switch self {
case .debug:
return "debugging"
case .release:
return "production"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@

import struct SPMBuildCore.BuildSystemProvider
import enum PackageModel.BuildConfiguration
import class PackageModel.UserToolchain

extension BuildSystemProvider.Kind {

@available(*, deprecated, message: "use binPath(for:scrathPath:triple) instead")
public func binPathSuffixes(for config: BuildConfiguration) -> [String] {
let suffix: String

#if os(Linux)
suffix = "-linux"
#elseif os(Windows)
suffix = "-windows"
suffix = "-windows"
#else
suffix = ""
#endif
Expand All @@ -34,4 +36,40 @@ extension BuildSystemProvider.Kind {
return ["apple", "Products" , "\(config)".capitalized + suffix]
}
}

public func binPath(
for config: BuildConfiguration,
scratchPath: [String] = [".build"],
triple: String? = nil,
) throws -> [String] {
let suffix: String

#if os(Linux)
suffix = "-linux"
#elseif os(Windows)
suffix = "-windows"
#else
suffix = ""
#endif

let tripleString: String
if let triple {
tripleString = triple
} else {
do {
tripleString = try UserToolchain.default.targetTriple.platformBuildPathComponent
} catch {
tripleString = ""
}
}
switch self {
case .native:
return scratchPath + [tripleString, "\(config)".lowercased()]
case .swiftbuild:
return scratchPath + [tripleString, "Products", "\(config)".capitalized + suffix]
case .xcode:
return scratchPath + ["apple", "Products", "\(config)".capitalized + suffix]
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import struct SPMBuildCore.BuildSystemProvider

import enum PackageModel.BuildConfiguration

public var SupportedBuildSystemOnAllPlatforms: [BuildSystemProvider.Kind] = BuildSystemProvider.Kind.allCases.filter { $0 != .xcode }

Expand All @@ -22,3 +22,16 @@ public var SupportedBuildSystemOnPlatform: [BuildSystemProvider.Kind] {
SupportedBuildSystemOnAllPlatforms
#endif
}

public struct BuildData {
public let buildSystem: BuildSystemProvider.Kind
public let config: BuildConfiguration
}

public func getBuildData(for buildSystems: [BuildSystemProvider.Kind]) -> [BuildData] {
buildSystems.flatMap { buildSystem in
BuildConfiguration.allCases.compactMap { config in
return BuildData(buildSystem: buildSystem, config: config)
}
}
}
3 changes: 1 addition & 2 deletions Sources/_InternalTestSupport/SwiftPMProduct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,12 @@ extension SwiftPM {

// Unset the internal env variable that allows skipping certain tests.
environment["_SWIFTPM_SKIP_TESTS_LIST"] = nil
environment["SWIFTPM_EXEC_NAME"] = self.executableName

for (key, value) in env ?? [:] {
environment[key] = value
}

var completeArgs = [xctestBinaryPath.pathString]
var completeArgs = [Self.xctestBinaryPath(for: RelativePath(self.executableName)).pathString]
if let packagePath = packagePath {
completeArgs += ["--package-path", packagePath.pathString]
}
Expand Down
67 changes: 64 additions & 3 deletions Sources/_InternalTestSupport/SwiftTesting+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,63 @@ public func expectFileExists(
)
}

public func expectFileDoesNotExists(
at fixturePath: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}
#expect(
!localFileSystem.exists(fixturePath),
"\(commentPrefix)\(fixturePath) does not exist",
sourceLocation: sourceLocation,
)
}

public func expectFileIsExecutable(
at fixturePath: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}
#expect(
localFileSystem.isExecutableFile(fixturePath),
"\(commentPrefix)\(fixturePath) does not exist",
sourceLocation: sourceLocation,
)
}

public func expectDirectoryExists(
at path: AbsolutePath,
sourceLocation: SourceLocation = #_sourceLocation,
) {
#expect(
localFileSystem.isDirectory(path),
"Expected directory doesn't exist: \(path)",
sourceLocation: sourceLocation,
)
}

public func expectDirectoryDoesNotExist(
at path: AbsolutePath,
sourceLocation: SourceLocation = #_sourceLocation,
) {
#expect(
!localFileSystem.isDirectory(path),
"Directory exists unexpectedly: \(path)",
sourceLocation: sourceLocation,
)
}

public func expectThrowsCommandExecutionError<T>(
_ expression: @autoclosure () async throws -> T,
Expand All @@ -32,8 +89,9 @@ public func expectThrowsCommandExecutionError<T>(
) async {
await expectAsyncThrowsError(try await expression(), message(), sourceLocation: sourceLocation) { error in
guard case SwiftPMError.executionFailure(let processError, let stdout, let stderr) = error,
case AsyncProcessResult.Error.nonZeroExit(let processResult) = processError,
processResult.exitStatus != .terminated(code: 0) else {
case AsyncProcessResult.Error.nonZeroExit(let processResult) = processError,
processResult.exitStatus != .terminated(code: 0)
else {
Issue.record("Unexpected error type: \(error.interpolationDescription)", sourceLocation: sourceLocation)
return
}
Expand All @@ -50,7 +108,10 @@ public func expectAsyncThrowsError<T>(
) async {
do {
_ = try await expression()
Issue.record(message() ?? "Expected an error, which did not not.", sourceLocation: sourceLocation)
Issue.record(
message() ?? "Expected an error, which did not occur.",
sourceLocation: sourceLocation,
)
} catch {
errorHandler(error)
}
Expand Down
35 changes: 34 additions & 1 deletion Sources/_InternalTestSupport/SwiftTesting+Tags.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ extension Tag.TestSize {
extension Tag.Feature {
public enum Command {}
public enum PackageType {}
public enum ProductType {}
public enum TargetType {}

@Tag public static var CodeCoverage: Tag
@Tag public static var Mirror: Tag
@Tag public static var NetRc: Tag
@Tag public static var Resource: Tag
@Tag public static var SpecialCharacters: Tag
@Tag public static var Traits: Tag
Expand All @@ -43,14 +46,31 @@ extension Tag.Feature.Command {
}

extension Tag.Feature.Command.Package {
@Tag public static var General: Tag
@Tag public static var AddDependency: Tag
@Tag public static var AddProduct: Tag
@Tag public static var ArchiveSource: Tag
@Tag public static var AddSetting: Tag
@Tag public static var AddTarget: Tag
@Tag public static var AddTargetDependency: Tag
@Tag public static var BuildPlugin: Tag
@Tag public static var Clean: Tag
@Tag public static var CommandPlugin: Tag
@Tag public static var CompletionTool: Tag
@Tag public static var Config: Tag
@Tag public static var Init: Tag
@Tag public static var Describe: Tag
@Tag public static var DumpPackage: Tag
@Tag public static var DumpSymbolGraph: Tag
@Tag public static var Edit: Tag
@Tag public static var Init: Tag
@Tag public static var Migrate: Tag
@Tag public static var Plugin: Tag
@Tag public static var Reset: Tag
@Tag public static var Resolve: Tag
@Tag public static var ShowDependencies: Tag
@Tag public static var ShowExecutables: Tag
@Tag public static var ToolsVersion: Tag
@Tag public static var Unedit: Tag
@Tag public static var Update: Tag
}

Expand All @@ -63,6 +83,19 @@ extension Tag.Feature.Command.PackageRegistry {
@Tag public static var Unset: Tag
}

extension Tag.Feature.TargetType {
@Tag public static var Executable: Tag
@Tag public static var Library: Tag
@Tag public static var Macro: Tag
}

extension Tag.Feature.ProductType {
@Tag public static var DynamicLibrary: Tag
@Tag public static var Executable: Tag
@Tag public static var Library: Tag
@Tag public static var Plugin: Tag
@Tag public static var StaticLibrary: Tag
}
extension Tag.Feature.PackageType {
@Tag public static var Library: Tag
@Tag public static var Executable: Tag
Expand Down
Loading