Ogeon/palette

tests fail when built with only feature std

jonassmedegaard opened this issue · 9 comments

When built without default features, only with std feature, a bunch of tests fail.

This can be fixed by adding appropriate feature guards, like this:

--- a/palette/src/chromatic_adaptation.rs
+++ b/palette/src/chromatic_adaptation.rs
@@ -215,7 +215,7 @@
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, feature = "approx"))]
 mod test {
     use super::{AdaptFrom, AdaptInto, Method, TransformMatrix};
     use crate::white_point::{WhitePoint, A, C, D50, D65};
--- a/palette/src/color_difference.rs
+++ b/palette/src/color_difference.rs
@@ -434,7 +434,7 @@
     fn hybrid_distance(self, other: Self) -> Self::Scalar;
 }
 
-#[cfg(test)]
+#[cfg(all(test, feature = "approx"))]
 mod test {
     use core::str::FromStr;
 
--- a/palette/src/hsl.rs
+++ b/palette/src/hsl.rs
@@ -766,6 +766,7 @@
     test_convert_into_from_xyz!(Hsl);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Hsl::from_color(Srgb::new(1.0, 0.0, 0.0));
         let b = Hsl::new_srgb(0.0, 1.0, 0.5);
@@ -776,6 +777,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn orange() {
         let a = Hsl::from_color(Srgb::new(1.0, 0.5, 0.0));
         let b = Hsl::new_srgb(30.0, 1.0, 0.5);
@@ -786,6 +788,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Hsl::from_color(Srgb::new(0.0, 1.0, 0.0));
         let b = Hsl::new_srgb(120.0, 1.0, 0.5);
@@ -796,6 +799,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Hsl::from_color(Srgb::new(0.0, 0.0, 1.0));
         let b = Hsl::new_srgb(240.0, 1.0, 0.5);
@@ -806,6 +810,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn purple() {
         let a = Hsl::from_color(Srgb::new(0.5, 0.0, 1.0));
         let b = Hsl::new_srgb(270.0, 1.0, 0.5);
@@ -816,6 +821,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Hsl<crate::encoding::Srgb, f64>;
@@ -834,6 +840,7 @@
     raw_pixel_conversion_fail_tests!(Hsl<crate::encoding::Srgb>: hue, saturation, lightness);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         use crate::encoding::Srgb;
 
@@ -843,6 +850,7 @@
         assert_relative_eq!(Hsl::<Srgb>::max_lightness(), 1.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Hsl<Srgb>,
         Hsl::new(0.1f32, 0.2, 0.3),
@@ -850,6 +858,7 @@
         Hsl::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{encoding::Srgb, hsl::Hsla};
 
--- a/palette/src/hsluv.rs
+++ b/palette/src/hsluv.rs
@@ -492,6 +492,7 @@
 
     #[cfg_attr(miri, ignore)]
     #[test]
+    #[cfg(feature = "approx")]
     fn lchuv_round_trip() {
         for hue in (0..=20).map(|x| x as f64 * 18.0) {
             for sat in (0..=20).map(|x| x as f64 * 5.0) {
@@ -509,6 +510,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Hsluv<D65, f64>;
@@ -541,6 +543,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn saturate() {
         for sat in (0..=10).map(|s| s as f64 * 10.0) {
             for a in (0..=10).map(|l| l as f64 * 10.0) {
@@ -560,6 +563,7 @@
     raw_pixel_conversion_fail_tests!(Hsluv<D65>: hue, saturation, lightness);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Hsluv::<D65>::min_saturation(), 0.0);
         assert_relative_eq!(Hsluv::<D65>::min_l(), 0.0);
@@ -567,6 +571,7 @@
         assert_relative_eq!(Hsluv::<D65>::max_l(), 100.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Hsluv<D65>,
         Hsluv::new(0.1f32, 0.2, 0.3),
@@ -574,6 +579,7 @@
         Hsluv::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{hsluv::Hsluva, white_point::D65};
 
--- a/palette/src/hsv.rs
+++ b/palette/src/hsv.rs
@@ -766,6 +766,7 @@
     test_convert_into_from_xyz!(Hsv);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Hsv::from_color(Srgb::new(1.0, 0.0, 0.0));
         let b = Hsv::new_srgb(0.0, 1.0, 1.0);
@@ -776,6 +777,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn orange() {
         let a = Hsv::from_color(Srgb::new(1.0, 0.5, 0.0));
         let b = Hsv::new_srgb(30.0, 1.0, 1.0);
@@ -786,6 +788,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Hsv::from_color(Srgb::new(0.0, 1.0, 0.0));
         let b = Hsv::new_srgb(120.0, 1.0, 1.0);
@@ -796,6 +799,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Hsv::from_color(Srgb::new(0.0, 0.0, 1.0));
         let b = Hsv::new_srgb(240.0, 1.0, 1.0);
@@ -806,6 +810,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn purple() {
         let a = Hsv::from_color(Srgb::new(0.5, 0.0, 1.0));
         let b = Hsv::new_srgb(270.0, 1.0, 1.0);
@@ -816,6 +821,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Hsv<crate::encoding::Srgb, f64>;
@@ -834,6 +840,7 @@
     raw_pixel_conversion_fail_tests!(Hsv<crate::encoding::Srgb>: hue, saturation, value);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         use crate::encoding::Srgb;
 
@@ -843,6 +850,7 @@
         assert_relative_eq!(Hsv::<Srgb>::max_value(), 1.0,);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Hsv<Srgb>,
         Hsv::new(0.1f32, 0.2, 0.3),
@@ -850,6 +858,7 @@
         Hsv::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{encoding::Srgb, hsv::Hsva};
 
--- a/palette/src/hues.rs
+++ b/palette/src/hues.rs
@@ -794,6 +794,7 @@
     };
 
     #[test]
+    #[cfg(feature = "approx")]
     fn oklabhue_ab_roundtrip() {
         for degree in [0.0_f64, 90.0, 30.0, 330.0, 120.0, 240.0] {
             let hue = OklabHue::from_degrees(degree);
@@ -804,6 +805,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn normalize_angle_0_360() {
         let inp = [
             -1000.0_f32,
@@ -846,6 +848,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn normalize_angle_180_180() {
         let inp = [
             -1000.0_f32,
@@ -885,6 +888,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn float_conversion() {
         for i in -180..180 {
             let hue = RgbHue::from(4.0 * i as f32);
--- a/palette/src/hwb.rs
+++ b/palette/src/hwb.rs
@@ -799,6 +799,7 @@
     test_convert_into_from_xyz!(Hwb);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Hwb::from_color(Srgb::new(1.0, 0.0, 0.0));
         let b = Hwb::new_srgb(0.0, 0.0, 0.0);
@@ -806,6 +807,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn orange() {
         let a = Hwb::from_color(Srgb::new(1.0, 0.5, 0.0));
         let b = Hwb::new_srgb(30.0, 0.0, 0.0);
@@ -813,6 +815,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Hwb::from_color(Srgb::new(0.0, 1.0, 0.0));
         let b = Hwb::new_srgb(120.0, 0.0, 0.0);
@@ -820,6 +823,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Hwb::from_color(Srgb::new(0.0, 0.0, 1.0));
         let b = Hwb::new_srgb(240.0, 0.0, 0.0);
@@ -827,6 +831,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn purple() {
         let a = Hwb::from_color(Srgb::new(0.5, 0.0, 1.0));
         let b = Hwb::new_srgb(270.0, 0.0, 0.0);
@@ -834,6 +839,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn clamp_invalid() {
         let expected = Hwb::new_srgb(240.0, 0.0, 0.0);
         let clamped = Hwb::new_srgb(240.0, -3.0, -4.0).clamp();
@@ -841,18 +847,21 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn clamp_none() {
         let expected = Hwb::new_srgb(240.0, 0.3, 0.7);
         let clamped = Hwb::new_srgb(240.0, 0.3, 0.7).clamp();
         assert_relative_eq!(expected, clamped);
     }
     #[test]
+    #[cfg(feature = "approx")]
     fn clamp_over_one() {
         let expected = Hwb::new_srgb(240.0, 0.2, 0.8);
         let clamped = Hwb::new_srgb(240.0, 5.0, 20.0).clamp();
         assert_relative_eq!(expected, clamped);
     }
     #[test]
+    #[cfg(feature = "approx")]
     fn clamp_under_one() {
         let expected = Hwb::new_srgb(240.0, 0.3, 0.1);
         let clamped = Hwb::new_srgb(240.0, 0.3, 0.1).clamp();
@@ -863,6 +872,7 @@
     raw_pixel_conversion_fail_tests!(Hwb<crate::encoding::Srgb>: hue, whiteness, blackness);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         use crate::encoding::Srgb;
 
@@ -872,6 +882,7 @@
         assert_relative_eq!(Hwb::<Srgb>::max_blackness(), 1.0,);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Hwb<Srgb>,
         Hwb::new(0.1f32, 0.2, 0.3),
@@ -879,6 +890,7 @@
         Hwb::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{encoding::Srgb, hwb::Hwba};
 
--- a/palette/src/lab.rs
+++ b/palette/src/lab.rs
@@ -507,6 +507,7 @@
     test_convert_into_from_xyz!(Lab);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Lab::from_color(LinSrgb::new(1.0, 0.0, 0.0));
         let b = Lab::new(53.23288, 80.09246, 67.2031);
@@ -514,6 +515,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Lab::from_color(LinSrgb::new(0.0, 1.0, 0.0));
         let b = Lab::new(87.73704, -86.184654, 83.18117);
@@ -521,6 +523,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Lab::from_color(LinSrgb::new(0.0, 0.0, 1.0));
         let b = Lab::new(32.302586, 79.19668, -107.863686);
@@ -528,6 +531,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Lab<D65, f64>;
@@ -545,6 +549,7 @@
     raw_pixel_conversion_fail_tests!(Lab<D65>: l, a, b);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Lab::<D65, f32>::min_l(), 0.0);
         assert_relative_eq!(Lab::<D65, f32>::min_a(), -128.0);
@@ -554,6 +559,7 @@
         assert_relative_eq!(Lab::<D65, f32>::max_b(), 127.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Lab<D65>,
         Lab::new(0.1f32, 0.2, 0.3),
@@ -561,6 +567,7 @@
         Lab::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{lab::Laba, white_point::D65};
 
--- a/palette/src/lch.rs
+++ b/palette/src/lch.rs
@@ -534,6 +534,7 @@
     test_convert_into_from_xyz!(Lch);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Lch<D65, f64>;
@@ -553,6 +554,7 @@
     raw_pixel_conversion_fail_tests!(Lch<D65>: l, chroma, hue);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Lch::<D65, f32>::min_l(), 0.0);
         assert_relative_eq!(Lch::<D65, f32>::max_l(), 100.0);
@@ -561,6 +563,7 @@
         assert_relative_eq!(Lch::<D65, f32>::max_extended_chroma(), 181.01933598375618);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Lch<D65>,
         Lch::new(0.1f32, 0.2, 0.3),
@@ -568,6 +571,7 @@
         Lch::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{lch::Lcha, white_point::D65};
 
--- a/palette/src/lchuv.rs
+++ b/palette/src/lchuv.rs
@@ -491,6 +491,7 @@
     test_convert_into_from_xyz!(Lchuv);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Lchuv<D65, f64>;
@@ -527,6 +528,7 @@
     raw_pixel_conversion_fail_tests!(Lchuv<D65>: l, chroma, hue);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Lchuv::<D65, f32>::min_l(), 0.0);
         assert_relative_eq!(Lchuv::<D65, f32>::max_l(), 100.0);
@@ -534,6 +536,7 @@
         assert_relative_eq!(Lchuv::<D65, f32>::max_chroma(), 180.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Lchuv<D65>,
         Lchuv::new(0.1f32, 0.2, 0.3),
@@ -544,6 +547,7 @@
     mod alpha {
         use crate::{lchuv::Lchuva, white_point::D65};
 
+        #[cfg(feature = "std")]
         struct_of_arrays_tests!(
             Lchuva<D65>,
             Lchuva::new(0.1f32, 0.2, 0.3, 0.4),
--- a/palette/src/lib.rs
+++ b/palette/src/lib.rs
@@ -305,7 +305,7 @@
 pub use relative_contrast::{contrast_ratio, RelativeContrast};
 
 //Helper macro for checking ranges and clamping.
-#[cfg(test)]
+#[cfg(all(test, feature = "approx"))]
 macro_rules! assert_ranges {
     (@make_tuple $first:pat, $next:ident,) => (($first, $next));
 
--- a/palette/src/luv.rs
+++ b/palette/src/luv.rs
@@ -464,6 +464,7 @@
     test_convert_into_from_xyz!(Luv);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let u = Luv::from_color(LinSrgb::new(1.0, 0.0, 0.0));
         let v = Luv::new(53.237116, 175.0098, 37.7650);
@@ -471,6 +472,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let u = Luv::from_color(LinSrgb::new(0.0, 1.0, 0.0));
         let v = Luv::new(87.73703, -83.07975, 107.40136);
@@ -478,6 +480,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let u = Luv::from_color(LinSrgb::new(0.0, 0.0, 1.0));
         let v = Luv::new(32.30087, -9.40241, -130.35109);
@@ -485,6 +488,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Luv<D65, f64>;
@@ -518,6 +522,7 @@
     raw_pixel_conversion_fail_tests!(Luv<D65>: l, u, v);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Luv::<D65, f32>::min_l(), 0.0);
         assert_relative_eq!(Luv::<D65, f32>::min_u(), -84.0);
@@ -527,6 +532,7 @@
         assert_relative_eq!(Luv::<D65, f32>::max_v(), 108.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Luv<D65>,
         Luv::new(0.1f32, 0.2, 0.3),
@@ -534,6 +540,7 @@
         Luv::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{luv::Luva, white_point::D65};
 
--- a/palette/src/luv_bounds.rs
+++ b/palette/src/luv_bounds.rs
@@ -125,6 +125,7 @@
 }
 
 #[cfg(test)]
+#[cfg(feature = "approx")]
 mod tests {
     use super::BoundaryLine;
 
--- a/palette/src/matrix.rs
+++ b/palette/src/matrix.rs
@@ -228,6 +228,7 @@
     use crate::Xyz;
 
     #[test]
+    #[cfg(feature = "approx")]
     fn matrix_multiply_3x3() {
         let inp1 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 2.0, 1.0, 3.0];
         let inp2 = [4.0, 5.0, 6.0, 6.0, 5.0, 4.0, 4.0, 6.0, 5.0];
@@ -240,6 +241,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn matrix_multiply_xyz() {
         let inp1 = [0.1, 0.2, 0.3, 0.3, 0.2, 0.1, 0.2, 0.1, 0.3];
         let inp2 = Xyz::new(0.4, 0.6, 0.8);
@@ -251,6 +253,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn matrix_inverse_check_1() {
         let input: [f64; 9] = [3.0, 0.0, 2.0, 2.0, 0.0, -2.0, 0.0, 1.0, 1.0];
 
@@ -261,6 +264,7 @@
         }
     }
     #[test]
+    #[cfg(feature = "approx")]
     fn matrix_inverse_check_2() {
         let input: [f64; 9] = [1.0, 0.0, 1.0, 0.0, 2.0, 1.0, 1.0, 1.0, 1.0];
 
@@ -279,6 +283,7 @@
 
     #[rustfmt::skip]
     #[test]
+    #[cfg(feature = "approx")]
     fn d65_rgb_conversion_matrix() {
         let expected = [
             0.4124564, 0.3575761, 0.1804375,
@@ -292,6 +297,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn d65_to_d50() {
         let input: Rgb<Linear<Srgb>> = Rgb::new(1.0, 1.0, 1.0);
         let expected: Rgb<Linear<(Srgb, D50)>> = Rgb::new(1.0, 1.0, 1.0);
--- a/palette/src/ok_utils.rs
+++ b/palette/src/ok_utils.rs
@@ -496,6 +496,7 @@
 
     #[cfg_attr(miri, ignore)]
     #[test]
+    #[cfg(feature = "approx")]
     fn test_roundtrip_toe_is_original() {
         let n = 500;
         for i in 0..n {
@@ -516,6 +517,7 @@
             .into_format();
         let grey50oklab = Oklab::from_color_unclamped(grey50srgb);
         println!("grey 50% oklab lightness: {}", grey50oklab.l);
+        #[cfg(feature = "approx")]
         assert!(relative_eq!(toe(grey50oklab.l), 0.5, epsilon = 1e-3));
     }
 
@@ -584,6 +586,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn max_saturation_f64_eq_f32() {
         let lin_srgb = LinSrgb::new(0.0, 0.0, 1.0);
         let oklab_64 = Oklab::<f64>::from_color_unclamped(lin_srgb);
--- a/palette/src/okhsl.rs
+++ b/palette/src/okhsl.rs
@@ -246,6 +246,7 @@
 
     use crate::convert::FromColorUnclamped;
     use crate::rgb::Rgb;
+    #[cfg(feature = "approx")]
     use crate::visual::{VisualColor, VisuallyEqual};
     use crate::{encoding, LinSrgb, Okhsl, Oklab, Srgb};
 
@@ -309,11 +310,13 @@
                 name, rgb, color
             );
 
+            #[cfg(feature = "approx")]
             println!("Color is white: {}", color.is_white(EPSILON));
 
             let okhsl = Okhsl::from_color_unclamped(color);
             println!("Okhsl: {:?}", okhsl);
             let roundtrip_color = Oklab::from_color_unclamped(okhsl);
+            #[cfg(feature = "approx")]
             assert!(
                 Oklab::visually_eq(roundtrip_color, color, EPSILON),
                 "'{}' failed.\n{:?}\n!=\n{:?}",
@@ -325,6 +328,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn test_blue() {
         let lab = Oklab::new(
             0.45201371519623734_f64,
@@ -357,6 +361,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn test_srgb_to_okhsl() {
         let red_hex = "#834941";
         let rgb: Srgb<f64> = Srgb::from_str(red_hex).unwrap().into_format();
@@ -391,12 +396,14 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn test_okhsl_to_srgb_saturated_black() {
         let okhsl = Okhsl::new(0.0_f32, 1.0, 0.0);
         let rgb = Srgb::from_color_unclamped(okhsl);
         assert_relative_eq!(rgb, Srgb::new(0.0, 0.0, 0.0));
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Okhsl,
         Okhsl::new(0.1f32, 0.2, 0.3),
@@ -404,6 +411,7 @@
         Okhsl::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::okhsl::Okhsla;
 
--- a/palette/src/okhsv.rs
+++ b/palette/src/okhsv.rs
@@ -297,6 +297,7 @@
 
     use crate::convert::FromColorUnclamped;
     use crate::rgb::Rgb;
+    #[cfg(feature = "approx")]
     use crate::visual::VisuallyEqual;
     use crate::{encoding, Clamp, IsWithinBounds, LinSrgb, Okhsv, Oklab, OklabHue, Srgb};
 
@@ -361,6 +362,7 @@
             let okhsv = Okhsv::from_color_unclamped(color);
             println!("Okhsv: {:?}", okhsv);
             let roundtrip_color = Oklab::from_color_unclamped(okhsv);
+            #[cfg(feature = "approx")]
             assert!(
                 Oklab::visually_eq(roundtrip_color, color, EPSILON),
                 "'{}' failed.\n{:?}\n!=\n{:?}",
@@ -378,6 +380,7 @@
     /// saturation: 1.0
     /// value: 1.0
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let lin_srgb_blue = LinSrgb::new(0.0, 0.0, 1.0);
         let oklab_blue_64 = Oklab::<f64>::from_color_unclamped(lin_srgb_blue);
@@ -404,6 +407,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn test_srgb_to_okhsv() {
         let red_hex = "#ff0004";
         let rgb: Srgb = Rgb::<encoding::Srgb, _>::from_str(red_hex)
@@ -430,6 +434,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn test_okhsv_to_srgb_saturated_black() {
         let okhsv = Okhsv::new(0.0_f32, 1.0, 0.0);
         let rgb = Srgb::from_color_unclamped(okhsv);
@@ -437,6 +442,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn black_eq_different_black() {
         assert!(Okhsv::visually_eq(
             Okhsv::from_color_unclamped(Oklab::new(0.0, 1.0, 0.0)),
@@ -446,6 +452,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn white_eq_different_white() {
         assert!(Okhsv::visually_eq(
             Okhsv::new(240.0, 0.0, 1.0),
@@ -455,6 +462,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn white_ne_grey_or_black() {
         assert!(!Okhsv::visually_eq(
             Okhsv::new(0.0, 0.0, 0.0),
@@ -469,6 +477,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn color_neq_different_color() {
         assert!(!Okhsv::visually_eq(
             Okhsv::new(10.0, 0.01, 0.5),
@@ -488,6 +497,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn grey_vs_grey() {
         // greys of different lightness are not equal
         assert!(!Okhsv::visually_eq(
@@ -549,6 +559,7 @@
         }
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Okhsv,
         Okhsv::new(0.1f32, 0.2, 0.3),
@@ -556,6 +567,7 @@
         Okhsv::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::okhsv::Okhsva;
 
--- a/palette/src/okhwb.rs
+++ b/palette/src/okhwb.rs
@@ -175,6 +175,7 @@
 mod tests {
     use crate::convert::FromColorUnclamped;
     use crate::rgb::Rgb;
+    #[cfg(feature = "approx")]
     use crate::visual::VisuallyEqual;
     use crate::{encoding, LinSrgb, Okhsv, Okhwb, Oklab};
 
@@ -239,6 +240,7 @@
             let okhwb_from_okhsv = Okhwb::from_color_unclamped(okhsv);
             let okhwb = Okhwb::from_color_unclamped(color);
             println!("Okhwb: {:?}", okhwb);
+            #[cfg(feature = "approx")]
             assert!(
                 Okhwb::visually_eq(okhwb, okhwb_from_okhsv, EPSILON),
                 "Okhwb \n{:?} is not visually equal to Okhwb from Okhsv \n{:?}\nwithin EPSILON {}",
@@ -247,6 +249,7 @@
                 EPSILON
             );
             let okhsv_from_okhwb = Okhsv::from_color_unclamped(okhwb);
+            #[cfg(feature = "approx")]
             assert!(
                 Okhsv::visually_eq(okhsv, okhsv_from_okhwb, EPSILON),
                 "Okhsv \n{:?} is not visually equal to Okhsv from Okhsv from Okhwb \n{:?}\nwithin EPSILON {}",
@@ -256,6 +259,7 @@
 
             let roundtrip_color = Oklab::from_color_unclamped(okhwb);
             let oklab_from_okhsv = Oklab::from_color_unclamped(okhsv);
+            #[cfg(feature = "approx")]
             assert!(
                 Oklab::visually_eq(roundtrip_color, oklab_from_okhsv, EPSILON),
                 "roundtrip color \n{:?} does not match \n{:?}\nwithin EPSILON {}",
@@ -263,6 +267,7 @@
                 oklab_from_okhsv,
                 EPSILON
             );
+            #[cfg(feature = "approx")]
             assert!(
                 Oklab::visually_eq(roundtrip_color, color, EPSILON),
                 "'{}' failed.\n\
@@ -276,6 +281,7 @@
         }
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Okhwb,
         Okhwb::new(0.1f32, 0.2, 0.3),
@@ -283,6 +289,7 @@
         Okhwb::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::okhwb::Okhwba;
 
--- a/palette/src/oklab.rs
+++ b/palette/src/oklab.rs
@@ -549,6 +549,7 @@
     use core::str::FromStr;
 
     use crate::rgb::Rgb;
+    #[cfg(feature = "approx")]
     use crate::visual::VisuallyEqual;
     use crate::{FromColor, Lab, LinSrgb, Srgb};
 
@@ -558,6 +559,7 @@
 
     /// Asserts that, for any color space, the lightness of pure white is converted to `l == 1.0`
     #[test]
+    #[cfg(feature = "approx")]
     fn lightness_of_white_is_one() {
         let rgb: Srgb<f64> = Rgb::from_str("#ffffff").unwrap().into_format();
         let lin_rgb = LinSrgb::from_color_unclamped(rgb);
@@ -577,6 +579,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue_srgb() {
         // use f64 to be comparable to javascript
         let rgb: Srgb<f64> = Rgb::from_str("#0000ff").unwrap().into_format();
@@ -591,6 +594,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Oklab::from_color(LinSrgb::new(1.0, 0.0, 0.0));
         // from https://github.com/bottosson/bottosson.github.io/blob/master/misc/ok_color.h
@@ -599,6 +603,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Oklab::from_color(LinSrgb::new(0.0, 1.0, 0.0));
         // from https://github.com/bottosson/bottosson.github.io/blob/master/misc/ok_color.h
@@ -611,6 +616,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Oklab::from_color(LinSrgb::new(0.0, 0.0, 1.0));
         println!("Oklab blue: {:?}", a);
@@ -620,6 +626,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn black_eq_different_black() {
         assert!(Oklab::visually_eq(
             Oklab::new(0.0, 1.0, 0.0),
@@ -629,6 +636,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn white_eq_different_white() {
         assert!(Oklab::visually_eq(
             Oklab::new(1.0, 1.0, 0.0),
@@ -638,6 +646,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn white_ne_black() {
         assert!(!Oklab::visually_eq(
             Oklab::new(1.0, 1.0, 0.0),
@@ -652,6 +661,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn non_bw_neq_different_non_bw() {
         assert!(!Oklab::visually_eq(
             Oklab::new(0.3, 1.0, 0.0),
@@ -661,6 +671,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Oklab<f64>;
@@ -679,6 +690,7 @@
         assert_eq!(Oklab::<f32>::max_l(), 1.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Oklab,
         Oklab::new(0.1f32, 0.2, 0.3),
@@ -686,6 +698,7 @@
         Oklab::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::oklab::Oklaba;
 
--- a/palette/src/oklch.rs
+++ b/palette/src/oklch.rs
@@ -162,6 +162,7 @@
 mod test {
     use crate::convert::FromColorUnclamped;
     use crate::rgb::Rgb;
+    #[cfg(feature = "approx")]
     use crate::visual::{VisualColor, VisuallyEqual};
     use crate::{encoding, LinSrgb, Oklab, Oklch};
 
@@ -221,11 +222,13 @@
                 name, rgb, color
             );
 
+            #[cfg(feature = "approx")]
             println!("Color is white: {}", color.is_white(EPSILON));
 
             let oklch = Oklch::from_color_unclamped(color);
             println!("Oklch: {:?}", oklch);
             let roundtrip_color = Oklab::from_color_unclamped(oklch);
+            #[cfg(feature = "approx")]
             assert!(
                 Oklab::visually_eq(roundtrip_color, color, EPSILON),
                 "'{}' failed.\n{:?}\n!=\n{:?}",
@@ -237,6 +240,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         // chroma: 0.0 => infinity
         assert_ranges! {
@@ -252,6 +256,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Oklch::<f32>::min_l(), 0.0);
         assert_relative_eq!(Oklch::<f32>::max_l(), 1.0);
@@ -275,6 +280,7 @@
         assert_eq!(deserialized, Oklch::new(0.3, 0.8, 0.1));
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Oklch,
         Oklch::new(0.1f32, 0.2, 0.3),
@@ -282,6 +288,7 @@
         Oklch::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::oklch::Oklcha;
 
--- a/palette/src/relative_contrast.rs
+++ b/palette/src/relative_contrast.rs
@@ -126,6 +126,7 @@
 
 #[cfg(test)]
 #[allow(deprecated)]
+#[cfg(feature = "approx")]
 mod test {
     use core::str::FromStr;
 
--- a/palette/src/stimulus.rs
+++ b/palette/src/stimulus.rs
@@ -271,6 +271,7 @@
 #[cfg(test)]
 mod test {
     use crate::stimulus::IntoStimulus;
+    #[cfg(feature = "approx")]
     use approx::assert_relative_eq;
 
     #[test]
@@ -352,6 +353,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn uint_to_float() {
         fn into_stimulus_old(n: u8) -> f32 {
             let max = core::u8::MAX as f32;
@@ -365,6 +367,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn uint_to_double() {
         fn into_stimulus_old(n: u8) -> f64 {
             let max = core::u8::MAX as f64;
--- a/palette/src/xyz.rs
+++ b/palette/src/xyz.rs
@@ -584,6 +584,7 @@
     test_convert_into_from_xyz!(Xyz);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn luma() {
         let a = Xyz::<D65>::from_color(LinLuma::new(0.5));
         let b = Xyz::new(0.475235, 0.5, 0.544415);
@@ -591,6 +592,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Xyz::from_color(LinSrgb::new(1.0, 0.0, 0.0));
         let b = Xyz::new(0.41240, 0.21260, 0.01930);
@@ -598,6 +600,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Xyz::from_color(LinSrgb::new(0.0, 1.0, 0.0));
         let b = Xyz::new(0.35760, 0.71520, 0.11920);
@@ -605,6 +608,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Xyz::from_color(LinSrgb::new(0.0, 0.0, 1.0));
         let b = Xyz::new(0.18050, 0.07220, 0.95030);
@@ -612,6 +616,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Xyz<D65, f64>;
@@ -629,6 +634,7 @@
     raw_pixel_conversion_fail_tests!(Xyz<D65>: x, y, z);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Xyz::<D65>::min_x(), 0.0);
         assert_relative_eq!(Xyz::<D65>::min_y(), 0.0);
@@ -638,6 +644,7 @@
         assert_relative_eq!(Xyz::<D65, f64>::max_z(), Z_N);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Xyz<D65>,
         Xyz::new(0.1f32, 0.2, 0.3),
@@ -645,6 +652,7 @@
         Xyz::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{white_point::D65, xyz::Xyza};
 
--- a/palette/src/yxy.rs
+++ b/palette/src/yxy.rs
@@ -459,6 +459,7 @@
     test_convert_into_from_xyz!(Yxy);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn luma() {
         let a = Yxy::<D65>::from_color(LinLuma::new(0.5));
         let b = Yxy::new(0.312727, 0.329023, 0.5);
@@ -466,6 +467,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn red() {
         let a = Yxy::from_color(LinSrgb::new(1.0, 0.0, 0.0));
         let b = Yxy::new(0.64, 0.33, 0.212673);
@@ -473,6 +475,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn green() {
         let a = Yxy::from_color(LinSrgb::new(0.0, 1.0, 0.0));
         let b = Yxy::new(0.3, 0.6, 0.715152);
@@ -480,6 +483,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn blue() {
         let a = Yxy::from_color(LinSrgb::new(0.0, 0.0, 1.0));
         let b = Yxy::new(0.15, 0.06, 0.072175);
@@ -487,6 +491,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Yxy<D65, f64>;
@@ -504,6 +509,7 @@
     raw_pixel_conversion_fail_tests!(Yxy<D65>: x, y, luma);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Yxy::<D65>::min_x(), 0.0);
         assert_relative_eq!(Yxy::<D65>::min_y(), 0.0);
@@ -513,6 +519,7 @@
         assert_relative_eq!(Yxy::<D65>::max_luma(), 1.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Yxy<D65>,
         Yxy::new(0.1f32, 0.2, 0.3),
@@ -520,6 +527,7 @@
         Yxy::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{white_point::D65, yxy::Yxya};
 
--- a/palette/src/alpha/alpha.rs
+++ b/palette/src/alpha/alpha.rs
@@ -1143,6 +1143,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Rgba::<Srgb>::min_alpha(), 0.0);
         assert_relative_eq!(Rgba::<Srgb>::max_alpha(), 1.0);
--- a/palette/src/blend/test.rs
+++ b/palette/src/blend/test.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 use crate::{
     blend::{Blend, BlendWith, Compose},
     LinSrgb, LinSrgba,
--- a/palette/src/encoding/srgb.rs
+++ b/palette/src/encoding/srgb.rs
@@ -159,6 +159,7 @@
     };
 
     #[test]
+    #[cfg(feature = "approx")]
     fn rgb_to_xyz() {
         let dynamic = rgb_to_xyz_matrix::<Srgb, f64>();
         let constant = Srgb::rgb_to_xyz_matrix().unwrap();
@@ -166,6 +167,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn xyz_to_rgb() {
         let dynamic = matrix_inverse(rgb_to_xyz_matrix::<Srgb, f64>());
         let constant = Srgb::xyz_to_rgb_matrix().unwrap();
--- a/palette/src/luma/luma.rs
+++ b/palette/src/luma/luma.rs
@@ -1018,6 +1018,7 @@
     test_convert_into_from_xyz!(Luma);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Luma<Srgb, f64>;
@@ -1080,11 +1081,13 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Luma::<Srgb, f32>::min_luma(), 0.0);
         assert_relative_eq!(Luma::<Srgb, f32>::max_luma(), 1.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Luma<Srgb>,
         Luma::new(0.1f32),
@@ -1092,6 +1095,7 @@
         Luma::new(0.3)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{encoding::Srgb, luma::Lumaa};
 
--- a/palette/src/rgb/channels.rs
+++ b/palette/src/rgb/channels.rs
@@ -100,6 +100,7 @@
         assert_eq!(a3.color, x3);
 
         let unpacked: Srgb<u8> = Packed::<Rgba, u32>::from(0x80FF_80FF).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgb::new(0.5, 1.0, 0.5),
             unpacked.into_format(),
@@ -120,6 +121,7 @@
         assert_eq!(b4.color, y4);
 
         let unpacked: Srgba<u8> = Packed::<Rgba, u32>::from(0x80FF_80FF).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgba::new(0.5, 1.0, 0.5, 1.0),
             unpacked.into_format(),
@@ -140,6 +142,7 @@
         assert_eq!(a3.color, x3);
 
         let unpacked: Srgb<u8> = Packed::<Argb, u32>::from(0x80FF_80FF).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgb::new(1.0, 0.5, 1.0),
             unpacked.into_format(),
@@ -160,6 +163,7 @@
         assert_eq!(b4.color, y4);
 
         let unpacked: Srgba<u8> = Packed::<Argb, u32>::from(0x80FF_80FF).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgba::new(1.0, 0.5, 1.0, 0.5),
             unpacked.into_format(),
@@ -180,6 +184,7 @@
         assert_eq!(a3.color, x3);
 
         let unpacked: Srgb<u8> = Packed::<Bgra, u32>::from(0x80FF_FF80).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgb::new(1.0, 1.0, 0.5),
             unpacked.into_format(),
@@ -200,6 +205,7 @@
         assert_eq!(b4.color, y4);
 
         let unpacked: Srgba<u8> = Packed::<Bgra, u32>::from(0x80FF_FF80).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgba::new(1.0, 1.0, 0.5, 0.5),
             unpacked.into_format(),
@@ -220,6 +226,7 @@
         assert_eq!(a3.color, x3);
 
         let unpacked: Srgb<u8> = Packed::<Abgr, u32>::from(0x80FF_FF80).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgb::new(0.5, 1.0, 1.0),
             unpacked.into_format(),
@@ -240,6 +247,7 @@
         assert_eq!(b4.color, y4);
 
         let unpacked: Srgba<u8> = Packed::<Abgr, u32>::from(0x80FF_FF80).into();
+        #[cfg(feature = "approx")]
         assert_relative_eq!(
             Srgba::new(0.5, 1.0, 1.0, 0.5),
             unpacked.into_format(),
--- a/palette/src/rgb/rgb.rs
+++ b/palette/src/rgb/rgb.rs
@@ -1201,6 +1201,7 @@
     test_convert_into_from_xyz!(Rgb);
 
     #[test]
+    #[cfg(feature = "approx")]
     fn ranges() {
         assert_ranges! {
             Rgb<Srgb, f64>;
@@ -1395,6 +1396,7 @@
     }
 
     #[test]
+    #[cfg(feature = "approx")]
     fn check_min_max_components() {
         assert_relative_eq!(Rgb::<Srgb, f32>::min_red(), 0.0);
         assert_relative_eq!(Rgb::<Srgb, f32>::min_green(), 0.0);
@@ -1404,6 +1406,7 @@
         assert_relative_eq!(Rgb::<Srgb, f32>::max_blue(), 1.0);
     }
 
+    #[cfg(feature = "std")]
     struct_of_arrays_tests!(
         Rgb<Srgb>,
         Rgb::new(0.1f32, 0.2, 0.3),
@@ -1411,6 +1414,7 @@
         Rgb::new(0.3, 0.4, 0.5)
     );
 
+    #[cfg(feature = "std")]
     mod alpha {
         use crate::{encoding::Srgb, rgb::Rgba};
 
--- a/palette/tests/color_checker_data/mod.rs
+++ b/palette/tests/color_checker_data/mod.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 mod babel;
 mod color_checker;
 mod load_data;
--- a/palette/tests/convert/data_color_mine.rs
+++ b/palette/tests/convert/data_color_mine.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 /*
 List of color from www.colormine.org
 */
--- a/palette/tests/convert/lab_lch.rs
+++ b/palette/tests/convert/lab_lch.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 use approx::assert_relative_eq;
 
 use palette::convert::IntoColorUnclamped;
--- a/palette/tests/convert/mod.rs
+++ b/palette/tests/convert/mod.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 mod data_cie_15_2004;
 mod data_ciede_2000;
 mod data_color_mine;
--- a/palette/tests/hsluv_dataset/mod.rs
+++ b/palette/tests/hsluv_dataset/mod.rs
@@ -1 +1,2 @@
+#![cfg(feature = "approx")]
 pub mod hsluv_dataset;
--- a/palette/tests/pointer_dataset/mod.rs
+++ b/palette/tests/pointer_dataset/mod.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "approx")]
 mod pointer_data;
 
 #[test]

Oh, and full credit for the above patch goes to @plugwash - I am simply forwarding here what he offered for the Debian packaging.

Ogeon commented

Thanks for taking the time to get this to work. This library has a long history, so I'm not surprised there are a few bumps in the road.

These two features have been considered always available to the tests. Unit tests have to run with the std library enabled (unless that has changed), so disabling the std feature would historically either be a hassle or not change much, although now there are more features that use Vec and Box. The approx feature is always there for floating point comparisons. Many of the test cases produce some small inaccuracies (sometimes platform dependent) and need less precise comparison than complete equality.

I suppose the std feature could be made optional for the tests. I should add an alloc feature, but that's perhaps for later. I'm not sure disabling approx is meaningful, since it should just result in a lot of the most important test cases being disabled. 🤔

Ogeon commented

Hello again! I'm finally looking through these issues again (I needed more of a break than first expected), and just want to know if this is a blocking issue for you. I'm most likely not gating the test functions on approx since it's such an essential part (only optional because users may not need it), but std could be added although preferably also with alloc separated out.

Since only tests fail, it is not exactly blocking: I do have the option of skipping tests failing due to this. Obvious problem in that is that I may mask detection of other bugs by doing so.

What I do now is apply the patch, and I intent on attempting to massage that patch to match newer releases for as long as I can - and if at some point I am no longer able to keep that hack of mine alive and you haven't addressed this issue by then, I will shift the the lesser preferred option of sloppily skipping tests that fail.

Thanks for all your work on this.

Ogeon commented

Hmm, that's not ideal. 😬 Are the tests only running the features one by one, or do they also try combinations? I'm asking because it's likely that some tests will need both approx and some other feature. If not already now, then perhaps in the future, if it turns out to be a good idea to give color spaces their own features for faster compile time. It wouldn't be great if they don't run at all because of that.

If it's not possible for you to run the tests with approx always enabled, it may at least perhaps be possible to find some option where it's not sprinkled all over the place. I should also go through them and see how many actually need it in that case. 🤔

It is possible for me to do whatever adjustments to tests needed - including always adding approx feature.

Sorry that I seemingly failed to get my point across: I am flexible, and as a last resort I can simply skip tests.

...and to answer your concrete question: No, what I practice currently is not a full combinational matrix of features, only each single feature done alone, and all features, and no features.

Ogeon commented

Thanks that's good to know, so I know what's expected to work. 👍

If it's not too much of a hassle, I think it's a safer bet to include approx than to use this patch. At least while they are written for that assumption. I can still check what it would take to avoid that special case, though, other than what's suggested in the patch.

Ogeon commented

Like I mentioned in the PR, this patch should be unnecessary after the next release. Just keep in mind that a couple of tests use both approx and alloc, in case you want to be extra thorough.