• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[cfg(test)]
2 mod tests {
3 
4     use std::io::Read;
5 
6     use crate::parser::*;
7     use nom::error::VerboseError;
8     use nom::Err;
9 
10     #[test]
test_parse_array()11     fn test_parse_array() {
12         // Test case 1: Valid input
13         let input = r#"[ "value1", "value2", "value3" ]"#;
14         let expected_output = Ok(("", vec!["value1".into(), "value2".into(), "value3".into()]));
15         assert_eq!(parse_array(input), expected_output);
16 
17         // Test case 2: Empty array
18         let input = r#"[]"#;
19         let expected_output = Ok(("", vec![]));
20         assert_eq!(parse_array(input), expected_output);
21 
22         // Test case 3: Array with whitespace
23         let input = r#"[ "value1" , "value2" , "value3" ]"#;
24         let expected_output = Ok(("", vec!["value1".into(), "value2".into(), "value3".into()]));
25         assert_eq!(parse_array(input), expected_output);
26 
27         // Test case 4: Array with empty values
28         let input = r#"[ "", "", "" ]"#;
29         let expected_output = Ok(("", vec!["".into(), "".into(), "".into()]));
30         assert_eq!(parse_array(input), expected_output);
31 
32         // Test case 5: Invalid input - missing closing bracket
33         let input = r#"[ "value1", "value2", "value3""#;
34         assert!(parse_array(input).is_err());
35 
36         // Test case 5: Invalid input - missing opening bracket
37         let input = r#""value1", "value2", "value3" ]"#;
38         assert!(parse_array(input).is_err());
39 
40         // Test case 6: Array with trailing comma is not an error
41         let input = r#"[ "value1", "value2", "value3", ]"#;
42         let expected_output = Ok(("", vec!["value1".into(), "value2".into(), "value3".into()]));
43         assert_eq!(parse_array(input), expected_output);
44     }
45     #[test]
test_parse_entry()46     fn test_parse_entry() {
47         // Test case 1: Valid input
48         let input = r#"key: "value""#;
49         let expected_output = Ok(("", ("key".to_string(), Value::String("value".to_string()))));
50         assert_eq!(parse_module_entry(input), expected_output);
51 
52         // Test case 2: Valid input with whitespace
53         let input = r#"  key  :   "value"  "#;
54         let expected_output = Ok(("", ("key".to_string(), Value::String("value".to_string()))));
55         assert_eq!(parse_module_entry(input), expected_output);
56 
57         // Test case 3: Valid input with array value
58         let input = r#"key: [ "value1", "value2", "value3" ]"#;
59         let expected_output = Ok((
60             "",
61             (
62                 "key".to_string(),
63                 Value::Array(vec!["value1".into(), "value2".into(), "value3".into()]),
64             ),
65         ));
66         assert_eq!(parse_module_entry(input), expected_output);
67 
68         // Test case 4: Invalid input - missing colon
69         let input = r#"key "value""#;
70         assert!(parse_module_entry(input).is_err());
71 
72         // Test case 5: Invalid input - missing value
73         let input = r#"key:"#;
74         assert!(parse_module_entry(input).is_err());
75 
76         // Test case 6: Invalid input - missing key
77         let input = r#":"value""#;
78         assert!(parse_module_entry(input).is_err());
79 
80         // Test case 7: Invalid input - missing key and value
81         let input = r#":"#;
82         assert!(parse_module_entry(input).is_err());
83     }
84     #[test]
test_parse_module()85     fn test_parse_module() {
86         let input = r#"
87             module_name {
88                 key1: "value1",
89                 key2: true,
90                 key3: [ "value2", "value3" ],
91             }
92         "#;
93 
94         let expected_output = Module {
95             typ: "module_name".to_string(),
96             entries: vec![
97                 ("key1".to_string(), Value::String("value1".to_string())),
98                 ("key2".to_string(), Value::Boolean(true)),
99                 (
100                     "key3".to_string(),
101                     Value::Array(vec!["value2".into(), "value3".into()]),
102                 ),
103             ]
104             .into_iter()
105             .collect(),
106         };
107 
108         assert_eq!(parse_module(input), Ok(("", expected_output)));
109     }
110     #[test]
test_parse_blueprint()111     fn test_parse_blueprint() {
112         let input = r#"
113             module_name {
114                 key1: "value1",
115                 key2: true,
116                 key3: [ "value2", "value3" ],
117             }
118             module_name2 {
119                 key1: "value1",
120                 key2: true,
121                 key3: [ "value2", "value3" ],
122             }"#;
123         let output = BluePrint::parse(input).unwrap();
124         assert_eq!(output.modules.len(), 2);
125         assert_eq!(output.modules[0].typ, "module_name");
126         assert_eq!(output.modules[1].typ, "module_name2");
127         let mut keys = output.modules[0]
128             .entries
129             .keys()
130             .map(|x| x.to_owned())
131             .collect::<Vec<_>>();
132         keys.sort();
133         assert_eq!(
134             keys,
135             vec!["key1".to_string(), "key2".to_string(), "key3".to_string()]
136         );
137     }
138     #[test]
test_nested_dict()139     fn test_nested_dict() {
140         let input = r#"
141         rust_test_host {
142             name: "ss",
143             srcs: ["src/ss.rs"],
144             test_options: {
145                 unit_test: true,
146             },
147         }        "#;
148         let output: Result<(&str, Module), Err<VerboseError<&str>>> = parse_module(input);
149         assert!(output.is_ok());
150     }
151 
152     #[test]
test_comment()153     fn test_comment() {
154         let input = r#"
155         rust_test_host {
156         //     name: "ss",
157         //
158         srcs: ["src/ss.rs"],
159         test_options: {
160             unit_test: true,
161         },
162         }        "#;
163         let output = parse_module(input);
164         display_error(input, &output);
165         assert!(output.is_ok());
166     }
167     #[test]
test_all_comment()168     fn test_all_comment() {
169         let input = r#"/*
170         rust_test_host {
171         //     name: "ss",
172         //
173         srcs: ["src/ss.rs"],
174         test_options: {
175             unit_test: true,
176         },
177         }
178         */"#;
179         let output = BluePrint::parse(input);
180         if output.is_err() {
181             println!("Error: {}", output.unwrap_err());
182             panic!("Error in parsing");
183         }
184     }
185 
186     #[test]
test_issue_1()187     fn test_issue_1() {
188         let input = r#"
189         aidl_interface {
190             name: "android.hardware.tetheroffload",
191             vendor_available: true,
192             srcs: ["android/hardware/tetheroffload/*.aidl"],
193             stability: "vintf",
194             backend: {
195                 cpp: {
196                     enabled: false,
197                 },
198                 java: {
199                     sdk_version: "module_current",
200                     apex_available: [
201                         "com.android.tethering",
202                     ],
203                     min_sdk_version: "30",
204                     enabled: true,
205                 },
206                 ndk: {
207                     apps_enabled: false,
208                 },
209             },
210             versions_with_info: [
211                 {
212                     version: "1",
213                     imports: [],
214                 },
215             ],
216             frozen: true,
217 
218         }
219         "#;
220         let output = parse_module(input);
221         display_error(input, &output);
222         assert!(output.is_ok());
223     }
224     #[test]
test_issue_2()225     fn test_issue_2() {
226         let input = r#"
227         aidl_interface {
228             name: "android.hardw\"are.tetheroffload",
229         }
230         "#;
231         let output = parse_module(input);
232         display_error(input, &output);
233         assert!(output.is_ok());
234     }
235     #[test]
test_module_second_form()236     fn test_module_second_form() {
237         let input = r#"
238         aidl_interface(name = "android.hardware.tetheroffload")
239         "#;
240         let output = parse_module(input);
241         display_error(input, &output);
242         assert!(output.is_ok());
243     }
display_error<T>(input: &str, output: &Result<(&str, T), Err<VerboseError<&str>>>) -> ()244     fn display_error<T>(input: &str, output: &Result<(&str, T), Err<VerboseError<&str>>>) -> () {
245         if let Err(e) = output {
246             println!("Error: {}", format_err(input, e.clone()));
247         }
248     }
249     #[test]
test_expr()250     fn test_expr() {
251         let input = r#""abc" + "def""#;
252         let output = parse_expr(input);
253         display_error(input, &output);
254         assert!(output.is_ok());
255         assert!(output.as_ref().unwrap().0.is_empty());
256         assert!(output.unwrap().1 == Value::String("abcdef".to_string()));
257     }
258     #[test]
test_expr_array()259     fn test_expr_array() {
260         let input = r#"["abc", "def"] + [ "ghi" ]"#;
261         let output = parse_expr(input);
262         display_error(input, &output);
263         assert!(output.is_ok());
264         assert!(output.as_ref().unwrap().0.is_empty());
265         assert!(output.unwrap().1 == Value::Array(vec!["abc".into(), "def".into(), "ghi".into()]));
266     }
267     #[test]
test_expr_ident()268     fn test_expr_ident() {
269         let input = r#"ident + [ "ghi" ]"#;
270         let output = parse_expr(input);
271         display_error(input, &output);
272         assert!(output.is_ok());
273         assert!(output.as_ref().unwrap().0.is_empty());
274         assert!(
275             output.unwrap().1
276                 == Value::ConcatExpr([
277                     Value::Ident("ident".to_string()),
278                     Value::Array(["ghi".into()].into())
279                 ].into())
280         );
281     }
282     #[test]
test_expr_value()283     fn test_expr_value() {
284         let input = r#"123"#;
285         let output = parse_expr(input);
286         display_error(input, &output);
287         assert!(output.is_ok());
288         assert!(output.as_ref().unwrap().0.is_empty());
289         assert!(
290             output.unwrap().1
291                 == Value::Integer(123));
292     }
293     // found in platform_testing/tests/health/scenarios/tests/Android.bp
294     #[test]
test_complicated_concat()295     fn test_complicated_concat() {
296         let input = r#""out_dir=$$(dirname $(out)) && assets_dir=\"assets\" " +
297         "&& mkdir -p $$out_dir/$$assets_dir && src_protos=($(locations assets/*.textpb)) " +
298         "&& for file in $${src_protos[@]} ; do fname=$$(basename $$file) " +
299         "&& if ! ($(location aprotoc) --encode=longevity.profile.Configuration " +
300         "$(location :profile-proto-def) < $$file > " +
301         "$$out_dir/$$assets_dir/$${fname//.textpb/.pb}) ; then " +
302         "echo \"\x1b[0;31mFailed to parse profile $$file. See above for errors.\x1b[0m\" " +
303         "&& exit 1 ; fi ; done && jar cf $(out) -C $$(dirname $(out)) $$assets_dir""#;
304         let output = parse_expr(input);
305         display_error(input, &output);
306         assert!(output.is_ok());
307         assert!(output.as_ref().unwrap().0.is_empty());
308 
309     }
310     #[test]
test_linecomment_wo_eol()311     fn test_linecomment_wo_eol() {
312         let input = r#"// foo"#;
313         let output = BluePrint::parse(input);
314         assert!(output.is_ok());
315 
316     }
317     #[test]
test_defines_extends()318     fn test_defines_extends(){
319         let input = r#"
320         var = ["a", "b"]
321         var2 = 12
322         var += ["c"]
323         var2 += 1
324         var3 = "abc"
325         var3 += "def"
326         "#;
327         let output = BluePrint::parse(input);
328         assert!(output.is_ok());
329         let bp = output.unwrap();
330         assert_eq!(bp.variables.get("var").unwrap(), &Value::Array(vec!["a".into(), "b".into(), "c".into()]));
331         assert_eq!(bp.variables.get("var2").unwrap(), &Value::Integer(13));
332         assert_eq!(bp.variables.get("var3").unwrap(), &Value::String("abcdef".to_string()));
333     }
334 
335     #[test]
test_defines_extends_error()336     fn test_defines_extends_error(){
337         let input = r#"
338         var = ["a", "b"]
339         var2 = 12
340         var += 1
341         var2 += "a"
342         "#;
343         let output = BluePrint::parse(input);
344         println!("Error: {}", output.unwrap_err());
345         // assert!(output.is_err());
346     }
347     #[test]
test_function()348     fn test_function() {
349         let input = r#"method("ss")"#;
350         let output = parse_expr(input);
351         display_error(input, &output);
352         assert!(output.is_ok());
353         assert_eq!(output.unwrap().1, Value::Function(Function {
354             name: "method".to_string(),
355             args: vec![Value::String("ss".to_string())]
356         }));
357 
358     }
359     #[test]
test_aosp_db()360     fn test_aosp_db() {
361         // generate tarball from aosp tree
362         // fd -g Android.bp | tar cJf ../rs-bp/src/test_db.tar.xz -T -
363         let data = include_bytes!("test_db.tar.xz");
364         let mut archive = tar::Archive::new(liblzma::read::XzDecoder::new(&data[..]));
365         let mut count = 0;
366         let mut bytes = 0;
367         let mut num_errors = 0;
368         let mut all_bp = Vec::new();
369         // first decompress in memory to avoid disk IO for measuring performance
370         for entry in archive.entries().unwrap() {
371             let entry = entry.unwrap();
372             let mut entry_data = std::io::BufReader::new(entry);
373             let mut contents = String::new();
374             entry_data.read_to_string(&mut contents).unwrap();
375             bytes += contents.len();
376             all_bp.push((format!("{:?}", entry_data.into_inner().path().unwrap()), contents));
377         }
378         let now = std::time::Instant::now();
379         for (path, contents) in all_bp {
380             let output = BluePrint::parse(&contents);
381             if output.is_err() {
382                 println!("Error for file: {:?}", path);
383                 println!("File content: {}", contents);
384                 println!("Error: {}", output.unwrap_err());
385                 num_errors += 1;
386             }
387             count += 1;
388         }
389         let elapsed = now.elapsed().as_secs_f32();
390         println!("{} files ({} bytes) parsed in {:.3}s {}MB/s", count, bytes, elapsed, bytes as f32 / elapsed / 1024.0 / 1024.0);
391         assert_eq!(num_errors, 0);
392     }
393 }
394