mirror of
https://github.com/GLEGram/GLEGram-iOS.git
synced 2026-04-23 19:36:26 +02:00
4647310322
Based on Swiftgram 12.5 (Telegram iOS 12.5). All GLEGram features ported and organized in GLEGram/ folder. Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass, Font Replacement, Fake Profile, Chat Export, Plugin System, and more. See CHANGELOG_12.5.md for full details.
908 lines
60 KiB
Swift
908 lines
60 KiB
Swift
import PathKit
|
|
import ProjectSpec
|
|
import Spectre
|
|
import XcodeProj
|
|
import XCTest
|
|
import TestSupport
|
|
import Version
|
|
|
|
class ProjectSpecTests: XCTestCase {
|
|
|
|
func testTargetType() {
|
|
describe {
|
|
|
|
let framework = Target(
|
|
name: "MyFramework",
|
|
type: .framework,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: ["SETTING_2": "VALUE"])
|
|
)
|
|
let staticLibrary = Target(
|
|
name: "MyStaticLibrary",
|
|
type: .staticLibrary,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: ["SETTING_2": "VALUE"])
|
|
)
|
|
let dynamicLibrary = Target(
|
|
name: "MyDynamicLibrary",
|
|
type: .dynamicLibrary,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: ["SETTING_2": "VALUE"])
|
|
)
|
|
$0.it("is a framework when it has the right extension") {
|
|
try expect(framework.type.isFramework).to.beTrue()
|
|
}
|
|
|
|
$0.it("is a library when it has the right type") {
|
|
try expect(staticLibrary.type.isLibrary).to.beTrue()
|
|
try expect(dynamicLibrary.type.isLibrary).to.beTrue()
|
|
}
|
|
}
|
|
}
|
|
|
|
func testTargetFilename() {
|
|
describe {
|
|
|
|
let framework = Target(
|
|
name: "MyFramework",
|
|
type: .framework,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: [:])
|
|
)
|
|
let staticLibrary = Target(
|
|
name: "MyStaticLibrary",
|
|
type: .staticLibrary,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: [:])
|
|
)
|
|
let dynamicLibrary = Target(
|
|
name: "MyDynamicLibrary",
|
|
type: .dynamicLibrary,
|
|
platform: .iOS,
|
|
settings: Settings(buildSettings: [:])
|
|
)
|
|
$0.it("has correct filename") {
|
|
try expect(framework.filename) == "MyFramework.framework"
|
|
try expect(staticLibrary.filename) == "libMyStaticLibrary.a"
|
|
try expect(dynamicLibrary.filename) == "MyDynamicLibrary.dylib"
|
|
}
|
|
}
|
|
}
|
|
|
|
func testDeploymentTarget() {
|
|
describe {
|
|
|
|
$0.it("has correct build setting") {
|
|
try expect(Platform.auto.deploymentTargetSetting) == ""
|
|
try expect(Platform.iOS.deploymentTargetSetting) == "IPHONEOS_DEPLOYMENT_TARGET"
|
|
try expect(Platform.tvOS.deploymentTargetSetting) == "TVOS_DEPLOYMENT_TARGET"
|
|
try expect(Platform.watchOS.deploymentTargetSetting) == "WATCHOS_DEPLOYMENT_TARGET"
|
|
try expect(Platform.macOS.deploymentTargetSetting) == "MACOSX_DEPLOYMENT_TARGET"
|
|
try expect(Platform.visionOS.deploymentTargetSetting) == "XROS_DEPLOYMENT_TARGET"
|
|
}
|
|
|
|
$0.it("has correct sdk root") {
|
|
try expect(Platform.auto.sdkRoot) == "auto"
|
|
try expect(Platform.iOS.sdkRoot) == "iphoneos"
|
|
try expect(Platform.tvOS.sdkRoot) == "appletvos"
|
|
try expect(Platform.watchOS.sdkRoot) == "watchos"
|
|
try expect(Platform.macOS.sdkRoot) == "macosx"
|
|
try expect(Platform.visionOS.sdkRoot) == "xros"
|
|
}
|
|
|
|
$0.it("parses version correctly") {
|
|
try expect(Version.parse("2").deploymentTarget) == "2.0"
|
|
try expect(Version.parse("2.0").deploymentTarget) == "2.0"
|
|
try expect(Version.parse("2.1").deploymentTarget) == "2.1"
|
|
try expect(Version.parse("2.10").deploymentTarget) == "2.10"
|
|
try expect(Version.parse("2.1.0").deploymentTarget) == "2.1"
|
|
try expect(Version.parse("2.12.0").deploymentTarget) == "2.12"
|
|
try expect(Version.parse("2.1.2").deploymentTarget) == "2.1.2"
|
|
try expect(Version.parse("2.10.2").deploymentTarget) == "2.10.2"
|
|
try expect(Version.parse("2.0.2").deploymentTarget) == "2.0.2"
|
|
try expect(Version.parse(2).deploymentTarget) == "2.0"
|
|
try expect(Version.parse(2.0).deploymentTarget) == "2.0"
|
|
try expect(Version.parse(2.1).deploymentTarget) == "2.1"
|
|
}
|
|
}
|
|
}
|
|
|
|
func testValidation() {
|
|
describe {
|
|
|
|
let baseProject = Project(name: "", configs: [Config(name: "invalid")])
|
|
let invalidSettings = Settings(
|
|
configSettings: ["invalidConfig": [:]],
|
|
groups: ["invalidSettingGroup"]
|
|
)
|
|
|
|
$0.it("fails with invalid XcodeGen version") {
|
|
let minimumVersion = try Version.parse("1.11.1")
|
|
var project = baseProject
|
|
project.options = SpecOptions(minimumXcodeGenVersion: minimumVersion)
|
|
|
|
func expectMinimumXcodeGenVersionError(_ project: Project, minimumVersion: Version, xcodeGenVersion: Version, file: String = #file, line: Int = #line) throws {
|
|
try expectError(SpecValidationError(errors: [SpecValidationError.ValidationError.invalidXcodeGenVersion(minimumVersion: minimumVersion, version: xcodeGenVersion)]), file: file, line: line) {
|
|
try project.validateMinimumXcodeGenVersion(xcodeGenVersion)
|
|
}
|
|
}
|
|
|
|
try expectMinimumXcodeGenVersionError(project, minimumVersion: minimumVersion, xcodeGenVersion: Version.parse("1.11.0"))
|
|
try expectMinimumXcodeGenVersionError(project, minimumVersion: minimumVersion, xcodeGenVersion: Version.parse("1.10.99"))
|
|
try expectMinimumXcodeGenVersionError(project, minimumVersion: minimumVersion, xcodeGenVersion: Version.parse("0.99"))
|
|
}
|
|
|
|
$0.it("fails with invalid project") {
|
|
var project = baseProject
|
|
project.settings = invalidSettings
|
|
project.configFiles = ["invalidConfig": "invalidConfigFile"]
|
|
project.fileGroups = ["invalidFileGroup"]
|
|
project.packages = ["invalidLocalPackage": .local(path: "invalidLocalPackage", group: nil, excludeFromProject: false)]
|
|
project.settingGroups = ["settingGroup1": Settings(
|
|
configSettings: ["invalidSettingGroupConfig": [:]],
|
|
groups: ["invalidSettingGroupSettingGroup"]
|
|
)]
|
|
|
|
try expectValidationError(project, .invalidConfigFileConfig("invalidConfig"))
|
|
try expectValidationError(project, .invalidBuildSettingConfig("invalidConfig"))
|
|
try expectValidationError(project, .invalidConfigFile(configFile: "invalidConfigFile", config: "invalidConfig"))
|
|
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
|
try expectValidationError(project, .invalidFileGroup("invalidFileGroup"))
|
|
try expectValidationError(project, .invalidLocalPackage("invalidLocalPackage"))
|
|
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroupSettingGroup"))
|
|
try expectValidationError(project, .invalidBuildSettingConfig("invalidSettingGroupConfig"))
|
|
}
|
|
|
|
$0.it("fails with duplicate dependencies") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
dependencies: [
|
|
Dependency(type: .target, reference: "dependency1"),
|
|
Dependency(type: .target, reference: "dependency1"),
|
|
Dependency(type: .framework, reference: "dependency2"),
|
|
Dependency(type: .framework, reference: "dependency2"),
|
|
|
|
// multiple package dependencies with different products should be allowed
|
|
Dependency(type: .package(products: ["one"]), reference: "package1"),
|
|
Dependency(type: .package(products: ["two"]), reference: "package1"),
|
|
]
|
|
),
|
|
Target(
|
|
name: "target2",
|
|
type: .framework,
|
|
platform: .iOS,
|
|
dependencies: [
|
|
Dependency(type: .framework, reference: "dependency3"),
|
|
Dependency(type: .target, reference: "dependency3"),
|
|
Dependency(type: .target, reference: "dependency4"),
|
|
Dependency(type: .target, reference: "dependency4"),
|
|
]
|
|
)
|
|
]
|
|
try expectValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "dependency1"))
|
|
try expectValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "dependency2"))
|
|
try expectValidationError(project, .duplicateDependencies(target: "target2", dependencyReference: "dependency4"))
|
|
|
|
try expectNoValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "package1"))
|
|
}
|
|
|
|
$0.it("unexpected supported destinations for watch app") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .watchOS,
|
|
supportedDestinations: [.macOS]
|
|
)
|
|
]
|
|
try expectValidationError(project, .unexpectedTargetPlatformForSupportedDestinations(target: "target1", platform: .watchOS))
|
|
}
|
|
|
|
$0.it("watchOS in multiplatform app's supported destinations") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .auto,
|
|
supportedDestinations: [.watchOS]
|
|
)
|
|
]
|
|
try expectValidationError(project, .containsWatchOSDestinationForMultiplatformApp(target: "target1"))
|
|
}
|
|
|
|
$0.it("watchOS in non-app's supported destinations") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .framework,
|
|
platform: .auto,
|
|
supportedDestinations: [.watchOS]
|
|
)
|
|
]
|
|
try expectNoValidationError(project, .containsWatchOSDestinationForMultiplatformApp(target: "target1"))
|
|
}
|
|
|
|
$0.it("multiple definitions of mac platform in supported destinations") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
supportedDestinations: [.macOS, .macCatalyst]
|
|
)
|
|
]
|
|
try expectValidationError(project, .multipleMacPlatformsInSupportedDestinations(target: "target1"))
|
|
}
|
|
|
|
$0.it("invalid target platform for macCatalyst supported destinations") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .tvOS,
|
|
supportedDestinations: [.tvOS, .macCatalyst]
|
|
)
|
|
]
|
|
try expectValidationError(project, .invalidTargetPlatformForSupportedDestinations(target: "target1"))
|
|
}
|
|
|
|
$0.it("missing target platform in supported destinations") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
supportedDestinations: [.tvOS]
|
|
)
|
|
]
|
|
try expectValidationError(project, .missingTargetPlatformInSupportedDestinations(target: "target1", platform: .iOS))
|
|
}
|
|
|
|
$0.it("allows non-existent configurations") {
|
|
var project = baseProject
|
|
project.options = SpecOptions(disabledValidations: [.missingConfigs])
|
|
let configPath = fixturePath + "test.xcconfig"
|
|
project.configFiles = ["missingConfiguration": configPath.string]
|
|
try project.validate()
|
|
}
|
|
|
|
$0.it("allows non-existent config files") {
|
|
var project = baseProject
|
|
project.options = SpecOptions(disabledValidations: [.missingConfigFiles])
|
|
project.configFiles = ["invalid": "doesntexist.xcconfig"]
|
|
try project.validate()
|
|
}
|
|
|
|
$0.it("fails with invalid target") {
|
|
var project = baseProject
|
|
project.targets = [Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
settings: invalidSettings,
|
|
configFiles: ["invalidConfig": "invalidConfigFile"],
|
|
sources: ["invalidSource"],
|
|
dependencies: [
|
|
Dependency(type: .target, reference: "invalidDependency"),
|
|
Dependency(type: .package(products: []), reference: "invalidPackage"),
|
|
],
|
|
preBuildScripts: [BuildScript(script: .path("invalidPreBuildScript"), name: "preBuildScript1")],
|
|
postCompileScripts: [BuildScript(script: .path("invalidPostCompileScript"))],
|
|
postBuildScripts: [BuildScript(script: .path("invalidPostBuildScript"))],
|
|
scheme: TargetScheme(testTargets: ["invalidTarget"])
|
|
)]
|
|
|
|
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
|
|
try expectValidationError(project, .invalidSwiftPackage(name: "invalidPackage", target: "target1"))
|
|
try expectValidationError(project, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
|
|
try expectValidationError(project, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
|
|
try expectValidationError(project, .invalidTargetSource(target: "target1", source: "invalidSource"))
|
|
try expectValidationError(project, .invalidBuildSettingConfig("invalidConfig"))
|
|
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
|
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: "preBuildScript1", path: "invalidPreBuildScript"))
|
|
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: nil, path: "invalidPostCompileScript"))
|
|
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: nil, path: "invalidPostBuildScript"))
|
|
|
|
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .debug))
|
|
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .release))
|
|
|
|
project.targets[0].scheme?.configVariants = ["invalidVariant"]
|
|
try expectValidationError(project, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
|
|
}
|
|
|
|
$0.it("fails with invalid aggregate target") {
|
|
var project = baseProject
|
|
project.aggregateTargets = [AggregateTarget(
|
|
name: "target1",
|
|
targets: ["invalidDependency"],
|
|
settings: invalidSettings,
|
|
configFiles: ["invalidConfig": "invalidConfigFile"],
|
|
buildScripts: [BuildScript(script: .path("invalidPrebuildScript"), name: "buildScript1")],
|
|
scheme: TargetScheme(testTargets: ["invalidTarget"])
|
|
)]
|
|
|
|
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
|
|
try expectValidationError(project, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
|
|
try expectValidationError(project, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
|
|
try expectValidationError(project, .invalidBuildSettingConfig("invalidConfig"))
|
|
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
|
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: "buildScript1", path: "invalidPrebuildScript"))
|
|
|
|
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .debug))
|
|
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .release))
|
|
|
|
project.aggregateTargets[0].scheme?.configVariants = ["invalidVariant"]
|
|
try expectValidationError(project, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
|
|
}
|
|
|
|
$0.it("fails with invalid sdk dependency") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
dependencies: [Dependency(type: .sdk(root: nil), reference: "invalidDependency")]
|
|
),
|
|
]
|
|
|
|
try expectValidationError(project, .invalidSDKDependency(target: "target1", dependency: "invalidDependency"))
|
|
}
|
|
|
|
$0.it("fails with invalid scheme") {
|
|
var project = baseProject
|
|
project.schemes = [Scheme(
|
|
name: "scheme1",
|
|
build: .init(targets: [.init(target: "invalidTarget")]),
|
|
run: .init(config: "debugInvalid"),
|
|
test: .init(config: "testInvalid", coverageTargets: ["SubProject/Yams"], targets: [.init(targetReference: "invalidTarget")]),
|
|
archive: .init(config: "releaseInvalid")
|
|
)]
|
|
|
|
try expectValidationError(project, .invalidSchemeTarget(scheme: "scheme1", target: "invalidTarget", action: "build"))
|
|
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "debugInvalid"))
|
|
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
|
|
try expectValidationError(project, .invalidSchemeTarget(scheme: "scheme1", target: "invalidTarget", action: "test"))
|
|
try expectValidationError(project, .invalidProjectReference(scheme: "scheme1", reference: "SubProject"))
|
|
}
|
|
|
|
$0.it("fails with invalid project reference in scheme") {
|
|
var project = baseProject
|
|
project.schemes = [Scheme(
|
|
name: "scheme1",
|
|
build: .init(targets: [.init(target: "invalidProjectRef/target1")])
|
|
)]
|
|
try expectValidationError(project, .invalidProjectReference(scheme: "scheme1", reference: "invalidProjectRef"))
|
|
}
|
|
|
|
$0.it("fails with invalid project reference path") {
|
|
var project = baseProject
|
|
let reference = ProjectReference(name: "InvalidProj", path: "invalid_path")
|
|
project.projectReferences = [reference]
|
|
try expectValidationError(project, .invalidProjectReferencePath(reference))
|
|
}
|
|
|
|
$0.it("fails with invalid project reference in dependency") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
dependencies: [Dependency(type: .target, reference: "invalidProjectRef/target2")]
|
|
),
|
|
]
|
|
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidProjectRef/target2"))
|
|
}
|
|
|
|
$0.it("allows project reference in target dependency") {
|
|
var project = baseProject
|
|
let externalProjectPath = fixturePath + "TestProject/AnotherProject/AnotherProject.xcodeproj"
|
|
project.projectReferences = [
|
|
ProjectReference(name: "validProjectRef", path: externalProjectPath.string),
|
|
]
|
|
project.targets = [
|
|
Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
dependencies: [Dependency(type: .target, reference: "validProjectRef/ExternalTarget")]
|
|
),
|
|
]
|
|
try project.validate()
|
|
}
|
|
|
|
$0.it("allows missing optional file") {
|
|
var project = baseProject
|
|
project.targets = [Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS,
|
|
sources: [.init(path: "generated.swift", optional: true)]
|
|
)]
|
|
try project.validate()
|
|
}
|
|
|
|
$0.it("validates missing default configurations") {
|
|
var project = baseProject
|
|
project.options = SpecOptions(defaultConfig: "foo")
|
|
try expectValidationError(project, .missingDefaultConfig(configName: "foo"))
|
|
}
|
|
|
|
$0.it("validates config settings format") {
|
|
var project = baseProject
|
|
project.configs = Config.defaultConfigs
|
|
project.settings.buildSettings = ["Debug": ["SETTING": "VALUE"], "Release": ["SETTING": "VALUE"]]
|
|
|
|
try expectValidationError(project, .invalidPerConfigSettings)
|
|
}
|
|
|
|
$0.it("allows custom scheme for aggregated target") {
|
|
var project = baseProject
|
|
let buildScript = BuildScript(script: .path(#file), name: "buildScript1")
|
|
let aggregatedTarget = AggregateTarget(
|
|
name: "target1",
|
|
targets: [],
|
|
settings: Settings(buildSettings: [:]),
|
|
configFiles: [:],
|
|
buildScripts: [buildScript],
|
|
scheme: nil,
|
|
attributes: [:]
|
|
)
|
|
project.aggregateTargets = [aggregatedTarget]
|
|
let buildTarget = Scheme.BuildTarget(target: "target1")
|
|
let scheme = Scheme(name: "target1-Scheme", build: Scheme.Build(targets: [buildTarget]))
|
|
project.schemes = [scheme]
|
|
try project.validate()
|
|
}
|
|
|
|
$0.it("validates scheme variants") {
|
|
|
|
func expectVariant(_ variant: String, type: ConfigType = .debug, for config: Config, matches: Bool, file: String = #file, line: Int = #line) throws {
|
|
let configs = [Config(name: "xxxxxxxxxxx", type: .debug), config]
|
|
let foundConfig = configs.first(including: variant, for: type)
|
|
let found = foundConfig != nil && foundConfig != configs[0]
|
|
try expect(found, file: file, line: line) == matches
|
|
}
|
|
|
|
try expectVariant("Dev", for: Config(name: "DevDebug", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "Dev debug", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "DEV DEBUG", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "Debug Dev", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "dev Debug", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "Dev debug", type: .release), matches: false)
|
|
try expectVariant("Dev", for: Config(name: "Dev-debug", type: .debug), matches: true)
|
|
try expectVariant("Dev", for: Config(name: "Dev_debug", type: .debug), matches: true)
|
|
try expectVariant("Prod", for: Config(name: "PreProd debug", type: .debug), matches: false)
|
|
try expectVariant("Develop", for: Config(name: "Dev debug", type: .debug), matches: false)
|
|
try expectVariant("Development", for: Config(name: "Debug (Development)", type: .debug), matches: true)
|
|
try expectVariant("Staging", for: Config(name: "Debug (Staging)", type: .debug), matches: true)
|
|
try expectVariant("Production", for: Config(name: "Debug (Production)", type: .debug), matches: true)
|
|
}
|
|
|
|
$0.it("fails on missing test plan file") {
|
|
var project = baseProject
|
|
|
|
project.configs = Config.defaultConfigs
|
|
|
|
project.targets = [Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS
|
|
)]
|
|
|
|
let testPlan = TestPlan(path: "does-not-exist.xctestplan")
|
|
|
|
let scheme = Scheme(
|
|
name: "xctestplan-scheme",
|
|
build: Scheme.Build(targets: [
|
|
Scheme.BuildTarget(target: "target1")
|
|
]),
|
|
test: Scheme.Test(config: "Debug",
|
|
testPlans: [testPlan]
|
|
)
|
|
)
|
|
|
|
project.schemes = [scheme]
|
|
|
|
try expectValidationError(project, .invalidTestPlan(testPlan))
|
|
}
|
|
|
|
$0.it("fails on multiple default test plans") {
|
|
var project = baseProject
|
|
|
|
project.configs = Config.defaultConfigs
|
|
|
|
project.targets = [Target(
|
|
name: "target1",
|
|
type: .application,
|
|
platform: .iOS
|
|
)]
|
|
|
|
let testPlan1 = TestPlan(path: "\(fixturePath.string)/TestProject/App_iOS/App_iOS.xctestplan", defaultPlan: true)
|
|
let testPlan2 = TestPlan(path: "\(fixturePath.string)/TestProject/App_iOS/App_iOS.xctestplan", defaultPlan: true)
|
|
|
|
let scheme = Scheme(
|
|
name: "xctestplan-scheme",
|
|
build: Scheme.Build(targets: [
|
|
Scheme.BuildTarget(target: "target1")
|
|
]),
|
|
test: Scheme.Test(config: "Debug",
|
|
testPlans: [testPlan1, testPlan2]
|
|
)
|
|
)
|
|
|
|
project.schemes = [scheme]
|
|
|
|
try expectValidationError(project, .multipleDefaultTestPlans)
|
|
}
|
|
|
|
$0.it("fails on packages has not plugin package reference") {
|
|
var project = baseProject
|
|
project.targets = [
|
|
Target(
|
|
name: "target",
|
|
type: .application,
|
|
platform: .iOS,
|
|
buildToolPlugins: [
|
|
BuildToolPlugin(plugin: "plugin", package: "package")
|
|
]
|
|
)
|
|
]
|
|
try expectValidationError(project, .invalidPluginPackageReference(plugin: "plugin", package: "package"))
|
|
}
|
|
|
|
$0.it("allow on packages has plugin package reference") {
|
|
var project = baseProject
|
|
project.packages["package"] = .remote(url: "url", versionRequirement: .branch("branch"))
|
|
project.targets = [
|
|
Target(
|
|
name: "target",
|
|
type: .application,
|
|
platform: .iOS,
|
|
buildToolPlugins: [
|
|
BuildToolPlugin(plugin: "plugin", package: "package")
|
|
]
|
|
)
|
|
]
|
|
try expectNoValidationError(project, .invalidPluginPackageReference(plugin: "plugin", package: "package"))
|
|
}
|
|
}
|
|
}
|
|
|
|
func testJSONEncodable() {
|
|
describe {
|
|
$0.it("encodes to json") {
|
|
let proj = Project(basePath: Path.current,
|
|
name: "ToJson",
|
|
configs: [Config(name: "DevelopmentConfig", type: .debug), Config(name: "ProductionConfig", type: .release)],
|
|
targets: [Target(name: "App",
|
|
type: .application,
|
|
platform: .iOS,
|
|
productName: "App",
|
|
deploymentTarget: Version(major: 0, minor: 1, patch: 2),
|
|
settings: Settings(buildSettings: ["foo": "bar"],
|
|
configSettings: ["foo": Settings(buildSettings: ["nested": "config"],
|
|
configSettings: [:],
|
|
groups: ["config-setting-group"])],
|
|
groups: ["setting-group"]),
|
|
configFiles: ["foo": "bar"],
|
|
sources: [TargetSource(path: "Source",
|
|
name: "Source",
|
|
compilerFlags: ["-Werror"],
|
|
excludes: ["foo", "bar"],
|
|
type: .folder,
|
|
optional: true,
|
|
buildPhase: .resources,
|
|
headerVisibility: .private,
|
|
createIntermediateGroups: true)],
|
|
dependencies: [Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic),
|
|
reference: "reference",
|
|
embed: true,
|
|
codeSign: true,
|
|
link: true,
|
|
implicit: true,
|
|
weakLink: true,
|
|
copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "example", phaseOrder: .postCompile))],
|
|
info: Plist(path: "info.plist", attributes: ["foo": "bar"]),
|
|
entitlements: Plist(path: "entitlements.plist", attributes: ["foo": "bar"]),
|
|
transitivelyLinkDependencies: true,
|
|
directlyEmbedCarthageDependencies: true,
|
|
requiresObjCLinking: true,
|
|
preBuildScripts: [BuildScript(script: .script("pwd"),
|
|
name: "Foo script",
|
|
inputFiles: ["foo"],
|
|
outputFiles: ["bar"],
|
|
inputFileLists: ["foo.xcfilelist"],
|
|
outputFileLists: ["bar.xcfilelist"],
|
|
shell: "/bin/bash",
|
|
runOnlyWhenInstalling: true,
|
|
showEnvVars: true,
|
|
basedOnDependencyAnalysis: false)],
|
|
buildToolPlugins: [BuildToolPlugin(plugin: "plugin", package: "Yams")],
|
|
postCompileScripts: [BuildScript(script: .path("cmd.sh"),
|
|
name: "Bar script",
|
|
inputFiles: ["foo"],
|
|
outputFiles: ["bar"],
|
|
inputFileLists: ["foo.xcfilelist"],
|
|
outputFileLists: ["bar.xcfilelist"],
|
|
shell: "/bin/bash",
|
|
runOnlyWhenInstalling: true,
|
|
showEnvVars: true,
|
|
basedOnDependencyAnalysis: false)],
|
|
postBuildScripts: [BuildScript(script: .path("cmd.sh"),
|
|
name: "an another script",
|
|
inputFiles: ["foo"],
|
|
outputFiles: ["bar"],
|
|
inputFileLists: ["foo.xcfilelist"],
|
|
outputFileLists: ["bar.xcfilelist"],
|
|
shell: "/bin/bash",
|
|
runOnlyWhenInstalling: true,
|
|
showEnvVars: true,
|
|
basedOnDependencyAnalysis: false),
|
|
BuildScript(script: .path("cmd.sh"),
|
|
name: "Dependency script",
|
|
inputFiles: ["foo"],
|
|
outputFiles: ["bar"],
|
|
inputFileLists: ["foo.xcfilelist"],
|
|
outputFileLists: ["bar.xcfilelist"],
|
|
shell: "/bin/bash",
|
|
runOnlyWhenInstalling: true,
|
|
showEnvVars: true,
|
|
basedOnDependencyAnalysis: true,
|
|
discoveredDependencyFile: "dep.d")],
|
|
buildRules: [BuildRule(fileType: .pattern("*.xcassets"),
|
|
action: .script("pre_process_swift.py"),
|
|
name: "My Build Rule",
|
|
outputFiles: ["$(SRCROOT)/Generated.swift"],
|
|
outputFilesCompilerFlags: ["foo"],
|
|
runOncePerArchitecture: false),
|
|
BuildRule(fileType: .type("sourcecode.swift"),
|
|
action: .compilerSpec("com.apple.xcode.tools.swift.compiler"),
|
|
name: nil,
|
|
outputFiles: ["bar"],
|
|
outputFilesCompilerFlags: ["foo"],
|
|
runOncePerArchitecture: true)],
|
|
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: "test target",
|
|
randomExecutionOrder: false,
|
|
parallelizable: false)],
|
|
configVariants: ["foo"],
|
|
gatherCoverageData: true,
|
|
coverageTargets: ["App"],
|
|
storeKitConfiguration: "Configuration.storekit",
|
|
disableMainThreadChecker: true,
|
|
stopOnEveryMainThreadCheckerIssue: false,
|
|
disableThreadPerformanceChecker: true,
|
|
commandLineArguments: ["foo": true],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "environmentVariable",
|
|
value: "bar",
|
|
enabled: true)],
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")]),
|
|
legacy: LegacyTarget(toolPath: "foo",
|
|
passSettings: true,
|
|
arguments: "bar",
|
|
workingDirectory: "foo"),
|
|
attributes: ["foo": "bar"],
|
|
putResourcesBeforeSourcesBuildPhase: true)],
|
|
aggregateTargets: [AggregateTarget(name: "aggregate target",
|
|
targets: ["App"],
|
|
settings: Settings(buildSettings: ["buildSettings": "bar"],
|
|
configSettings: ["configSettings": Settings(buildSettings: [:],
|
|
configSettings: [:],
|
|
groups: [])],
|
|
groups: ["foo"]),
|
|
configFiles: ["configFiles": "bar"],
|
|
buildScripts: [BuildScript(script: .path("script"),
|
|
name: "foo",
|
|
inputFiles: ["foo"],
|
|
outputFiles: ["bar"],
|
|
inputFileLists: ["foo.xcfilelist"],
|
|
outputFileLists: ["bar.xcfilelist"],
|
|
shell: "/bin/bash",
|
|
runOnlyWhenInstalling: true,
|
|
showEnvVars: false,
|
|
basedOnDependencyAnalysis: false)],
|
|
scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(targetReference: "test target",
|
|
randomExecutionOrder: false,
|
|
parallelizable: false)],
|
|
configVariants: ["foo"],
|
|
gatherCoverageData: true,
|
|
disableMainThreadChecker: true,
|
|
disableThreadPerformanceChecker: true,
|
|
commandLineArguments: ["foo": true],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "environmentVariable",
|
|
value: "bar",
|
|
enabled: true)],
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")]),
|
|
attributes: ["foo": "bar"])],
|
|
settings: Settings(buildSettings: ["foo": "bar"],
|
|
configSettings: ["foo": Settings(buildSettings: ["nested": "config"],
|
|
configSettings: [:],
|
|
groups: ["config-setting-group"])],
|
|
groups: ["setting-group"]),
|
|
settingGroups: ["foo": Settings(buildSettings: ["foo": "bar"],
|
|
configSettings: ["foo": Settings(buildSettings: ["nested": "config"],
|
|
configSettings: [:],
|
|
groups: ["config-setting-group"])],
|
|
groups: ["setting-group"])],
|
|
schemes: [Scheme(name: "scheme",
|
|
build: Scheme.Build(targets: [Scheme.BuildTarget(target: "foo",
|
|
buildTypes: [.archiving, .analyzing])],
|
|
parallelizeBuild: false,
|
|
buildImplicitDependencies: false,
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")]),
|
|
run: Scheme.Run(config: "run config",
|
|
commandLineArguments: ["foo": true],
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo",
|
|
value: "bar",
|
|
enabled: false)],
|
|
enableGPUFrameCaptureMode: .openGL,
|
|
launchAutomaticallySubstyle: "2",
|
|
storeKitConfiguration: "Configuration.storekit"),
|
|
test: Scheme.Test(config: "Config",
|
|
gatherCoverageData: true,
|
|
disableMainThreadChecker: true,
|
|
randomExecutionOrder: false,
|
|
parallelizable: false,
|
|
commandLineArguments: ["foo": true],
|
|
targets: [Scheme.Test.TestTarget(targetReference: "foo",
|
|
randomExecutionOrder: false,
|
|
parallelizable: false)],
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo",
|
|
value: "bar",
|
|
enabled: false)]),
|
|
profile: Scheme.Profile(config: "profile config",
|
|
commandLineArguments: ["foo": true],
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo",
|
|
value: "bar",
|
|
enabled: false)]),
|
|
analyze: Scheme.Analyze(config: "analyze config"),
|
|
archive: Scheme.Archive(config: "archive config",
|
|
customArchiveName: "customArchiveName",
|
|
revealArchiveInOrganizer: true,
|
|
preActions: [Scheme.ExecutionAction(name: "preAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")],
|
|
postActions: [Scheme.ExecutionAction(name: "postAction",
|
|
script: "bar",
|
|
settingsTarget: "foo")]))],
|
|
packages: [
|
|
"Yams": .remote(
|
|
url: "https://github.com/jpsim/Yams",
|
|
versionRequirement: .upToNextMajorVersion("2.0.0")
|
|
),
|
|
],
|
|
options: SpecOptions(minimumXcodeGenVersion: Version(major: 3, minor: 4, patch: 5),
|
|
carthageBuildPath: "carthageBuildPath",
|
|
carthageExecutablePath: "carthageExecutablePath",
|
|
createIntermediateGroups: true,
|
|
bundleIdPrefix: "bundleIdPrefix",
|
|
settingPresets: .project,
|
|
developmentLanguage: "developmentLanguage",
|
|
indentWidth: 123,
|
|
tabWidth: 456,
|
|
usesTabs: true,
|
|
xcodeVersion: "xcodeVersion",
|
|
deploymentTarget: DeploymentTarget(iOS: Version(major: 1, minor: 2, patch: 3),
|
|
tvOS: nil,
|
|
watchOS: Version(major: 4, minor: 5, patch: 6),
|
|
macOS: nil),
|
|
disabledValidations: [.missingConfigFiles],
|
|
defaultConfig: "defaultConfig",
|
|
transitivelyLinkDependencies: true,
|
|
groupSortPosition: .top,
|
|
generateEmptyDirectories: true,
|
|
findCarthageFrameworks: false),
|
|
fileGroups: ["foo", "bar"],
|
|
configFiles: ["configFiles": "bar"],
|
|
attributes: ["attributes": "bar"])
|
|
|
|
let json = proj.toJSONDictionary()
|
|
let restoredProj = try Project(basePath: Path.current, jsonDictionary: json)
|
|
|
|
// Examine some properties to make debugging easier
|
|
try expect(proj.aggregateTargets) == restoredProj.aggregateTargets
|
|
try expect(proj.configFiles) == restoredProj.configFiles
|
|
try expect(proj.settings) == restoredProj.settings
|
|
try expect(proj.basePath) == restoredProj.basePath
|
|
try expect(proj.fileGroups) == restoredProj.fileGroups
|
|
try expect(proj.schemes) == restoredProj.schemes
|
|
try expect(proj.options) == restoredProj.options
|
|
try expect(proj.settingGroups) == restoredProj.settingGroups
|
|
try expect(proj.targets) == restoredProj.targets
|
|
try expect(proj.packages) == restoredProj.packages
|
|
|
|
try expect(proj) == restoredProj
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func expectValidationErrors(_ project: Project, _ expectedErrors: Set<SpecValidationError.ValidationError>, file: String = #file, line: Int = #line) throws {
|
|
let expectedErrorString = expectedErrors
|
|
.map { $0.description }
|
|
.sorted()
|
|
.joined(separator: "\n")
|
|
do {
|
|
try project.validate()
|
|
if !expectedErrors.isEmpty {
|
|
throw failure("Supposed to fail with:\n\(expectedErrorString)", file: file, line: line)
|
|
}
|
|
} catch let error as SpecValidationError {
|
|
if Set(error.errors) != expectedErrors {
|
|
throw failure("Supposed to fail with:\n\(expectedErrorString)\nbut got:\n\(error.errors.map { $0.description }.sorted().joined(separator: "\n"))", file: file, line: line)
|
|
}
|
|
return
|
|
} catch {
|
|
throw failure("Supposed to fail with:\n\(expectedErrorString)", file: file, line: line)
|
|
}
|
|
}
|
|
|
|
private func expectValidationError(_ project: Project, _ expectedError: SpecValidationError.ValidationError, file: String = #file, line: Int = #line) throws {
|
|
do {
|
|
try project.validate()
|
|
throw failure("Supposed to fail with \"\(expectedError)\"", file: file, line: line)
|
|
} catch let error as SpecValidationError {
|
|
if !error.errors.contains(expectedError) {
|
|
throw failure("Supposed to fail with:\n\(expectedError)\nbut got:\n\(error.errors.map { $0.description }.joined(separator: "\n"))", file: file, line: line)
|
|
}
|
|
} catch {
|
|
throw failure("Supposed to fail with \"\(expectedError)\"", file: file, line: line)
|
|
}
|
|
}
|
|
|
|
private func expectNoValidationError(_ project: Project, _ error: SpecValidationError.ValidationError, file: String = #file, line: Int = #line) throws {
|
|
do {
|
|
try project.validate()
|
|
} catch let validationError as SpecValidationError {
|
|
if validationError.errors.contains(error) {
|
|
throw failure("Failed with:\n\(error.description)", file: file, line: line)
|
|
}
|
|
} catch {
|
|
throw failure("Failed with:\n\(error)", file: file, line: line)
|
|
}
|
|
}
|