1 #[macro_export] 2 macro_rules! glam_test { 3 ($name:ident, $block:block) => { 4 #[cfg_attr(not(target_arch = "wasm32"), test)] 5 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] 6 fn $name() { 7 $block 8 } 9 }; 10 } 11 12 #[macro_export] 13 macro_rules! should_panic { 14 ($block:block) => {{ 15 #[cfg(all(feature = "std", not(target_arch = "wasm32")))] 16 assert!(std::panic::catch_unwind(|| $block).is_err()); 17 }}; 18 } 19 20 #[macro_export] 21 macro_rules! should_glam_assert { 22 ($block:block) => {{ 23 #[cfg(any(feature = "glam-assert", feature = "debug-glam-assert"))] 24 should_panic!($block); 25 }}; 26 } 27 28 #[macro_export] 29 macro_rules! assert_approx_eq { 30 ($a:expr, $b:expr) => {{ 31 #[allow(unused_imports)] 32 use $crate::support::FloatCompare; 33 let eps = core::f32::EPSILON; 34 let (a, b) = (&$a, &$b); 35 assert!( 36 a.approx_eq(b, eps), 37 "assertion failed: `(left !== right)` \ 38 (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)", 39 *a, 40 *b, 41 eps, 42 a.abs_diff(b) 43 ); 44 }}; 45 ($a:expr, $b:expr, $eps:expr) => {{ 46 use $crate::support::FloatCompare; 47 let (a, b) = (&$a, &$b); 48 let eps = $eps; 49 assert!( 50 a.approx_eq(b, $eps), 51 "assertion failed: `(left !== right)` \ 52 (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)", 53 *a, 54 *b, 55 eps, 56 a.abs_diff(b) 57 ); 58 }}; 59 ($a:expr, $b:expr, $eps:expr, $ctx:expr) => {{ 60 use $crate::support::FloatCompare; 61 let (a, b) = (&$a, &$b); 62 let eps = $eps; 63 assert!( 64 a.approx_eq(b, $eps), 65 "assertion failed: `(left !== right)` \ 66 (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`), \ 67 additional context: {}", 68 *a, 69 *b, 70 eps, 71 a.abs_diff(b), 72 $ctx 73 ); 74 }}; 75 } 76 77 /// Test vector normalization for float vector 78 #[macro_export] 79 macro_rules! impl_vec_float_normalize_tests { 80 ($t:ident, $vec:ident) => { 81 use core::$t::MAX; 82 use core::$t::MIN_POSITIVE; 83 84 /// Works for vec2, vec3, vec4 85 fn from_x_y(x: $t, y: $t) -> $vec { 86 let mut v = $vec::ZERO; 87 v.x = x; 88 v.y = y; 89 v 90 } 91 92 glam_test!(test_normalize, { 93 assert_eq!(from_x_y(-42.0, 0.0).normalize(), from_x_y(-1.0, 0.0)); 94 assert_eq!(from_x_y(MAX.sqrt(), 0.0).normalize(), from_x_y(1.0, 0.0)); 95 // assert_eq!(from_x_y(MAX, 0.0).normalize(), from_x_y(1.0, 0.0)); // normalize fails for huge vectors and returns zero 96 97 // We expect not to be able to normalize small numbers: 98 should_glam_assert!({ from_x_y(0.0, 0.0).normalize() }); 99 should_glam_assert!({ from_x_y(MIN_POSITIVE, 0.0).normalize() }); 100 101 // We expect not to be able to normalize non-finite vectors: 102 should_glam_assert!({ from_x_y(INFINITY, 0.0).normalize() }); 103 should_glam_assert!({ from_x_y(NAN, 0.0).normalize() }); 104 }); 105 106 #[cfg(not(any(feature = "debug-glam-assert", feature = "glam-assert")))] 107 glam_test!(test_normalize_no_glam_assert, { 108 // We expect not to be able to normalize small numbers: 109 assert!(!from_x_y(0.0, 0.0).normalize().is_finite()); 110 assert!(!from_x_y(MIN_POSITIVE, 0.0).normalize().is_finite()); 111 112 // We expect not to be able to normalize non-finite vectors: 113 assert!(!from_x_y(INFINITY, 0.0).normalize().is_finite()); 114 assert!(!from_x_y(NAN, 0.0).normalize().is_finite()); 115 }); 116 117 glam_test!(test_try_normalize, { 118 assert_eq!( 119 from_x_y(-42.0, 0.0).try_normalize(), 120 Some(from_x_y(-1.0, 0.0)) 121 ); 122 assert_eq!( 123 from_x_y(MAX.sqrt(), 0.0).try_normalize(), 124 Some(from_x_y(1.0, 0.0)) 125 ); 126 127 // We expect `try_normalize` to return None when inputs are very small: 128 assert_eq!(from_x_y(0.0, 0.0).try_normalize(), None); 129 assert_eq!(from_x_y(MIN_POSITIVE, 0.0).try_normalize(), None); 130 131 // We expect `try_normalize` to return None when inputs are non-finite: 132 assert_eq!(from_x_y(INFINITY, 0.0).try_normalize(), None); 133 assert_eq!(from_x_y(NAN, 0.0).try_normalize(), None); 134 135 // We expect `try_normalize` to return None when inputs are very large: 136 assert_eq!(from_x_y(MAX, 0.0).try_normalize(), None); 137 assert_eq!(from_x_y(MAX, MAX).try_normalize(), None); 138 }); 139 140 glam_test!(test_normalize_or_zero, { 141 assert_eq!( 142 from_x_y(-42.0, 0.0).normalize_or_zero(), 143 from_x_y(-1.0, 0.0) 144 ); 145 assert_eq!( 146 from_x_y(MAX.sqrt(), 0.0).normalize_or_zero(), 147 from_x_y(1.0, 0.0) 148 ); 149 150 // We expect `normalize_or_zero` to return zero when inputs are very small: 151 assert_eq!(from_x_y(0.0, 0.0).normalize_or_zero(), $vec::ZERO); 152 assert_eq!(from_x_y(MIN_POSITIVE, 0.0).normalize_or_zero(), $vec::ZERO); 153 154 // We expect `normalize_or_zero` to return zero when inputs are non-finite: 155 assert_eq!(from_x_y(INFINITY, 0.0).normalize_or_zero(), $vec::ZERO); 156 assert_eq!(from_x_y(NAN, 0.0).normalize_or_zero(), $vec::ZERO); 157 158 // We expect `normalize_or_zero` to return zero when inputs are very large: 159 assert_eq!(from_x_y(MAX, 0.0).normalize_or_zero(), $vec::ZERO); 160 assert_eq!(from_x_y(MAX, MAX).normalize_or_zero(), $vec::ZERO); 161 }); 162 }; 163 } 164 165 /// Useful test vectors 166 #[macro_export] 167 macro_rules! vec3_float_test_vectors { 168 ($vec3:ident) => { 169 [ 170 $vec3::X, 171 $vec3::Y, 172 $vec3::Z, 173 -$vec3::X, 174 -$vec3::Y, 175 -$vec3::Z, 176 $vec3::new(1.0, 1e-3, 0.0), 177 $vec3::new(1.0, 1e-4, 0.0), 178 $vec3::new(1.0, 1e-5, 0.0), 179 $vec3::new(1.0, 1e-6, 0.0), 180 $vec3::new(1.0, 1e-7, 0.0), 181 $vec3::new(1.0, 1e-14, 0.0), 182 $vec3::new(1.0, 1e-15, 0.0), 183 $vec3::new(1.0, 1e-16, 0.0), 184 $vec3::new(0.1, 0.2, 0.3), 185 $vec3::new(0.2, 0.3, 0.4), 186 $vec3::new(4.0, -5.0, 6.0), 187 $vec3::new(-2.0, 0.5, -1.0), 188 // Pathalogical cases from <https://graphics.pixar.com/library/OrthonormalB/paper.pdf>: 189 $vec3::new(0.00038527316, 0.00038460016, -0.99999988079), 190 $vec3::new(-0.00019813581, -0.00008946839, -0.99999988079), 191 ] 192 }; 193 } 194 195 #[macro_export] 196 macro_rules! vec2_float_test_vectors { 197 ($vec2:ident) => { 198 [ 199 $vec2::X, 200 $vec2::Y, 201 -$vec2::X, 202 -$vec2::Y, 203 $vec2::new(1.0, 1e-3), 204 $vec2::new(1.0, 1e-4), 205 $vec2::new(1.0, 1e-5), 206 $vec2::new(1.0, 1e-6), 207 $vec2::new(1.0, 1e-7), 208 $vec2::new(1.0, 1e-14), 209 $vec2::new(1.0, 1e-15), 210 $vec2::new(1.0, 1e-16), 211 $vec2::new(0.1, 0.2), 212 $vec2::new(0.2, 0.3), 213 $vec2::new(4.0, -5.0), 214 $vec2::new(-2.0, 0.5), 215 // Pathalogical cases from <https://graphics.pixar.com/library/OrthonormalB/paper.pdf>: 216 $vec2::new(0.00038527316, 0.00038460016), 217 $vec2::new(-0.00019813581, -0.00008946839), 218 ] 219 }; 220 } 221