|
| 1 | +//===----------------------------------------------------------*- swift -*-===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift Argument Parser open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2020 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See https://swift.org/LICENSE.txt for license information |
| 9 | +// |
| 10 | +//===----------------------------------------------------------------------===// |
| 11 | + |
| 12 | +import XCTest |
| 13 | +import ArgumentParserTestHelpers |
| 14 | +import ArgumentParser |
| 15 | + |
| 16 | +/// The goal of this test class is to validate source compatibility. By running |
| 17 | +/// this class's tests, all property wrapper initializers should be called. |
| 18 | +final class SourceCompatEndToEndTests: XCTestCase {} |
| 19 | + |
| 20 | +// MARK: - Property Wrapper Initializers |
| 21 | + |
| 22 | +fileprivate struct AlmostAllArguments: ParsableArguments { |
| 23 | + @Argument(default: 0, help: "") var a: Int |
| 24 | + @Argument() var a0: Int |
| 25 | + @Argument(help: "") var a1: Int |
| 26 | + @Argument(default: 0) var a2: Int |
| 27 | + |
| 28 | + @Argument(default: 0, help: "", transform: { _ in 0 }) var b: Int |
| 29 | + @Argument(default: 0) var b1: Int |
| 30 | + @Argument(help: "") var b2: Int |
| 31 | + @Argument(transform: { _ in 0 }) var b3: Int |
| 32 | + @Argument(help: "", transform: { _ in 0 }) var b4: Int |
| 33 | + @Argument(default: 0, transform: { _ in 0 }) var b5: Int |
| 34 | + @Argument(default: 0, help: "") var b6: Int |
| 35 | + |
| 36 | + @Argument(default: 0, help: "") var c: Int? |
| 37 | + @Argument() var c0: Int? |
| 38 | + @Argument(help: "") var c1: Int? |
| 39 | + @Argument(default: 0) var c2: Int? |
| 40 | + |
| 41 | + @Argument(default: 0, help: "", transform: { _ in 0 }) var d: Int? |
| 42 | + @Argument(default: 0) var d1: Int? |
| 43 | + @Argument(help: "") var d2: Int? |
| 44 | + @Argument(transform: { _ in 0 }) var d3: Int? |
| 45 | + @Argument(help: "", transform: { _ in 0 }) var d4: Int? |
| 46 | + @Argument(default: 0, transform: { _ in 0 }) var d5: Int? |
| 47 | + @Argument(default: 0, help: "") var d6: Int? |
| 48 | + |
| 49 | + @Argument(parsing: .remaining, help: "") var e: [Int] |
| 50 | + @Argument() var e0: [Int] |
| 51 | + @Argument(help: "") var e1: [Int] |
| 52 | + @Argument(parsing: .remaining) var e2: [Int] |
| 53 | + @Argument(parsing: .remaining, help: "", transform: { _ in 0 }) var e3: [Int] |
| 54 | + @Argument(transform: { _ in 0 }) var e4: [Int] |
| 55 | + @Argument(help: "", transform: { _ in 0 }) var e5: [Int] |
| 56 | + @Argument(parsing: .remaining, transform: { _ in 0 }) var e6: [Int] |
| 57 | +} |
| 58 | + |
| 59 | +fileprivate struct AllOptions: ParsableArguments { |
| 60 | + @Option(name: .long, default: 0, parsing: .next, help: "") var a: Int |
| 61 | + @Option(default: 0, parsing: .next, help: "") var a1: Int |
| 62 | + @Option(name: .long, parsing: .next, help: "") var a2: Int |
| 63 | + @Option(name: .long, default: 0, help: "") var a3: Int |
| 64 | + @Option(parsing: .next, help: "") var a4: Int |
| 65 | + @Option(default: 0, help: "") var a5: Int |
| 66 | + @Option(default: 0, parsing: .next) var a6: Int |
| 67 | + @Option(name: .long, help: "") var a7: Int |
| 68 | + @Option(name: .long, parsing: .next) var a8: Int |
| 69 | + @Option(name: .long, default: 0) var a9: Int |
| 70 | + @Option(name: .long) var a10: Int |
| 71 | + @Option(default: 0) var a11: Int |
| 72 | + @Option(parsing: .next) var a12: Int |
| 73 | + @Option(help: "") var a13: Int |
| 74 | + |
| 75 | + @Option(name: .long, default: 0, parsing: .next, help: "") var b: Int? |
| 76 | + @Option(default: 0, parsing: .next, help: "") var b1: Int? |
| 77 | + @Option(name: .long, parsing: .next, help: "") var b2: Int? |
| 78 | + @Option(name: .long, default: 0, help: "") var b3: Int? |
| 79 | + @Option(parsing: .next, help: "") var b4: Int? |
| 80 | + @Option(default: 0, help: "") var b5: Int? |
| 81 | + @Option(default: 0, parsing: .next) var b6: Int? |
| 82 | + @Option(name: .long, help: "") var b7: Int? |
| 83 | + @Option(name: .long, parsing: .next) var b8: Int? |
| 84 | + @Option(name: .long, default: 0) var b9: Int? |
| 85 | + @Option(name: .long) var b10: Int? |
| 86 | + @Option(default: 0) var b11: Int? |
| 87 | + @Option(parsing: .next) var b12: Int? |
| 88 | + @Option(help: "") var b13: Int? |
| 89 | + |
| 90 | + @Option(name: .long, default: 0, parsing: .next, help: "", transform: { _ in 0 }) var c: Int |
| 91 | + @Option(default: 0, parsing: .next, help: "", transform: { _ in 0 }) var c1: Int |
| 92 | + @Option(name: .long, parsing: .next, help: "", transform: { _ in 0 }) var c2: Int |
| 93 | + @Option(name: .long, default: 0, help: "", transform: { _ in 0 }) var c3: Int |
| 94 | + @Option(parsing: .next, help: "", transform: { _ in 0 }) var c4: Int |
| 95 | + @Option(default: 0, help: "", transform: { _ in 0 }) var c5: Int |
| 96 | + @Option(default: 0, parsing: .next, transform: { _ in 0 }) var c6: Int |
| 97 | + @Option(name: .long, help: "", transform: { _ in 0 }) var c7: Int |
| 98 | + @Option(name: .long, parsing: .next, transform: { _ in 0 }) var c8: Int |
| 99 | + @Option(name: .long, default: 0, transform: { _ in 0 }) var c9: Int |
| 100 | + @Option(name: .long, transform: { _ in 0 }) var c10: Int |
| 101 | + @Option(default: 0, transform: { _ in 0 }) var c11: Int |
| 102 | + @Option(parsing: .next, transform: { _ in 0 }) var c12: Int |
| 103 | + @Option(help: "", transform: { _ in 0 }) var c13: Int |
| 104 | + |
| 105 | + @Option(name: .long, default: 0, parsing: .next, help: "", transform: { _ in 0 }) var d: Int? |
| 106 | + @Option(default: 0, parsing: .next, help: "", transform: { _ in 0 }) var d1: Int? |
| 107 | + @Option(name: .long, parsing: .next, help: "", transform: { _ in 0 }) var d2: Int? |
| 108 | + @Option(name: .long, default: 0, help: "", transform: { _ in 0 }) var d3: Int? |
| 109 | + @Option(parsing: .next, help: "", transform: { _ in 0 }) var d4: Int? |
| 110 | + @Option(default: 0, help: "", transform: { _ in 0 }) var d5: Int? |
| 111 | + @Option(default: 0, parsing: .next, transform: { _ in 0 }) var d6: Int? |
| 112 | + @Option(name: .long, help: "", transform: { _ in 0 }) var d7: Int? |
| 113 | + @Option(name: .long, parsing: .next, transform: { _ in 0 }) var d8: Int? |
| 114 | + @Option(name: .long, default: 0, transform: { _ in 0 }) var d9: Int? |
| 115 | + @Option(name: .long, transform: { _ in 0 }) var d10: Int? |
| 116 | + @Option(default: 0, transform: { _ in 0 }) var d11: Int? |
| 117 | + @Option(parsing: .next, transform: { _ in 0 }) var d12: Int? |
| 118 | + @Option(help: "", transform: { _ in 0 }) var d13: Int? |
| 119 | + |
| 120 | + @Option(name: .long, parsing: .singleValue, help: "") var e: [Int] |
| 121 | + @Option(parsing: .singleValue, help: "") var e1: [Int] |
| 122 | + @Option(name: .long, help: "") var e2: [Int] |
| 123 | + @Option(name: .long, parsing: .singleValue) var e3: [Int] |
| 124 | + @Option(name: .long) var e4: [Int] |
| 125 | + @Option(parsing: .singleValue) var e5: [Int] |
| 126 | + @Option(help: "") var e6: [Int] |
| 127 | + |
| 128 | + @Option(name: .long, parsing: .singleValue, help: "", transform: { _ in 0 }) var f: [Int] |
| 129 | + @Option(parsing: .singleValue, help: "", transform: { _ in 0 }) var f1: [Int] |
| 130 | + @Option(name: .long, help: "", transform: { _ in 0 }) var f2: [Int] |
| 131 | + @Option(name: .long, parsing: .singleValue, transform: { _ in 0 }) var f3: [Int] |
| 132 | + @Option(name: .long, transform: { _ in 0 }) var f4: [Int] |
| 133 | + @Option(parsing: .singleValue, transform: { _ in 0 }) var f5: [Int] |
| 134 | + @Option(help: "", transform: { _ in 0 }) var f6: [Int] |
| 135 | +} |
| 136 | + |
| 137 | +struct AllFlags: ParsableArguments { |
| 138 | + enum E: String, EnumerableFlag { |
| 139 | + case one, two, three |
| 140 | + } |
| 141 | + |
| 142 | + @Flag(name: .long, help: "") var a: Bool |
| 143 | + @Flag() var a0: Bool |
| 144 | + @Flag(name: .long) var a1: Bool |
| 145 | + @Flag(help: "") var a2: Bool |
| 146 | + |
| 147 | + @Flag(name: .long, inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var b: Bool |
| 148 | + @Flag(inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var b1: Bool |
| 149 | + @Flag(name: .long, inversion: .prefixedNo, help: "") var b2: Bool |
| 150 | + @Flag(name: .long, inversion: .prefixedNo, exclusivity: .chooseLast) var b3: Bool |
| 151 | + @Flag(inversion: .prefixedNo, help: "") var b4: Bool |
| 152 | + @Flag(inversion: .prefixedNo, exclusivity: .chooseLast) var b5: Bool |
| 153 | + @Flag(name: .long, inversion: .prefixedNo) var b6: Bool |
| 154 | + @Flag(inversion: .prefixedNo) var b7: Bool |
| 155 | + |
| 156 | + @Flag(name: .long, default: false, inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var c: Bool |
| 157 | + @Flag(default: false, inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var c1: Bool |
| 158 | + @Flag(name: .long, default: false, inversion: .prefixedNo, help: "") var c2: Bool |
| 159 | + @Flag(name: .long, default: false, inversion: .prefixedNo, exclusivity: .chooseLast) var c3: Bool |
| 160 | + @Flag(default: false, inversion: .prefixedNo, help: "") var c4: Bool |
| 161 | + @Flag(default: false, inversion: .prefixedNo, exclusivity: .chooseLast) var c5: Bool |
| 162 | + @Flag(name: .long, default: false, inversion: .prefixedNo) var c6: Bool |
| 163 | + @Flag(default: false, inversion: .prefixedNo) var c7: Bool |
| 164 | + |
| 165 | + @Flag(name: .long, default: nil, inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var d: Bool |
| 166 | + @Flag(default: nil, inversion: .prefixedNo, exclusivity: .chooseLast, help: "") var d1: Bool |
| 167 | + @Flag(name: .long, default: nil, inversion: .prefixedNo, help: "") var d2: Bool |
| 168 | + @Flag(name: .long, default: nil, inversion: .prefixedNo, exclusivity: .chooseLast) var d3: Bool |
| 169 | + @Flag(default: nil, inversion: .prefixedNo, help: "") var d4: Bool |
| 170 | + @Flag(default: nil, inversion: .prefixedNo, exclusivity: .chooseLast) var d5: Bool |
| 171 | + @Flag(name: .long, default: nil, inversion: .prefixedNo) var d6: Bool |
| 172 | + @Flag(default: nil, inversion: .prefixedNo) var d7: Bool |
| 173 | + |
| 174 | + @Flag(name: .long, help: "") var e: Int |
| 175 | + @Flag() var e0: Int |
| 176 | + @Flag(name: .long) var e1: Int |
| 177 | + @Flag(help: "") var e2: Int |
| 178 | + |
| 179 | + @Flag(default: .one, exclusivity: .chooseLast, help: "") var f: E |
| 180 | + @Flag() var f1: E |
| 181 | + @Flag(exclusivity: .chooseLast, help: "") var f2: E |
| 182 | + @Flag(default: .one, help: "") var f3: E |
| 183 | + @Flag(default: .one, exclusivity: .chooseLast) var f4: E |
| 184 | + @Flag(help: "") var f5: E |
| 185 | + @Flag(exclusivity: .chooseLast) var f6: E |
| 186 | + @Flag(default: .one) var f7: E |
| 187 | + |
| 188 | + @Flag(exclusivity: .chooseLast, help: "") var g: E? |
| 189 | + @Flag() var g1: E? |
| 190 | + @Flag(help: "") var g2: E? |
| 191 | + @Flag(exclusivity: .chooseLast) var g3: E? |
| 192 | + |
| 193 | + @Flag(help: "") var h: [E] |
| 194 | + @Flag() var h1: [E] |
| 195 | +} |
| 196 | + |
| 197 | +extension SourceCompatEndToEndTests { |
| 198 | + func testParsingAll() throws { |
| 199 | + // This is just checking building the argument definitions, not the actual |
| 200 | + // validation or usage of these definitions, which would fail. |
| 201 | + _ = AlmostAllArguments() |
| 202 | + _ = AllOptions() |
| 203 | + _ = AllFlags() |
| 204 | + } |
| 205 | +} |
| 206 | + |
| 207 | +// MARK: - Deprecated APIs |
| 208 | + |
| 209 | +fileprivate struct DeprecatedFlags: ParsableArguments { |
| 210 | + enum One: String, CaseIterable { |
| 211 | + case one |
| 212 | + } |
| 213 | + enum Two: String, CaseIterable { |
| 214 | + case two |
| 215 | + } |
| 216 | + enum Three: String, CaseIterable { |
| 217 | + case three |
| 218 | + case four |
| 219 | + } |
| 220 | + |
| 221 | + @Flag() var single: One |
| 222 | + @Flag() var optional: Two? |
| 223 | + @Flag() var array: [Three] |
| 224 | + @Flag(name: .long) var size: Size? |
| 225 | +} |
| 226 | + |
| 227 | +extension SourceCompatEndToEndTests { |
| 228 | + func testParsingDeprecatedFlags() throws { |
| 229 | + AssertParse(DeprecatedFlags.self, ["--one"]) { options in |
| 230 | + XCTAssertEqual(options.single, .one) |
| 231 | + XCTAssertNil(options.optional) |
| 232 | + XCTAssertTrue(options.array.isEmpty) |
| 233 | + } |
| 234 | + |
| 235 | + AssertParse(DeprecatedFlags.self, ["--one", "--two", "--three", "--four", "--three"]) { options in |
| 236 | + XCTAssertEqual(options.single, .one) |
| 237 | + XCTAssertEqual(options.optional, .two) |
| 238 | + XCTAssertEqual(options.array, [.three, .four, .three]) |
| 239 | + } |
| 240 | + } |
| 241 | +} |
| 242 | + |
0 commit comments