1use clap::Parser;
2
3#[derive(Parser, Debug)]
5#[clap(author, version, about)]
6pub struct Args {
7 #[clap(short = 'd', long, default_value = ".")]
9 pub input: String,
10
11 #[clap(short, long, default_value = "output.md")]
13 pub output: String,
14
15 #[clap(short = 'f', long, value_delimiter = ',')]
17 pub filter: Vec<String>,
18
19 #[clap(short = 'i', long)]
21 pub ignore: Vec<String>,
22
23 #[clap(long)]
25 pub preview: bool,
26
27 #[clap(long)]
29 pub token_count: bool,
30
31 #[clap(long)]
33 pub line_numbers: bool,
34
35 #[clap(short = 'y', long)]
38 pub yes: bool,
39
40 #[clap(long, default_value_t = false)]
44 pub diff_only: bool,
45}
46
47#[cfg(test)]
48mod tests {
49 use super::Args;
50 use clap::Parser;
51
52 #[test]
53 fn parses_with_no_args() {
54 let res = Args::try_parse_from(["context-builder"]);
55 assert!(res.is_ok(), "Expected success when no args are provided");
56 }
57
58 #[test]
59
60 fn parses_all_flags_and_options() {
61 let args = Args::try_parse_from([
62 "context-builder",
63 "--input",
64 "some/dir",
65 "--output",
66 "ctx.md",
67 "--filter",
68 "rs",
69 "--filter",
70 "toml",
71 "--ignore",
72 "target",
73 "--ignore",
74 "node_modules",
75 "--preview",
76 "--token-count",
77 "--line-numbers",
78 "--diff-only",
79 ])
80 .expect("should parse");
81
82 assert_eq!(args.input, "some/dir");
83
84 assert_eq!(args.output, "ctx.md");
85
86 assert_eq!(args.filter, vec!["rs".to_string(), "toml".to_string()]);
87
88 assert_eq!(
89 args.ignore,
90 vec!["target".to_string(), "node_modules".to_string()]
91 );
92
93 assert!(args.preview);
94
95 assert!(args.token_count);
96
97 assert!(args.line_numbers);
98
99 assert!(args.diff_only);
100 }
101
102 #[test]
103 fn short_flags_parse_correctly() {
104 let args = Args::try_parse_from([
105 "context-builder",
106 "-d",
107 ".",
108 "-o",
109 "out.md",
110 "-f",
111 "md",
112 "-f",
113 "rs",
114 "-i",
115 "target",
116 "-i",
117 ".git",
118 ])
119 .expect("should parse");
120
121 assert_eq!(args.input, ".");
122 assert_eq!(args.output, "out.md");
123 assert_eq!(args.filter, vec!["md".to_string(), "rs".to_string()]);
124 assert_eq!(args.ignore, vec!["target".to_string(), ".git".to_string()]);
125 assert!(!args.preview);
126 assert!(!args.line_numbers);
127 }
128
129 #[test]
130
131 fn defaults_for_options_when_not_provided() {
132 let args = Args::try_parse_from(["context-builder", "-d", "proj"]).expect("should parse");
133
134 assert_eq!(args.input, "proj");
135
136 assert_eq!(args.output, "output.md");
137
138 assert!(args.filter.is_empty());
139
140 assert!(args.ignore.is_empty());
141
142 assert!(!args.preview);
143
144 assert!(!args.line_numbers);
145
146 assert!(!args.diff_only);
147 }
148
149 #[test]
150 fn parses_diff_only_flag() {
151 let args = Args::try_parse_from(["context-builder", "--diff-only"])
152 .expect("should parse diff-only flag");
153 assert!(args.diff_only);
154 }
155}