Skip to content

Commit c9a8f60

Browse files
authored
add more tests for additional dependency validation (#3714)
motivation: exapnd the tests as we are changing the functionaly changes: * add facilities to use urls in mocks, not just path * add tests that demonstrate the current behabviour when depednecy identity conflict (different URLs, same identity) is encountered
1 parent 29dfdd5 commit c9a8f60

File tree

11 files changed

+290
-67
lines changed

11 files changed

+290
-67
lines changed

Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ public struct PubgrubDependencyResolver {
230230
return (package: package, binding: details.binding, products: details.products)
231231
}
232232

233-
// Add overriden packages to the result.
233+
// Add overridden packages to the result.
234234
for (package, override) in state.overriddenPackages {
235235
// TODO: replace with async/await when available
236236
let container = try temp_await { provider.getContainer(for: package, completion: $0) }

Sources/SPMTestSupport/InMemoryGitRepository.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ public final class InMemoryGitRepositoryProvider: RepositoryProvider {
385385
/// Add a repository to this provider. Only the repositories added with this interface can be operated on
386386
/// with this provider.
387387
public func add(specifier: RepositorySpecifier, repository: InMemoryGitRepository) {
388-
// Save the repository in specifer map.
388+
// Save the repository in specifier map.
389389
specifierMap[specifier] = repository
390390
}
391391

@@ -398,7 +398,7 @@ public final class InMemoryGitRepositoryProvider: RepositoryProvider {
398398
// Note: These methods use force unwrap (instead of throwing) to honor their preconditions.
399399

400400
public func fetch(repository: RepositorySpecifier, to path: AbsolutePath) throws {
401-
let repo = specifierMap[RepositorySpecifier(url: repository.url.spm_dropGitSuffix())]!
401+
let repo = specifierMap[RepositorySpecifier(url: repository.url)]!
402402
fetchedMap[path] = try repo.copy()
403403
add(specifier: RepositorySpecifier(url: path.asURL.absoluteString), repository: repo)
404404
}

Sources/SPMTestSupport/MockDependency.swift

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,86 @@ public struct MockDependency {
1616
public typealias Requirement = PackageDependency.SourceControl.Requirement
1717

1818
public let deprecatedName: String?
19-
public let path: String
20-
public let requirement: Requirement?
19+
public let location: Location
2120
public let products: ProductFilter
22-
23-
init(deprecatedName: String? = nil, path: String, requirement: Requirement?, products: ProductFilter = .everything) {
21+
22+
init(deprecatedName: String? = nil, location: Location, products: ProductFilter = .everything) {
2423
self.deprecatedName = deprecatedName
25-
self.path = path
26-
self.requirement = requirement
24+
self.location = location
2725
self.products = products
2826
}
29-
27+
3028
// TODO: refactor this when adding registry support
3129
public func convert(baseURL: AbsolutePath, identityResolver: IdentityResolver) -> PackageDependency {
32-
let path = baseURL.appending(RelativePath(self.path))
33-
let location = identityResolver.resolveLocation(from: path.pathString)
34-
let identity = identityResolver.resolveIdentity(for: location)
35-
if let requirement = self.requirement {
36-
return .scm(identity: identity,
37-
deprecatedName: self.deprecatedName,
38-
location: location,
39-
requirement: requirement,
40-
productFilter: self.products)
41-
} else {
42-
return .local(identity: identity,
43-
deprecatedName: self.deprecatedName,
44-
path: location,
45-
productFilter: self.products)
30+
switch self.location {
31+
case .fileSystem(let path):
32+
let path = baseURL.appending(path)
33+
let location = identityResolver.resolveLocation(from: path.pathString)
34+
let identity = identityResolver.resolveIdentity(for: location)
35+
return .fileSystem(
36+
identity: identity,
37+
deprecatedName: self.deprecatedName,
38+
path: location,
39+
productFilter: self.products
40+
)
41+
case .sourceControlPath(let path, let requirement):
42+
let path = baseURL.appending(path)
43+
let location = identityResolver.resolveLocation(from: path.pathString)
44+
let identity = identityResolver.resolveIdentity(for: location)
45+
return .sourceControl(
46+
identity: identity,
47+
deprecatedName: self.deprecatedName,
48+
location: location,
49+
requirement: requirement,
50+
productFilter: self.products
51+
)
52+
case .sourceControlURL(let url, let requirement):
53+
let location = identityResolver.resolveLocation(from: url)
54+
let identity = identityResolver.resolveIdentity(for: location)
55+
return .sourceControl(
56+
identity: identity,
57+
deprecatedName: self.deprecatedName,
58+
location: location,
59+
requirement: requirement,
60+
productFilter: self.products
61+
)
4662
}
4763
}
48-
64+
65+
public static func fileSystem(path: String, products: ProductFilter = .everything) -> MockDependency {
66+
MockDependency(location: .fileSystem(path: RelativePath(path)), products: products)
67+
}
68+
69+
public static func sourceControl(path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency {
70+
MockDependency(location: .sourceControlPath(path: RelativePath(path), requirement: requirement), products: products)
71+
}
72+
73+
public static func sourceControlWithDeprecatedName(name: String, path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency {
74+
MockDependency(deprecatedName: name, location: .sourceControlPath(path: RelativePath(path), requirement: requirement), products: products)
75+
}
76+
77+
public static func sourceControl(url: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency {
78+
MockDependency(location: .sourceControlURL(url: url, requirement: requirement), products: products)
79+
}
80+
81+
// for backwards compatibility
4982
public static func local(path: String, products: ProductFilter = .everything) -> MockDependency {
50-
MockDependency(path: path, requirement: nil, products: products)
83+
Self.fileSystem(path: path, products: products)
5184
}
5285

86+
// for backwards compatibility
5387
public static func scm(path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency {
54-
MockDependency(path: path, requirement: requirement, products: products)
88+
Self.sourceControl(path: path, requirement: requirement, products: products)
5589
}
5690

91+
// for backwards compatibility
5792
public static func scmWithDeprecatedName(name: String, path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency {
58-
MockDependency(deprecatedName: name, path: path, requirement: requirement, products: products)
93+
Self.sourceControlWithDeprecatedName(name: name, path: path, requirement: requirement, products: products)
5994
}
6095

96+
public enum Location {
97+
case fileSystem(path: RelativePath)
98+
case sourceControlPath(path: RelativePath, requirement: Requirement)
99+
case sourceControlURL(url: String, requirement: Requirement)
100+
}
61101
}

Sources/SPMTestSupport/MockPackage.swift

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
*/
1010

1111
import PackageModel
12+
import TSCBasic
1213

1314
public struct MockPackage {
1415
public let name: String
1516
public let platforms: [PlatformDescription]
16-
public let path: String?
17+
public let location: Location
1718
public let targets: [MockTarget]
1819
public let products: [MockProduct]
1920
public let dependencies: [MockDependency]
@@ -33,7 +34,27 @@ public struct MockPackage {
3334
) {
3435
self.name = name
3536
self.platforms = platforms
36-
self.path = path
37+
self.location = .fileSystem(path: RelativePath(path ?? name))
38+
self.targets = targets
39+
self.products = products
40+
self.dependencies = dependencies
41+
self.versions = versions
42+
self.toolsVersion = toolsVersion
43+
}
44+
45+
public init(
46+
name: String,
47+
platforms: [PlatformDescription] = [],
48+
url: String,
49+
targets: [MockTarget],
50+
products: [MockProduct],
51+
dependencies: [MockDependency] = [],
52+
versions: [String?] = [],
53+
toolsVersion: ToolsVersion? = nil
54+
) {
55+
self.name = name
56+
self.platforms = platforms
57+
self.location = .sourceControl(url: url)
3758
self.targets = targets
3859
self.products = products
3960
self.dependencies = dependencies
@@ -53,4 +74,9 @@ public struct MockPackage {
5374
versions: ["1.0.0"]
5475
)
5576
}
77+
78+
public enum Location {
79+
case fileSystem(path: RelativePath)
80+
case sourceControl(url: String)
81+
}
5682
}

Sources/SPMTestSupport/MockWorkspace.swift

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ public final class MockWorkspace {
8080
}
8181

8282
private func url(for package: MockPackage) -> String {
83-
return self.packagesDir.appending(RelativePath(package.path ?? package.name)).pathString
83+
switch package.location {
84+
case .fileSystem(let path):
85+
return self.packagesDir.appending(path).pathString
86+
case .sourceControl(let url):
87+
return url
88+
}
8489
}
8590

8691
private func create() throws {
@@ -95,10 +100,27 @@ public final class MockWorkspace {
95100
var manifests: [MockManifestLoader.Key: Manifest] = [:]
96101

97102
func create(package: MockPackage, basePath: AbsolutePath, packageKind: PackageReference.Kind) throws {
98-
let packagePath = basePath.appending(RelativePath(package.path ?? package.name))
103+
let packagePath: AbsolutePath
104+
switch package.location {
105+
case .fileSystem(let path):
106+
packagePath = basePath.appending(path)
107+
case .sourceControl(let url):
108+
packagePath = basePath.appending(RelativePath(url.spm_mangledToC99ExtendedIdentifier()))
109+
}
99110

100-
let packageLocation = (packageKind == .root ? packagePath : self.packagesDir.appending(RelativePath(package.path ?? package.name))).pathString
101-
let specifier = RepositorySpecifier(url: packageLocation)
111+
let packageLocation: String
112+
let specifier: RepositorySpecifier
113+
switch (packageKind, package.location) {
114+
case (.root, _):
115+
packageLocation = packagePath.pathString
116+
specifier = RepositorySpecifier(url: packageLocation)
117+
case (_, .fileSystem(let path)):
118+
packageLocation = self.packagesDir.appending(path).pathString
119+
specifier = RepositorySpecifier(url: packageLocation)
120+
case (_, .sourceControl(let url)):
121+
packageLocation = url
122+
specifier = RepositorySpecifier(url: url)
123+
}
102124

103125
// Create targets on disk.
104126
let repo = self.repoProvider.specifierMap[specifier] ?? InMemoryGitRepository(path: packagePath, fs: self.fs as! InMemoryFileSystem)
@@ -118,7 +140,7 @@ public final class MockWorkspace {
118140
let manifestPath = packagePath.appending(component: Manifest.filename)
119141
for version in versions {
120142
let v = version.flatMap(Version.init(_:))
121-
manifests[.init(url: packageLocation, version: v)] = Manifest(
143+
manifests[.init(url: specifier.url, version: v)] = Manifest(
122144
name: package.name,
123145
path: manifestPath,
124146
packageKind: packageKind,

Sources/SPMTestSupport/PackageDependencyDescriptionExtensions.swift

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,6 @@ public extension PackageDependency {
3535
productFilter: productFilter)
3636
}
3737

38-
// backwards compatibility with existing tests
39-
static func local(identity: PackageIdentity? = nil,
40-
deprecatedName: String? = nil,
41-
path: String,
42-
productFilter: ProductFilter = .everything
43-
) -> Self {
44-
return .fileSystem(identity: identity,
45-
deprecatedName: deprecatedName,
46-
path: AbsolutePath(path),
47-
productFilter: productFilter)
48-
}
49-
50-
// backwards compatibility with existing tests
51-
static func local(identity: PackageIdentity? = nil,
52-
deprecatedName: String? = nil,
53-
path: AbsolutePath,
54-
productFilter: ProductFilter = .everything
55-
) -> Self {
56-
return .fileSystem(identity: identity,
57-
deprecatedName: deprecatedName,
58-
path: path,
59-
productFilter: productFilter)
60-
}
61-
6238
static func sourceControl(identity: PackageIdentity? = nil,
6339
deprecatedName: String? = nil,
6440
location: String,

Tests/CommandsTests/PackageToolTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ final class PackageToolTests: XCTestCase {
358358
packageLocation: "/PackageA",
359359
v: .v5_3,
360360
dependencies: [
361-
.local(path: "/PackageB"),
362-
.local(path: "/PackageC"),
361+
.fileSystem(path: "/PackageB"),
362+
.fileSystem(path: "/PackageC"),
363363
],
364364
products: [
365365
.init(name: "exe", type: .executable, targets: ["TargetA"])
@@ -376,8 +376,8 @@ final class PackageToolTests: XCTestCase {
376376
packageLocation: "/PackageB",
377377
v: .v5_3,
378378
dependencies: [
379-
.local(path: "/PackageC"),
380-
.local(path: "/PackageD"),
379+
.fileSystem(path: "/PackageC"),
380+
.fileSystem(path: "/PackageD"),
381381
],
382382
products: [
383383
.init(name: "PackageB", type: .library(.dynamic), targets: ["TargetB"])
@@ -394,7 +394,7 @@ final class PackageToolTests: XCTestCase {
394394
packageLocation: "/PackageC",
395395
v: .v5_3,
396396
dependencies: [
397-
.local(path: "/PackageD"),
397+
.fileSystem(path: "/PackageD"),
398398
],
399399
products: [
400400
.init(name: "PackageC", type: .library(.dynamic), targets: ["TargetC"])

Tests/PackageGraphTests/PackageGraphTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ class PackageGraphTests: XCTestCase {
11281128
path: "/Foo",
11291129
packageLocation: "/Foo",
11301130
dependencies: [
1131-
.local(path: "/Biz"),
1131+
.fileSystem(path: "/Biz"),
11321132
],
11331133
targets: [
11341134
TargetDescription(name: "Foo", dependencies: [

Tests/PackageLoadingTests/PackageBuilderTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,7 @@ class PackageBuilderTests: XCTestCase {
21352135
name: "Foo",
21362136
v: .v5,
21372137
dependencies: [
2138-
.local(path: "/Biz"),
2138+
.fileSystem(path: "/Biz"),
21392139
],
21402140
targets: [
21412141
try TargetDescription(

0 commit comments

Comments
 (0)