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