Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Testing
import struct SPMBuildCore.BuildSystemProvider
import enum PackageModel.BuildConfiguration

Expand All @@ -28,6 +29,12 @@ public struct BuildData {
public let config: BuildConfiguration
}

extension BuildData: CustomTestStringConvertible {
public var testDescription: String {
return "\(buildSystem):\(config)"
}
}

public func getBuildData(for buildSystems: [BuildSystemProvider.Kind]) -> [BuildData] {
buildSystems.flatMap { buildSystem in
BuildConfiguration.allCases.compactMap { config in
Expand Down
145 changes: 97 additions & 48 deletions Sources/_InternalTestSupport/SwiftTesting+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,106 +11,155 @@
import Basics
import Testing

// MARK: File System Helpers

/// Verifies that a file exists at the specified path.
///
/// - Parameters:
/// - path: The absolute path to check for file existence.
/// - sourceLocation: The source location where the expectation is made.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: thank you for adding documentation to these files! this makes it a lot more readable.

public func expectFileExists(
at path: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}
let msgSuffix: String
do {
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path.parentDirectory))"
} catch {
msgSuffix = ""
}
#expect(
localFileSystem.exists(path),
"\(commentPrefix)File '\(path)' does not exist. \(msgSuffix)",
wrapMessage(
"Files '\(path)' does not exist.",
comment: comment,
directoryPath: path.parentDirectory
),
sourceLocation: sourceLocation,
)
}

public func expectFileDoesNotExists(
/// Requires that a file exists at the specified path.
///
/// - Parameters:
/// - path: The absolute path to check for file existence.
/// - sourceLocation: The source location where the expectation is made.
public func requireFileExists(
at path: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) throws {
try #require(
localFileSystem.exists(path),
wrapMessage(
"Files '\(path)' does not exist.",
comment: comment,
directoryPath: path.parentDirectory
),
sourceLocation: sourceLocation,
)
}

/// Verifies that a file does not exist at the specified path.
///
/// - Parameters:
/// - path: The absolute path to check for file non-existence.
/// - comment: An optional comment to include in the failure message.
/// - sourceLocation: The source location where the expectation is made.
public func expectFileDoesNotExist(
at path: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}
let msgSuffix: String
do {
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path.parentDirectory))"
} catch {
msgSuffix = ""
}
#expect(
!localFileSystem.exists(path),
"\(commentPrefix)File: '\(path)' was not expected to exist, but does.\(msgSuffix))",
wrapMessage(
"File: '\(path)' was not expected to exist, but does.",
comment: comment,
directoryPath: path.parentDirectory
),
sourceLocation: sourceLocation,
)
}

/// Verifies that a file exists and is executable at the specified path.
///
/// - Parameters:
/// - fixturePath: The absolute path to check for executable file existence.
/// - comment: An optional comment to include in the failure message.
/// - sourceLocation: The source location where the expectation is made.
public func expectFileIsExecutable(
at fixturePath: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}
#expect(
localFileSystem.isExecutableFile(fixturePath),
"\(commentPrefix)File '\(fixturePath)' expected to be executable, but is not.",
wrapMessage("File '\(fixturePath)' expected to be executable, but is not.", comment: comment),
sourceLocation: sourceLocation,
)
}

/// Verifies that a directory exists at the specified path.
///
/// - Parameters:
/// - path: The absolute path to check for directory existence.
/// - sourceLocation: The source location where the expectation is made.
public func expectDirectoryExists(
at path: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let msgSuffix: String
do {
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path))"
} catch {
msgSuffix = ""
}
#expect(
localFileSystem.isDirectory(path),
"Expected directory doesn't exist: '\(path)'. \(msgSuffix)",
wrapMessage("Expected directory doesn't exist: '\(path)'", comment: comment, directoryPath: path),
sourceLocation: sourceLocation,
)
}

/// Verifies that a directory does not exist at the specified path.
///
/// - Parameters:
/// - path: The absolute path to check for directory non-existence.
/// - sourceLocation: The source location where the expectation is made.
public func expectDirectoryDoesNotExist(
at path: AbsolutePath,
_ comment: Comment? = nil,
sourceLocation: SourceLocation = #_sourceLocation,
) {
let msgSuffix: String
do {
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path))"
} catch {
msgSuffix = ""
}
#expect(
!localFileSystem.isDirectory(path),
"Directory exists unexpectedly: '\(path)'.\(msgSuffix)",
wrapMessage("Directory exists unexpectedly: '\(path)'", comment: comment, directoryPath: path),
sourceLocation: sourceLocation,
)
}

