gitignore_template_generator/parser/
api.rs

1use std::ffi::OsString;
2
3use crate::ProgramExit;
4pub use crate::parser::impls::ClapArgsParser;
5
6/// Struct to gather cli args parsing result.
7///
8/// Used by [`crate::parser::ArgsParser`] implementations to store
9/// parsing result.
10#[derive(Debug, PartialEq, Default)]
11pub struct Args {
12    /// A non-empty list of gitignore template names.
13    ///
14    /// * Represented by the provided positional arguments, and required
15    ///     unless any of `author`, `version` or `help` options are given.
16    /// * This field does not allow commas in any of its field.
17    pub template_names: Vec<String>,
18
19    /// The gitignore template generator service url.
20    ///
21    /// * Optional value represented by the cli option
22    ///     [`crate::constant::cli_options::SERVER_URL`] that takes a string
23    ///     value, and falling back to
24    ///     [`crate::constant::template_manager::BASE_URL`] if not provided
25    ///     in cli args.
26    pub server_url: String,
27
28    /// The gitignore template generator service endpoint uri.
29    ///
30    /// * Optional value represented by the cli option
31    ///     [`crate::constant::cli_options::GENERATOR_URI`] that takes a string
32    ///     value, and falling back to
33    ///     [`crate::constant::template_manager::GENERATOR_URI`] if not provided in cli
34    ///     args.
35    pub generator_uri: String,
36
37    /// The gitignore template lister service endpoint uri.
38    ///
39    /// * Optional value represented by the cli option
40    ///     [`crate::constant::cli_options::LISTER_URI`] that takes a string
41    ///     value, and falling back to
42    ///     [`crate::constant::template_manager::LISTER_URI`] if not provided in cli
43    ///     args.
44    pub lister_uri: String,
45
46    /// The boolean indicator of whether to display help infos or not.
47    ///
48    /// * Optional value represented by the cli option
49    ///     [`crate::constant::cli_options::HELP`], and falling back to `false`
50    ///     if not provided in cli args.
51    /// * Has precedence over version and author options if multiple are given
52    pub show_help: bool,
53
54    /// The boolean indicator of whether to display version infos or not.
55    ///
56    /// * Optional value represented by the cli option
57    ///     [`crate::constant::cli_options::VERSION`], and falling back to
58    ///     `false` if not provided in cli args.
59    /// * Has precedence over author option if multiple are given
60    pub show_version: bool,
61
62    /// The boolean indicator of whether to display author infos or not.
63    ///
64    /// * Optional value represented by the cli option
65    ///     [`crate::constant::cli_options::AUTHOR`], and falling back to
66    ///     `false` if not provided in cli args.
67    pub show_author: bool,
68
69    /// The boolean indicator of whether to display list of available templates
70    /// or not.
71    ///
72    /// * Optional value represented by the cli option
73    ///     [`crate::constant::cli_options::LIST`], and falling back to
74    ///     `false` if not provided in cli args.
75    pub show_list: bool,
76
77    /// The boolean indicator of whether to enable robust template check or not.
78    ///
79    /// Robust template check allow the script to handle template existence
80    /// check without reaching the generator endpoint.
81    ///
82    /// * Optional value represented by the cli option
83    ///     [`crate::constant::cli_options::CHECK`], and falling back to
84    ///     `false` if not provided in cli args.
85    pub check_template_names: bool,
86}
87
88impl Args {
89    /// Sets new value for `template_names` field.
90    ///
91    /// It needs to be called on struct instance and effectively mutates it.
92    ///
93    /// # Arguments
94    ///
95    /// * `template_names` - The new value to be assigned to `template_names`
96    ///     field.
97    ///
98    /// # Returns
99    ///
100    /// The mutated borrowed instance.
101    pub fn with_template_names(mut self, template_names: Vec<String>) -> Self {
102        self.template_names = template_names;
103        self
104    }
105
106    /// Sets new value for `server_url` field.
107    ///
108    /// It needs to be called on struct instance and effectively mutates it.
109    ///
110    /// # Arguments
111    ///
112    /// * `server_url` - The new value to be assigned to `server_url`
113    ///     field.
114    ///
115    /// # Returns
116    ///
117    /// The mutated borrowed instance.
118    pub fn with_server_url(mut self, server_url: &str) -> Self {
119        self.server_url = server_url.to_string();
120        self
121    }
122
123    /// Sets new value for `generator_uri` field.
124    ///
125    /// It needs to be called on struct instance and effectively mutates it.
126    ///
127    /// # Arguments
128    ///
129    /// * `generator_uri` - The new value to be assigned to
130    ///     `generator_uri` field.
131    ///
132    /// # Returns
133    ///
134    /// The mutated borrowed instance.
135    pub fn with_generator_uri(mut self, generator_uri: &str) -> Self {
136        self.generator_uri = generator_uri.to_string();
137        self
138    }
139
140    /// Sets new value for `lister_uri` field.
141    ///
142    /// It needs to be called on struct instance and effectively mutates it.
143    ///
144    /// # Arguments
145    ///
146    /// * `lister_uri` - The new value to be assigned to `lister_uri` field.
147    ///
148    /// # Returns
149    ///
150    /// The mutated borrowed instance.
151    pub fn with_lister_uri(mut self, lister_uri: &str) -> Self {
152        self.lister_uri = lister_uri.to_string();
153        self
154    }
155
156    /// Sets new value for `show_list` field.
157    ///
158    /// It needs to be called on struct instance and effectively mutates it.
159    ///
160    /// # Arguments
161    ///
162    /// * `show_list` - The new value to be assigned to `show_list`
163    ///     field.
164    ///
165    /// # Returns
166    ///
167    /// The mutated borrowed instance.
168    pub fn with_show_list(mut self, show_list: bool) -> Self {
169        self.show_list = show_list;
170        self
171    }
172
173    /// Sets new value for `check_template_names` field.
174    ///
175    /// It needs to be called on struct instance and effectively mutates it.
176    ///
177    /// # Arguments
178    ///
179    /// * `check_template_names` - The new value to be assigned to
180    ///     `check_template_names` field.
181    ///
182    /// # Returns
183    ///
184    /// The mutated borrowed instance.
185    pub fn with_check_template_names(
186        mut self,
187        check_template_names: bool,
188    ) -> Self {
189        self.check_template_names = check_template_names;
190        self
191    }
192}
193
194/// Cli args parser trait to parse CLI args and return them in an [`Args`].
195///
196/// The produced Args instance needs to comply with constraints of each
197/// one of its fields (see fields doc in [`Args`] for more infos).
198pub trait ArgsParser {
199    /// Parses given cli args and return them as an [`Args`] instance.
200    ///
201    /// * First CLI args should be the binary name
202    /// * Rely on [`ArgsParser::try_parse`] method but additionally wrap
203    ///     error handling logic
204    ///
205    /// # Arguments
206    ///
207    /// * `args` - The CLI args to be parsed. Typically retrieved from
208    ///     [`std::env::args_os`].
209    ///
210    /// # Returns
211    ///
212    /// An owned instance of [`Args`] containing parsing result of given args.
213    fn parse(&self, args: impl IntoIterator<Item = OsString>) -> Args;
214
215    /// Parses given cli args and return them as an [`Args`] instance if no
216    /// error or early exit occurred.
217    ///
218    /// * First CLI args should be the binary name
219    /// * Version, author and help options are considered as early program
220    ///     exit
221    /// * Returned Args complies with expected constraints (see fields doc
222    ///     in [`Args`] for more infos)
223    ///
224    /// # Arguments
225    ///
226    ///  * `args` - The CLI args to be parsed. Typically retrieved from
227    ///     [`std::env::args_os`].
228    ///
229    /// # Returns
230    ///
231    /// A result containing an owned instance of [`Args`] if successful parsing,
232    /// or a [`ProgramExit`] if any error or early exit occurred (e.g. version/
233    /// author/help infos printing, invalid cli args...)
234    fn try_parse(
235        &self,
236        args: impl IntoIterator<Item = OsString>,
237    ) -> Result<Args, ProgramExit>;
238}
239
240#[cfg(test)]
241mod tests {
242    use rstest::*;
243
244    use super::*;
245    use crate::helper::*;
246
247    mod default_args_parser {
248        use super::*;
249
250        mod try_parse {
251            use super::*;
252
253            mod success {
254                use super::*;
255                use crate::{ExitKind, constant};
256
257                #[rstest]
258                #[case("-V")]
259                #[case("--version")]
260                #[case("-V rust")]
261                #[case("rust -V")]
262                #[case("rust -s foo -V")]
263                #[case("rust -g bar -V")]
264                #[case("rust -i bar -V")]
265                #[case("rust -c bar -V")]
266                #[case("-aV")]
267                #[case("rust -l -V")]
268                fn it_parses_version_cli_option(#[case] cli_args: &str) {
269                    let cli_args = parse_cli_args(cli_args);
270                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
271
272                    let actual_error = parsed_args.as_ref().err();
273                    let expected_error = ProgramExit {
274                        message: format!(
275                            "{} {}",
276                            env!("CARGO_PKG_NAME"),
277                            env!("CARGO_PKG_VERSION")
278                        ),
279                        exit_status: 0,
280                        styled_message: None,
281                        kind: ExitKind::VersionInfos,
282                    };
283                    let expected_error = Some(&expected_error);
284
285                    assert!(actual_error.is_some());
286                    assert_eq!(actual_error, expected_error);
287                }
288
289                #[rstest]
290                #[case("-h")]
291                #[case("--help")]
292                #[case("-h rust")]
293                #[case("rust -h")]
294                #[case("rust -s foo -h")]
295                #[case("rust -g bar -h")]
296                #[case("rust -i bar -h")]
297                #[case("rust -c bar -h")]
298                #[case("-aVh")]
299                #[case("rust -l -h")]
300                fn it_parses_help_cli_option(#[case] cli_args: &str) {
301                    let cli_args = parse_cli_args(cli_args);
302                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
303
304                    let actual_error = parsed_args.as_ref().err();
305                    let expected_error = ProgramExit {
306                        message: get_help_message(),
307                        exit_status: 0,
308                        styled_message: Some(get_ansi_help_message()),
309                        kind: ExitKind::HelpInfos,
310                    };
311                    let expected_error = Some(&expected_error);
312
313                    assert!(actual_error.is_some());
314                    assert_eq!(actual_error, expected_error);
315                }
316
317                #[rstest]
318                #[case("-a")]
319                #[case("--author")]
320                #[case("-a rust")]
321                #[case("rust -a")]
322                #[case("rust -s foo -a")]
323                #[case("rust -g bar -a")]
324                #[case("rust -i bar -a")]
325                #[case("rust -c bar -a")]
326                #[case("rust -l -a")]
327                fn it_parses_author_cli_option_preemptively(
328                    #[case] cli_args: &str,
329                ) {
330                    let cli_args = parse_cli_args(cli_args);
331                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
332
333                    let actual_error = parsed_args.as_ref().err();
334                    let expected_error = ProgramExit {
335                        message: env!("CARGO_PKG_AUTHORS").to_string(),
336                        exit_status: 0,
337                        styled_message: None,
338                        kind: ExitKind::AuthorInfos,
339                    };
340                    let expected_error = Some(&expected_error);
341
342                    assert!(actual_error.is_some());
343                    assert_eq!(actual_error, expected_error);
344                }
345
346                #[rstest]
347                #[case("rust")]
348                #[case("rust python node")]
349                fn it_parses_pos_args_without_server_url_cli_option(
350                    #[case] cli_options: &str,
351                ) {
352                    let cli_args = parse_cli_args(cli_options);
353                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
354
355                    let actual_result = parsed_args.as_ref().ok();
356                    let expected_result = Args::default()
357                        .with_template_names(make_string_vec(cli_options))
358                        .with_server_url(constant::template_manager::BASE_URL)
359                        .with_generator_uri(
360                            constant::template_manager::GENERATOR_URI,
361                        )
362                        .with_lister_uri(
363                            constant::template_manager::LISTER_URI,
364                        );
365                    let expected_result = Some(&expected_result);
366
367                    println!("{:?}", parsed_args);
368                    assert!(actual_result.is_some());
369                    assert_eq!(actual_result, expected_result);
370                }
371
372                #[rstest]
373                #[case("rust -s https://test.com")]
374                #[case("rust --server-url https://test.com")]
375                fn it_parses_pos_args_with_server_url_cli_option(
376                    #[case] cli_args: &str,
377                ) {
378                    let cli_args = parse_cli_args(cli_args);
379                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
380
381                    let actual_result = parsed_args.as_ref().ok();
382                    let expected_result = Args::default()
383                        .with_template_names(make_string_vec("rust"))
384                        .with_server_url("https://test.com")
385                        .with_generator_uri(
386                            constant::template_manager::GENERATOR_URI,
387                        )
388                        .with_lister_uri(
389                            constant::template_manager::LISTER_URI,
390                        );
391                    let expected_result = Some(&expected_result);
392
393                    assert!(actual_result.is_some());
394                    assert_eq!(actual_result, expected_result);
395                }
396
397                #[rstest]
398                #[case("rust -g /test/api")]
399                #[case("rust --generator-uri /test/api")]
400                fn it_parses_pos_args_with_generator_uri_cli_option(
401                    #[case] cli_args: &str,
402                ) {
403                    let cli_args = parse_cli_args(cli_args);
404                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
405
406                    let actual_result = parsed_args.as_ref().ok();
407                    let expected_result = Args::default()
408                        .with_template_names(make_string_vec("rust"))
409                        .with_server_url(constant::template_manager::BASE_URL)
410                        .with_generator_uri("/test/api")
411                        .with_lister_uri(
412                            constant::template_manager::LISTER_URI,
413                        );
414                    let expected_result = Some(&expected_result);
415
416                    assert!(actual_result.is_some());
417                    assert_eq!(actual_result, expected_result);
418                }
419
420                #[rstest]
421                #[case("rust -i /test/api")]
422                #[case("rust --lister-uri /test/api")]
423                fn it_parses_pos_args_with_lister_uri_cli_option(
424                    #[case] cli_args: &str,
425                ) {
426                    let cli_args = parse_cli_args(cli_args);
427                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
428
429                    let actual_result = parsed_args.as_ref().ok();
430                    let expected_result = Args::default()
431                        .with_template_names(make_string_vec("rust"))
432                        .with_server_url(constant::template_manager::BASE_URL)
433                        .with_generator_uri(
434                            constant::template_manager::GENERATOR_URI,
435                        )
436                        .with_lister_uri("/test/api");
437                    let expected_result = Some(&expected_result);
438
439                    assert!(actual_result.is_some());
440                    assert_eq!(actual_result, expected_result);
441                }
442
443                #[rstest]
444                #[case("-l", "")]
445                #[case("--list", "")]
446                #[case("rust --list", "rust")]
447                #[case("rust python --list", "rust python")]
448                fn it_parses_list_cli_option(
449                    #[case] cli_args: &str,
450                    #[case] template_names: &str,
451                ) {
452                    let cli_args = parse_cli_args(cli_args);
453                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
454
455                    let actual_result = parsed_args.as_ref().ok();
456                    let expected_result = Args::default()
457                        .with_template_names(make_string_vec(template_names))
458                        .with_server_url(constant::template_manager::BASE_URL)
459                        .with_generator_uri(
460                            constant::template_manager::GENERATOR_URI,
461                        )
462                        .with_show_list(true)
463                        .with_lister_uri(
464                            constant::template_manager::LISTER_URI,
465                        );
466                    let expected_result = Some(&expected_result);
467
468                    assert!(actual_result.is_some());
469                    assert_eq!(actual_result, expected_result);
470                }
471
472                #[rstest]
473                #[case("rust python -c")]
474                #[case("rust python --check")]
475                fn it_parses_check_option(#[case] cli_args: &str) {
476                    let cli_args = parse_cli_args(cli_args);
477                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
478
479                    let actual_result = parsed_args.as_ref().ok();
480                    let expected_result = Args::default()
481                        .with_template_names(make_string_vec("rust python"))
482                        .with_server_url(constant::template_manager::BASE_URL)
483                        .with_generator_uri(
484                            constant::template_manager::GENERATOR_URI,
485                        )
486                        .with_lister_uri(constant::template_manager::LISTER_URI)
487                        .with_check_template_names(true);
488                    let expected_result = Some(&expected_result);
489
490                    assert!(actual_result.is_some());
491                    assert_eq!(actual_result, expected_result);
492                }
493            }
494
495            mod failure {
496                use super::*;
497                use crate::{ExitKind, constant};
498
499                #[test]
500                fn it_fails_parsing_when_no_pos_args_given() {
501                    let cli_args = parse_cli_args("");
502                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
503
504                    let actual_error = parsed_args.as_ref().err();
505                    let expected_error = ProgramExit {
506                        message: load_expectation_file_as_string(
507                            "no_pos_args_error",
508                        ),
509                        exit_status: constant::exit_status::GENERIC,
510
511                        styled_message: Some(load_expectation_file_as_string(
512                            "ansi_no_pos_args_error",
513                        )),
514                        kind: ExitKind::Error,
515                    };
516                    let expected_error = Some(&expected_error);
517
518                    assert!(actual_error.is_some());
519                    assert_eq!(actual_error, expected_error);
520                }
521
522                #[test]
523                fn it_fails_parsing_when_commas_in_pos_args() {
524                    let cli_args = parse_cli_args("python,java");
525                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
526
527                    let actual_error = parsed_args.as_ref().err();
528                    let expected_error = ProgramExit {
529                        message: load_expectation_file_as_string(
530                            "comma_pos_args_error",
531                        ),
532                        exit_status: constant::exit_status::GENERIC,
533
534                        styled_message: Some(load_expectation_file_as_string(
535                            "ansi_comma_pos_args_error",
536                        )),
537                        kind: ExitKind::Error,
538                    };
539                    let expected_error = Some(&expected_error);
540
541                    assert!(actual_error.is_some());
542                    assert_eq!(actual_error, expected_error);
543                }
544
545                #[test]
546                fn it_fails_parsing_when_whitespaces_in_pos_args() {
547                    let cli_args = vec![
548                        OsString::from(env!("CARGO_PKG_NAME")),
549                        OsString::from("r "),
550                    ];
551                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
552
553                    let actual_error = parsed_args.as_ref().err();
554                    let expected_error = ProgramExit {
555                        message: load_expectation_file_as_string(
556                            "whitespace_pos_args_error",
557                        ),
558                        exit_status: constant::exit_status::GENERIC,
559
560                        styled_message: Some(load_expectation_file_as_string(
561                            "ansi_whitespace_pos_args_error",
562                        )),
563                        kind: ExitKind::Error,
564                    };
565                    let expected_error = Some(&expected_error);
566
567                    assert!(actual_error.is_some());
568                    assert_eq!(actual_error, expected_error);
569                }
570
571                #[test]
572                fn it_fails_parsing_when_commas_and_whitespaces_in_pos_args() {
573                    let cli_args = vec![
574                        OsString::from(env!("CARGO_PKG_NAME")),
575                        OsString::from("r ,"),
576                    ];
577                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
578
579                    let actual_error = parsed_args.as_ref().err();
580                    let expected_error = ProgramExit {
581                        message: load_expectation_file_as_string(
582                            "comma_whitespace_pos_args_error",
583                        ),
584                        exit_status: constant::exit_status::GENERIC,
585
586                        styled_message: Some(load_expectation_file_as_string(
587                            "ansi_comma_whitespace_pos_args_error",
588                        )),
589                        kind: ExitKind::Error,
590                    };
591                    let expected_error = Some(&expected_error);
592
593                    assert!(actual_error.is_some());
594                    assert_eq!(actual_error, expected_error);
595                }
596
597                #[test]
598                fn it_fails_parsing_when_server_url_but_no_pos_args() {
599                    let cli_args = parse_cli_args("-s https://test.com");
600                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
601
602                    let actual_error = parsed_args.as_ref().err();
603                    let expected_error = ProgramExit {
604                        message: load_expectation_file_as_string(
605                            "server_url_no_pos_args_error",
606                        ),
607                        exit_status: constant::exit_status::GENERIC,
608
609                        styled_message: Some(load_expectation_file_as_string(
610                            "ansi_server_url_no_pos_args_error",
611                        )),
612                        kind: ExitKind::Error,
613                    };
614                    let expected_error = Some(&expected_error);
615
616                    assert!(actual_error.is_some());
617                    assert_eq!(actual_error, expected_error);
618                }
619
620                #[test]
621                fn it_fails_parsing_when_generator_uri_but_no_pos_args() {
622                    let cli_args = parse_cli_args("-g /test/api");
623                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
624
625                    let actual_error = parsed_args.as_ref().err();
626                    let expected_error = ProgramExit {
627                        message: load_expectation_file_as_string(
628                            "generator_uri_no_pos_args_error",
629                        ),
630                        exit_status: constant::exit_status::GENERIC,
631
632                        styled_message: Some(load_expectation_file_as_string(
633                            "ansi_generator_uri_no_pos_args_error",
634                        )),
635                        kind: ExitKind::Error,
636                    };
637                    let expected_error = Some(&expected_error);
638
639                    assert!(actual_error.is_some());
640                    assert_eq!(actual_error, expected_error);
641                }
642
643                #[test]
644                fn it_fails_parsing_when_lister_uri_but_no_pos_args() {
645                    let cli_args = parse_cli_args("-i /test/api");
646                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
647
648                    let actual_error = parsed_args.as_ref().err();
649                    let expected_error = ProgramExit {
650                        message: load_expectation_file_as_string(
651                            "lister_uri_no_pos_args_error",
652                        ),
653                        exit_status: constant::exit_status::GENERIC,
654
655                        styled_message: Some(load_expectation_file_as_string(
656                            "ansi_lister_uri_no_pos_args_error",
657                        )),
658                        kind: ExitKind::Error,
659                    };
660                    let expected_error = Some(&expected_error);
661
662                    assert!(actual_error.is_some());
663                    assert_eq!(actual_error, expected_error);
664                }
665
666                #[test]
667                fn it_fails_parsing_when_check_option_but_no_pos_args() {
668                    let cli_args = parse_cli_args("--check");
669                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
670
671                    let actual_error = parsed_args.as_ref().err();
672                    let expected_error = ProgramExit {
673                        message: load_expectation_file_as_string(
674                            "check_option_no_pos_args_error",
675                        ),
676                        exit_status: constant::exit_status::GENERIC,
677
678                        styled_message: Some(load_expectation_file_as_string(
679                            "ansi_check_option_no_pos_args_error",
680                        )),
681                        kind: ExitKind::Error,
682                    };
683                    let expected_error = Some(&expected_error);
684
685                    assert!(actual_error.is_some());
686                    assert_eq!(actual_error, expected_error);
687                }
688
689                #[test]
690                fn it_fails_parsing_when_inexistent_cli_option() {
691                    let cli_args = parse_cli_args("-x");
692                    let parsed_args = ClapArgsParser::new().try_parse(cli_args);
693
694                    let actual_error = parsed_args.as_ref().err();
695                    let expected_error = ProgramExit {
696                        message: load_expectation_file_as_string(
697                            "unexpected_argument_error",
698                        ),
699                        exit_status: constant::exit_status::GENERIC,
700                        styled_message: Some(load_expectation_file_as_string(
701                            "ansi_unexpected_argument_error",
702                        )),
703                        kind: ExitKind::Error,
704                    };
705                    let expected_error = Some(&expected_error);
706
707                    assert!(actual_error.is_some());
708                    assert_eq!(actual_error, expected_error);
709                }
710            }
711        }
712
713        mod parse {
714            use super::*;
715
716            mod success {
717                use super::*;
718
719                #[test]
720                fn it_parses_given_cli_options() {
721                    let cli_args = parse_cli_args(
722                        "rust python -s test -g foo -i bar --check --list",
723                    );
724
725                    let actual_result = ClapArgsParser::new().parse(cli_args);
726                    let expected_result = Args::default()
727                        .with_template_names(make_string_vec("rust python"))
728                        .with_server_url("test")
729                        .with_generator_uri("foo")
730                        .with_lister_uri("bar")
731                        .with_check_template_names(true)
732                        .with_show_list(true);
733
734                    assert_eq!(actual_result, expected_result);
735                }
736            }
737        }
738    }
739}