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