1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use quote::{format_ident, quote};
use std::env;
use std::path::PathBuf;
use syn::{bracketed, punctuated::Punctuated, LitStr, Token};
#[proc_macro]
pub fn build_foreign_language_testcases(paths: proc_macro::TokenStream) -> proc_macro::TokenStream {
let paths = syn::parse_macro_input!(paths as FilePaths);
let pkg_dir = env::var("CARGO_MANIFEST_DIR")
.expect("Missing $CARGO_MANIFEST_DIR, cannot build tests for generated bindings");
let udl_file = &paths.udl_file;
let test_functions = paths.test_scripts
.iter()
.map(|file_path| {
let test_file_pathbuf: PathBuf = [&pkg_dir, &file_path].iter().collect();
let test_file_path = test_file_pathbuf.to_string_lossy();
let test_file_name = test_file_pathbuf
.file_name()
.expect("Test file has no name, cannot build tests for generated bindings")
.to_string_lossy();
let test_name = format_ident!(
"uniffi_foreign_language_testcase_{}",
test_file_name.replace(|c: char| !c.is_alphanumeric(), "_")
);
quote! {
#[test]
fn #test_name () -> uniffi::deps::anyhow::Result<()> {
uniffi::testing::run_foreign_language_testcase(#pkg_dir, #udl_file, #test_file_path)
}
}
})
.collect::<Vec<proc_macro2::TokenStream>>();
let test_module = quote! {
#(#test_functions)*
};
proc_macro::TokenStream::from(test_module)
}
#[derive(Debug)]
struct FilePaths {
udl_file: String,
test_scripts: Vec<String>,
}
impl syn::parse::Parse for FilePaths {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let udl_file: LitStr = input.parse()?;
let _comma: Token![,] = input.parse()?;
let array_contents;
bracketed!(array_contents in input);
let test_scripts = Punctuated::<LitStr, Token![,]>::parse_terminated(&array_contents)?
.iter()
.map(|s| s.value())
.collect();
Ok(FilePaths {
udl_file: udl_file.value(),
test_scripts,
})
}
}