Skip to content

Commit

Permalink
[6.0.0] Update package templates to use Swift Testing in the toolchai…
Browse files Browse the repository at this point in the history
…n rather than as a package dependency. (#7911)
  • Loading branch information
grynspan authored Aug 27, 2024
1 parent aeaab78 commit 5bd155f
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 142 deletions.
13 changes: 2 additions & 11 deletions Fixtures/Miscellaneous/TestDiscovery/SwiftTesting/Package.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
// swift-tools-version: 5.10
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
name: "SwiftTesting",
platforms: [
.macOS(.v13), .iOS(.v16), .watchOS(.v9), .tvOS(.v16), .visionOS(.v1)
],
dependencies: [
.package(url: "https://github.com/apple/swift-testing.git", branch: "main"),
],
targets: [
.testTarget(
name: "SwiftTestingTests",
dependencies: [.product(name: "Testing", package: "swift-testing"),]
),
.testTarget(name: "SwiftTestingTests"),
]
)
12 changes: 7 additions & 5 deletions Sources/Commands/PackageCommands/Init.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ extension SwiftPackageCommand {

let packageName = self.packageName ?? cwd.basename

// Which testing libraries should be used? XCTest is on by default,
// but Swift Testing must remain off by default until it is present
// in the Swift toolchain.
// Testing is on by default, with XCTest only enabled explicitly.
// For macros this is reversed, since we don't support testing
// macros with Swift Testing yet.
var supportedTestingLibraries = Set<BuildParameters.Testing.Library>()
if testLibraryOptions.isEnabled(.xctest) {
if testLibraryOptions.isExplicitlyEnabled(.xctest) ||
(initMode == .macro && testLibraryOptions.isEnabled(.xctest)) {
supportedTestingLibraries.insert(.xctest)
}
if testLibraryOptions.isExplicitlyEnabled(.swiftTesting) {
if testLibraryOptions.isExplicitlyEnabled(.swiftTesting) ||
(initMode != .macro && testLibraryOptions.isEnabled(.swiftTesting)) {
supportedTestingLibraries.insert(.swiftTesting)
}

Expand Down
51 changes: 1 addition & 50 deletions Sources/PackageModelSyntax/AddTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ public struct AddTarget {
// SwiftSyntax.
target.dependencies.append(contentsOf: macroTargetDependencies)

case .test where configuration.testHarness == .swiftTesting:
// Testing targets using swift-testing need to depend on
// SwiftTesting from the swift-testing package.
target.dependencies.append(contentsOf: swiftTestingTestTargetDependencies)

default:
break;
}
Expand Down Expand Up @@ -163,17 +158,6 @@ public struct AddTarget {
}
}

case .test where configuration.testHarness == .swiftTesting:
if !manifest.description.contains("swift-testing") {
newPackageCall = try AddPackageDependency
.addPackageDependencyLocal(
.swiftTesting(
configuration: installedSwiftPMConfiguration
),
to: newPackageCall
)
}

default: break;
}

Expand Down Expand Up @@ -212,8 +196,7 @@ public struct AddTarget {
importModuleNames.append("XCTest")

case .swiftTesting:
// Import is handled by the added dependency.
break
importModuleNames.append("Testing")
}
}

Expand Down Expand Up @@ -380,35 +363,3 @@ fileprivate extension PackageDependency {
)
}
}

/// The set of dependencies we need to introduce to a newly-created macro
/// target.
fileprivate let swiftTestingTestTargetDependencies: [TargetDescription.Dependency] = [
.product(name: "Testing", package: "swift-testing"),
]


