@@ -8,7 +8,7 @@ use clap::{Parser, ValueHint};
8
8
/// Supported formats: tar, zip, gz, xz/lzma, bz/bz2, lz4, sz, zst.
9
9
///
10
10
/// Repository: https://github.com/ouch-org/ouch
11
- #[ derive( Parser , Debug ) ]
11
+ #[ derive( Parser , Debug , PartialEq ) ]
12
12
#[ command( about, version) ]
13
13
// Disable rustdoc::bare_urls because rustdoc parses URLs differently than Clap
14
14
#[ allow( rustdoc:: bare_urls) ]
@@ -41,7 +41,7 @@ pub struct CliArgs {
41
41
#[ arg( short, long, global = true ) ]
42
42
pub format : Option < OsString > ,
43
43
44
- /// Ouch and claps subcommands
44
+ // Ouch and claps subcommands
45
45
#[ command( subcommand) ]
46
46
pub cmd : Subcommand ,
47
47
}
@@ -97,3 +97,155 @@ pub enum Subcommand {
97
97
tree : bool ,
98
98
} ,
99
99
}
100
+
101
+ #[ cfg( test) ]
102
+ mod tests {
103
+ use super :: * ;
104
+
105
+ fn args_splitter ( input : & str ) -> impl Iterator < Item = & str > {
106
+ input. split_whitespace ( )
107
+ }
108
+
109
+ fn to_paths ( iter : impl IntoIterator < Item = & ' static str > ) -> Vec < PathBuf > {
110
+ iter. into_iter ( ) . map ( PathBuf :: from) . collect ( )
111
+ }
112
+
113
+ macro_rules! test {
114
+ ( $args: expr, $expected: expr) => {
115
+ let result = match CliArgs :: try_parse_from( args_splitter( $args) ) {
116
+ Ok ( result) => result,
117
+ Err ( err) => panic!(
118
+ "CLI result is Err, expected Ok, input: '{}'.\n Result: '{err}'" ,
119
+ $args
120
+ ) ,
121
+ } ;
122
+ assert_eq!( result, $expected, "CLI result mismatched, input: '{}'." , $args) ;
123
+ } ;
124
+ }
125
+
126
+ fn mock_cli_args ( ) -> CliArgs {
127
+ CliArgs {
128
+ yes : false ,
129
+ no : false ,
130
+ accessible : false ,
131
+ hidden : false ,
132
+ quiet : false ,
133
+ gitignore : false ,
134
+ format : None ,
135
+ // This is usually replaced in assertion tests
136
+ cmd : Subcommand :: Decompress {
137
+ // Put a crazy value here so no test can assert it unintentionally
138
+ files : vec ! [ "\x00 \x11 \x22 " . into( ) ] ,
139
+ output_dir : None ,
140
+ } ,
141
+ }
142
+ }
143
+
144
+ #[ test]
145
+ fn test_clap_cli_ok ( ) {
146
+ test ! (
147
+ "ouch decompress file.tar.gz" ,
148
+ CliArgs {
149
+ cmd: Subcommand :: Decompress {
150
+ files: to_paths( [ "file.tar.gz" ] ) ,
151
+ output_dir: None ,
152
+ } ,
153
+ ..mock_cli_args( )
154
+ }
155
+ ) ;
156
+ test ! (
157
+ "ouch d file.tar.gz" ,
158
+ CliArgs {
159
+ cmd: Subcommand :: Decompress {
160
+ files: to_paths( [ "file.tar.gz" ] ) ,
161
+ output_dir: None ,
162
+ } ,
163
+ ..mock_cli_args( )
164
+ }
165
+ ) ;
166
+ test ! (
167
+ "ouch d a b c" ,
168
+ CliArgs {
169
+ cmd: Subcommand :: Decompress {
170
+ files: to_paths( [ "a" , "b" , "c" ] ) ,
171
+ output_dir: None ,
172
+ } ,
173
+ ..mock_cli_args( )
174
+ }
175
+ ) ;
176
+
177
+ test ! (
178
+ "ouch compress file file.tar.gz" ,
179
+ CliArgs {
180
+ cmd: Subcommand :: Compress {
181
+ files: to_paths( [ "file" ] ) ,
182
+ output: PathBuf :: from( "file.tar.gz" ) ,
183
+ level: None ,
184
+ fast: false ,
185
+ slow: false ,
186
+ } ,
187
+ ..mock_cli_args( )
188
+ }
189
+ ) ;
190
+ test ! (
191
+ "ouch compress a b c archive.tar.gz" ,
192
+ CliArgs {
193
+ cmd: Subcommand :: Compress {
194
+ files: to_paths( [ "a" , "b" , "c" ] ) ,
195
+ output: PathBuf :: from( "archive.tar.gz" ) ,
196
+ level: None ,
197
+ fast: false ,
198
+ slow: false ,
199
+ } ,
200
+ ..mock_cli_args( )
201
+ }
202
+ ) ;
203
+ test ! (
204
+ "ouch compress a b c archive.tar.gz" ,
205
+ CliArgs {
206
+ cmd: Subcommand :: Compress {
207
+ files: to_paths( [ "a" , "b" , "c" ] ) ,
208
+ output: PathBuf :: from( "archive.tar.gz" ) ,
209
+ level: None ,
210
+ fast: false ,
211
+ slow: false ,
212
+ } ,
213
+ ..mock_cli_args( )
214
+ }
215
+ ) ;
216
+
217
+ let inputs = [
218
+ "ouch compress a b c output --format tar.gz" ,
219
+ // https://github.com/clap-rs/clap/issues/5115
220
+ // "ouch compress a b c --format tar.gz output",
221
+ // "ouch compress a b --format tar.gz c output",
222
+ // "ouch compress a --format tar.gz b c output",
223
+ "ouch compress --format tar.gz a b c output" ,
224
+ "ouch --format tar.gz compress a b c output" ,
225
+ ] ;
226
+ for input in inputs {
227
+ test ! (
228
+ input,
229
+ CliArgs {
230
+ cmd: Subcommand :: Compress {
231
+ files: to_paths( [ "a" , "b" , "c" ] ) ,
232
+ output: PathBuf :: from( "output" ) ,
233
+ level: None ,
234
+ fast: false ,
235
+ slow: false ,
236
+ } ,
237
+ format: Some ( "tar.gz" . into( ) ) ,
238
+ ..mock_cli_args( )
239
+ }
240
+ ) ;
241
+ }
242
+ }
243
+
244
+ #[ test]
245
+ fn test_clap_cli_err ( ) {
246
+ assert ! ( CliArgs :: try_parse_from( args_splitter( "ouch c" ) ) . is_err( ) ) ;
247
+ assert ! ( CliArgs :: try_parse_from( args_splitter( "ouch c input" ) ) . is_err( ) ) ;
248
+ assert ! ( CliArgs :: try_parse_from( args_splitter( "ouch d" ) ) . is_err( ) ) ;
249
+ assert ! ( CliArgs :: try_parse_from( args_splitter( "ouch l" ) ) . is_err( ) ) ;
250
+ }
251
+ }
0 commit comments