1 use super::*;
2 use crate::expansion::test::DummyExpander;
3
compare(input: &str, expected: &[WordToken<'_>])4 fn compare(input: &str, expected: &[WordToken<'_>]) {
5 let mut correct = 0;
6 for (actual, expected) in WordIterator::new(input, true).zip(expected.iter()) {
7 assert_eq!(actual, *expected, "{:?} != {:?}", actual, expected);
8 correct += 1;
9 }
10 assert_eq!(expected.len(), correct);
11 }
12
13 #[test]
string_method()14 fn string_method() {
15 let input = "$join(array 'pattern') $join(array 'pattern')";
16 let expected = &[
17 WordToken::StringMethod(StringMethod {
18 method: "join",
19 variable: "array",
20 pattern: "'pattern'",
21 selection: None,
22 }),
23 WordToken::Whitespace(" "),
24 WordToken::StringMethod(StringMethod {
25 method: "join",
26 variable: "array",
27 pattern: "'pattern'",
28 selection: None,
29 }),
30 ];
31 compare(input, expected);
32 }
33
34 #[test]
escape_with_backslash()35 fn escape_with_backslash() {
36 let input = r#"\$FOO\$BAR \$FOO"#;
37 let expected = &[
38 WordToken::Normal("$FOO$BAR".into(), false, false),
39 WordToken::Whitespace(" "),
40 WordToken::Normal("$FOO".into(), false, false),
41 ];
42 compare(input, expected);
43 }
44
45 #[test]
array_expressions()46 fn array_expressions() {
47 let input = "[ one two [three four]] [[one two] three four][0]";
48 let first = vec!["one", "two", "[three four]"];
49 let second = vec!["[one two]", "three", "four"];
50 let expected = &[
51 WordToken::Array(first, None),
52 WordToken::Whitespace(" "),
53 WordToken::Array(second, Some("0")),
54 ];
55 compare(input, expected);
56 }
57
58 #[test]
array_variables()59 fn array_variables() {
60 let input = "@array @array[0] @{array[1..]}";
61 let expected = &[
62 WordToken::ArrayVariable("array", false, None),
63 WordToken::Whitespace(" "),
64 WordToken::ArrayVariable("array", false, Some("0")),
65 WordToken::Whitespace(" "),
66 WordToken::ArrayVariable("array", false, Some("1..")),
67 ];
68 compare(input, expected);
69 }
70
71 #[test]
array_processes()72 fn array_processes() {
73 let input = "@(echo one two three) @(echo one two three)[0]";
74 let expected = &[
75 WordToken::ArrayProcess("echo one two three", false, None),
76 WordToken::Whitespace(" "),
77 WordToken::ArrayProcess("echo one two three", false, Some("0")),
78 ];
79 compare(input, expected);
80 }
81
82 #[test]
array_process_within_string_process()83 fn array_process_within_string_process() {
84 compare(
85 "echo $(let free=[@(free -h)]; echo @free[6]@free[8]/@free[7])",
86 &[
87 WordToken::Normal("echo".into(), false, false),
88 WordToken::Whitespace(" "),
89 WordToken::Process("let free=[@(free -h)]; echo @free[6]@free[8]/@free[7]", None),
90 ],
91 )
92 }
93
94 #[test]
indexes()95 fn indexes() {
96 let input = "@array[0..3] @array[0...3] @array[abc] @array[..3] @array[3..]";
97 let expected = &[
98 WordToken::ArrayVariable("array", false, Some("0..3")),
99 WordToken::Whitespace(" "),
100 WordToken::ArrayVariable("array", false, Some("0...3")),
101 WordToken::Whitespace(" "),
102 WordToken::ArrayVariable("array", false, Some("abc")),
103 WordToken::Whitespace(" "),
104 WordToken::ArrayVariable("array", false, Some("..3")),
105 WordToken::Whitespace(" "),
106 WordToken::ArrayVariable("array", false, Some("3..")),
107 ];
108 compare(input, expected);
109 }
110
111 #[test]
string_keys()112 fn string_keys() {
113 let input = "@array['key'] @array[key] @array[]";
114 let expected = &[
115 WordToken::ArrayVariable("array", false, Some("'key'")),
116 WordToken::Whitespace(" "),
117 WordToken::ArrayVariable("array", false, Some("key")),
118 WordToken::Whitespace(" "),
119 WordToken::ArrayVariable("array", false, Some("")),
120 ];
121 compare(input, expected);
122 }
123
124 #[test]
nested_processes()125 fn nested_processes() {
126 let input = "echo $(echo $(echo one)) $(echo one $(echo two) three)";
127 let expected = &[
128 WordToken::Normal("echo".into(), false, false),
129 WordToken::Whitespace(" "),
130 WordToken::Process("echo $(echo one)", None),
131 WordToken::Whitespace(" "),
132 WordToken::Process("echo one $(echo two) three", None),
133 ];
134 compare(input, expected);
135 }
136
137 #[test]
words_process_with_quotes()138 fn words_process_with_quotes() {
139 let input = "echo $(git branch | rg '[*]' | awk '{print $2}')";
140 let expected = &[
141 WordToken::Normal("echo".into(), false, false),
142 WordToken::Whitespace(" "),
143 WordToken::Process("git branch | rg '[*]' | awk '{print $2}'", None),
144 ];
145 compare(input, expected);
146
147 let input = "echo $(git branch | rg \"[*]\" | awk '{print $2}')";
148 let expected = &[
149 WordToken::Normal("echo".into(), false, false),
150 WordToken::Whitespace(" "),
151 WordToken::Process("git branch | rg \"[*]\" | awk '{print $2}'", None),
152 ];
153 compare(input, expected);
154 }
155
156 #[test]
test_words()157 fn test_words() {
158 let input = "echo $ABC \"${ABC}\" one{$ABC,$ABC} ~ $(echo foo) \"$(seq 1 100)\"";
159 let expected = &[
160 WordToken::Normal("echo".into(), false, false),
161 WordToken::Whitespace(" "),
162 WordToken::Variable("ABC", None),
163 WordToken::Whitespace(" "),
164 WordToken::Variable("ABC", None),
165 WordToken::Whitespace(" "),
166 WordToken::Normal("one".into(), false, false),
167 WordToken::Brace(vec!["$ABC", "$ABC"]),
168 WordToken::Whitespace(" "),
169 WordToken::Normal("~".into(), false, true),
170 WordToken::Whitespace(" "),
171 WordToken::Process("echo foo", None),
172 WordToken::Whitespace(" "),
173 WordToken::Process("seq 1 100", None),
174 ];
175 compare(input, expected);
176 }
177
178 #[test]
test_multiple_escapes()179 fn test_multiple_escapes() {
180 let input = "foo\\(\\) bar\\(\\)";
181 let expected = &[
182 WordToken::Normal("foo()".into(), false, false),
183 WordToken::Whitespace(" "),
184 WordToken::Normal("bar()".into(), false, false),
185 ];
186 compare(input, expected);
187 }
188
189 #[test]
test_arithmetic()190 fn test_arithmetic() {
191 let input = "echo $((foo bar baz bing 3 * 2))";
192 let expected = &[
193 WordToken::Normal("echo".into(), false, false),
194 WordToken::Whitespace(" "),
195 WordToken::Arithmetic("foo bar baz bing 3 * 2"),
196 ];
197 compare(input, expected);
198 }
199
200 #[test]
test_globbing()201 fn test_globbing() {
202 let input = "barbaz* bingcrosb*";
203 let expected = &[
204 WordToken::Normal("barbaz*".into(), true, false),
205 WordToken::Whitespace(" "),
206 WordToken::Normal("bingcrosb*".into(), true, false),
207 ];
208 compare(input, expected);
209 }
210
211 #[test]
test_empty_strings()212 fn test_empty_strings() {
213 let input = "rename '' 0 a \"\"";
214 let expected = &[
215 WordToken::Normal("rename".into(), false, false),
216 WordToken::Whitespace(" "),
217 WordToken::Normal("".into(), false, false),
218 WordToken::Whitespace(" "),
219 WordToken::Normal("0".into(), false, false),
220 WordToken::Whitespace(" "),
221 WordToken::Normal("a".into(), false, false),
222 WordToken::Whitespace(" "),
223 WordToken::Normal("".into(), false, false),
224 ];
225 compare(input, expected);
226 }
227
228 #[test]
test_braces()229 fn test_braces() {
230 let input = "echo {c[a,b],d}";
231 let expected = &[
232 WordToken::Normal("echo".into(), false, false),
233 WordToken::Whitespace(" "),
234 WordToken::Brace(vec!["c[a,b]", "d"]),
235 ];
236 compare(input, expected);
237 }
238
239 #[test]
array_methods()240 fn array_methods() {
241 let method = ArrayMethod::new("graphemes", "pkmn1", Pattern::Whitespace, Some("3"));
242 let expected = args!["é"];
243 assert_eq!(method.handle_as_array(&mut DummyExpander).unwrap(), expected);
244 let method = ArrayMethod::new("chars", "pkmn2", Pattern::Whitespace, Some("3"));
245 let expected = args!["e"];
246 assert_eq!(method.handle_as_array(&mut DummyExpander).unwrap(), expected);
247 let method = ArrayMethod::new("bytes", "pkmn2", Pattern::Whitespace, Some("1"));
248 let expected = args!["111"];
249 assert_eq!(method.handle_as_array(&mut DummyExpander).unwrap(), expected);
250 }
251