/// The package dependency for swift-testing, for use in test files.
fileprivate extension PackageDependency {
/// Source control URL for the swift-syntax package.
static var swiftTestingURL: SourceControlURL {
"https://github.com/apple/swift-testing.git"
}

/// Package dependency on the swift-testing package.
static func swiftTesting(
configuration: InstalledSwiftPMConfiguration
) -> PackageDependency {
let swiftTestingVersionDefault =
configuration.swiftTestingVersionForTestTemplate
let swiftTestingVersion = Version(swiftTestingVersionDefault.description)!

return .sourceControl(
identity: PackageIdentity(url: swiftTestingURL),
nameForTargetDependencyResolutionOnly: nil,
location: .remote(swiftTestingURL),
requirement: .range(.upToNextMajor(from: swiftTestingVersion)),
productFilter: .everything
)
}
}
2 changes: 1 addition & 1 deletion Sources/SPMTestSupport/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ extension InitPackage {
public convenience init(
name: String,
packageType: PackageType,
supportedTestingLibraries: Set<BuildParameters.Testing.Library> = [.xctest],
supportedTestingLibraries: Set<BuildParameters.Testing.Library> = [.swiftTesting],
destinationPath: AbsolutePath,
fileSystem: FileSystem
) throws {
Expand Down
51 changes: 21 additions & 30 deletions Sources/Workspace/InitPackage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public final class InitPackage {

public init(
packageType: PackageType,
supportedTestingLibraries: Set<BuildParameters.Testing.Library> = [.xctest],
supportedTestingLibraries: Set<BuildParameters.Testing.Library>,
platforms: [SupportedPlatform] = []
) {
self.packageType = packageType
Expand Down Expand Up @@ -186,8 +186,8 @@ public final class InitPackage {

var platforms = options.platforms

// Macros and swift-testing require macOS 10.15, iOS 13, etc.
if packageType == .macro || options.supportedTestingLibraries.contains(.swiftTesting) {
// Macros require macOS 10.15, iOS 13, etc.
if packageType == .macro {
func addIfMissing(_ newPlatform: SupportedPlatform) {
if platforms.contains(where: { platform in
platform.platform == newPlatform.platform
Expand Down Expand Up @@ -275,9 +275,6 @@ public final class InitPackage {
} else if packageType == .macro {
dependencies.append(#".package(url: "https://github.com/swiftlang/swift-syntax.git", from: "\#(self.installedSwiftPMConfiguration.swiftSyntaxVersionForMacroTemplate.description)")"#)
}
if options.supportedTestingLibraries.contains(.swiftTesting) {
dependencies.append(#".package(url: "https://github.com/apple/swift-testing.git", from: "0.11.0")"#)
}
if !dependencies.isEmpty {
let dependencies = dependencies.map { dependency in
" \(dependency),"
Expand Down Expand Up @@ -384,17 +381,7 @@ public final class InitPackage {
"""
} else {
let testTarget: String
if options.supportedTestingLibraries.contains(.swiftTesting) {
testTarget = """
.testTarget(
name: "\(pkgname)Tests",
dependencies: [
"\(pkgname)",
.product(name: "Testing", package: "swift-testing"),
]
),
"""
} else if options.supportedTestingLibraries.contains(.xctest) {
if !options.supportedTestingLibraries.isEmpty {
testTarget = """
.testTarget(
name: "\(pkgname)Tests",
Expand Down Expand Up @@ -687,6 +674,10 @@ public final class InitPackage {
private func writeLibraryTestsFile(_ path: AbsolutePath) throws {
var content = ""

// XCTest is only added if it was explicitly asked for, so add tests
// for it *and* Testing if it is enabled (or just XCTest if Testing
// is explicitly disabled).

if options.supportedTestingLibraries.contains(.swiftTesting) {
content += "import Testing\n"
}
Expand All @@ -695,20 +686,18 @@ public final class InitPackage {
}
content += "@testable import \(moduleName)\n"

// Prefer swift-testing if specified, otherwise XCTest. If both are
// specified, the developer is free to write tests using both
// libraries, but we still only want to present a single library's
// example tests.

if options.supportedTestingLibraries.contains(.swiftTesting) {
content += """
@Test func example() throws {
// swift-testing Documentation
// https://swiftpackageindex.com/apple/swift-testing/main/documentation/testing
@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
}
"""
} else if options.supportedTestingLibraries.contains(.xctest) {
}

if options.supportedTestingLibraries.contains(.xctest) {
content += """
final class \(moduleName)Tests: XCTestCase {
Expand Down Expand Up @@ -761,13 +750,15 @@ public final class InitPackage {
"""##

// Prefer swift-testing if specified, otherwise XCTest. If both are
// specified, the developer is free to write tests using both
// libraries, but we still only want to present a single library's
// example tests.

// XCTest is only added if it was explicitly asked for, so add tests
// for it *and* Testing if it is enabled.

if options.supportedTestingLibraries.contains(.swiftTesting) {
// FIXME: https://github.com/swiftlang/swift-syntax/issues/2400
} else if options.supportedTestingLibraries.contains(.xctest) {
}

if options.supportedTestingLibraries.contains(.xctest) {
content += ##"""
final class \##(moduleName)Tests: XCTestCase {
func testMacro() throws {
Expand Down
18 changes: 18 additions & 0 deletions Tests/CommandsTests/TestCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,28 @@ final class TestCommandTests: CommandsTestCase {
}

func testBasicSwiftTestingIntegration() async throws {
#if !canImport(TestingDisabled)
try XCTSkipUnless(
nil != Environment.current["SWIFT_PM_SWIFT_TESTING_TESTS_ENABLED"],
"Skipping \(#function) because swift-testing tests are not explicitly enabled"
)
#endif

try await fixture(name: "Miscellaneous/TestDiscovery/SwiftTesting") { fixturePath in
do {
let (stdout, _) = try await SwiftPM.Test.execute(["--enable-swift-testing", "--disable-xctest"], packagePath: fixturePath)
XCTAssertMatch(stdout, .contains(#"Test "SOME TEST FUNCTION" started"#))
}
}
}

func testBasicSwiftTestingIntegration_ExperimentalFlag() async throws {
#if !canImport(TestingDisabled)
try XCTSkipUnless(
nil != Environment.current["SWIFT_PM_SWIFT_TESTING_TESTS_ENABLED"],
"Skipping \(#function) because swift-testing tests are not explicitly enabled"
)
#endif

try await fixture(name: "Miscellaneous/TestDiscovery/SwiftTesting") { fixturePath in
do {
Expand Down
16 changes: 5 additions & 11 deletions Tests/PackageModelSyntaxTests/ManifestEditTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -575,14 +575,8 @@ class ManifestEditTests: XCTestCase {
// swift-tools-version: 5.5
let package = Package(
name: "packages",
dependencies: [
.package(url: "https://github.com/apple/swift-testing.git", from: "0.8.0"),
],
targets: [
.testTarget(
name: "MyTest",
dependencies: [ .product(name: "Testing", package: "swift-testing") ]
),
.testTarget(name: "MyTest"),
]
)
""",
Expand Down Expand Up @@ -618,7 +612,7 @@ class ManifestEditTests: XCTestCase {
let package = Package(
name: "packages",
dependencies: [
.package(url: "https://github.com/apple/swift-testing.git", from: "0.8.0"),
.package(url: "https://github.com/swiftlang/swift-example.git", from: "1.2.3"),
],
targets: [
.testTarget(
Expand All @@ -632,20 +626,20 @@ class ManifestEditTests: XCTestCase {
let package = Package(
name: "packages",
dependencies: [
.package(url: "https://github.com/apple/swift-testing.git", from: "0.8.0"),
.package(url: "https://github.com/swiftlang/swift-example.git", from: "1.2.3"),
],
targets: [
.testTarget(
name: "MyTest",
dependencies: [
.product(name: "Testing", package: "swift-testing"),
.product(name: "SomethingOrOther", package: "swift-example"),
]
),
]
)
""") { manifest in
try AddTargetDependency.addTargetDependency(
.product(name: "Testing", package: "swift-testing"),
.product(name: "SomethingOrOther", package: "swift-example"),
targetName: "MyTest",
to: manifest
)
Expand Down
Loading

0 comments on commit 5bd155f

Please sign in to comment.