1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
//===----------------------------------------------------------*- swift -*-===//
//
// This source file is part of the Swift Argument Parser open source project
//
// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
import XCTest
import ArgumentParserTestHelpers
import ArgumentParser
final class OptionGroupEndToEndTests: XCTestCase {
}
fileprivate struct Inner: TestableParsableArguments {
@Flag(name: [.short, .long])
var extraVerbiage: Bool = false
@Option
var size: Int = 0
@Argument()
var name: String
let didValidateExpectation = XCTestExpectation(singleExpectation: "inner validated")
private enum CodingKeys: CodingKey {
case extraVerbiage
case size
case name
}
}
fileprivate struct Outer: TestableParsableArguments {
@Flag
var verbose: Bool = false
@Argument()
var before: String
@OptionGroup()
var inner: Inner
@Argument()
var after: String
let didValidateExpectation = XCTestExpectation(singleExpectation: "outer validated")
private enum CodingKeys: CodingKey {
case verbose
case before
case inner
case after
}
}
fileprivate struct Command: TestableParsableCommand {
static let configuration = CommandConfiguration(commandName: "testCommand")
@OptionGroup()
var outer: Outer
let didValidateExpectation = XCTestExpectation(singleExpectation: "Command validated")
let didRunExpectation = XCTestExpectation(singleExpectation: "Command ran")
private enum CodingKeys: CodingKey {
case outer
}
}
extension OptionGroupEndToEndTests {
func testOptionGroup_Defaults() throws {
AssertParse(Outer.self, ["prefix", "name", "postfix"]) { options in
XCTAssertEqual(options.verbose, false)
XCTAssertEqual(options.before, "prefix")
XCTAssertEqual(options.after, "postfix")
XCTAssertEqual(options.inner.extraVerbiage, false)
XCTAssertEqual(options.inner.size, 0)
XCTAssertEqual(options.inner.name, "name")
}
AssertParse(Outer.self, ["prefix", "--extra-verbiage", "name", "postfix", "--verbose", "--size", "5"]) { options in
XCTAssertEqual(options.verbose, true)
XCTAssertEqual(options.before, "prefix")
XCTAssertEqual(options.after, "postfix")
XCTAssertEqual(options.inner.extraVerbiage, true)
XCTAssertEqual(options.inner.size, 5)
XCTAssertEqual(options.inner.name, "name")
}
}
func testOptionGroup_isValidated() {
// Parse the command, this should cause validation to be once each on
// - command.outer.inner
// - command.outer
// - command
AssertParseCommand(Command.self, Command.self, ["prefix", "name", "postfix"]) { command in
wait(for: [command.didValidateExpectation, command.outer.didValidateExpectation, command.outer.inner.didValidateExpectation], timeout: 0.1)
}
}
func testOptionGroup_Fails() throws {
XCTAssertThrowsError(try Outer.parse([]))
XCTAssertThrowsError(try Outer.parse(["prefix"]))
XCTAssertThrowsError(try Outer.parse(["prefix", "name"]))
XCTAssertThrowsError(try Outer.parse(["prefix", "name", "postfix", "extra"]))
XCTAssertThrowsError(try Outer.parse(["prefix", "name", "postfix", "--size", "a"]))
}
}
fileprivate struct DuplicatedFlagGroupCustom: ParsableArguments {
@Flag(name: .customLong("duplicated-option"))
var duplicated: Bool = false
}
fileprivate struct DuplicatedFlagGroupCustomCommand: ParsableCommand {
@Flag var duplicated: Bool = false
@OptionGroup var option: DuplicatedFlagGroupCustom
}
fileprivate struct DuplicatedFlagGroupLong: ParsableArguments {
@Flag var duplicated: Bool = false
}
fileprivate struct DuplicatedFlagGroupLongCommand: ParsableCommand {
@Flag(name: .customLong("duplicated-option"))
var duplicated: Bool = false
@OptionGroup var option: DuplicatedFlagGroupLong
}
extension OptionGroupEndToEndTests {
func testUniqueNamesForDuplicatedFlag_NoFlags() throws {
AssertParse(DuplicatedFlagGroupCustomCommand.self, []) { command in
XCTAssertFalse(command.duplicated)
XCTAssertFalse(command.option.duplicated)
}
AssertParse(DuplicatedFlagGroupLongCommand.self, []) { command in
XCTAssertFalse(command.duplicated)
XCTAssertFalse(command.option.duplicated)
}
}
func testUniqueNamesForDuplicatedFlag_RootOnly() throws {
AssertParse(DuplicatedFlagGroupCustomCommand.self, ["--duplicated"]) { command in
XCTAssertTrue(command.duplicated)
XCTAssertFalse(command.option.duplicated)
}
AssertParse(DuplicatedFlagGroupLongCommand.self, ["--duplicated"]) { command in
XCTAssertFalse(command.duplicated)
XCTAssertTrue(command.option.duplicated)
}
}
func testUniqueNamesForDuplicatedFlag_OptionOnly() throws {
AssertParse(DuplicatedFlagGroupCustomCommand.self, ["--duplicated-option"]) { command in
XCTAssertFalse(command.duplicated)
XCTAssertTrue(command.option.duplicated)
}
AssertParse(DuplicatedFlagGroupLongCommand.self, ["--duplicated-option"]) { command in
XCTAssertTrue(command.duplicated)
XCTAssertFalse(command.option.duplicated)
}
}
func testUniqueNamesForDuplicatedFlag_RootAndOption() throws {
AssertParse(DuplicatedFlagGroupCustomCommand.self, ["--duplicated", "--duplicated-option"]) { command in
XCTAssertTrue(command.duplicated)
XCTAssertTrue(command.option.duplicated)
}
AssertParse(DuplicatedFlagGroupLongCommand.self, ["--duplicated", "--duplicated-option"]) { command in
XCTAssertTrue(command.duplicated)
XCTAssertTrue(command.option.duplicated)
}
}
}
|