✨ (pagetop): Añade PageTopSvg::Tile y ajusta Image
This commit is contained in:
parent
16eec316c4
commit
f8f023b513
5 changed files with 263 additions and 18 deletions
133
tests/component_image.rs
Normal file
133
tests/component_image.rs
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
async fn render(mut image: Image) -> String {
|
||||
image.render(&mut Context::default()).await.into_string()
|
||||
}
|
||||
|
||||
fn logo() -> Image {
|
||||
Image::with(image::Source::logo(PageTopSvg::Color))
|
||||
}
|
||||
|
||||
// **< Logo size >**********************************************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_without_size_gets_the_default_dimensions() {
|
||||
let html = render(logo()).await;
|
||||
|
||||
assert!(html.contains(r#"style="width: 1.25rem; height: 1.25rem""#));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_with_only_width_does_not_get_a_default_height() {
|
||||
let html = render(logo().with_size(image::Size::Width(UnitValue::Px(320)))).await;
|
||||
|
||||
assert!(html.contains(r#"style="width: 320px""#));
|
||||
assert!(!html.contains("height"));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_with_only_height_does_not_get_a_default_width() {
|
||||
let html = render(logo().with_size(image::Size::Height(UnitValue::Px(40)))).await;
|
||||
|
||||
assert!(html.contains(r#"style="height: 40px""#));
|
||||
assert!(!html.contains("width:"));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_with_a_percentage_keeps_a_single_dimension() {
|
||||
// A percentage height would refer to the container height, not to the width.
|
||||
let html = render(logo().with_size(image::Size::Width(UnitValue::RelPct(33.0)))).await;
|
||||
|
||||
assert!(html.contains(r#"style="width: 33%""#));
|
||||
assert!(!html.contains("height"));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_with_both_dimensions_uses_them() {
|
||||
let both = render(logo().with_size(image::Size::Both(UnitValue::Px(36)))).await;
|
||||
let different = render(logo().with_size(image::Size::Dimensions(
|
||||
UnitValue::Px(10),
|
||||
UnitValue::Px(20),
|
||||
)))
|
||||
.await;
|
||||
|
||||
assert!(both.contains(r#"style="width: 36px; height: 36px""#));
|
||||
// Both dimensions are set explicitly, so the default is not applied.
|
||||
assert!(different.contains(r#"style="width: 10px; height: 20px""#));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_keeps_a_custom_style_instead_of_the_default_dimensions() {
|
||||
let width = render(logo().with_prop(PropsOp::add_style("width", "3em"))).await;
|
||||
let both = render(
|
||||
logo()
|
||||
.with_prop(PropsOp::add_style("width", "3em"))
|
||||
.with_prop(PropsOp::add_style("height", "4em")),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(width.contains(r#"style="width: 3em""#));
|
||||
assert!(!width.contains("height"));
|
||||
assert!(both.contains(r#"style="width: 3em; height: 4em""#));
|
||||
assert!(!both.contains("1.25rem"));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_with_a_size_without_value_gets_the_default_dimensions() {
|
||||
// `UnitValue::None` writes no declaration, so no dimension is actually set.
|
||||
for size in [
|
||||
image::Size::Width(UnitValue::None),
|
||||
image::Size::Height(UnitValue::None),
|
||||
image::Size::Both(UnitValue::None),
|
||||
image::Size::Dimensions(UnitValue::None, UnitValue::None),
|
||||
] {
|
||||
let html = render(logo().with_size(size)).await;
|
||||
|
||||
assert!(html.contains(r#"style="width: 1.25rem; height: 1.25rem""#));
|
||||
}
|
||||
}
|
||||
|
||||
// **< Other sources >******************************************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn responsive_image_without_size_has_no_style() {
|
||||
let html = render(Image::with(image::Source::responsive("/photo.jpg"))).await;
|
||||
|
||||
assert!(html.starts_with(r#"<img src="/photo.jpg""#));
|
||||
assert!(!html.contains("style="));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn responsive_image_with_only_width_does_not_get_a_height() {
|
||||
let html = render(
|
||||
Image::with(image::Source::responsive("/photo.jpg"))
|
||||
.with_size(image::Size::Width(UnitValue::Px(320))),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(html.contains(r#"style="width: 320px""#));
|
||||
assert!(!html.contains("height"));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn responsive_image_with_a_size_without_value_has_no_style() {
|
||||
let html = render(
|
||||
Image::with(image::Source::responsive("/photo.jpg"))
|
||||
.with_size(image::Size::Width(UnitValue::None)),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!html.contains("style="));
|
||||
}
|
||||
|
||||
// **< Alternative text >***************************************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn logo_alternative_is_an_accessible_label_or_hides_the_svg() {
|
||||
let labeled = render(logo().with_alternative(Lc::n("PageTop"))).await;
|
||||
let decorative = render(logo()).await;
|
||||
|
||||
assert!(labeled.contains(r#"role="img" aria-label="PageTop""#));
|
||||
assert!(decorative.contains(r#"aria-hidden="true""#));
|
||||
assert!(!decorative.contains("aria-label"));
|
||||
}
|
||||
53
tests/html_logo.rs
Normal file
53
tests/html_logo.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
// The background is made of `rect`s; only the logo paths use the line color.
|
||||
fn line_color(bg: (u8, u8, u8)) -> &'static str {
|
||||
let svg = PageTopSvg::TileRGB(bg.0, bg.1, bg.2).markup().into_string();
|
||||
let dark = svg.contains("<path fill=\"rgb(10,11,9)\"");
|
||||
let white = svg.contains("<path fill=\"rgb(255,255,255)\"");
|
||||
assert_ne!(dark, white, "the line must use exactly one color");
|
||||
if dark { "dark" } else { "white" }
|
||||
}
|
||||
|
||||
// **< PageTopSvg::TileRGB >************************************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn tile_rgb_uses_a_white_line_on_dark_backgrounds() {
|
||||
assert_eq!(line_color((0, 82, 204)), "white");
|
||||
assert_eq!(line_color((0, 0, 0)), "white");
|
||||
assert_eq!(line_color((220, 20, 60)), "white");
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn tile_rgb_uses_a_dark_line_on_light_backgrounds() {
|
||||
assert_eq!(line_color((255, 184, 75)), "dark");
|
||||
assert_eq!(line_color((0, 255, 0)), "dark");
|
||||
assert_eq!(line_color((255, 255, 255)), "dark");
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn tile_rgb_switches_line_color_around_the_contrast_threshold() {
|
||||
// Relative luminance ~0.181 and ~0.188 respectively; with the default dark and light lines the
|
||||
// contrast with both is equal at ~0.186.
|
||||
assert_eq!(line_color((118, 118, 118)), "white");
|
||||
assert_eq!(line_color((120, 120, 120)), "dark");
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn tile_keeps_a_white_line_on_its_default_dark_background() {
|
||||
let svg = PageTopSvg::Tile.markup().into_string();
|
||||
|
||||
assert!(svg.contains("<path fill=\"rgb(255,255,255)\""));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn tile_keeps_a_square_bottom_right_corner() {
|
||||
for svg in [
|
||||
PageTopSvg::Tile.markup().into_string(),
|
||||
PageTopSvg::TileRGB(0, 82, 204).markup().into_string(),
|
||||
] {
|
||||
// Rounded background plus a square of the same color covering the bottom-right corner.
|
||||
assert!(svg.contains("rx=\"200\""));
|
||||
assert!(svg.contains("<rect x=\"1414\" y=\"1414\" width=\"200\" height=\"200\""));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue