iocore_test/
lib.rs

1//! iocore_test is a testing tool for crates that utilize the
2//! [`iocore`] crate.
3
4/// `seq_bytes` returns a [`Vec<u8>`] containing a sequence of [`u8`]
5/// bytes and applying the remainder operation if `count` is longer
6/// than `u8::MAX`
7pub fn seq_bytes(count: usize) -> Vec<u8> {
8    (0..count)
9        .map(|n| {
10            TryInto::<u8>::try_into(if n > u8::MAX.into() {
11                n % <u8 as Into<usize>>::into(u8::MAX)
12            } else {
13                n
14            })
15            .unwrap()
16        })
17        .collect()
18}
19
20#[macro_export]
21macro_rules! current_source_file {
22    () => {{
23        let mut parts = std::collections::VecDeque::<String>::new();
24        for part in file!().split(std::path::MAIN_SEPARATOR_STR) {
25            parts.push_back(part.to_string());
26        };
27
28        let mut path = std::path::absolute(std::path::Path::new(".")).unwrap();
29        while parts.len() > 0 {
30            let mut test_path = path.clone();
31            for part in &parts {
32                test_path.push(part.to_string().as_str());
33            }
34            if test_path.exists() {
35                path = test_path.clone();
36                break;
37            } else {
38                parts.pop_front();
39            }
40        };
41
42        format!("{}", path.display())
43    }};
44    // () => {{
45    //     let parts = module_path!().to_string().split("::").map(String::from).collect::<Vec<String>>();
46    //     let mut path = std::path::absolute(std::path::Path::new(".")).unwrap();
47    //     for part in parts {
48    //         let file = format!("{}.rs",part);
49    //         if path.join(&file).exists() {
50    //             path.push(&file);
51    //             path = path.canonicalize().unwrap();
52    //         } else if path.join(&part).exists() {
53    //             path.push(&part);
54    //             path = path.canonicalize().unwrap();
55    //         } else {
56    //             break
57    //         }
58    //     }
59    //     format!("{}", path.display())
60    // }};
61}
62
63/// `path_to_test_file` returns the path to an empty file within the same dir as the calling test file, creates parent directories if necessary and deletes the file if exists
64#[macro_export]
65macro_rules! path_to_test_file {
66    ($name:expr) => {{
67        let path = $crate::folder_path!("__test_files__").join($crate::test_name!()).join($name);
68        path.parent().unwrap().mkdir().map(|_| ()).unwrap_or_default();
69        path.delete().map(|_| ()).unwrap_or_default();
70        path
71    }};
72}
73
74/// `folder_path` returns the path to the parent folder of the calling test file, if called with an argument then calls [`iocore::Path::join`] on the folder path (creates folder if necessary)
75#[macro_export]
76macro_rules! folder_path {
77    () => {{
78        let path = iocore::Path::raw($crate::current_source_file!()).relative_to_cwd()
79            .parent()
80            .expect(&format!("{:#?} has no parent folder!!", $crate::current_source_file!()));
81        path
82    }};
83    ($name:expr) => {{
84        let path = $crate::folder_path!();
85        let path = path.join($name);
86        path.mkdir_unchecked();
87        path
88    }};
89}
90/// `directory_path` returns the path to the parent directory of the calling test file, if called with an argument then calls [`iocore::Path::join`] on the directory path (creates directory if necessary)
91#[macro_export]
92macro_rules! directory_path {
93    () => {{
94        $crate::folder_path!()
95    }};
96    ($name:expr) => {
97        $crate::folder_path!($name)
98    };
99}
100
101/// `test_folder_parent_path` returns the parent folder of the test file which calls it joined with the given "name" (creates the directory if necessary)
102#[macro_export]
103macro_rules! test_folder_parent_path {
104    ($name:expr) => {{
105        let path = iocore::Path::raw($crate::current_source_file!()).relative_to_cwd()
106            .parent()
107            .expect(&format!("parent directory of {:#?}", $crate::current_source_file!()));
108        let path = path.join($name);
109        path.mkdir_unchecked();
110        path
111    }};
112}
113/// `test_directory_parent_path` returns the parent directory of the test file which calls it joined with the given "name" (creates the directory if necessary)
114#[macro_export]
115macro_rules! test_directory_parent_path {
116    ($name:expr) => {{
117        $crate::test_folder_parent_path($name)
118    }};
119}
120/// `test_name` returns the name of the test function
121#[macro_export]
122macro_rules! test_name {
123    () => {{
124        fn f() {}
125        fn type_name_of<T>(_: T) -> &'static str {
126            std::any::type_name::<T>()
127        }
128        let name = type_name_of(f);
129        let name = name.strip_suffix("::f").unwrap().replace("::", std::path::MAIN_SEPARATOR_STR);
130        name
131    }};
132}
133
134/// `path_to_test_file` returns the path to a test directory as the test file
135#[macro_export]
136macro_rules! path_to_test_folder {
137    () => {{
138        let path = $crate::folder_path!("__test_files__").join($crate::test_name!());
139        path.mkdir_unchecked();
140        path
141    }};
142    ($name:expr) => {{
143        let path = $crate::path_to_test_folder!().join($name);
144        path.mkdir_unchecked();
145        path
146    }};
147}
148
149/// `path_to_test_file` returns the path to a test directory as the test file
150#[macro_export]
151macro_rules! path_to_test_directory {
152    () => {{
153        $crate::path_to_test_folder!()
154    }};
155    ($name:expr) => {{
156        $crate::path_to_test_folder!($name)
157    }};
158}