@@ -69,3 +69,110 @@ extension DefaultSubcommandEndToEndTests {
69
69
XCTAssertThrowsError ( try Main . parseAsRoot ( [ " qux " ] ) )
70
70
}
71
71
}
72
+
73
+ extension DefaultSubcommandEndToEndTests {
74
+ fileprivate struct MyCommand : ParsableCommand {
75
+ static var configuration = CommandConfiguration (
76
+ subcommands: [ Plugin . self, NonDefault . self, Other . self] ,
77
+ defaultSubcommand: Plugin . self
78
+ )
79
+
80
+ @OptionGroup
81
+ var options : CommonOptions
82
+ }
83
+
84
+ fileprivate struct CommonOptions : ParsableArguments {
85
+ @Flag ( name: [ . customLong( " verbose " ) , . customShort( " v " ) ] ,
86
+ help: " Enable verbose aoutput. " )
87
+ var verbose = false
88
+ }
89
+
90
+ fileprivate struct Plugin : ParsableCommand {
91
+ @OptionGroup var options : CommonOptions
92
+ @Argument var pluginName : String
93
+
94
+ @Argument ( parsing: . unconditionalRemaining)
95
+ var pluginArguments : [ String ] = [ ]
96
+ }
97
+
98
+ fileprivate struct NonDefault : ParsableCommand {
99
+ @OptionGroup var options : CommonOptions
100
+ @Argument var pluginName : String
101
+
102
+ @Argument ( parsing: . unconditionalRemaining)
103
+ var pluginArguments : [ String ] = [ ]
104
+ }
105
+
106
+ fileprivate struct Other : ParsableCommand {
107
+ @OptionGroup var options : CommonOptions
108
+ }
109
+
110
+ func testRemainingDefaultImplicit( ) throws {
111
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " my-plugin " ] ) { plugin in
112
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
113
+ XCTAssertEqual ( plugin. pluginArguments, [ ] )
114
+ XCTAssertEqual ( plugin. options. verbose, false )
115
+ }
116
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " my-plugin " , " --verbose " ] ) { plugin in
117
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
118
+ XCTAssertEqual ( plugin. pluginArguments, [ " --verbose " ] )
119
+ XCTAssertEqual ( plugin. options. verbose, false )
120
+ }
121
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " --verbose " , " my-plugin " , " --verbose " ] ) { plugin in
122
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
123
+ XCTAssertEqual ( plugin. pluginArguments, [ " --verbose " ] )
124
+ XCTAssertEqual ( plugin. options. verbose, true )
125
+ }
126
+ }
127
+
128
+ func testRemainingDefaultExplicit( ) throws {
129
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " plugin " , " my-plugin " ] ) { plugin in
130
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
131
+ XCTAssertEqual ( plugin. pluginArguments, [ ] )
132
+ XCTAssertEqual ( plugin. options. verbose, false )
133
+ }
134
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " plugin " , " my-plugin " , " --verbose " ] ) { plugin in
135
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
136
+ XCTAssertEqual ( plugin. pluginArguments, [ " --verbose " ] )
137
+ XCTAssertEqual ( plugin. options. verbose, false )
138
+ }
139
+ AssertParseCommand ( MyCommand . self, Plugin . self, [ " --verbose " , " plugin " , " my-plugin " , " --verbose " ] ) { plugin in
140
+ XCTAssertEqual ( plugin. pluginName, " my-plugin " )
141
+ XCTAssertEqual ( plugin. pluginArguments, [ " --verbose " ] )
142
+ XCTAssertEqual ( plugin. options. verbose, true )
143
+ }
144
+ }
145
+
146
+ func testRemainingNonDefault( ) throws {
147
+ AssertParseCommand ( MyCommand . self, NonDefault . self, [ " non-default " , " my-plugin " ] ) { nondef in
148
+ XCTAssertEqual ( nondef. pluginName, " my-plugin " )
149
+ XCTAssertEqual ( nondef. pluginArguments, [ ] )
150
+ XCTAssertEqual ( nondef. options. verbose, false )
151
+ }
152
+ AssertParseCommand ( MyCommand . self, NonDefault . self, [ " non-default " , " my-plugin " , " --verbose " ] ) { nondef in
153
+ XCTAssertEqual ( nondef. pluginName, " my-plugin " )
154
+ XCTAssertEqual ( nondef. pluginArguments, [ " --verbose " ] )
155
+ XCTAssertEqual ( nondef. options. verbose, false )
156
+ }
157
+ AssertParseCommand ( MyCommand . self, NonDefault . self, [ " --verbose " , " non-default " , " my-plugin " , " --verbose " ] ) { nondef in
158
+ XCTAssertEqual ( nondef. pluginName, " my-plugin " )
159
+ XCTAssertEqual ( nondef. pluginArguments, [ " --verbose " ] )
160
+ XCTAssertEqual ( nondef. options. verbose, true )
161
+ }
162
+ }
163
+
164
+ func testRemainingDefaultOther( ) throws {
165
+ AssertParseCommand ( MyCommand . self, Other . self, [ " other " ] ) { other in
166
+ XCTAssertEqual ( other. options. verbose, false )
167
+ }
168
+ AssertParseCommand ( MyCommand . self, Other . self, [ " other " , " --verbose " ] ) { other in
169
+ XCTAssertEqual ( other. options. verbose, true )
170
+ }
171
+ }
172
+
173
+ func testRemainingDefaultFailure( ) {
174
+ XCTAssertThrowsError ( try MyCommand . parseAsRoot ( [ ] ) )
175
+ XCTAssertThrowsError ( try MyCommand . parseAsRoot ( [ " --verbose " ] ) )
176
+ XCTAssertThrowsError ( try MyCommand . parseAsRoot ( [ " plugin " , " --verbose " , " my-plugin " ] ) )
177
+ }
178
+ }
0 commit comments