| //! Ensure that `for_each_function!` isn't missing any symbols. |
| |
| use std::collections::HashSet; |
| use std::env; |
| use std::path::Path; |
| use std::process::Command; |
| |
| macro_rules! callback { |
| ( |
| fn_name: $name:ident, |
| attrs: [$($attr:meta),*], |
| extra: [$set:ident], |
| ) => { |
| let name = stringify!($name); |
| let new = $set.insert(name); |
| assert!(new, "duplicate function `{name}` in `ALL_OPERATIONS`"); |
| }; |
| } |
| |
| #[test] |
| fn test_for_each_function_all_included() { |
| let all_functions: HashSet<_> = include_str!("../../etc/function-list.txt") |
| .lines() |
| .filter(|line| !line.starts_with("#")) |
| .collect(); |
| |
| let mut tested = HashSet::new(); |
| |
| libm_macros::for_each_function! { |
| callback: callback, |
| extra: [tested], |
| }; |
| |
| let untested = all_functions.difference(&tested); |
| if untested.clone().next().is_some() { |
| panic!( |
| "missing tests for the following: {untested:#?} \ |
| \nmake sure any new functions are entered in \ |
| `ALL_OPERATIONS` (in `libm-macros`)." |
| ); |
| } |
| assert_eq!(all_functions, tested); |
| } |
| |
| #[test] |
| fn ensure_list_updated() { |
| if libm_test::ci() { |
| // Most CI tests run in Docker where we don't have Python or Rustdoc, so it's easiest |
| // to just run the python file directly when it is available. |
| eprintln!("skipping test; CI runs the python file directly"); |
| return; |
| } |
| |
| let res = Command::new("python3") |
| .arg(Path::new(env!("CARGO_MANIFEST_DIR")).join("../etc/update-api-list.py")) |
| .arg("--check") |
| .status() |
| .unwrap(); |
| |
| assert!(res.success(), "May need to run `./etc/update-api-list.py`"); |
| } |