• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }
60 
61 /// Test vector normalization for float vector
62 #[macro_export]
63 macro_rules! impl_vec_float_normalize_tests {
64     ($t:ident, $vec:ident) => {
65         use core::$t::MAX;
66         use core::$t::MIN_POSITIVE;
67 
68         /// Works for vec2, vec3, vec4
69         fn from_x_y(x: $t, y: $t) -> $vec {
70             let mut v = $vec::ZERO;
71             v.x = x;
72             v.y = y;
73             v
74         }
75 
76         glam_test!(test_normalize, {
77             assert_eq!(from_x_y(-42.0, 0.0).normalize(), from_x_y(-1.0, 0.0));
78             assert_eq!(from_x_y(MAX.sqrt(), 0.0).normalize(), from_x_y(1.0, 0.0));
79             // assert_eq!(from_x_y(MAX, 0.0).normalize(), from_x_y(1.0, 0.0)); // normalize fails for huge vectors and returns zero
80 
81             // We expect not to be able to normalize small numbers:
82             should_glam_assert!({ from_x_y(0.0, 0.0).normalize() });
83             should_glam_assert!({ from_x_y(MIN_POSITIVE, 0.0).normalize() });
84 
85             // We expect not to be able to normalize non-finite vectors:
86             should_glam_assert!({ from_x_y(INFINITY, 0.0).normalize() });
87             should_glam_assert!({ from_x_y(NAN, 0.0).normalize() });
88         });
89 
90         #[cfg(not(any(feature = "debug-glam-assert", feature = "glam-assert")))]
91         glam_test!(test_normalize_no_glam_assert, {
92             // We expect not to be able to normalize small numbers:
93             assert!(!from_x_y(0.0, 0.0).normalize().is_finite());
94             assert!(!from_x_y(MIN_POSITIVE, 0.0).normalize().is_finite());
95 
96             // We expect not to be able to normalize non-finite vectors:
97             assert!(!from_x_y(INFINITY, 0.0).normalize().is_finite());
98             assert!(!from_x_y(NAN, 0.0).normalize().is_finite());
99         });
100 
101         glam_test!(test_try_normalize, {
102             assert_eq!(
103                 from_x_y(-42.0, 0.0).try_normalize(),
104                 Some(from_x_y(-1.0, 0.0))
105             );
106             assert_eq!(
107                 from_x_y(MAX.sqrt(), 0.0).try_normalize(),
108                 Some(from_x_y(1.0, 0.0))
109             );
110 
111             // We expect `try_normalize` to return None when inputs are very small:
112             assert_eq!(from_x_y(0.0, 0.0).try_normalize(), None);
113             assert_eq!(from_x_y(MIN_POSITIVE, 0.0).try_normalize(), None);
114 
115             // We expect `try_normalize` to return None when inputs are non-finite:
116             assert_eq!(from_x_y(INFINITY, 0.0).try_normalize(), None);
117             assert_eq!(from_x_y(NAN, 0.0).try_normalize(), None);
118 
119             // We expect `try_normalize` to return None when inputs are very large:
120             assert_eq!(from_x_y(MAX, 0.0).try_normalize(), None);
121             assert_eq!(from_x_y(MAX, MAX).try_normalize(), None);
122         });
123 
124         glam_test!(test_normalize_or_zero, {
125             assert_eq!(
126                 from_x_y(-42.0, 0.0).normalize_or_zero(),
127                 from_x_y(-1.0, 0.0)
128             );
129             assert_eq!(
130                 from_x_y(MAX.sqrt(), 0.0).normalize_or_zero(),
131                 from_x_y(1.0, 0.0)
132             );
133 
134             // We expect `normalize_or_zero` to return zero when inputs are very small:
135             assert_eq!(from_x_y(0.0, 0.0).normalize_or_zero(), $vec::ZERO);
136             assert_eq!(from_x_y(MIN_POSITIVE, 0.0).normalize_or_zero(), $vec::ZERO);
137 
138             // We expect `normalize_or_zero` to return zero when inputs are non-finite:
139             assert_eq!(from_x_y(INFINITY, 0.0).normalize_or_zero(), $vec::ZERO);
140             assert_eq!(from_x_y(NAN, 0.0).normalize_or_zero(), $vec::ZERO);
141 
142             // We expect `normalize_or_zero` to return zero when inputs are very large:
143             assert_eq!(from_x_y(MAX, 0.0).normalize_or_zero(), $vec::ZERO);
144             assert_eq!(from_x_y(MAX, MAX).normalize_or_zero(), $vec::ZERO);
145         });
146     };
147 }
148 
149 /// Useful test vectors
150 #[macro_export]
151 macro_rules! vec3_float_test_vectors {
152     ($vec3:ident) => {
153         [
154             $vec3::X,
155             $vec3::Y,
156             $vec3::Z,
157             -$vec3::X,
158             -$vec3::Y,
159             -$vec3::Z,
160             $vec3::new(1.0, 1e-3, 0.0),
161             $vec3::new(1.0, 1e-4, 0.0),
162             $vec3::new(1.0, 1e-5, 0.0),
163             $vec3::new(1.0, 1e-6, 0.0),
164             $vec3::new(1.0, 1e-7, 0.0),
165             $vec3::new(1.0, 1e-14, 0.0),
166             $vec3::new(1.0, 1e-15, 0.0),
167             $vec3::new(1.0, 1e-16, 0.0),
168             $vec3::new(0.1, 0.2, 0.3),
169             $vec3::new(0.2, 0.3, 0.4),
170             $vec3::new(4.0, -5.0, 6.0),
171             $vec3::new(-2.0, 0.5, -1.0),
172             // Pathalogical cases from <https://graphics.pixar.com/library/OrthonormalB/paper.pdf>:
173             $vec3::new(0.00038527316, 0.00038460016, -0.99999988079),
174             $vec3::new(-0.00019813581, -0.00008946839, -0.99999988079),
175         ]
176     };
177 }
178 
179 #[macro_export]
180 macro_rules! vec2_float_test_vectors {
181     ($vec2:ident) => {
182         [
183             $vec2::X,
184             $vec2::Y,
185             -$vec2::X,
186             -$vec2::Y,
187             $vec2::new(1.0, 1e-3),
188             $vec2::new(1.0, 1e-4),
189             $vec2::new(1.0, 1e-5),
190             $vec2::new(1.0, 1e-6),
191             $vec2::new(1.0, 1e-7),
192             $vec2::new(1.0, 1e-14),
193             $vec2::new(1.0, 1e-15),
194             $vec2::new(1.0, 1e-16),
195             $vec2::new(0.1, 0.2),
196             $vec2::new(0.2, 0.3),
197             $vec2::new(4.0, -5.0),
198             $vec2::new(-2.0, 0.5),
199             // Pathalogical cases from <https://graphics.pixar.com/library/OrthonormalB/paper.pdf>:
200             $vec2::new(0.00038527316, 0.00038460016),
201             $vec2::new(-0.00019813581, -0.00008946839),
202         ]
203     };
204 }
205