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        //     let parts = module_path!().to_string().split("::").map(String::from).collect::<Vec<String>>();
45        //     let mut path = std::path::absolute(std::path::Path::new(".")).unwrap();
46        //     for part in parts {
47        //         let file = format!("{}.rs",part);
48        //         if path.join(&file).exists() {
49        //             path.push(&file);
50        //             path = path.canonicalize().unwrap();
51        //         } else if path.join(&part).exists() {
52        //             path.push(&part);
53        //             path = path.canonicalize().unwrap();
54        //         } else {
55        //             break
56        //         }
57        //     }
58        //     format!("{}", path.display())
59        // }};
60}
61
62/// `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
63#[macro_export]
64macro_rules! path_to_test_file {
65    ($name:expr $(,)?) => {{
66        let path = $crate::folder_path!("__test_files__").join($crate::test_name!()).join($name);
67        path.parent().unwrap().mkdir().map(|_| ()).unwrap_or_default();
68        path.delete().map(|_| ()).unwrap_or_default();
69        path
70    }};
71}
72
73/// `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)
74#[macro_export]
75macro_rules! folder_path {
76    () => {{
77        let path = iocore::Path::raw($crate::current_source_file!())
78            .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    () => {{ $crate::folder_path!() }};
94    ($name:expr $(,)?) => {
95        $crate::folder_path!($name)
96    };
97}
98
99/// `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)
100#[macro_export]
101macro_rules! test_folder_parent_path {
102    ($name:expr $(,)?) => {{
103        let path = iocore::Path::raw($crate::current_source_file!())
104            .relative_to_cwd()
105            .parent()
106            .expect(&format!("parent directory of {:#?}", $crate::current_source_file!()));
107        let path = path.join($name);
108        path.mkdir_unchecked();
109        path
110    }};
111}
112/// `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)
113#[macro_export]
114macro_rules! test_directory_parent_path {
115    ($name:expr $(,)?) => {{ $crate::test_folder_parent_path($name) }};
116}
117/// `test_name` returns the name of the test function
118#[macro_export]
119macro_rules! test_name {
120    () => {{
121        fn f() {}
122        fn type_name_of<T>(_: T) -> &'static str {
123            std::any::type_name::<T>()
124        }
125        let name = type_name_of(f);
126        let name = name.strip_suffix("::f").unwrap().replace("::", std::path::MAIN_SEPARATOR_STR);
127        name
128    }};
129}
130
131/// `path_to_test_file` returns the path to a test directory as the test file
132#[macro_export]
133macro_rules! path_to_test_folder {
134    () => {{
135        let path = $crate::folder_path!("__test_files__").join($crate::test_name!());
136        path.mkdir_unchecked();
137        path
138    }};
139    ($name:expr $(,)?) => {{
140        let path = $crate::path_to_test_folder!().join($name);
141        path.mkdir_unchecked();
142        path
143    }};
144}
145
146/// `path_to_test_file` returns the path to a test directory as the test file
147#[macro_export]
148macro_rules! path_to_test_directory {
149    () => {{ $crate::path_to_test_folder!() }};
150    ($name:expr $(,)?) => {{ $crate::path_to_test_folder!($name) }};
151}