use super::*;
use snora_design::{Color as SnColor, Tokens, contrast::contrast_ratio};
const AA: f32 = 4.5;
const VISIBILITY_FLOOR: f32 = 1.3;
fn named_presets() -> [(&'static str, Tokens); 4] {
[
("light", Tokens::light()),
("dark", Tokens::dark()),
("high_contrast_light", Tokens::high_contrast_light()),
("high_contrast_dark", Tokens::high_contrast_dark()),
]
}
fn to_sn(c: iced::Color) -> SnColor {
SnColor::rgba(c.r, c.g, c.b, c.a)
}
fn composite(fg: iced::Color, bg: iced::Color) -> iced::Color {
let a = fg.a;
iced::Color {
r: fg.r * a + bg.r * (1.0 - a),
g: fg.g * a + bg.g * (1.0 - a),
b: fg.b * a + bg.b * (1.0 - a),
a: 1.0,
}
}
#[test]
fn dim_visible_against_background_all_presets() {
for (name, t) in named_presets() {
let background = to_iced_color(t.palette.background);
let dim = dim_color(&t);
let composited = composite(dim, background);
let r = contrast_ratio(to_sn(composited), to_sn(background));
assert!(
r >= VISIBILITY_FLOOR,
"{name}: dim composited over background contrast {r:.3} < {VISIBILITY_FLOOR} \
— the modal dim is not visibly distinguishable from the page"
);
}
}
#[test]
fn dim_alpha_is_always_dim_alpha_constant() {
for (name, t) in named_presets() {
let dim = dim_color(&t);
assert_eq!(
dim.a, DIM_ALPHA,
"{name}: dim_color's alpha must stay fixed at DIM_ALPHA regardless of preset"
);
}
}
#[test]
fn dim_color_picks_the_opposite_pole() {
let mut white_bg_tokens = Tokens::light();
white_bg_tokens.palette.background = SnColor::rgb(1.0, 1.0, 1.0);
let dim = dim_color(&white_bg_tokens);
assert_eq!(
(dim.r, dim.g, dim.b),
(0.0, 0.0, 0.0),
"a light (white) background must pick the black pole"
);
let mut black_bg_tokens = Tokens::high_contrast_dark();
black_bg_tokens.palette.background = SnColor::rgb(0.0, 0.0, 0.0);
let dim = dim_color(&black_bg_tokens);
assert_eq!(
(dim.r, dim.g, dim.b),
(1.0, 1.0, 1.0),
"a dark (black) background must pick the white pole"
);
}
#[test]
fn card_border_distinguishable_from_background_all_presets() {
for (name, t) in named_presets() {
let background = to_iced_color(t.palette.background);
let card = dialog_card_style(&t);
let r = contrast_ratio(to_sn(card.style.border.color), to_sn(background));
assert!(
r >= VISIBILITY_FLOOR,
"{name}: card border vs background contrast {r:.3} < {VISIBILITY_FLOOR} \
— a border this close to the page would make the card's edge invisible"
);
}
}
#[test]
fn fill_equals_background_in_light_presets_by_token_design() {
for name in ["light", "high_contrast_light"] {
let t = if name == "light" {
Tokens::light()
} else {
Tokens::high_contrast_light()
};
assert_eq!(
t.palette.surface_raised, t.palette.background,
"{name}: this test's premise (fill == background in these two presets) no longer \
holds — re-evaluate whether card_border_distinguishable_from_background_all_presets \
is still the right test, or whether a fill-distinguishable test is now possible too"
);
}
}
#[test]
fn card_style_matches_token_roles_exactly() {
for (name, t) in named_presets() {
let card = dialog_card_style(&t);
assert_eq!(
card.style.background,
Some(to_iced_color(t.palette.surface_raised).into()),
"{name}: card fill must equal surface_raised exactly"
);
assert_eq!(
card.style.border.color,
to_iced_color(t.palette.border),
"{name}: card border color must equal the border role exactly"
);
assert_eq!(
card.style.border.radius,
t.radius.lg.into(),
"{name}: card border radius must equal radius.lg exactly"
);
assert_eq!(
card.padding, t.spacing.lg,
"{name}: card padding must equal spacing.lg exactly"
);
assert_eq!(
card.style.shadow,
iced::Shadow::default(),
"{name}: card must be border-defined, not shadow-defined (RFC-039) — \
card_raised's shadow must be zeroed, not inherited"
);
}
}
#[test]
fn card_text_meets_aa_all_presets() {
for (name, t) in named_presets() {
let card = dialog_card_style(&t);
let text = card
.style
.text_color
.expect("card style must set a text color");
let fill = to_iced_color(t.palette.surface_raised);
let r = contrast_ratio(to_sn(text), to_sn(fill));
assert!(
r >= AA,
"{name}: card text contrast {r:.2} < {AA} (WCAG AA)"
);
}
}