Start working on the validation
This commit is contained in:
parent
9347df368e
commit
ae82c7d5b0
|
@ -92,6 +92,9 @@
|
|||
B9F1EDEF208D1DB200477835 /* BuildPhase+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDEE208D1DB200477835 /* BuildPhase+TestData.swift */; };
|
||||
B9F1EDF1208D1F0F00477835 /* Settings+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDF0208D1F0F00477835 /* Settings+TestData.swift */; };
|
||||
B9F1EDF3208D200C00477835 /* Scheme+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDF2208D200C00477835 /* Scheme+TestData.swift */; };
|
||||
B9F1EDF6208D228600477835 /* ProjectValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDF5208D228600477835 /* ProjectValidator.swift */; };
|
||||
B9F1EDF8208D22D900477835 /* TargetValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDF7208D22D900477835 /* TargetValidator.swift */; };
|
||||
B9F1EDFB208D24F700477835 /* ProjectValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F1EDFA208D24F700477835 /* ProjectValidatorTests.swift */; };
|
||||
B9FB2DBF2086506E00BC2FB3 /* Basic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9FB2DBB20864FF800BC2FB3 /* Basic.framework */; };
|
||||
B9FB2DC62086515F00BC2FB3 /* Basic.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9FB2DBB20864FF800BC2FB3 /* Basic.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
B9FB2DC72086516500BC2FB3 /* POSIX.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9FB2DC02086507200BC2FB3 /* POSIX.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
|
@ -298,6 +301,9 @@
|
|||
B9F1EDEE208D1DB200477835 /* BuildPhase+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BuildPhase+TestData.swift"; sourceTree = "<group>"; };
|
||||
B9F1EDF0208D1F0F00477835 /* Settings+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Settings+TestData.swift"; sourceTree = "<group>"; };
|
||||
B9F1EDF2208D200C00477835 /* Scheme+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Scheme+TestData.swift"; sourceTree = "<group>"; };
|
||||
B9F1EDF5208D228600477835 /* ProjectValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectValidator.swift; sourceTree = "<group>"; };
|
||||
B9F1EDF7208D22D900477835 /* TargetValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetValidator.swift; sourceTree = "<group>"; };
|
||||
B9F1EDFA208D24F700477835 /* ProjectValidatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectValidatorTests.swift; sourceTree = "<group>"; };
|
||||
B9FB2DBB20864FF800BC2FB3 /* Basic.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Basic.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B9FB2DBD2086502100BC2FB3 /* Utility.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Utility.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B9FB2DC02086507200BC2FB3 /* POSIX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = POSIX.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -411,6 +417,7 @@
|
|||
B915ED3B2063B04C004B6630 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9F1EDF9208D24EA00477835 /* Validator */,
|
||||
B9589605208B4E3500F00ACF /* Generator */,
|
||||
B92BF9FC2075607C00EE4EBD /* Extensions */,
|
||||
B92BF9ED2075599900EE4EBD /* Models */,
|
||||
|
@ -425,6 +432,7 @@
|
|||
B915ED3E2063B04C004B6630 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9F1EDF4208D215600477835 /* Validator */,
|
||||
B95895F1208A2A9E00F00ACF /* Generator */,
|
||||
B9B6299C20864E2300EE9E07 /* App */,
|
||||
B9B629BD20864E7D00EE9E07 /* Commands */,
|
||||
|
@ -643,6 +651,23 @@
|
|||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B9F1EDF4208D215600477835 /* Validator */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9F1EDF5208D228600477835 /* ProjectValidator.swift */,
|
||||
B9F1EDF7208D22D900477835 /* TargetValidator.swift */,
|
||||
);
|
||||
path = Validator;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B9F1EDF9208D24EA00477835 /* Validator */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9F1EDFA208D24F700477835 /* ProjectValidatorTests.swift */,
|
||||
);
|
||||
path = Validator;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B9FB2DCD2086538E00BC2FB3 /* Loader */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -961,7 +986,9 @@
|
|||
B9FB2DE62086544900BC2FB3 /* Scheme.swift in Sources */,
|
||||
B95895FB208A2FFB00F00ACF /* WorkspaceGenerator.swift in Sources */,
|
||||
B9589600208A37B700F00ACF /* GraphJSONInitiatable.swift in Sources */,
|
||||
B9F1EDF8208D22D900477835 /* TargetValidator.swift in Sources */,
|
||||
B9B6299F20864E2300EE9E07 /* Constants.swift in Sources */,
|
||||
B9F1EDF6208D228600477835 /* ProjectValidator.swift in Sources */,
|
||||
B9FB2DCA2086527B00BC2FB3 /* BuildFiles.swift in Sources */,
|
||||
B9FB2DE1208653F500BC2FB3 /* GraphController.swift in Sources */,
|
||||
B9B629AA20864E3A00EE9E07 /* TechLogger.swift in Sources */,
|
||||
|
@ -986,6 +1013,7 @@
|
|||
B9F1EDED208D1CFE00477835 /* Target+TestData.swift in Sources */,
|
||||
B9F1EDD3208CD2E200477835 /* ShellCompletion+Equatable.swift in Sources */,
|
||||
B9E2DC9E20872D400061DF86 /* AppTests.swift in Sources */,
|
||||
B9F1EDFB208D24F700477835 /* ProjectValidatorTests.swift in Sources */,
|
||||
B9E2DC9720872B5D0061DF86 /* MockManifestLoader.swift in Sources */,
|
||||
B9E2DCC82089B78D0061DF86 /* DumpCommandTests.swift in Sources */,
|
||||
B9E2DCA32087651D0061DF86 /* Project+TestData.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import Basic
|
||||
import Foundation
|
||||
|
||||
enum ProjectValidationError: Error, CustomStringConvertible, Equatable {
|
||||
case duplicatedTargets([String], AbsolutePath)
|
||||
var description: String {
|
||||
switch self {
|
||||
case let .duplicatedTargets(targets, projectPath):
|
||||
return "Targets \(targets.joined(separator: ", ")) from project at \(projectPath.asString) have duplicates."
|
||||
}
|
||||
}
|
||||
|
||||
static func == (lhs: ProjectValidationError, rhs: ProjectValidationError) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (.duplicatedTargets(lhsTargets, lhsPath), .duplicatedTargets(rhsTargets, rhsPath)):
|
||||
return lhsTargets == rhsTargets && lhsPath == rhsPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates the format of the project.
|
||||
class ProjectValidator {
|
||||
let targetValidator: TargetValidator = TargetValidator()
|
||||
|
||||
func validate(_ project: Project) throws {
|
||||
try validateTargets(project: project)
|
||||
}
|
||||
|
||||
fileprivate func validateTargets(project: Project) throws {
|
||||
try project.targets.forEach(targetValidator.validate)
|
||||
try validateNotDuplicatedTargets(project: project)
|
||||
}
|
||||
|
||||
fileprivate func validateNotDuplicatedTargets(project: Project) throws {
|
||||
let duplicatedTargets = project.targets.map({ $0.name })
|
||||
.reduce(into: [String: Int]()) { $0[$1] = ($0[$1] ?? 0) + 1 }
|
||||
.filter({ $0.value > 1 })
|
||||
.keys
|
||||
if duplicatedTargets.count == 0 { return }
|
||||
throw ProjectValidationError.duplicatedTargets(Array(duplicatedTargets), project.path)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
class TargetValidator {
|
||||
func validate(_: Target) throws {
|
||||
}
|
||||
}
|
|
@ -3,12 +3,12 @@ import Foundation
|
|||
@testable import xcbuddykit
|
||||
|
||||
extension Project {
|
||||
static func testData(path: AbsolutePath = AbsolutePath("/test/"),
|
||||
name: String = "Project",
|
||||
config: Config? = nil,
|
||||
schemes: [Scheme] = [Scheme.test()],
|
||||
settings: Settings? = Settings.test(),
|
||||
targets: [Target] = [Target.test()]) -> Project {
|
||||
static func test(path: AbsolutePath = AbsolutePath("/test/"),
|
||||
name: String = "Project",
|
||||
config: Config? = nil,
|
||||
schemes: [Scheme] = [Scheme.test()],
|
||||
settings: Settings? = Settings.test(),
|
||||
targets: [Target] = [Target.test()]) -> Project {
|
||||
return Project(path: path,
|
||||
name: name,
|
||||
config: config,
|
||||
|
|
|
@ -6,8 +6,8 @@ extension Target {
|
|||
static func test(name: String = "Target",
|
||||
platform: Platform = .ios,
|
||||
product: Product = .module,
|
||||
infoPlist: AbsolutePath = AbsolutePath("Info.plist"),
|
||||
entitlements: AbsolutePath? = AbsolutePath("Test.entitlements"),
|
||||
infoPlist: AbsolutePath = AbsolutePath("/Info.plist"),
|
||||
entitlements: AbsolutePath? = AbsolutePath("/Test.entitlements"),
|
||||
settings: Settings? = Settings.test(),
|
||||
buildPhases: [BuildPhase] = [
|
||||
SourcesBuildPhase.test(),
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import Basic
|
||||
import Foundation
|
||||
@testable import xcbuddykit
|
||||
import XCTest
|
||||
|
||||
final class ProjectValidationErrorTests: XCTestCase {
|
||||
func test_description_whenDuplicatedTargets() {
|
||||
let error = ProjectValidationError.duplicatedTargets(["A", "B"], AbsolutePath("/test"))
|
||||
XCTAssertEqual(error.description, "Targets A, B from project at /test have duplicates.")
|
||||
}
|
||||
}
|
||||
|
||||
final class ProjectValidatorTests: XCTestCase {
|
||||
var subject: ProjectValidator!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
subject = ProjectValidator()
|
||||
}
|
||||
|
||||
func test_validate_throws_when_there_are_duplicated_targets() throws {
|
||||
let target = Target.test(name: "A")
|
||||
let project = Project.test(targets: [target, target])
|
||||
XCTAssertThrowsError(try subject.validate(project)) { error in
|
||||
XCTAssertEqual(error as? ProjectValidationError, ProjectValidationError.duplicatedTargets(["A"], project.path))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue