From da8bae8c0698c4a31ab5420016c5dd3e8aa7eee0 Mon Sep 17 00:00:00 2001 From: Bassam Khouri Date: Mon, 21 Oct 2024 22:08:55 -0400 Subject: [PATCH] Convert most WorkspaceTests to Swift Testing Convert most of the WorkspaceTests from XCTests to Swift Testing to make use of parallelism and, in some cases, test parameterization. Not all Test Suites in WorkspaceTests have been converted as some use helpers in swift-tools-core-support, which don't have a matching Swift Testing helper. --- .../AuthorizationProviderTests.swift | 84 +++--- .../MirrorsConfigurationTests.swift | 58 ++-- ...sVersionSpecificationGenerationTests.swift | 43 +-- ...olsVersionSpecificationRewriterTests.swift | 277 +++++++++--------- .../WorkspaceTests/WorkspaceStateTests.swift | 60 ++-- 5 files changed, 270 insertions(+), 252 deletions(-) diff --git a/Tests/WorkspaceTests/AuthorizationProviderTests.swift b/Tests/WorkspaceTests/AuthorizationProviderTests.swift index 4e8bebabed2..a49d0e44705 100644 --- a/Tests/WorkspaceTests/AuthorizationProviderTests.swift +++ b/Tests/WorkspaceTests/AuthorizationProviderTests.swift @@ -9,14 +9,16 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// +import Foundation @testable import Basics import _InternalTestSupport import Workspace -import XCTest +import Testing -final class AuthorizationProviderTests: XCTestCase { - func testNetrcAuthorizationProviders() throws { +fileprivate struct AuthorizationProviderTests { + @Test + func netrcAuthorizationProviders() throws { let observability = ObservabilitySystem.makeForTesting() // custom .netrc file @@ -32,19 +34,20 @@ final class AuthorizationProviderTests: XCTestCase { let configuration = Workspace.Configuration.Authorization(netrc: .custom(customPath), keychain: .disabled) let authorizationProvider = try configuration.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? CompositeAuthorizationProvider - let netrcProviders = authorizationProvider?.providers.compactMap { $0 as? NetrcAuthorizationProvider } + let netrcProviders = try #require(authorizationProvider?.providers.compactMap { $0 as? NetrcAuthorizationProvider }) - XCTAssertEqual(netrcProviders?.count, 1) - XCTAssertEqual(try netrcProviders?.first.map { try resolveSymlinks($0.path) }, try resolveSymlinks(customPath)) + let expectedNetrcProvider = try resolveSymlinks(customPath) + #expect(netrcProviders.count == 1) + #expect(try netrcProviders.first.map { try resolveSymlinks($0.path) } == expectedNetrcProvider) - let auth = authorizationProvider?.authentication(for: "https://mymachine.labkey.org") - XCTAssertEqual(auth?.user, "custom@labkey.org") - XCTAssertEqual(auth?.password, "custom") + let auth = try #require(authorizationProvider?.authentication(for: "https://mymachine.labkey.org")) + #expect(auth.user == "custom@labkey.org") + #expect(auth.password == "custom") // delete it try fileSystem.removeFileTree(customPath) - XCTAssertThrowsError(try configuration.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope), "error expected") { error in - XCTAssertEqual(error as? StringError, StringError("Did not find netrc file at \(customPath).")) + #expect(throws: StringError("Did not find netrc file at \(customPath).")) { + try configuration.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) } } @@ -61,25 +64,27 @@ final class AuthorizationProviderTests: XCTestCase { let configuration = Workspace.Configuration.Authorization(netrc: .user, keychain: .disabled) let authorizationProvider = try configuration.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? CompositeAuthorizationProvider - let netrcProviders = authorizationProvider?.providers.compactMap { $0 as? NetrcAuthorizationProvider } + let netrcProviders = try #require(authorizationProvider?.providers.compactMap { $0 as? NetrcAuthorizationProvider }) - XCTAssertEqual(netrcProviders?.count, 1) - XCTAssertEqual(try netrcProviders?.first.map { try resolveSymlinks($0.path) }, try resolveSymlinks(userPath)) + let expectedNetrcProvider = try resolveSymlinks(userPath) + #expect(netrcProviders.count == 1) + #expect(try netrcProviders.first.map { try resolveSymlinks($0.path) } == expectedNetrcProvider) - let auth = authorizationProvider?.authentication(for: "https://mymachine.labkey.org") - XCTAssertEqual(auth?.user, "user@labkey.org") - XCTAssertEqual(auth?.password, "user") + let auth = try #require(authorizationProvider?.authentication(for: "https://mymachine.labkey.org")) + #expect(auth.user == "user@labkey.org") + #expect(auth.password == "user") // delete it do { try fileSystem.removeFileTree(userPath) let authorizationProvider = try configuration.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? CompositeAuthorizationProvider - XCTAssertNil(authorizationProvider) + #expect(authorizationProvider == nil) } } } - func testRegistryNetrcAuthorizationProviders() throws { + @Test + func registryNetrcAuthorizationProviders() throws { let observability = ObservabilitySystem.makeForTesting() // custom .netrc file @@ -97,17 +102,18 @@ final class AuthorizationProviderTests: XCTestCase { let configuration = Workspace.Configuration.Authorization(netrc: .custom(customPath), keychain: .disabled) let netrcProvider = try configuration.makeRegistryAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? NetrcAuthorizationProvider - XCTAssertNotNil(netrcProvider) - XCTAssertEqual(try netrcProvider.map { try resolveSymlinks($0.path) }, try resolveSymlinks(customPath)) + let expectedNetrcProvider = try resolveSymlinks(customPath) + #expect(netrcProvider != nil) + #expect(try netrcProvider.map { try resolveSymlinks($0.path) } == expectedNetrcProvider) - let auth = netrcProvider?.authentication(for: "https://mymachine.labkey.org") - XCTAssertEqual(auth?.user, "custom@labkey.org") - XCTAssertEqual(auth?.password, "custom") + let auth = try #require(netrcProvider?.authentication(for: "https://mymachine.labkey.org")) + #expect(auth.user == "custom@labkey.org") + #expect(auth.password == "custom") // delete it try fileSystem.removeFileTree(customPath) - XCTAssertThrowsError(try configuration.makeRegistryAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope), "error expected") { error in - XCTAssertEqual(error as? StringError, StringError("did not find netrc file at \(customPath)")) + #expect(throws: StringError("did not find netrc file at \(customPath)")) { + try configuration.makeRegistryAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) } } @@ -126,22 +132,28 @@ final class AuthorizationProviderTests: XCTestCase { let configuration = Workspace.Configuration.Authorization(netrc: .user, keychain: .disabled) let netrcProvider = try configuration.makeRegistryAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? NetrcAuthorizationProvider - XCTAssertNotNil(netrcProvider) - XCTAssertEqual(try netrcProvider.map { try resolveSymlinks($0.path) }, try resolveSymlinks(userPath)) + let expectedNetrcProvider = try resolveSymlinks(userPath) + #expect(netrcProvider != nil) + #expect(try netrcProvider.map { try resolveSymlinks($0.path) } == expectedNetrcProvider) - let auth = netrcProvider?.authentication(for: "https://mymachine.labkey.org") - XCTAssertEqual(auth?.user, "user@labkey.org") - XCTAssertEqual(auth?.password, "user") + let auth = try #require(netrcProvider?.authentication(for: "https://mymachine.labkey.org")) + #expect(auth.user == "user@labkey.org") + #expect(auth.password == "user") // delete it do { try fileSystem.removeFileTree(userPath) - let authorizationProvider = try configuration.makeRegistryAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observability.topScope) as? NetrcAuthorizationProvider + let authorizationProviderOpt = + try configuration.makeRegistryAuthorizationProvider( + fileSystem: fileSystem, + observabilityScope: observability.topScope, + ) as? NetrcAuthorizationProvider // Even if user .netrc file doesn't exist, the provider will be non-nil but contain no data. - XCTAssertNotNil(authorizationProvider) - XCTAssertEqual(try authorizationProvider.map { try resolveSymlinks($0.path) }, try resolveSymlinks(userPath)) - - XCTAssertTrue(authorizationProvider!.machines.isEmpty) + let expectedAuthorizationProvider = try resolveSymlinks(userPath) + let authorizationProvider: NetrcAuthorizationProvider = try #require( + authorizationProviderOpt) + #expect(authorizationProvider.path == expectedAuthorizationProvider) + #expect(authorizationProvider.machines.isEmpty) } } } diff --git a/Tests/WorkspaceTests/MirrorsConfigurationTests.swift b/Tests/WorkspaceTests/MirrorsConfigurationTests.swift index d91861303c1..7d584bcab17 100644 --- a/Tests/WorkspaceTests/MirrorsConfigurationTests.swift +++ b/Tests/WorkspaceTests/MirrorsConfigurationTests.swift @@ -13,10 +13,11 @@ import Basics import _InternalTestSupport import Workspace -import XCTest +import Testing -final class MirrorsConfigurationTests: XCTestCase { - func testLoadingSchema1() throws { +fileprivate struct MirrorsConfigurationTests { + @Test + func loadingSchema1() throws { let fs = InMemoryFileSystem() let configFile = AbsolutePath("/config/mirrors.json") @@ -42,30 +43,33 @@ final class MirrorsConfigurationTests: XCTestCase { let config = Workspace.Configuration.MirrorsStorage(path: configFile, fileSystem: fs, deleteWhenEmpty: true) let mirrors = try config.get() - XCTAssertEqual(mirrors.mirror(for: originalURL),mirrorURL) - XCTAssertEqual(mirrors.original(for: mirrorURL), originalURL) + #expect(mirrors.mirror(for: originalURL) == mirrorURL) + #expect(mirrors.original(for: mirrorURL) == originalURL) } - func testThrowsWhenNotFound() throws { + @Test + func throwsWhenNotFound() throws { + let gitUrl = "https://github.com/apple/swift-argument-parser.git" let fs = InMemoryFileSystem() let configFile = AbsolutePath("/config/mirrors.json") let config = Workspace.Configuration.MirrorsStorage(path: configFile, fileSystem: fs, deleteWhenEmpty: true) let mirrors = try config.get() - XCTAssertThrows(StringError("Mirror not found for 'https://github.com/apple/swift-argument-parser.git'")) { - try mirrors.unset(originalOrMirror: "https://github.com/apple/swift-argument-parser.git") + #expect(throws: StringError("Mirror not found for '\(gitUrl)'")) { + try mirrors.unset(originalOrMirror: gitUrl) } } - func testDeleteWhenEmpty() throws { + @Test + func deleteWhenEmpty() throws { let fs = InMemoryFileSystem() let configFile = AbsolutePath("/config/mirrors.json") let config = Workspace.Configuration.MirrorsStorage(path: configFile, fileSystem: fs, deleteWhenEmpty: true) try config.apply{ _ in } - XCTAssertFalse(fs.exists(configFile)) + #expect(!fs.exists(configFile)) let originalURL = "https://github.com/apple/swift-argument-parser.git" let mirrorURL = "https://github.com/mona/swift-argument-parser.git" @@ -73,22 +77,23 @@ final class MirrorsConfigurationTests: XCTestCase { try config.apply{ mirrors in try mirrors.set(mirror: mirrorURL, for: originalURL) } - XCTAssertTrue(fs.exists(configFile)) + #expect(fs.exists(configFile)) try config.apply{ mirrors in try mirrors.unset(originalOrMirror: originalURL) } - XCTAssertFalse(fs.exists(configFile)) + #expect(!fs.exists(configFile)) } - func testDontDeleteWhenEmpty() throws { + @Test + func dontDeleteWhenEmpty() throws { let fs = InMemoryFileSystem() let configFile = AbsolutePath("/config/mirrors.json") let config = Workspace.Configuration.MirrorsStorage(path: configFile, fileSystem: fs, deleteWhenEmpty: false) try config.apply{ _ in } - XCTAssertFalse(fs.exists(configFile)) + #expect(!fs.exists(configFile)) let originalURL = "https://github.com/apple/swift-argument-parser.git" let mirrorURL = "https://github.com/mona/swift-argument-parser.git" @@ -96,16 +101,17 @@ final class MirrorsConfigurationTests: XCTestCase { try config.apply{ mirrors in try mirrors.set(mirror: mirrorURL, for: originalURL) } - XCTAssertTrue(fs.exists(configFile)) + #expect(fs.exists(configFile)) try config.apply{ mirrors in try mirrors.unset(originalOrMirror: originalURL) } - XCTAssertTrue(fs.exists(configFile)) - XCTAssertTrue(try config.get().isEmpty) + #expect(fs.exists(configFile)) + #expect(try config.get().isEmpty) } - func testLocalAndShared() throws { + @Test + func localAndShared() throws { let fs = InMemoryFileSystem() let localConfigFile = AbsolutePath("/config/local-mirrors.json") let sharedConfigFile = AbsolutePath("/config/shared-mirrors.json") @@ -125,9 +131,9 @@ final class MirrorsConfigurationTests: XCTestCase { try mirrors.set(mirror: mirror1URL, for: original1URL) } - XCTAssertEqual(config.mirrors.count, 1) - XCTAssertEqual(config.mirrors.mirror(for: original1URL), mirror1URL) - XCTAssertEqual(config.mirrors.original(for: mirror1URL), original1URL) + #expect(config.mirrors.count == 1) + #expect(config.mirrors.mirror(for: original1URL) == mirror1URL) + #expect(config.mirrors.original(for: mirror1URL) == original1URL) // now write to local location @@ -138,12 +144,12 @@ final class MirrorsConfigurationTests: XCTestCase { try mirrors.set(mirror: mirror2URL, for: original2URL) } - XCTAssertEqual(config.mirrors.count, 1) - XCTAssertEqual(config.mirrors.mirror(for: original2URL), mirror2URL) - XCTAssertEqual(config.mirrors.original(for: mirror2URL), original2URL) + #expect(config.mirrors.count == 1) + #expect(config.mirrors.mirror(for: original2URL) == mirror2URL) + #expect(config.mirrors.original(for: mirror2URL) == original2URL) // should not see the shared any longer - XCTAssertEqual(config.mirrors.mirror(for: original1URL), nil) - XCTAssertEqual(config.mirrors.original(for: mirror1URL), nil) + #expect(config.mirrors.mirror(for: original1URL) == nil) + #expect(config.mirrors.original(for: mirror1URL) == nil) } } diff --git a/Tests/WorkspaceTests/ToolsVersionSpecificationGenerationTests.swift b/Tests/WorkspaceTests/ToolsVersionSpecificationGenerationTests.swift index 0b5bed54c69..8e84be7d014 100644 --- a/Tests/WorkspaceTests/ToolsVersionSpecificationGenerationTests.swift +++ b/Tests/WorkspaceTests/ToolsVersionSpecificationGenerationTests.swift @@ -9,36 +9,45 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// +import Foundation /// /// This file tests the generation of a Swift tools version specification from a known version. /// -import XCTest +import Testing import PackageModel import struct TSCUtility.Version /// Test cases for the generation of Swift tools version specifications. -class ToolsVersionSpecificationGenerationTests: XCTestCase { +fileprivate struct ToolsVersionSpecificationGenerationTests { /// Tests the generation of Swift tools version specifications. - func testToolsVersionSpecificationGeneration() throws { + @Test + func toolsVersionSpecificationGeneration() throws { let versionWithNonZeroPatch = ToolsVersion(version: Version(4, 3, 2)) - XCTAssertEqual(versionWithNonZeroPatch.specification(), "// swift-tools-version:4.3.2") - XCTAssertEqual(versionWithNonZeroPatch.specification(roundedTo: .automatic), "// swift-tools-version:4.3.2") - XCTAssertEqual(versionWithNonZeroPatch.specification(roundedTo: .minor), "// swift-tools-version:4.3") - XCTAssertEqual(versionWithNonZeroPatch.specification(roundedTo: .patch), "// swift-tools-version:4.3.2") - + #expect(versionWithNonZeroPatch.specification() == "// swift-tools-version:4.3.2") + #expect(versionWithNonZeroPatch.specification(roundedTo: .automatic) == "// swift-tools-version:4.3.2") + #expect(versionWithNonZeroPatch.specification(roundedTo: .minor) == "// swift-tools-version:4.3") + #expect(versionWithNonZeroPatch.specification(roundedTo: .patch) == "// swift-tools-version:4.3.2") + let versionWithZeroPatch = ToolsVersion.v5_3 // 5.3.0 - XCTAssertEqual(versionWithZeroPatch.specification(), "// swift-tools-version:5.3") - XCTAssertEqual(versionWithZeroPatch.specification(roundedTo: .automatic), "// swift-tools-version:5.3") - XCTAssertEqual(versionWithZeroPatch.specification(roundedTo: .minor), "// swift-tools-version:5.3") - XCTAssertEqual(versionWithZeroPatch.specification(roundedTo: .patch), "// swift-tools-version:5.3.0") - + #expect(versionWithZeroPatch.specification() == "// swift-tools-version:5.3") + #expect(versionWithZeroPatch.specification(roundedTo: .automatic) == "// swift-tools-version:5.3") + #expect(versionWithZeroPatch.specification(roundedTo: .minor) == "// swift-tools-version:5.3") + #expect(versionWithZeroPatch.specification(roundedTo: .patch) == "// swift-tools-version:5.3.0") + let newMajorVersion = ToolsVersion.v5 // 5.0.0 - XCTAssertEqual(newMajorVersion.specification(), "// swift-tools-version:5.0") - XCTAssertEqual(newMajorVersion.specification(roundedTo: .automatic), "// swift-tools-version:5.0") - XCTAssertEqual(newMajorVersion.specification(roundedTo: .minor), "// swift-tools-version:5.0") - XCTAssertEqual(newMajorVersion.specification(roundedTo: .patch), "// swift-tools-version:5.0.0") + #expect(newMajorVersion.specification() == "// swift-tools-version:5.0") + #expect(newMajorVersion.specification(roundedTo: .automatic) == "// swift-tools-version:5.0") + #expect(newMajorVersion.specification(roundedTo: .minor) == "// swift-tools-version:5.0") + #expect(newMajorVersion.specification(roundedTo: .patch) == "// swift-tools-version:5.0.0") + + let allZeroVersion = ToolsVersion(version: Version(0, 0, 0)) + #expect(allZeroVersion.specification() == "// swift-tools-version:0.0") + #expect(allZeroVersion.specification(roundedTo: .automatic) == "// swift-tools-version:0.0") + #expect(allZeroVersion.specification(roundedTo: .minor) == "// swift-tools-version:0.0") + #expect(allZeroVersion.specification(roundedTo: .patch) == "// swift-tools-version:0.0.0") } + } diff --git a/Tests/WorkspaceTests/ToolsVersionSpecificationRewriterTests.swift b/Tests/WorkspaceTests/ToolsVersionSpecificationRewriterTests.swift index 486951cbb26..9a67dd5ad5a 100644 --- a/Tests/WorkspaceTests/ToolsVersionSpecificationRewriterTests.swift +++ b/Tests/WorkspaceTests/ToolsVersionSpecificationRewriterTests.swift @@ -17,185 +17,170 @@ import Basics import PackageModel @testable import Workspace -import XCTest +import Testing /// Test cases for `rewriteToolsVersionSpecification(toDefaultManifestIn:specifying:fileSystem:)` -final class ToolsVersionSpecificationRewriterTests: XCTestCase { - - /// Tests `rewriteToolsVersionSpecification(toDefaultManifestIn:specifying:fileSystem:)`. - func testNonVersionSpecificManifests() throws { - // Empty file. - rewriteToolsVersionSpecificationToDefaultManifest(content: "") { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n") - } - - // File with just a new line. - rewriteToolsVersionSpecificationToDefaultManifest(content: "\n") { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n\n") - } - - // File with some contents. - rewriteToolsVersionSpecificationToDefaultManifest(content: "let package = ... \n") { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\nlet package = ... \n") - } +fileprivate struct ToolsVersionSpecificationRewriterTests { - // File already having a valid version specifier. - let content = """ - // swift-tools-version:3.1.2 - ... - """ - - rewriteToolsVersionSpecificationToDefaultManifest(content: content) { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n...") - } + struct NonVersionSpecificManifestTestData: Identifiable { + let id: String + let content: String + let version: ToolsVersion + let expected: String + } + @Test( + arguments:[ + NonVersionSpecificManifestTestData( + id: "Empty file.", + content: "", + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n" + ), + NonVersionSpecificManifestTestData( + id: "File with just a new line.", + content: "\n", + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n\n" + ), + NonVersionSpecificManifestTestData( + id: "File with some contents.", + content: "let package = ... \n", + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\nlet package = ... \n" + ), + NonVersionSpecificManifestTestData( + id: "File already having a valid version specifier.", + content: """ + // swift-tools-version:3.1.2 + ... + """, + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n..." + ), + NonVersionSpecificManifestTestData( + id: "File already having a valid version specifier.", + content: """ + // swift-tools-version:3.1.2 + ... + """, + version: ToolsVersion(version: "2.1.0"), + expected: "// swift-tools-version:2.1\n..." + ), + NonVersionSpecificManifestTestData( + id: "Contents with invalid tools version specification (ignoring the validity of the version specifier).", + content: """ + // swift-tool-version:3.1.2 + ... + """, + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n// swift-tool-version:3.1.2\n..." + ), + NonVersionSpecificManifestTestData( + id: "Contents with invalid version specifier.", + content: """ + // swift-tools-version:3.1.2 + ... + """, + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n..." + ), + NonVersionSpecificManifestTestData( + id: "Contents with invalid version specifier and some meta data.", + content: """ + // swift-tools-version:3.1.2 + ... + """, + version: ToolsVersion(version: "4.1.2"), + expected: "// swift-tools-version:4.1.2\n..." + ), + NonVersionSpecificManifestTestData( + id: "Try to write a version with prerelease and build meta data.", + content: "let package = ... \n", + version: ToolsVersion(version: "4.1.2-alpha.beta+sha.1234"), + expected: "// swift-tools-version:4.1.2\nlet package = ... \n" + ) + ] + ) + func nonVersionSpecificManifests(_ data: NonVersionSpecificManifestTestData) throws { + let content = data.content + let version = data.version + let expected = data.expected - // Write a version with zero in patch number. - rewriteToolsVersionSpecificationToDefaultManifest( - content: """ - // swift-tools-version:3.1.2 - ... - """, - version: ToolsVersion(version: "2.1.0") - ) { result in - XCTAssertEqual(result, "// swift-tools-version:2.1\n...") - } + let inMemoryFileSystem = InMemoryFileSystem() - // Contents with invalid tools version specification (ignoring the validity of the version specifier). - rewriteToolsVersionSpecificationToDefaultManifest( - content: """ - // swift-tool-version:3.1.2 - ... - """ - ) { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n// swift-tool-version:3.1.2\n...") - } + let manifestFilePath = AbsolutePath("/pkg/Package.swift") - // Contents with invalid version specifier. - rewriteToolsVersionSpecificationToDefaultManifest( - content: """ - // swift-tools-version:3.1.2 - ... - """ - ) { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n...") - } + try inMemoryFileSystem.createDirectory(manifestFilePath.parentDirectory, recursive: true) + try inMemoryFileSystem.writeFileContents(manifestFilePath, string: content) - // Contents with invalid version specifier and some meta data. - rewriteToolsVersionSpecificationToDefaultManifest( - content: """ - // swift-tools-version:3.1.2 - ... - """ - ) { result in - // Note: Right now we lose the metadata but if we ever start using it, we should preserve it. - XCTAssertEqual(result, "// swift-tools-version:4.1.2\n...") - } + try ToolsVersionSpecificationWriter.rewriteSpecification( + manifestDirectory: manifestFilePath.parentDirectory, + toolsVersion: version, + fileSystem: inMemoryFileSystem + ) - // Try to write a version with prerelease and build meta data. - let toolsVersion = ToolsVersion(version: "4.1.2-alpha.beta+sha.1234") - rewriteToolsVersionSpecificationToDefaultManifest( - content: "let package = ... \n", - version: toolsVersion - ) { result in - XCTAssertEqual(result, "// swift-tools-version:4.1.2\nlet package = ... \n") - } + // resultHandler(try inMemoryFileSystem.readFileContents(manifestFilePath)) + let actual = try #require(try inMemoryFileSystem.readFileContents(manifestFilePath)) + #expect(actual.validDescription == expected, "Actual is not expected") } - - func testManifestAccessFailures() throws { + + @Test + func manifestAccessFailures() throws { let toolsVersion = ToolsVersion.v5_3 - + let inMemoryFileSystem = InMemoryFileSystem() let manifestFilePath = AbsolutePath("/pkg/Package.swift/Package.swift") try inMemoryFileSystem.createDirectory(manifestFilePath.parentDirectory, recursive: true) // /pkg/Package.swift/ - + // Test `ManifestAccessError.Kind.isADirectory` - XCTAssertThrowsError( + + #expect{ try ToolsVersionSpecificationWriter.rewriteSpecification( manifestDirectory: manifestFilePath.parentDirectory.parentDirectory, // /pkg/ toolsVersion: toolsVersion, fileSystem: inMemoryFileSystem - ), - "'/pkg/Package.swift' is a directory, and an error should've been thrown" - ) { error in - guard let error = error as? ToolsVersionSpecificationWriter.ManifestAccessError else { - XCTFail("a ManifestAccessError should've been thrown") - return - } - XCTAssertEqual( - error.kind, - .isADirectory ) - XCTAssertEqual( - error.description, - "no accessible Swift Package Manager manifest file found at '\(manifestFilePath.parentDirectory)'; the path is a directory; a file is expected" // /pkg/Package.swift/ + } throws: { error in + let error = try #require( + error as? ToolsVersionSpecificationWriter.ManifestAccessError, + "a ManifestAccessError should've been thrown" ) + let isExpectedKind = (error.kind == .isADirectory) + let isExpectedDescription = (error.description == "no accessible Swift Package Manager manifest file found at '\(manifestFilePath.parentDirectory)'; the path is a directory; a file is expected") + + return isExpectedKind && isExpectedDescription } - + // Test `ManifestAccessError.Kind.noSuchFileOrDirectory` - XCTAssertThrowsError( + #expect { try ToolsVersionSpecificationWriter.rewriteSpecification( manifestDirectory: manifestFilePath.parentDirectory, // /pkg/Package.swift/ toolsVersion: toolsVersion, fileSystem: inMemoryFileSystem - ), - "'/pkg/Package.swift' is a directory, and an error should've been thrown" - ) { error in - guard let error = error as? ToolsVersionSpecificationWriter.ManifestAccessError else { - XCTFail("a ManifestAccessError should've been thrown") - return - } - XCTAssertEqual( - error.kind, - .noSuchFileOrDirectory ) - XCTAssertEqual( - error.description, - "no accessible Swift Package Manager manifest file found at '\(manifestFilePath)'; a component of the path does not exist, or the path is an empty string" // /pkg/Package.swift/Package.swift + } throws: { error in + let error = try #require( + error as? ToolsVersionSpecificationWriter.ManifestAccessError, + "a ManifestAccessError should've been thrown" ) + let isExpectedKind = (error.kind == .noSuchFileOrDirectory) + let isExpectedDescription = (error.description == "no accessible Swift Package Manager manifest file found at '\(manifestFilePath)'; a component of the path does not exist, or the path is an empty string") + + return isExpectedKind && isExpectedDescription } - - // TODO: Test `ManifestAccessError.Kind.unknown` } - + // Private functions are not run in tests. - private func testVersionSpecificManifests() throws { - // TODO: Add the functionality and tests for version-specific manifests too. - } + @Test + func versionSpecificManifests() throws { - func testZeroedPatchVersion() { - XCTAssertEqual(ToolsVersion(version: "4.2.1").zeroedPatch.description, "4.2.0") - XCTAssertEqual(ToolsVersion(version: "4.2.0").zeroedPatch.description, "4.2.0") - XCTAssertEqual(ToolsVersion(version: "6.0.129").zeroedPatch.description, "6.0.0") } - - /// Does the boilerplate filesystem preparations, then calls `rewriteToolsVersionSpecification(toDefaultManifestIn:specifying:fileSystem:)`, for `testNonVersionSpecificManifests()`. - /// - Parameters: - /// - stream: The stream to read from and write to the filesystem. - /// - version: The Swift tools version to specify. - /// - resultHandler: The result handler. - func rewriteToolsVersionSpecificationToDefaultManifest( - content: String, - version: ToolsVersion = ToolsVersion(version: "4.1.2"), - resultHandler: (String) -> Void - ) { - do { - let inMemoryFileSystem = InMemoryFileSystem() - - let manifestFilePath = AbsolutePath("/pkg/Package.swift") - - try inMemoryFileSystem.createDirectory(manifestFilePath.parentDirectory, recursive: true) - try inMemoryFileSystem.writeFileContents(manifestFilePath, string: content) - - try ToolsVersionSpecificationWriter.rewriteSpecification( - manifestDirectory: manifestFilePath.parentDirectory, - toolsVersion: version, - fileSystem: inMemoryFileSystem - ) - resultHandler(try inMemoryFileSystem.readFileContents(manifestFilePath)) - } catch { - XCTFail("Failed with error \(error)") - } + @Test + func zeroedPatchVersion() { + #expect(ToolsVersion(version: "4.2.1").zeroedPatch.description == "4.2.0") + #expect(ToolsVersion(version: "4.2.0").zeroedPatch.description == "4.2.0") + #expect(ToolsVersion(version: "6.0.129").zeroedPatch.description == "6.0.0") } - + } diff --git a/Tests/WorkspaceTests/WorkspaceStateTests.swift b/Tests/WorkspaceTests/WorkspaceStateTests.swift index fda8eac54d2..3785a12e2e3 100644 --- a/Tests/WorkspaceTests/WorkspaceStateTests.swift +++ b/Tests/WorkspaceTests/WorkspaceStateTests.swift @@ -9,13 +9,13 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// - import Basics @testable import Workspace -import XCTest +import Testing -final class WorkspaceStateTests: XCTestCase { - func testV4Format() async throws { +fileprivate struct WorkspaceStateTests { + @Test + func v4Format() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -83,12 +83,13 @@ final class WorkspaceStateTests: XCTestCase { ) let dependencies = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).dependencies - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) } - func testV4FormatWithPath() async throws { + @Test + func v4FormatWithPath() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -156,12 +157,13 @@ final class WorkspaceStateTests: XCTestCase { ) let dependencies = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).dependencies - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) } - func testV5Format() async throws { + @Test + func v5Format() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -229,12 +231,13 @@ final class WorkspaceStateTests: XCTestCase { ) let dependencies = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).dependencies - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) - XCTAssertTrue(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("yams") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-tools-support-core") })) + #expect(dependencies.contains(where: { $0.packageRef.identity == .plain("swift-argument-parser") })) } - func testSavedDependenciesAreSorted() async throws { + @Test + func savedDependenciesAreSorted() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -292,13 +295,14 @@ final class WorkspaceStateTests: XCTestCase { let serialized: String = try fs.readFileContents(statePath) - let argpRange = try XCTUnwrap(serialized.range(of: "swift-argument-parser")) - let yamsRange = try XCTUnwrap(serialized.range(of: "yams")) + let argpRange = try #require(serialized.range(of: "swift-argument-parser")) + let yamsRange = try #require(serialized.range(of: "yams")) - XCTAssertTrue(argpRange.lowerBound < yamsRange.lowerBound) + #expect(argpRange.lowerBound < yamsRange.lowerBound) } - func testArtifacts() async throws { + @Test + func artifacts() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -363,13 +367,14 @@ final class WorkspaceStateTests: XCTestCase { ) let artifacts = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).artifacts - XCTAssertTrue(artifacts.contains(where: { $0.packageRef.identity == .plain("foo") && $0.targetName == "foo" })) - XCTAssertTrue(artifacts.contains(where: { $0.packageRef.identity == .plain("foo") && $0.targetName == "bar" })) - XCTAssertTrue(artifacts.contains(where: { $0.packageRef.identity == .plain("bar") && $0.targetName == "bar" })) + #expect(artifacts.contains(where: { $0.packageRef.identity == .plain("foo") && $0.targetName == "foo" })) + #expect(artifacts.contains(where: { $0.packageRef.identity == .plain("foo") && $0.targetName == "bar" })) + #expect(artifacts.contains(where: { $0.packageRef.identity == .plain("bar") && $0.targetName == "bar" })) } // rdar://86857825 - func testDuplicateDependenciesDoNotCrash() async throws { + @Test + func duplicateDependenciesDoNotCrash() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -425,11 +430,12 @@ final class WorkspaceStateTests: XCTestCase { let dependencies = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).dependencies // empty since we have dups so we warn and fail the loading // TODO: test for diagnostics when we can get them from the WorkspaceState initializer - XCTAssertTrue(dependencies.isEmpty) + #expect(dependencies.isEmpty) } // rdar://86857825 - func testDuplicateArtifactsDoNotCrash() async throws { + @Test + func duplicateArtifactsDoNotCrash() async throws { let fs = InMemoryFileSystem() let buildDir = AbsolutePath("/.build") @@ -481,7 +487,7 @@ final class WorkspaceStateTests: XCTestCase { let artifacts = await WorkspaceState(fileSystem: fs, storageDirectory: buildDir).artifacts // empty since we have dups so we warn and fail the loading // TODO: test for diagnostics when we can get them from the WorkspaceState initializer - XCTAssertTrue(artifacts.isEmpty) + #expect(artifacts.isEmpty) } }