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.
1677 lines
82 KiB
Swift
1677 lines
82 KiB
Swift
import Foundation
|
|
import PathKit
|
|
import ProjectSpec
|
|
import Spectre
|
|
import XcodeProj
|
|
import XCTest
|
|
import Yams
|
|
import TestSupport
|
|
import Version
|
|
|
|
class SpecLoadingTests: XCTestCase {
|
|
|
|
func testSpecLoaderDuplicateImports() {
|
|
describe {
|
|
$0.it("merges each file only once") {
|
|
let path = fixturePath + "duplicated_include/duplicated_import_sut.yml"
|
|
let project = try loadSpec(path: path)
|
|
|
|
try expect(project.fileGroups) == ["First", "Second", "Third"]
|
|
|
|
let sutTarget = project.targets.first
|
|
try expect(sutTarget?.sources) == [TargetSource(path: "template")]
|
|
try expect(sutTarget?.preBuildScripts) == [BuildScript(script: .script("swiftlint"), name: "Swiftlint")]
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSpecLoader() {
|
|
describe {
|
|
$0.it("merges includes") {
|
|
let path = fixturePath + "include_test.yml"
|
|
let project = try loadSpec(path: path, variables: [:])
|
|
|
|
try expect(project.name) == "NewName"
|
|
try expect(project.settingGroups) == [
|
|
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}"]),
|
|
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
|
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
|
]
|
|
try expect(project.targets) == [
|
|
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "Yams")]),
|
|
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
|
]
|
|
}
|
|
|
|
$0.it("merges includes with additional") {
|
|
let path = fixturePath + "include_test.yml"
|
|
let project = try loadSpec(path: path, variables: ["INCLUDE_ADDITIONAL_YAML": "YES"])
|
|
|
|
try expect(project.name) == "NewName"
|
|
try expect(project.settingGroups) == [
|
|
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}", "MY_SETTING5": "ADDITIONAL"]),
|
|
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
|
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
|
]
|
|
try expect(project.targets) == [
|
|
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "SwiftPM"), Dependency(type: .package(products: []), reference: "Yams")]),
|
|
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
|
]
|
|
}
|
|
|
|
$0.it("merges includes without additional by environment variable") {
|
|
let path = fixturePath + "include_test.yml"
|
|
let project = try loadSpec(path: path, variables: ["INCLUDE_ADDITIONAL_YAML": "NO"])
|
|
|
|
try expect(project.name) == "NewName"
|
|
try expect(project.settingGroups) == [
|
|
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}"]),
|
|
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
|
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
|
]
|
|
try expect(project.targets) == [
|
|
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "Yams")]),
|
|
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
|
]
|
|
}
|
|
|
|
$0.it("expands directories") {
|
|
let path = fixturePath + "paths_test.yml"
|
|
let project = try loadSpec(path: path)
|
|
|
|
try expect(project.configFiles) == [
|
|
"IncludedConfig": "paths_test/config",
|
|
"NewConfig": "config",
|
|
"RecursiveConfig": "paths_test/recursive_test/config",
|
|
]
|
|
|
|
try expect(project.options) == SpecOptions(
|
|
carthageBuildPath: "paths_test/recursive_test/carthage_build",
|
|
carthageExecutablePath: "carthage_executable"
|
|
)
|
|
|
|
try expect(project.projectReferences) == [
|
|
ProjectReference(name: "ProjX", path: "TestProject/Project.xcodeproj"),
|
|
]
|
|
|
|
try expect(project.aggregateTargets) == [
|
|
AggregateTarget(
|
|
name: "IncludedAggregateTarget",
|
|
targets: ["IncludedTarget"],
|
|
configFiles: ["Config": "paths_test/config"],
|
|
buildScripts: [BuildScript(script: .path("paths_test/buildScript"))]
|
|
),
|
|
AggregateTarget(
|
|
name: "NewAggregateTarget",
|
|
targets: ["NewTarget"],
|
|
configFiles: ["Config": "config"],
|
|
buildScripts: [BuildScript(script: .path("buildScript"))]
|
|
),
|
|
AggregateTarget(
|
|
name: "RecursiveAggregateTarget",
|
|
targets: ["RecursiveTarget"],
|
|
configFiles: ["Config": "paths_test/recursive_test/config"],
|
|
buildScripts: [BuildScript(script: .path("paths_test/recursive_test/buildScript"))]
|
|
),
|
|
]
|
|
|
|
try expect(project.targets) == [
|
|
Target(
|
|
name: "IncludedTarget",
|
|
type: .application,
|
|
platform: .tvOS,
|
|
configFiles: ["Config": "paths_test/config"],
|
|
sources: [
|
|
"paths_test/simplesource",
|
|
TargetSource(path: "paths_test/source", excludes: ["file"]),
|
|
],
|
|
dependencies: [Dependency(type: .framework, reference: "paths_test/Framework")],
|
|
info: Plist(path: "paths_test/info"),
|
|
entitlements: Plist(path: "paths_test/entitlements"),
|
|
preBuildScripts: [BuildScript(script: .path("paths_test/preBuildScript"))],
|
|
postCompileScripts: [BuildScript(script: .path("paths_test/postCompileScript"))],
|
|
postBuildScripts: [BuildScript(script: .path("paths_test/postBuildScript"))],
|
|
scheme: TargetScheme(testPlans: [.init(path: "paths_test/TestPlan.xctestplan")])
|
|
),
|
|
Target(
|
|
name: "NewTarget",
|
|
type: .application,
|
|
platform: .iOS,
|
|
configFiles: ["Config": "config"],
|
|
sources: [
|
|
"paths_test/template_source",
|
|
"source",
|
|
],
|
|
dependencies: [Dependency(type: .framework, reference: "Framework")],
|
|
info: Plist(path: "info"),
|
|
entitlements: Plist(path: "entitlements"),
|
|
preBuildScripts: [BuildScript(script: .path("preBuildScript"))],
|
|
postCompileScripts: [BuildScript(script: .path("postCompileScript"))],
|
|
postBuildScripts: [BuildScript(script: .path("postBuildScript"))]
|
|
),
|
|
Target(
|
|
name: "RecursiveTarget",
|
|
type: .application,
|
|
platform: .macOS,
|
|
configFiles: ["Config": "paths_test/recursive_test/config"],
|
|
sources: ["paths_test/recursive_test/source"],
|
|
dependencies: [Dependency(type: .framework, reference: "paths_test/recursive_test/Framework")],
|
|
info: Plist(path: "paths_test/recursive_test/info"),
|
|
entitlements: Plist(path: "paths_test/recursive_test/entitlements"),
|
|
preBuildScripts: [BuildScript(script: .path("paths_test/recursive_test/prebuildScript"))],
|
|
postCompileScripts: [BuildScript(script: .path("paths_test/recursive_test/postCompileScript"))],
|
|
postBuildScripts: [BuildScript(script: .path("paths_test/recursive_test/postBuildScript"))]
|
|
),
|
|
Target(
|
|
name: "app",
|
|
type: .application,
|
|
platform: .macOS,
|
|
sources: ["paths_test/same_relative_path_test/source"],
|
|
dependencies: [
|
|
Dependency(type: .target, reference: "target1"),
|
|
Dependency(type: .target, reference: "target2")
|
|
]
|
|
),
|
|
Target(
|
|
name: "target1",
|
|
type: .framework,
|
|
platform: .macOS,
|
|
sources: ["paths_test/same_relative_path_test/parent1/same/target1/source"]
|
|
),
|
|
Target(
|
|
name: "target2",
|
|
type: .framework,
|
|
platform: .macOS,
|
|
sources: ["paths_test/same_relative_path_test/parent2/same/target2/source"]
|
|
)
|
|
]
|
|
|
|
try expect(project.schemes) == [
|
|
Scheme(
|
|
name: "Scheme",
|
|
build: .init(targets: [.init(target: "NewTarget")]),
|
|
test: .init(testPlans: [.init(path: "paths_test/TestPlan.xctestplan")])
|
|
)
|
|
]
|
|
|
|
try expect(project.packages) == [
|
|
"LocalPackage": .local(path: "paths_test/relative_local_package/LocalPackage", group: nil, excludeFromProject: false),
|
|
]
|
|
|
|
try expect(project.fileGroups.contains("paths_test/relative_file_groups/TestFile.md")) == true
|
|
}
|
|
|
|
$0.it("respects directory expansion preference") {
|
|
let path = fixturePath + "legacy_paths_test.yml"
|
|
let project = try loadSpec(path: path)
|
|
|
|
try expect(project.configFiles) == [
|
|
"IncludedConfig": "config",
|
|
]
|
|
|
|
try expect(project.options) == SpecOptions(
|
|
carthageBuildPath: "carthage_build",
|
|
carthageExecutablePath: "carthage_executable"
|
|
)
|
|
|
|
try expect(project.aggregateTargets) == [
|
|
AggregateTarget(
|
|
name: "IncludedAggregateTarget",
|
|
targets: ["IncludedTarget"],
|
|
configFiles: ["Config": "config"],
|
|
buildScripts: [BuildScript(script: .path("buildScript"))]
|
|
),
|
|
]
|
|
|
|
try expect(project.targets) == [
|
|
Target(
|
|
name: "IncludedTarget",
|
|
type: .application,
|
|
platform: .tvOS,
|
|
configFiles: ["Config": "config"],
|
|
sources: ["source"],
|
|
dependencies: [Dependency(type: .framework, reference: "Framework")],
|
|
info: Plist(path: "info"),
|
|
entitlements: Plist(path: "entitlements"),
|
|
preBuildScripts: [BuildScript(script: .path("preBuildScript"))],
|
|
postCompileScripts: [BuildScript(script: .path("postCompileScript"))],
|
|
postBuildScripts: [BuildScript(script: .path("postBuildScript"))]
|
|
),
|
|
]
|
|
}
|
|
|
|
$0.it("parses yaml types") {
|
|
let path = fixturePath + "yaml.yml"
|
|
let dictionary = try loadYamlDictionary(path: path)
|
|
let expectedDictionary: [String: Any] = [
|
|
"true": true,
|
|
"false": false,
|
|
"yes": true,
|
|
"no": false,
|
|
"yesQuote": "YES",
|
|
"noQuote": "NO",
|
|
"int": 1,
|
|
"intQuote": "1",
|
|
"float": 3.2,
|
|
"floatQuote": "10.10",
|
|
"string": "hello",
|
|
"stringQuote": "hello",
|
|
"space": " ",
|
|
"empty": "",
|
|
"emptyQuote": "",
|
|
"emptyDictionary": [String: Any](),
|
|
"arrayLiteral": [1, 2],
|
|
"arrayList": [1, 2],
|
|
]
|
|
for (key, expectedValue) in expectedDictionary {
|
|
guard let parsedValue = dictionary[key] else {
|
|
throw failure("\(key) does not exist")
|
|
}
|
|
if String(describing: expectedValue) != String(describing: parsedValue) {
|
|
throw failure("\(key): \(parsedValue) does not equal \(expectedValue)")
|
|
}
|
|
}
|
|
if !(dictionary as NSDictionary).isEqual(expectedDictionary as NSDictionary) {
|
|
throw failure("parsed yaml types don't match:\n\nParsed:\n\t\(dictionary.map { "\($0.key): \($0.value)" }.joined(separator: "\n\t"))\nExpected:\n\t\(expectedDictionary.map { "\($0.key): \($0.value)" }.joined(separator: "\n\t"))")
|
|
}
|
|
}
|
|
|
|
$0.it("expands variables") {
|
|
let path = fixturePath + "variables_test.yml"
|
|
let project = try loadSpec(path: path, variables: [
|
|
"SETTING1": "ENV VALUE1",
|
|
"SETTING4": "ENV VALUE4",
|
|
"variable": "doesWin",
|
|
])
|
|
|
|
try expect(project.name) == "NewName"
|
|
try expect(project.settingGroups) == [
|
|
"test": Settings(dictionary: ["MY_SETTING1": "ENV VALUE1", "MY_SETTING2": "VALUE2", "MY_SETTING4": "ENV VALUE4"]),
|
|
"toReplace": Settings(dictionary: ["MY_SETTING1": "VALUE1"]),
|
|
]
|
|
try expect(project.targets.last?.sources) == ["SomeTarget", "doesWin", "templateVariable"]
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSpecLoaderLoadingJSON() {
|
|
describe {
|
|
$0.it("merges includes") {
|
|
let path = fixturePath + "include_test.json"
|
|
let project = try loadSpec(path: path)
|
|
|
|
try expect(project.name) == "NewName"
|
|
try expect(project.settingGroups) == [
|
|
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}"]),
|
|
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
|
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
|
]
|
|
try expect(project.targets) == [
|
|
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"]),
|
|
Target(name: "NewTarget", type: .application, platform: .iOS),
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSpecWarningValidation() {
|
|
describe {
|
|
var path: Path!
|
|
$0.before {
|
|
path = Path(components: [NSTemporaryDirectory(), "\(NSUUID().uuidString).yaml"])
|
|
|
|
}
|
|
$0.after {
|
|
try? FileManager.default.removeItem(atPath: path.string)
|
|
}
|
|
$0.it("fails validating warnings for deprecated placeholder usage") {
|
|
let dictionary: [String: Any] = [
|
|
"name": "TestSpecWarningValidation",
|
|
"templates": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"sources": ["${target_name}/${platform}/Sources"],
|
|
],
|
|
],
|
|
"targets": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"platform": "iOS",
|
|
"templates": ["Framework"],
|
|
],
|
|
],
|
|
]
|
|
try? Yams.dump(object: dictionary).write(toFile: path.string, atomically: true, encoding: .utf8)
|
|
let specLoader = SpecLoader(version: "1.1.0")
|
|
do {
|
|
_ = try specLoader.loadProject(path: path)
|
|
} catch {
|
|
throw failure("\(error)")
|
|
}
|
|
}
|
|
|
|
$0.it("successfully validates warnings for new placeholder usage") {
|
|
let dictionary: [String: Any] = [
|
|
"name": "TestSpecWarningValidation",
|
|
"templates": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"sources": ["${target_name}/${platform}/Sources"],
|
|
],
|
|
],
|
|
"targets": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"platform": "iOS",
|
|
"templates": ["Framework"],
|
|
],
|
|
],
|
|
]
|
|
try? Yams.dump(object: dictionary).write(toFile: path.string, atomically: true, encoding: .utf8)
|
|
let specLoader = SpecLoader(version: "1.1.0")
|
|
do {
|
|
_ = try specLoader.loadProject(path: path)
|
|
} catch {
|
|
throw failure("\(error)")
|
|
}
|
|
do {
|
|
try specLoader.validateProjectDictionaryWarnings()
|
|
} catch {
|
|
throw failure("Expected to not throw a validation error. Got: \(error)")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testProjectSpecParser() {
|
|
let validTarget: [String: Any] = ["type": "application", "platform": "iOS"]
|
|
let validBreakpoint: [String: Any] = ["type": "Exception", "scope": "All", "stopOnStyle": "Catch"]
|
|
let invalid = "invalid"
|
|
|
|
describe {
|
|
|
|
$0.it("fails with incorrect platform") {
|
|
var target = validTarget
|
|
target["platform"] = invalid
|
|
try expectTargetError(target, .unknownTargetPlatform(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect product type") {
|
|
var target = validTarget
|
|
target["type"] = invalid
|
|
try expectTargetError(target, .unknownTargetType(invalid))
|
|
}
|
|
|
|
$0.it("fails with invalid dependency") {
|
|
var target = validTarget
|
|
target["dependencies"] = [[invalid: "name"]]
|
|
try expectTargetError(target, .invalidDependency([invalid: "name"]))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint type") {
|
|
var breakpoint = validBreakpoint
|
|
breakpoint["type"] = invalid
|
|
try expectBreakpointError(breakpoint, .unknownBreakpointType(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint scope") {
|
|
var target = validBreakpoint
|
|
target["scope"] = invalid
|
|
try expectBreakpointError(target, .unknownBreakpointScope(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint stop on style") {
|
|
var target = validBreakpoint
|
|
target["stopOnStyle"] = invalid
|
|
try expectBreakpointError(target, .unknownBreakpointStopOnStyle(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint action type") {
|
|
var breakpoint = validBreakpoint
|
|
breakpoint["actions"] = [["type": invalid]]
|
|
try expectBreakpointError(breakpoint, .unknownBreakpointActionType(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint action conveyance type") {
|
|
var breakpoint = validBreakpoint
|
|
breakpoint["actions"] = [["type": "Log", "conveyanceType": invalid]]
|
|
try expectBreakpointError(breakpoint, .unknownBreakpointActionConveyanceType(invalid))
|
|
}
|
|
|
|
$0.it("fails with incorrect breakpoint action sound name") {
|
|
var breakpoint = validBreakpoint
|
|
breakpoint["actions"] = [["type": "Sound", "sound": invalid]]
|
|
try expectBreakpointError(breakpoint, .unknownBreakpointActionSoundName(invalid))
|
|
}
|
|
|
|
$0.it("parses breakpoints") {
|
|
let breakpointDictionaries = [
|
|
["type": "File", "path": "Foo.swift", "line": 7, "column": 14, "condition": "bar == nil"],
|
|
["type": "Exception", "scope": "All", "stopOnStyle": "Catch"],
|
|
["type": "SwiftError", "enabled": false],
|
|
["type": "OpenGLError", "ignoreCount": 2],
|
|
["type": "Symbolic", "symbol": "UIViewAlertForUnsatisfiableConstraints", "module": "UIKitCore"],
|
|
["type": "IDEConstraintError", "continueAfterRunningActions": true],
|
|
["type": "IDETestFailure"],
|
|
]
|
|
|
|
let project = try getProjectSpec(["breakpoints": breakpointDictionaries])
|
|
|
|
let expectedBreakpoints = [
|
|
Breakpoint(type: .file(path: "Foo.swift", line: 7, column: 14), condition: "bar == nil"),
|
|
Breakpoint(type: .exception(.init(scope: .all, stopOnStyle: .catch))),
|
|
Breakpoint(type: .swiftError, enabled: false),
|
|
Breakpoint(type: .openGLError, ignoreCount: 2),
|
|
Breakpoint(type: .symbolic(symbol: "UIViewAlertForUnsatisfiableConstraints", module: "UIKitCore")),
|
|
Breakpoint(type: .ideConstraintError, continueAfterRunningActions: true),
|
|
Breakpoint(type: .ideTestFailure),
|
|
]
|
|
|
|
try expect(project.breakpoints) == expectedBreakpoints
|
|
}
|
|
|
|
$0.it("parses breakpoint actions") {
|
|
var breakpointDicationary = validBreakpoint
|
|
breakpointDicationary["actions"] = [
|
|
["type": "DebuggerCommand", "command": "po $arg1"],
|
|
["type": "Log", "message": "message", "conveyanceType": "speak"],
|
|
["type": "ShellCommand", "path": "script.sh", "arguments": "argument1, argument2", "waitUntilDone": true],
|
|
["type": "GraphicsTrace"],
|
|
["type": "AppleScript", "script": #"display alert "Hello!""#],
|
|
["type": "Sound", "sound": "Hero"],
|
|
]
|
|
|
|
let breakpoint = try Breakpoint(jsonDictionary: breakpointDicationary)
|
|
|
|
let expectedActions: [Breakpoint.Action] = [
|
|
.debuggerCommand("po $arg1"),
|
|
.log(.init(message: "message", conveyanceType: .speak)),
|
|
.shellCommand(path: "script.sh", arguments: "argument1, argument2", waitUntilDone: true),
|
|
.graphicsTrace,
|
|
.appleScript(#"display alert "Hello!""#),
|
|
.sound(.hero),
|
|
]
|
|
|
|
try expect(breakpoint.actions) == expectedActions
|
|
}
|
|
|
|
$0.it("parses sources") {
|
|
var targetDictionary1 = validTarget
|
|
targetDictionary1["sources"] = [
|
|
"sourceString",
|
|
["path": "sourceObject"],
|
|
["path": "sourceWithFlagsArray", "compilerFlags": ["-Werror"]],
|
|
["path": "sourceWithFlagsString", "compilerFlags": "-Werror -Wextra"],
|
|
["path": "sourceWithExcludes", "excludes": ["Foo.swift"]],
|
|
["path": "sourceWithFileType", "type": "file"],
|
|
["path": "sourceWithGroupType", "type": "group"],
|
|
["path": "sourceWithFolderType", "type": "folder"],
|
|
["path": "sourceWithResourceTags", "resourceTags": ["tag1", "tag2"]],
|
|
]
|
|
var targetDictionary2 = validTarget
|
|
targetDictionary2["sources"] = "source3"
|
|
|
|
let target1 = try Target(name: "test", jsonDictionary: targetDictionary1)
|
|
let target2 = try Target(name: "test", jsonDictionary: targetDictionary2)
|
|
|
|
let target1SourcesExpect = [
|
|
TargetSource(path: "sourceString"),
|
|
TargetSource(path: "sourceObject"),
|
|
TargetSource(path: "sourceWithFlagsArray", compilerFlags: ["-Werror"]),
|
|
TargetSource(path: "sourceWithFlagsString", compilerFlags: ["-Werror", "-Wextra"]),
|
|
TargetSource(path: "sourceWithExcludes", excludes: ["Foo.swift"]),
|
|
TargetSource(path: "sourceWithFileType", type: .file),
|
|
TargetSource(path: "sourceWithGroupType", type: .group),
|
|
TargetSource(path: "sourceWithFolderType", type: .folder),
|
|
TargetSource(path: "sourceWithResourceTags", resourceTags: ["tag1", "tag2"]),
|
|
]
|
|
|
|
try expect(target1.sources) == target1SourcesExpect
|
|
try expect(target2.sources) == ["source3"]
|
|
}
|
|
|
|
$0.it("parses target dependencies") {
|
|
var targetDictionary = validTarget
|
|
targetDictionary["dependencies"] = [
|
|
["target": "name", "embed": false, "platformFilter": "all"],
|
|
["target": "project/name", "embed": false, "platformFilter": "macOS"],
|
|
["carthage": "name", "findFrameworks": true, "platformFilter": "iOS"],
|
|
["carthage": "name", "findFrameworks": true, "linkType": "static"],
|
|
["framework": "path", "weak": true],
|
|
["sdk": "Contacts.framework"],
|
|
[
|
|
"sdk": "Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework",
|
|
"root": "DEVELOPER_DIR",
|
|
],
|
|
["target": "conditionalMatch", "platforms": ["iOS"]],
|
|
["target": "conditionalMiss", "platforms": ["watchOS"]],
|
|
]
|
|
let target = try Target(name: "test", jsonDictionary: targetDictionary)
|
|
try expect(target.dependencies.count) == 8
|
|
try expect(target.dependencies[0]) == Dependency(type: .target, reference: "name", embed: false, platformFilter: .all)
|
|
try expect(target.dependencies[1]) == Dependency(type: .target, reference: "project/name", embed: false, platformFilter: .macOS)
|
|
try expect(target.dependencies[2]) == Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "name", platformFilter: .iOS)
|
|
try expect(target.dependencies[3]) == Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "name")
|
|
try expect(target.dependencies[4]) == Dependency(type: .framework, reference: "path", weakLink: true)
|
|
try expect(target.dependencies[5]) == Dependency(type: .sdk(root: nil), reference: "Contacts.framework")
|
|
try expect(target.dependencies[6]) == Dependency(type: .sdk(root: "DEVELOPER_DIR"), reference: "Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework")
|
|
try expect(target.dependencies[7]) == Dependency(type: .target, reference: "conditionalMatch", platforms: [.iOS])
|
|
}
|
|
|
|
$0.it("parses info plist") {
|
|
var targetDictionary = validTarget
|
|
targetDictionary["info"] = [
|
|
"path": "Info.plist",
|
|
"properties": [
|
|
"CFBundleName": "MyAppName",
|
|
"UIBackgroundModes": ["fetch"],
|
|
],
|
|
]
|
|
|
|
let target = try Target(name: "", jsonDictionary: targetDictionary)
|
|
try expect(target.info) == Plist(path: "Info.plist", attributes: [
|
|
"CFBundleName": "MyAppName",
|
|
"UIBackgroundModes": ["fetch"],
|
|
])
|
|
}
|
|
|
|
$0.it("parses entitlement plist") {
|
|
var targetDictionary = validTarget
|
|
targetDictionary["entitlements"] = [
|
|
"path": "app.entitlements",
|
|
"properties": [
|
|
"com.apple.security.application-groups": "com.group",
|
|
],
|
|
]
|
|
|
|
let target = try Target(name: "", jsonDictionary: targetDictionary)
|
|
try expect(target.entitlements) == Plist(path: "app.entitlements", attributes: [
|
|
"com.apple.security.application-groups": "com.group",
|
|
])
|
|
}
|
|
|
|
$0.it("parses cross platform targets") {
|
|
let targetDictionary: [String: Any] = [
|
|
"platform": ["iOS", "tvOS"],
|
|
"deploymentTarget": ["iOS": 9.0, "tvOS": "10.0"],
|
|
"type": "framework",
|
|
"sources": ["Framework", "Framework ${platform}"],
|
|
"settings": ["SETTING": "value_${platform}"],
|
|
]
|
|
|
|
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
|
var target_iOS = Target(name: "Framework_iOS", type: .framework, platform: .iOS)
|
|
var target_tvOS = Target(name: "Framework_tvOS", type: .framework, platform: .tvOS)
|
|
|
|
target_iOS.sources = ["Framework", "Framework iOS"]
|
|
target_tvOS.sources = ["Framework", "Framework tvOS"]
|
|
target_iOS.settings = ["PRODUCT_NAME": "Framework", "SETTING": "value_iOS"]
|
|
target_tvOS.settings = ["PRODUCT_NAME": "Framework", "SETTING": "value_tvOS"]
|
|
target_iOS.deploymentTarget = Version(major: 9, minor: 0, patch: 0)
|
|
target_tvOS.deploymentTarget = Version(major: 10, minor: 0, patch: 0)
|
|
|
|
try expect(project.targets) == [target_iOS, target_tvOS]
|
|
}
|
|
|
|
$0.it("parses no platform fallbacks to auto if we are using supported destinations") {
|
|
let targetDictionary: [String: Any] = [
|
|
"type": "framework",
|
|
"supportedDestinations": ["iOS", "tvOS"]
|
|
]
|
|
|
|
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
|
let target = Target(name: "Framework", type: .framework, platform: .auto)
|
|
|
|
try expect(project.targets) == [target]
|
|
}
|
|
|
|
$0.it("parses no platform fails if we are not using supported destinations") {
|
|
let expectedError = SpecParsingError.unknownTargetPlatform("")
|
|
|
|
let projectDictionary: [String: Any] = [
|
|
"name": "test",
|
|
"targets": ["target1": [
|
|
"type": "application"
|
|
] as [String : Any]]
|
|
]
|
|
|
|
try expectError(expectedError) {
|
|
_ = try Project(jsonDictionary: projectDictionary)
|
|
}
|
|
}
|
|
|
|
$0.it("parses supported destinations with macCatalyst but not iOS, we add iOS") {
|
|
let targetDictionary: [String: Any] = [
|
|
"type": "framework",
|
|
"supportedDestinations": ["macCatalyst"]
|
|
]
|
|
|
|
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
|
let target = Target(name: "Framework", type: .framework, platform: .auto)
|
|
|
|
try expect(project.targets) == [target]
|
|
try expect(project.targets.first?.supportedDestinations) == [.macCatalyst, .iOS]
|
|
}
|
|
|
|
$0.it("invalid target platform because platform is an array and supported destinations is in use") {
|
|
let expectedError = SpecParsingError.invalidTargetPlatformAsArray
|
|
|
|
let projectDictionary: [String: Any] = [
|
|
"name": "test",
|
|
"targets": ["target1": [
|
|
"type": "application",
|
|
"platform": ["iOS", "tvOS"],
|
|
"supportedDestinations": ["iOS", "tvOS"]
|
|
] as [String : Any]]
|
|
]
|
|
|
|
try expectError(expectedError) {
|
|
_ = try Project(jsonDictionary: projectDictionary)
|
|
}
|
|
}
|
|
|
|
$0.it("parses target templates") {
|
|
|
|
let targetDictionary: [String: Any] = [
|
|
"deploymentTarget": "1.2.0",
|
|
"sources": ["targetSource"],
|
|
"templates": ["temp2", "temp"],
|
|
"templateAttributes": [
|
|
"source": "replacedSource",
|
|
],
|
|
]
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": ["Framework": targetDictionary],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"platform": "iOS",
|
|
"sources": [
|
|
"templateSource",
|
|
["path": "Sources/${target_name}"],
|
|
],
|
|
],
|
|
"temp2": [
|
|
"type": "framework",
|
|
"platform": "tvOS",
|
|
"deploymentTarget": "1.1.0",
|
|
"configFiles": [
|
|
"debug": "Configs/${target_name}/debug.xcconfig",
|
|
"release": "Configs/${target_name}/release.xcconfig",
|
|
],
|
|
"sources": ["${source}"],
|
|
],
|
|
],
|
|
])
|
|
|
|
let target = project.targets.first!
|
|
try expect(target.type) == .framework // uses value
|
|
try expect(target.platform) == .iOS // uses latest value
|
|
try expect(target.deploymentTarget) == Version("1.2.0") // keeps value
|
|
try expect(target.sources) == ["replacedSource", "templateSource", "Sources/Framework", "targetSource"] // merges array in order and replace ${target_name}
|
|
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
|
|
try expect(target.configFiles["release"]) == "Configs/Framework/release.xcconfig" // replaces ${target_name}
|
|
}
|
|
|
|
$0.it("parses nested target templates") {
|
|
|
|
let targetDictionary: [String: Any] = [
|
|
"deploymentTarget": "1.2.0",
|
|
"sources": ["targetSource"],
|
|
"templates": ["temp2"],
|
|
]
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": ["Framework": targetDictionary],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"type": "framework",
|
|
"platform": "iOS",
|
|
"sources": ["nestedTemplateSource1"],
|
|
],
|
|
"temp1": [
|
|
"type": "application",
|
|
"sources": ["nestedTemplateSource2"],
|
|
],
|
|
"temp2": [
|
|
"platform": "tvOS",
|
|
"deploymentTarget": "1.1.0",
|
|
"configFiles": ["debug": "Configs/${target_name}/debug.xcconfig"],
|
|
"templates": ["temp", "temp1"],
|
|
"sources": ["templateSource"],
|
|
],
|
|
],
|
|
])
|
|
|
|
let target = project.targets.first!
|
|
try expect(target.type) == .application // uses value of last nested template
|
|
try expect(target.platform) == .tvOS // uses latest value
|
|
try expect(target.deploymentTarget) == Version("1.2.0") // keeps value
|
|
try expect(target.sources) == ["nestedTemplateSource1", "nestedTemplateSource2", "templateSource", "targetSource"] // merges array in order
|
|
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
|
|
}
|
|
|
|
$0.it("parses complex nested target templates") {
|
|
|
|
let targetDictionary: [String: Any] = [
|
|
"type": "framework",
|
|
"platform": "iOS",
|
|
"templates": ["temp"],
|
|
"sources": ["target"],
|
|
"templateAttributes": [
|
|
"temp": "temp-by-target",
|
|
"a": "a-by-target",
|
|
"b": "b-by-target", // This should win over attributes defined in template "temp"
|
|
],
|
|
]
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": ["Framework": targetDictionary],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"templates": ["a", "d"],
|
|
"sources": ["temp", "${temp}"],
|
|
"templateAttributes": [
|
|
"b": "b-by-temp",
|
|
"c": "c-by-temp",
|
|
"d": "d-by-temp",
|
|
],
|
|
],
|
|
"a": [
|
|
"templates": ["b", "c"],
|
|
"sources": ["a", "${a}"],
|
|
"templateAttributes": [
|
|
"c": "c-by-a",
|
|
],
|
|
],
|
|
"b": [
|
|
"sources": ["b", "${b}"],
|
|
],
|
|
"c": [
|
|
"sources": ["c", "${c}"],
|
|
],
|
|
"d": [
|
|
"sources": ["d", "${d}"],
|
|
"templates": ["e"],
|
|
"templateAttributes": [
|
|
"e": "e-by-d",
|
|
],
|
|
],
|
|
"e": [
|
|
"sources": ["e", "${e}"],
|
|
],
|
|
|
|
],
|
|
])
|
|
|
|
let target = project.targets.first!
|
|
try expect(target.type) == .framework // uses value of last nested template
|
|
try expect(target.platform) == .iOS // uses latest value
|
|
try expect(target.sources) == ["b", "b-by-target",
|
|
"c", "c-by-temp",
|
|
"a", "a-by-target",
|
|
"e", "e-by-d",
|
|
"d", "d-by-temp",
|
|
"temp", "temp-by-target",
|
|
"target"] // merges array in order
|
|
}
|
|
|
|
$0.it("parses nested target templates with cycle") {
|
|
|
|
let targetDictionary: [String: Any] = [
|
|
"deploymentTarget": "1.2.0",
|
|
"sources": ["targetSource"],
|
|
"templates": ["temp2"],
|
|
]
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": ["Framework": targetDictionary],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"type": "framework",
|
|
"platform": "iOS",
|
|
"templates": ["temp1"],
|
|
"sources": ["nestedTemplateSource1"],
|
|
],
|
|
"temp1": [
|
|
"platform": "macOS",
|
|
"templates": ["temp2"],
|
|
"sources": ["nestedTemplateSource2"],
|
|
],
|
|
"temp2": [
|
|
"platform": "tvOS",
|
|
"deploymentTarget": "1.1.0",
|
|
"configFiles": ["debug": "Configs/${target_name}/debug.xcconfig"],
|
|
"templates": ["temp", "temp1"],
|
|
"sources": ["templateSource"],
|
|
],
|
|
],
|
|
])
|
|
|
|
let target = project.targets.first!
|
|
try expect(target.type) == .framework // uses value
|
|
try expect(target.platform) == .tvOS // uses latest value
|
|
try expect(target.deploymentTarget) == Version("1.2.0") // keeps value
|
|
try expect(target.sources) == ["nestedTemplateSource2", "nestedTemplateSource1", "templateSource", "targetSource"] // merges array in order
|
|
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
|
|
}
|
|
|
|
$0.it("parses cross platform target templates") {
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"templates": ["temp"],
|
|
],
|
|
],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"platform": ["iOS", "tvOS"],
|
|
],
|
|
],
|
|
])
|
|
|
|
let iOSTarget = project.targets.first { $0.platform == .iOS }
|
|
let tvOSTarget = project.targets.first { $0.platform == .tvOS }
|
|
try expect(iOSTarget?.type) == .framework
|
|
try expect(tvOSTarget?.type) == .framework
|
|
}
|
|
|
|
$0.it("parses platform specific templates") {
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": [
|
|
"Framework": [
|
|
"type": "framework",
|
|
"platform": ["iOS", "tvOS"],
|
|
"templates": ["${platform}"],
|
|
],
|
|
],
|
|
"targetTemplates": [
|
|
"iOS": [
|
|
"sources": "A",
|
|
],
|
|
"tvOS": [
|
|
"sources": "B",
|
|
],
|
|
],
|
|
])
|
|
|
|
let iOSTarget = project.targets.first { $0.platform == .iOS }
|
|
let tvOSTarget = project.targets.first { $0.platform == .tvOS }
|
|
try expect(iOSTarget?.sources) == ["A"]
|
|
try expect(tvOSTarget?.sources) == ["B"]
|
|
}
|
|
|
|
$0.it("parses aggregate targets") {
|
|
let dictionary: [String: Any] = [
|
|
"targets": ["target_1", "target_2"],
|
|
"settings": ["SETTING": "VALUE"],
|
|
"configFiles": ["debug": "file.xcconfig"],
|
|
]
|
|
|
|
let project = try getProjectSpec(["aggregateTargets": ["AggregateTarget": dictionary]])
|
|
let expectedTarget = AggregateTarget(name: "AggregateTarget", targets: ["target_1", "target_2"], settings: ["SETTING": "VALUE"], configFiles: ["debug": "file.xcconfig"])
|
|
try expect(project.aggregateTargets) == [expectedTarget]
|
|
}
|
|
|
|
$0.it("parses target schemes") {
|
|
var targetDictionary = validTarget
|
|
targetDictionary["scheme"] = [
|
|
"testTargets": ["t1", ["name": "t2"]],
|
|
"configVariants": ["dev", "app-store"],
|
|
"commandLineArguments": [
|
|
"ENV1": true,
|
|
],
|
|
"gatherCoverageData": true,
|
|
"coverageTargets": ["t1"],
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
"language": "en",
|
|
"region": "US",
|
|
"disableMainThreadChecker": true,
|
|
"stopOnEveryMainThreadCheckerIssue": true,
|
|
"disableThreadPerformanceChecker": true,
|
|
"environmentVariables": [
|
|
"TEST_VAR": "TEST_VAL",
|
|
],
|
|
"preActions": [
|
|
[
|
|
"script": "dothing",
|
|
"name": "Do Thing",
|
|
"settingsTarget": "test",
|
|
],
|
|
],
|
|
"postActions": [
|
|
[
|
|
"script": "hello",
|
|
],
|
|
],
|
|
"management": [
|
|
"shared": false,
|
|
"isShown": true,
|
|
"orderHint": 10
|
|
],
|
|
]
|
|
|
|
let target = try Target(name: "test", jsonDictionary: targetDictionary)
|
|
|
|
let scheme = TargetScheme(
|
|
testTargets: ["t1", "t2"],
|
|
configVariants: ["dev", "app-store"],
|
|
gatherCoverageData: true,
|
|
coverageTargets: ["t1"],
|
|
storeKitConfiguration: "Configuration.storekit",
|
|
language: "en",
|
|
region: "US",
|
|
disableMainThreadChecker: true,
|
|
stopOnEveryMainThreadCheckerIssue: true,
|
|
disableThreadPerformanceChecker: true,
|
|
commandLineArguments: ["ENV1": true],
|
|
environmentVariables: [XCScheme.EnvironmentVariable(variable: "TEST_VAR", value: "TEST_VAL", enabled: true)],
|
|
preActions: [.init(name: "Do Thing", script: "dothing", settingsTarget: "test")],
|
|
postActions: [.init(name: "Run Script", script: "hello")],
|
|
management: Scheme.Management(shared: false, orderHint: 10, isShown: true)
|
|
)
|
|
|
|
try expect(target.scheme) == scheme
|
|
}
|
|
|
|
$0.it("parses schemes") {
|
|
let schemeDictionary: [String: Any] = [
|
|
"build": [
|
|
"parallelizeBuild": false,
|
|
"buildImplicitDependencies": false,
|
|
"runPostActionsOnFailure": true,
|
|
"targets": [
|
|
"Target1": "all",
|
|
"Target2": "testing",
|
|
"Target3": "none",
|
|
"Target4": ["testing": true],
|
|
"Target5": ["testing": false],
|
|
"Target6": ["test", "analyze"],
|
|
"ExternalProject/Target7": ["run"],
|
|
],
|
|
"preActions": [
|
|
[
|
|
"script": "echo Before Build",
|
|
"name": "Before Build",
|
|
"settingsTarget": "Target1",
|
|
],
|
|
],
|
|
],
|
|
"run": [
|
|
"config": "debug",
|
|
"launchAutomaticallySubstyle": 2,
|
|
"enableGPUFrameCaptureMode": "disabled",
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
"disableThreadPerformanceChecker": true,
|
|
],
|
|
"test": [
|
|
"config": "debug",
|
|
"targets": [
|
|
"Target1",
|
|
[
|
|
"name": "ExternalProject/Target2",
|
|
"parallelizable": true,
|
|
"skipped": true,
|
|
"location": "test.gpx",
|
|
"randomExecutionOrder": true,
|
|
"skippedTests": ["Test/testExample()"],
|
|
],
|
|
],
|
|
"gatherCoverageData": true,
|
|
"disableMainThreadChecker": true,
|
|
"stopOnEveryMainThreadCheckerIssue": true,
|
|
"testPlans": [
|
|
[
|
|
"path": "Path/Plan.xctestplan"
|
|
],
|
|
[
|
|
"path": "Path/Plan2.xctestplan"
|
|
]
|
|
],
|
|
"preferredScreenCaptureFormat": "screenshots",
|
|
],
|
|
"management": [
|
|
"isShown": false,
|
|
"orderHint": 4
|
|
],
|
|
]
|
|
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
|
let expectedTargets: [Scheme.BuildTarget] = [
|
|
Scheme.BuildTarget(target: "Target1", buildTypes: BuildType.all),
|
|
Scheme.BuildTarget(target: "Target2", buildTypes: [.testing, .analyzing]),
|
|
Scheme.BuildTarget(target: "Target3", buildTypes: []),
|
|
Scheme.BuildTarget(target: "Target4", buildTypes: [.testing]),
|
|
Scheme.BuildTarget(target: "Target5", buildTypes: []),
|
|
Scheme.BuildTarget(target: "Target6", buildTypes: [.testing, .analyzing]),
|
|
Scheme.BuildTarget(target: "ExternalProject/Target7", buildTypes: [.running]),
|
|
]
|
|
try expect(scheme.name) == "Scheme"
|
|
try expect(scheme.build.targets) == expectedTargets
|
|
try expect(scheme.build.preActions.first?.script) == "echo Before Build"
|
|
try expect(scheme.build.preActions.first?.name) == "Before Build"
|
|
try expect(scheme.build.preActions.first?.settingsTarget) == "Target1"
|
|
|
|
try expect(scheme.build.parallelizeBuild) == false
|
|
try expect(scheme.build.buildImplicitDependencies) == false
|
|
try expect(scheme.build.runPostActionsOnFailure) == true
|
|
|
|
let expectedRun = Scheme.Run(
|
|
config: "debug",
|
|
enableGPUFrameCaptureMode: .disabled,
|
|
disableThreadPerformanceChecker: true,
|
|
launchAutomaticallySubstyle: "2",
|
|
storeKitConfiguration: "Configuration.storekit"
|
|
)
|
|
try expect(scheme.run) == expectedRun
|
|
|
|
let expectedTest = Scheme.Test(
|
|
config: "debug",
|
|
gatherCoverageData: true,
|
|
disableMainThreadChecker: true,
|
|
targets: [
|
|
"Target1",
|
|
Scheme.Test.TestTarget(
|
|
targetReference: "ExternalProject/Target2",
|
|
randomExecutionOrder: true,
|
|
parallelizable: true,
|
|
location: "test.gpx",
|
|
skipped: true,
|
|
skippedTests: ["Test/testExample()"]
|
|
),
|
|
],
|
|
testPlans: [
|
|
.init(path: "Path/Plan.xctestplan"),
|
|
.init(path: "Path/Plan2.xctestplan")
|
|
],
|
|
preferredScreenCaptureFormat: .screenshots
|
|
)
|
|
try expect(scheme.test) == expectedTest
|
|
|
|
let expectedManagement = Scheme.Management(shared: true, orderHint: 4, isShown: false)
|
|
try expect(scheme.management) == expectedManagement
|
|
}
|
|
|
|
$0.it("parses alternate test schemes") {
|
|
let schemeDictionary: [String: Any] = [
|
|
"build": [
|
|
"targets": ["Target1": "all"],
|
|
],
|
|
"test": [
|
|
"config": "debug",
|
|
"targets": [
|
|
"Target1",
|
|
[
|
|
"name": "ExternalProject/Target2",
|
|
"parallelizable": true,
|
|
"location": "New York, NY, USA",
|
|
"randomExecutionOrder": true,
|
|
"selectedTests": ["Test/testExample()"],
|
|
],
|
|
],
|
|
"gatherCoverageData": true,
|
|
"disableMainThreadChecker": true,
|
|
"stopOnEveryMainThreadCheckerIssue": true,
|
|
],
|
|
"management": [
|
|
"isShown": false
|
|
],
|
|
]
|
|
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
|
|
|
let expectedTest = Scheme.Test(
|
|
config: "debug",
|
|
gatherCoverageData: true,
|
|
disableMainThreadChecker: true,
|
|
targets: [
|
|
"Target1",
|
|
Scheme.Test.TestTarget(
|
|
targetReference: "ExternalProject/Target2",
|
|
randomExecutionOrder: true,
|
|
parallelizable: true,
|
|
location: "New York, NY, USA",
|
|
selectedTests: ["Test/testExample()"]
|
|
),
|
|
]
|
|
)
|
|
try expect(scheme.test) == expectedTest
|
|
|
|
let expectedManagement = Scheme.Management(shared: true, orderHint: nil, isShown: false)
|
|
try expect(scheme.management) == expectedManagement
|
|
}
|
|
|
|
$0.it("parses schemes variables") {
|
|
let schemeDictionary: [String: Any] = [
|
|
"build": [
|
|
"targets": ["Target1": "all"],
|
|
],
|
|
"run": [
|
|
"environmentVariables": [
|
|
["variable": "BOOL_TRUE", "value": true],
|
|
["variable": "BOOL_YES", "value": "YES"],
|
|
["variable": "ENVIRONMENT", "value": "VARIABLE"],
|
|
["variable": "OTHER_ENV_VAR", "value": "VAL", "isEnabled": false],
|
|
],
|
|
"launchAutomaticallySubstyle": "2",
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
],
|
|
"test": [
|
|
"environmentVariables": [
|
|
"BOOL_TRUE": true,
|
|
"BOOL_YES": "YES",
|
|
"TEST": "VARIABLE",
|
|
],
|
|
],
|
|
"profile": [
|
|
"config": "Release",
|
|
],
|
|
]
|
|
|
|
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
|
|
|
let expectedRunVariables = [
|
|
XCScheme.EnvironmentVariable(variable: "BOOL_TRUE", value: "YES", enabled: true),
|
|
XCScheme.EnvironmentVariable(variable: "BOOL_YES", value: "YES", enabled: true),
|
|
XCScheme.EnvironmentVariable(variable: "ENVIRONMENT", value: "VARIABLE", enabled: true),
|
|
XCScheme.EnvironmentVariable(variable: "OTHER_ENV_VAR", value: "VAL", enabled: false),
|
|
]
|
|
|
|
let expectedTestVariables = [
|
|
XCScheme.EnvironmentVariable(variable: "BOOL_TRUE", value: "YES", enabled: true),
|
|
XCScheme.EnvironmentVariable(variable: "BOOL_YES", value: "YES", enabled: true),
|
|
XCScheme.EnvironmentVariable(variable: "TEST", value: "VARIABLE", enabled: true),
|
|
]
|
|
|
|
try expect(scheme.run?.environmentVariables) == expectedRunVariables
|
|
try expect(scheme.run?.launchAutomaticallySubstyle) == "2"
|
|
try expect(scheme.run?.storeKitConfiguration) == "Configuration.storekit"
|
|
try expect(scheme.test?.environmentVariables) == expectedTestVariables
|
|
try expect(scheme.profile?.config) == "Release"
|
|
try expect(scheme.profile?.environmentVariables.isEmpty) == true
|
|
}
|
|
|
|
$0.it("parses alternate schemes variables") {
|
|
let schemeDictionary: [String: Any] = [
|
|
"build": [
|
|
"targets": ["Target1": "all"],
|
|
],
|
|
"run": [
|
|
"launchAutomaticallySubstyle": 2, // Both integer and string supported
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
],
|
|
]
|
|
|
|
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
|
try expect(scheme.run?.launchAutomaticallySubstyle) == "2"
|
|
try expect(scheme.run?.storeKitConfiguration) == "Configuration.storekit"
|
|
}
|
|
|
|
$0.it("parses scheme templates") {
|
|
let targetDictionary: [String: Any] = [
|
|
"deploymentTarget": "1.2.0",
|
|
"sources": ["targetSource"],
|
|
"templates": ["temp2", "temp"],
|
|
"templateAttributes": [
|
|
"source": "replacedSource",
|
|
],
|
|
]
|
|
|
|
let project = try getProjectSpec([
|
|
"targets": ["Framework": targetDictionary],
|
|
"targetTemplates": [
|
|
"temp": [
|
|
"platform": "iOS",
|
|
"sources": [
|
|
"templateSource",
|
|
["path": "Sources/${target_name}"],
|
|
],
|
|
],
|
|
"temp2": [
|
|
"type": "framework",
|
|
"platform": "tvOS",
|
|
"deploymentTarget": "1.1.0",
|
|
"configFiles": [
|
|
"debug": "Configs/${target_name}/debug.xcconfig",
|
|
"release": "Configs/${target_name}/release.xcconfig",
|
|
],
|
|
"sources": ["${source}"],
|
|
],
|
|
],
|
|
"schemeTemplates": [
|
|
"base_scheme": [
|
|
"build": [
|
|
"parallelizeBuild": false,
|
|
"buildImplicitDependencies": false,
|
|
"runPostActionsOnFailure": true,
|
|
"targets": [
|
|
"Target${name_1}": "all",
|
|
"Target2": "testing",
|
|
"Target${name_3}": "none",
|
|
"Target4": ["testing": true],
|
|
"Target5": ["testing": false],
|
|
"Target6": ["test", "analyze"],
|
|
],
|
|
"preActions": [
|
|
[
|
|
"script": "${pre-action-name}",
|
|
"name": "Before Build ${scheme_name}",
|
|
"settingsTarget": "Target${name_1}",
|
|
],
|
|
],
|
|
],
|
|
"run": [
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
],
|
|
"test": [
|
|
"config": "debug",
|
|
"targets": [
|
|
"Target${name_1}",
|
|
[
|
|
"name": "Target2",
|
|
"parallelizable": true,
|
|
"randomExecutionOrder": true,
|
|
"skippedTests": ["Test/testExample()"],
|
|
],
|
|
],
|
|
"gatherCoverageData": true,
|
|
"disableMainThreadChecker": true,
|
|
"stopOnEveryMainThreadCheckerIssue": false,
|
|
],
|
|
"management": [
|
|
"shared": false,
|
|
"orderHint": 8
|
|
],
|
|
],
|
|
],
|
|
"schemes": [
|
|
"temp2": [
|
|
"templates": ["base_scheme"],
|
|
"templateAttributes": [
|
|
"pre-action-name": "modified-name",
|
|
"name_1": "FirstTarget",
|
|
"name_3": "ThirdTarget",
|
|
],
|
|
],
|
|
],
|
|
])
|
|
|
|
let scheme = project.schemes.first!
|
|
let expectedTargets: [Scheme.BuildTarget] = [
|
|
Scheme.BuildTarget(target: "TargetFirstTarget", buildTypes: BuildType.all),
|
|
Scheme.BuildTarget(target: "Target2", buildTypes: [.testing, .analyzing]),
|
|
Scheme.BuildTarget(target: "TargetThirdTarget", buildTypes: []),
|
|
Scheme.BuildTarget(target: "Target4", buildTypes: [.testing]),
|
|
Scheme.BuildTarget(target: "Target5", buildTypes: []),
|
|
Scheme.BuildTarget(target: "Target6", buildTypes: [.testing, .analyzing]),
|
|
]
|
|
try expect(scheme.name) == "temp2"
|
|
try expect(Set(scheme.build.targets)) == Set(expectedTargets)
|
|
try expect(scheme.build.preActions.first?.script) == "modified-name"
|
|
try expect(scheme.build.preActions.first?.name) == "Before Build temp2"
|
|
try expect(scheme.build.preActions.first?.settingsTarget) == "TargetFirstTarget"
|
|
|
|
try expect(scheme.build.parallelizeBuild) == false
|
|
try expect(scheme.build.buildImplicitDependencies) == false
|
|
try expect(scheme.build.runPostActionsOnFailure) == true
|
|
|
|
try expect(scheme.run?.storeKitConfiguration) == "Configuration.storekit"
|
|
|
|
let expectedTest = Scheme.Test(
|
|
config: "debug",
|
|
gatherCoverageData: true,
|
|
disableMainThreadChecker: true,
|
|
targets: [
|
|
"TargetFirstTarget",
|
|
Scheme.Test.TestTarget(
|
|
targetReference: "Target2",
|
|
randomExecutionOrder: true,
|
|
parallelizable: true,
|
|
skippedTests: ["Test/testExample()"]
|
|
),
|
|
]
|
|
)
|
|
try expect(scheme.test) == expectedTest
|
|
|
|
let expectedManagement = Scheme.Management(shared: false, orderHint: 8, isShown: nil)
|
|
try expect(scheme.management) == expectedManagement
|
|
}
|
|
|
|
$0.it("parses copy files on install") {
|
|
var targetSource = validTarget
|
|
targetSource["onlyCopyFilesOnInstall"] = true
|
|
let target = try Target(name: "Embed Frameworks", jsonDictionary: targetSource)
|
|
try expect(target.onlyCopyFilesOnInstall) == true
|
|
}
|
|
|
|
$0.it("parses put resources before Sources Build Phase") {
|
|
var targetSource = validTarget
|
|
targetSource["putResourcesBeforeSourcesBuildPhase"] = true
|
|
let target = try Target(name: "Embed Frameworks", jsonDictionary: targetSource)
|
|
try expect(target.putResourcesBeforeSourcesBuildPhase) == true
|
|
}
|
|
|
|
$0.it("parses settings") {
|
|
let project = try Project(path: fixturePath + "settings_test.yml")
|
|
let buildSettings: BuildSettings = ["SETTING": "value"]
|
|
let configSettings: [String: Settings] = ["config1": Settings(buildSettings: ["SETTING1": "value"])]
|
|
let groups = ["preset1"]
|
|
|
|
let preset1 = Settings(buildSettings: buildSettings, configSettings: [:], groups: [])
|
|
let preset2 = Settings(buildSettings: [:], configSettings: configSettings, groups: [])
|
|
let preset3 = Settings(buildSettings: buildSettings, configSettings: configSettings, groups: [])
|
|
let preset4 = Settings(buildSettings: buildSettings, configSettings: [:], groups: [])
|
|
let preset5 = Settings(buildSettings: buildSettings, configSettings: [:], groups: groups)
|
|
let preset6 = Settings(buildSettings: buildSettings, configSettings: configSettings, groups: groups)
|
|
let preset7 = Settings(buildSettings: buildSettings, configSettings: ["config1": Settings(buildSettings: buildSettings, groups: groups)])
|
|
let preset8 = Settings(buildSettings: [:], configSettings: ["config1": Settings(configSettings: configSettings)])
|
|
|
|
try expect(project.settingGroups.count) == 8
|
|
try expect(project.settingGroups["preset1"]) == preset1
|
|
try expect(project.settingGroups["preset2"]) == preset2
|
|
try expect(project.settingGroups["preset3"]) == preset3
|
|
try expect(project.settingGroups["preset4"]) == preset4
|
|
try expect(project.settingGroups["preset5"]) == preset5
|
|
try expect(project.settingGroups["preset6"]) == preset6
|
|
try expect(project.settingGroups["preset7"]) == preset7
|
|
try expect(project.settingGroups["preset8"]) == preset8
|
|
}
|
|
|
|
$0.it("parses run scripts") {
|
|
var target = validTarget
|
|
let scripts: [[String: Any]] = [
|
|
["path": "script.sh"],
|
|
["script": "shell script\ndo thing", "name": "myscript", "inputFiles": ["file", "file2"], "outputFiles": ["file", "file2"], "shell": "bin/customshell", "runOnlyWhenInstalling": true],
|
|
["script": "shell script\ndo thing", "name": "myscript", "inputFiles": ["file", "file2"], "outputFiles": ["file", "file2"], "shell": "bin/customshell", "showEnvVars": false],
|
|
["script": "shell script\ndo thing", "name": "myscript", "inputFiles": ["file", "file2"], "outputFiles": ["file", "file2"], "shell": "bin/customshell", "basedOnDependencyAnalysis": false],
|
|
["script": "shell script\nwith file lists", "name": "myscript", "inputFileLists": ["inputList.xcfilelist"], "outputFileLists": ["outputList.xcfilelist"], "shell": "bin/customshell", "runOnlyWhenInstalling": true],
|
|
["script": "shell script\nwith file lists", "name": "myscript", "inputFileLists": ["inputList.xcfilelist"], "outputFileLists": ["outputList.xcfilelist"], "shell": "bin/customshell", "showEnvVars": false],
|
|
["script": "shell script\nwith file lists", "name": "myscript", "inputFileLists": ["inputList.xcfilelist"], "outputFileLists": ["outputList.xcfilelist"], "shell": "bin/customshell", "basedOnDependencyAnalysis": false],
|
|
]
|
|
target["preBuildScripts"] = scripts
|
|
target["postCompileScripts"] = scripts
|
|
target["postBuildScripts"] = scripts
|
|
|
|
let expectedScripts = [
|
|
BuildScript(script: .path("script.sh")),
|
|
BuildScript(script: .script("shell script\ndo thing"), name: "myscript", inputFiles: ["file", "file2"], outputFiles: ["file", "file2"], shell: "bin/customshell", runOnlyWhenInstalling: true, showEnvVars: true, basedOnDependencyAnalysis: true),
|
|
BuildScript(script: .script("shell script\ndo thing"), name: "myscript", inputFiles: ["file", "file2"], outputFiles: ["file", "file2"], shell: "bin/customshell", runOnlyWhenInstalling: false, showEnvVars: false, basedOnDependencyAnalysis: true),
|
|
BuildScript(script: .script("shell script\ndo thing"), name: "myscript", inputFiles: ["file", "file2"], outputFiles: ["file", "file2"], shell: "bin/customshell", runOnlyWhenInstalling: false, showEnvVars: true, basedOnDependencyAnalysis: false),
|
|
BuildScript(script: .script("shell script\nwith file lists"), name: "myscript", inputFileLists: ["inputList.xcfilelist"], outputFileLists: ["outputList.xcfilelist"], shell: "bin/customshell", runOnlyWhenInstalling: true, showEnvVars: true, basedOnDependencyAnalysis: true),
|
|
BuildScript(script: .script("shell script\nwith file lists"), name: "myscript", inputFileLists: ["inputList.xcfilelist"], outputFileLists: ["outputList.xcfilelist"], shell: "bin/customshell", runOnlyWhenInstalling: false, showEnvVars: false, basedOnDependencyAnalysis: true),
|
|
BuildScript(script: .script("shell script\nwith file lists"), name: "myscript", inputFileLists: ["inputList.xcfilelist"], outputFileLists: ["outputList.xcfilelist"], shell: "bin/customshell", runOnlyWhenInstalling: false, showEnvVars: true, basedOnDependencyAnalysis: false),
|
|
]
|
|
|
|
let parsedTarget = try Target(name: "test", jsonDictionary: target)
|
|
try expect(parsedTarget.preBuildScripts) == expectedScripts
|
|
try expect(parsedTarget.postCompileScripts) == expectedScripts
|
|
try expect(parsedTarget.postBuildScripts) == expectedScripts
|
|
}
|
|
|
|
$0.it("parses build rules") {
|
|
var target = validTarget
|
|
let buildRules: [[String: Any]] = [
|
|
[
|
|
"name": "My Rule",
|
|
"script": "my script",
|
|
"filePattern": "*.swift",
|
|
"outputFiles": ["file1", "file2"],
|
|
"outputFilesCompilerFlags": ["-a", "-b"],
|
|
],
|
|
[
|
|
"compilerSpec": "apple.tool",
|
|
"fileType": "sourcecode.swift",
|
|
],
|
|
]
|
|
target["buildRules"] = buildRules
|
|
|
|
let expectedBuildRules = [
|
|
BuildRule(fileType: .pattern("*.swift"), action: .script("my script"), name: "My Rule", outputFiles: ["file1", "file2"], outputFilesCompilerFlags: ["-a", "-b"]),
|
|
BuildRule(fileType: .type("sourcecode.swift"), action: .compilerSpec("apple.tool")),
|
|
]
|
|
|
|
let parsedTarget = try Target(name: "test", jsonDictionary: target)
|
|
try expect(parsedTarget.buildRules) == expectedBuildRules
|
|
}
|
|
|
|
$0.it("parses options") {
|
|
let options = SpecOptions(
|
|
carthageBuildPath: "../Carthage/Build",
|
|
carthageExecutablePath: "../bin/carthage",
|
|
createIntermediateGroups: true,
|
|
bundleIdPrefix: "com.test",
|
|
developmentLanguage: "ja",
|
|
deploymentTarget: DeploymentTarget(
|
|
iOS: "11.1",
|
|
tvOS: "10.0",
|
|
watchOS: "3.0",
|
|
macOS: "10.12.1"
|
|
),
|
|
fileTypes: ["abc": FileType(
|
|
file: false,
|
|
buildPhase: .sources,
|
|
attributes: ["a1", "a2"],
|
|
resourceTags: ["r1", "r2"],
|
|
compilerFlags: ["c1", "c2"])],
|
|
findCarthageFrameworks: true,
|
|
preGenCommand: "swiftgen",
|
|
postGenCommand: "pod install",
|
|
schemePathPrefix: "../"
|
|
)
|
|
let expected = Project(name: "test", options: options)
|
|
let dictionary: [String: Any] = ["options": [
|
|
"carthageBuildPath": "../Carthage/Build",
|
|
"carthageExecutablePath": "../bin/carthage",
|
|
"bundleIdPrefix": "com.test",
|
|
"createIntermediateGroups": true,
|
|
"developmentLanguage": "ja",
|
|
"deploymentTarget": ["iOS": 11.1, "tvOS": 10.0, "watchOS": "3", "macOS": "10.12.1"],
|
|
"findCarthageFrameworks": true,
|
|
"preGenCommand": "swiftgen",
|
|
"postGenCommand": "pod install",
|
|
"fileTypes": ["abc": [
|
|
"file": false,
|
|
"buildPhase": "sources",
|
|
"attributes": ["a1", "a2"],
|
|
"resourceTags": ["r1", "r2"],
|
|
"compilerFlags": ["c1", "c2"],
|
|
]],
|
|
"schemePathPrefix": "../",
|
|
]]
|
|
let parsedSpec = try getProjectSpec(dictionary)
|
|
try expect(parsedSpec) == expected
|
|
}
|
|
|
|
$0.it("parses packages") {
|
|
let project = Project(name: "spm", packages: [
|
|
"package1": .remote(url: "package.git", versionRequirement: .exact("1.2.2")),
|
|
"package2": .remote(url: "package.git", versionRequirement: .upToNextMajorVersion("1.2.2")),
|
|
"package3": .remote(url: "package.git", versionRequirement: .upToNextMinorVersion("1.2.2")),
|
|
"package4": .remote(url: "package.git", versionRequirement: .branch("master")),
|
|
"package5": .remote(url: "package.git", versionRequirement: .revision("x")),
|
|
"package6": .remote(url: "package.git", versionRequirement: .range(from: "1.2.0", to: "1.2.5")),
|
|
"package7": .remote(url: "package.git", versionRequirement: .exact("1.2.2")),
|
|
"package8": .remote(url: "package.git", versionRequirement: .upToNextMajorVersion("4.0.0-beta.5")),
|
|
"package9": .local(path: "package/package", group: nil, excludeFromProject: false),
|
|
"package10": .remote(url: "https://github.com/yonaskolb/XcodeGen", versionRequirement: .exact("1.2.2")),
|
|
"XcodeGen": .local(path: "../XcodeGen", group: nil, excludeFromProject: false),
|
|
"package11": .local(path: "../XcodeGen", group: "Packages/Feature", excludeFromProject: false),
|
|
], options: .init(localPackagesGroup: "MyPackages"))
|
|
|
|
let dictionary: [String: Any] = [
|
|
"name": "spm",
|
|
"options": [
|
|
"localPackagesGroup": "MyPackages",
|
|
],
|
|
"packages": [
|
|
"package1": ["url": "package.git", "exactVersion": "1.2.2"],
|
|
"package2": ["url": "package.git", "majorVersion": "1.2.2"],
|
|
"package3": ["url": "package.git", "minorVersion": "1.2.2"],
|
|
"package4": ["url": "package.git", "branch": "master"],
|
|
"package5": ["url": "package.git", "revision": "x"],
|
|
"package6": ["url": "package.git", "minVersion": "1.2.0", "maxVersion": "1.2.5"],
|
|
"package7": ["url": "package.git", "version": "1.2.2"],
|
|
"package8": ["url": "package.git", "majorVersion": "4.0.0-beta.5"],
|
|
"package9": ["path": "package/package"],
|
|
"package10": ["github": "yonaskolb/XcodeGen", "exactVersion": "1.2.2"],
|
|
"package11": ["path": "../XcodeGen", "group": "Packages/Feature"],
|
|
],
|
|
"localPackages": ["../XcodeGen"],
|
|
]
|
|
let parsedSpec = try getProjectSpec(dictionary)
|
|
try expect(parsedSpec) == project
|
|
}
|
|
|
|
$0.it("parses old local package format") {
|
|
let project = Project(name: "spm", packages: [
|
|
"XcodeGen": .local(path: "../XcodeGen", group: nil, excludeFromProject: false),
|
|
"Yams": .local(path: "Yams", group: nil, excludeFromProject: false),
|
|
], options: .init(localPackagesGroup: "MyPackages"))
|
|
|
|
let dictionary: [String: Any] = [
|
|
"name": "spm",
|
|
"options": [
|
|
"localPackagesGroup": "MyPackages",
|
|
],
|
|
"localPackages": ["../XcodeGen", "Yams"],
|
|
]
|
|
let parsedSpec = try getProjectSpec(dictionary)
|
|
try expect(parsedSpec) == project
|
|
}
|
|
|
|
$0.it("parses TargetScheme storeKitConfiguration as string") {
|
|
var targetDictionary = validTarget
|
|
targetDictionary["scheme"] = [
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
]
|
|
|
|
let target = try Target(name: "test", jsonDictionary: targetDictionary)
|
|
|
|
let scheme = TargetScheme(
|
|
storeKitConfiguration: "Configuration.storekit"
|
|
)
|
|
|
|
try expect(target.scheme) == scheme
|
|
}
|
|
|
|
$0.it("parses Scheme.Run storeKitConfiguration as string") {
|
|
let schemeDictionary: [String: Any] = [
|
|
"build": [
|
|
"targets": [:],
|
|
],
|
|
"run": [
|
|
"config": "debug",
|
|
"storeKitConfiguration": "Configuration.storekit",
|
|
],
|
|
]
|
|
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
|
|
|
let runAction = Scheme.Run(
|
|
config: "debug",
|
|
storeKitConfiguration: "Configuration.storekit"
|
|
)
|
|
|
|
try expect(scheme.run) == runAction
|
|
}
|
|
|
|
$0.it("parses buildToolPlugins") {
|
|
var target = validTarget
|
|
let buildToolPlugins: [[String: Any]] = [
|
|
[
|
|
"plugin": "FirstPlugin",
|
|
"package": "FirstPackage"
|
|
],
|
|
[
|
|
"plugin": "SecondPlugin",
|
|
"package": "SecondPackage"
|
|
]
|
|
]
|
|
target["buildToolPlugins"] = buildToolPlugins
|
|
|
|
let expectedBuildToolPlugins = [
|
|
BuildToolPlugin(plugin: "FirstPlugin", package: "FirstPackage"),
|
|
BuildToolPlugin(plugin: "SecondPlugin", package: "SecondPackage")
|
|
]
|
|
|
|
let parsedTarget = try Target(name: "test", jsonDictionary: target)
|
|
try expect(parsedTarget.buildToolPlugins) == expectedBuildToolPlugins
|
|
}
|
|
}
|
|
}
|
|
|
|
func testPackagesVersion() {
|
|
describe {
|
|
let invalidPackages = [
|
|
["url": "package.git", "majorVersion": "master"],
|
|
["url": "package.git", "from": "develop"],
|
|
["url": "package.git", "minVersion": "feature/swift5.2", "maxVersion": "9.1.0"],
|
|
["url": "package.git", "minorVersion": "x.1.2"],
|
|
["url": "package.git", "exactVersion": "1.2.3.1"],
|
|
["url": "package.git", "version": "foo-bar"],
|
|
]
|
|
|
|
$0.it("is an invalid package version") {
|
|
for dictionary in invalidPackages {
|
|
try expect(expression: { _ = try SwiftPackage(jsonDictionary: dictionary) }).toThrow()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testDecoding() throws {
|
|
describe {
|
|
$0.it("decodes dots in dictionary keys") {
|
|
let dictionary: [String: Any] = [
|
|
"test": [
|
|
"one.two": true,
|
|
],
|
|
]
|
|
|
|
let booleans: [String: Bool] = try dictionary.json(atKeyPath: "test")
|
|
try expect(booleans) == ["one.two": true]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@discardableResult
|
|
private func getProjectSpec(_ project: [String: Any], file: String = #file, line: Int = #line) throws -> Project {
|
|
var projectDictionary: [String: Any] = ["name": "test"]
|
|
for (key, value) in project {
|
|
projectDictionary[key] = value
|
|
}
|
|
do {
|
|
return try Project(jsonDictionary: projectDictionary)
|
|
} catch {
|
|
throw failure("\(error)", file: file, line: line)
|
|
}
|
|
}
|
|
|
|
private func loadSpec(path: Path, variables: [String: String] = [:], file: String = #file, line: Int = #line) throws -> Project {
|
|
do {
|
|
let specLoader = SpecLoader(version: "1.1.0")
|
|
return try specLoader.loadProject(path: path, variables: variables)
|
|
} catch {
|
|
throw failure("\(error)", file: file, line: line)
|
|
}
|
|
}
|
|
|
|
private func expectSpecError(_ project: [String: Any], _ expectedError: SpecParsingError, file: String = #file, line: Int = #line) throws {
|
|
try expectError(expectedError, file: file, line: line) {
|
|
try getProjectSpec(project)
|
|
}
|
|
}
|
|
|
|
private func expectTargetError(_ target: [String: Any], _ expectedError: SpecParsingError, file: String = #file, line: Int = #line) throws {
|
|
try expectError(expectedError, file: file, line: line) {
|
|
_ = try Target(name: "test", jsonDictionary: target)
|
|
}
|
|
}
|
|
|
|
private func expectBreakpointError(_ breakpoint: [String: Any], _ expectedError: SpecParsingError, file: String = #file, line: Int = #line) throws {
|
|
try expectError(expectedError, file: file, line: line) {
|
|
_ = try Breakpoint(jsonDictionary: breakpoint)
|
|
}
|
|
}
|