/// Wraps a message with an optional comment prefix and directory contents suffix.
///
/// - Parameters:
/// - message: The base message to wrap.
/// - comment: An optional comment to prefix the message with.
/// - directoryPath: An optional path to a folder whose contents will be appended to the message.
/// - Returns: The formatted message with prefix and suffix.
private func wrapMessage(
_ message: Comment,
comment: Comment? = nil,
directoryPath: AbsolutePath? = nil
) -> Comment {
let commentPrefix =
if let comment {
"\(comment): "
} else {
""
}

var msgSuffix = ""
if let directoryPath {
do {
msgSuffix = try " Directory contents: \(localFileSystem.getDirectoryContents(directoryPath))"
} catch {
// Silently ignore errors when getting directory contents
}
}

return "\(commentPrefix)\(message)\(msgSuffix)"
}

/// Expects that the expression throws a CommandExecutionError and passes it to the provided throwing error handler.
/// - Parameters:
/// - expression: The expression expected to throw
Expand Down
10 changes: 9 additions & 1 deletion Sources/_InternalTestSupport/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,15 @@ public func testWithTemporaryDirectory<Result>(
.replacing(")", with: "")
.replacing(".", with: "")
.replacing(":", with: "_")
return try await withTemporaryDirectory(prefix: "spm-tests-\(cleanedFunction)") { tmpDirPath in

// Use shorter prefix on Windows to avoid MAX_PATH issues
#if os(Windows)
let prefix = "spm-"
#else
let prefix = "spm-tests-\(cleanedFunction)"
#endif

return try await withTemporaryDirectory(prefix: prefix) { tmpDirPath in
defer {
// Unblock and remove the tmp dir on deinit.
try? localFileSystem.chmod(.userWritable, path: tmpDirPath, options: [.recursive])
Expand Down
14 changes: 7 additions & 7 deletions Tests/CommandsTests/PackageCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2866,7 +2866,7 @@ struct PackageCommandTests {
configuration: data.config,
buildSystem: data.buildSystem,
)
expectFileDoesNotExists(at: binFile)
expectFileDoesNotExist(at: binFile)
// Clean again to ensure we get no error.
_ = try await execute(
["clean"],
Expand Down Expand Up @@ -2911,7 +2911,7 @@ struct PackageCommandTests {
configuration: data.config,
buildSystem: data.buildSystem,
)
expectFileDoesNotExists(at: binFile)
expectFileDoesNotExist(at: binFile)
try #expect(
!localFileSystem.getDirectoryContents(buildPath.appending("repositories")).isEmpty
)
Expand Down Expand Up @@ -3014,7 +3014,7 @@ struct PackageCommandTests {
#expect(!result.stderr.contains("Could not find Package.swift"))

// Verify manifest.db was removed (the purge implementation removes this file)
expectFileDoesNotExists(at: manifestDB, "manifest.db should be removed after purge")
expectFileDoesNotExist(at: manifestDB, "manifest.db should be removed after purge")

// Note: SQLite auxiliary files (WAL/SHM) may or may not be removed depending on SQLite state
// The important check is that the main database file is removed
Expand Down Expand Up @@ -5341,7 +5341,7 @@ struct PackageCommandTests {
buildSystem: buildData.buildSystem,
)
expectFileIsExecutable(at: fixturePath.appending(components: debugTarget), "build-target")
expectFileDoesNotExists(
expectFileDoesNotExist(
at: fixturePath.appending(components: releaseTarget),
"build-target build-inherit"
)
Expand Down Expand Up @@ -5375,7 +5375,7 @@ struct PackageCommandTests {
at: fixturePath.appending(components: debugTarget),
"build-target build-debug"
)
expectFileDoesNotExists(
expectFileDoesNotExist(
at: fixturePath.appending(components: releaseTarget),
"build-target build-inherit"
)
Expand Down Expand Up @@ -5406,7 +5406,7 @@ struct PackageCommandTests {
configuration: buildData.config,
buildSystem: buildData.buildSystem,
)
expectFileDoesNotExists(
expectFileDoesNotExist(
at: fixturePath.appending(components: debugTarget),
"build-target build-inherit"
)
Expand Down Expand Up @@ -5450,7 +5450,7 @@ struct PackageCommandTests {
fileShouldNotExist = fixturePath.appending(components: debugTarget)
fileShouldExist = fixturePath.appending(components: releaseTarget)
}
expectFileDoesNotExists(at: fileShouldNotExist, "build-target build-inherit")
expectFileDoesNotExist(at: fileShouldNotExist, "build-target build-inherit")
expectFileIsExecutable(at: fileShouldExist, "build-target build-inherit")
}
} when: {
Expand Down
Loading