use super::*;
use crate::{Color, Length};
#[test]
fn test_margin_single_value() {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(10.0));
ShorthandExpander::expand(&mut props, "margin", &value).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
}
#[test]
fn test_margin_two_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(10.0)),
PropertyValue::Length(Length::from_pt(20.0)),
]);
ShorthandExpander::expand(&mut props, "margin", &value).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
}
#[test]
fn test_margin_four_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(10.0)),
PropertyValue::Length(Length::from_pt(20.0)),
PropertyValue::Length(Length::from_pt(30.0)),
PropertyValue::Length(Length::from_pt(40.0)),
]);
ShorthandExpander::expand(&mut props, "margin", &value).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(30.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(40.0))
);
}
#[test]
fn test_padding_expansion() {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(5.0));
ShorthandExpander::expand(&mut props, "padding", &value).unwrap();
assert_eq!(
props.get(PropertyId::PaddingTop).unwrap().as_length(),
Some(Length::from_pt(5.0))
);
}
#[test]
fn test_non_shorthand() {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(10.0));
let expanded = ShorthandExpander::expand(&mut props, "font-size", &value).unwrap();
assert!(!expanded); }
#[test]
fn test_border_shorthand() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::String(std::borrow::Cow::Borrowed("solid")),
PropertyValue::Color(Color::RED),
]);
ShorthandExpander::expand(&mut props, "border", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::BorderRightWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::RED)
);
assert_eq!(
props.get(PropertyId::BorderBottomColor).unwrap().as_color(),
Some(Color::RED)
);
}
#[test]
fn test_border_top_shorthand() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(3.0)),
PropertyValue::Color(Color::BLUE),
]);
ShorthandExpander::expand(&mut props, "border-top", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::BLUE)
);
}
#[test]
fn test_border_width_single_value() {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(1.0));
ShorthandExpander::expand(&mut props, "border-width", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::BorderRightWidth).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
}
#[test]
fn test_border_color_four_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Color(Color::RED),
PropertyValue::Color(Color::GREEN),
PropertyValue::Color(Color::BLUE),
PropertyValue::Color(Color::BLACK),
]);
ShorthandExpander::expand(&mut props, "border-color", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::RED)
);
assert_eq!(
props.get(PropertyId::BorderRightColor).unwrap().as_color(),
Some(Color::GREEN)
);
assert_eq!(
props.get(PropertyId::BorderBottomColor).unwrap().as_color(),
Some(Color::BLUE)
);
assert_eq!(
props.get(PropertyId::BorderLeftColor).unwrap().as_color(),
Some(Color::BLACK)
);
}
#[test]
fn test_background_color_only() {
let mut props = PropertyList::new();
let value = PropertyValue::Color(Color::RED);
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::RED)
);
}
#[test]
fn test_background_image_only() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("url(bg.png)"));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundImage).unwrap().as_string(),
Some("url(bg.png)")
);
}
#[test]
fn test_background_repeat_only() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("no-repeat"));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some("no-repeat")
);
}
#[test]
fn test_background_attachment_only() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("fixed"));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundAttachment)
.unwrap()
.as_string(),
Some("fixed")
);
}
#[test]
fn test_background_position_keyword() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("center"));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundPosition)
.unwrap()
.as_string(),
Some("center")
);
}
#[test]
fn test_background_full_shorthand() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Color(Color::rgb(255, 0, 0)),
PropertyValue::String(std::borrow::Cow::Borrowed("url(bg.png)")),
PropertyValue::String(std::borrow::Cow::Borrowed("no-repeat")),
PropertyValue::String(std::borrow::Cow::Borrowed("fixed")),
PropertyValue::String(std::borrow::Cow::Borrowed("center")),
]);
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::rgb(255, 0, 0))
);
assert_eq!(
props.get(PropertyId::BackgroundImage).unwrap().as_string(),
Some("url(bg.png)")
);
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some("no-repeat")
);
assert_eq!(
props
.get(PropertyId::BackgroundAttachment)
.unwrap()
.as_string(),
Some("fixed")
);
assert_eq!(
props
.get(PropertyId::BackgroundPosition)
.unwrap()
.as_string(),
Some("center")
);
}
#[test]
fn test_background_partial_shorthand() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Color(Color::BLUE),
PropertyValue::String(std::borrow::Cow::Borrowed("no-repeat")),
]);
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::BLUE)
);
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some("no-repeat")
);
}
#[test]
fn test_background_different_order() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::String(std::borrow::Cow::Borrowed("no-repeat")),
PropertyValue::String(std::borrow::Cow::Borrowed("url(image.jpg)")),
PropertyValue::Color(Color::GREEN),
]);
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::GREEN)
);
assert_eq!(
props.get(PropertyId::BackgroundImage).unwrap().as_string(),
Some("url(image.jpg)")
);
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some("no-repeat")
);
}
#[test]
fn test_background_repeat_values() {
for repeat_val in [
"repeat",
"repeat-x",
"repeat-y",
"no-repeat",
"space",
"round",
] {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(repeat_val));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some(repeat_val)
);
}
}
#[test]
fn test_background_attachment_values() {
for attach_val in ["scroll", "fixed", "local"] {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(attach_val));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundAttachment)
.unwrap()
.as_string(),
Some(attach_val)
);
}
}
#[test]
fn test_background_position_keywords() {
for pos_val in ["top", "bottom", "left", "right", "center"] {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(pos_val));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundPosition)
.unwrap()
.as_string(),
Some(pos_val)
);
}
}
#[test]
fn test_background_position_with_percentage() {
use fop_types::Percentage;
let mut props = PropertyList::new();
let value = PropertyValue::Percentage(Percentage::new(50.0));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundPosition)
.unwrap()
.as_percentage(),
Some(Percentage::new(50.0))
);
}
#[test]
fn test_background_position_with_length() {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(100.0));
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BackgroundPosition)
.unwrap()
.as_length(),
Some(Length::from_pt(100.0))
);
}
#[test]
fn test_background_with_hex_color() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Color(Color::from_hex("#FF5733").unwrap()),
PropertyValue::String(std::borrow::Cow::Borrowed("repeat-x")),
]);
ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::from_hex("#FF5733").unwrap())
);
assert_eq!(
props.get(PropertyId::BackgroundRepeat).unwrap().as_string(),
Some("repeat-x")
);
}
#[test]
fn test_font_shorthand_full() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(
"italic small-caps bold 12pt/14pt Times New Roman, serif",
));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("italic")
);
assert_eq!(
props.get(PropertyId::FontVariant).unwrap().as_string(),
Some("small-caps")
);
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("bold")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
assert_eq!(
props.get(PropertyId::LineHeight).unwrap().as_length(),
Some(Length::from_pt(14.0))
);
match props.get(PropertyId::FontFamily).unwrap() {
PropertyValue::List(families) => {
assert_eq!(families.len(), 2);
assert_eq!(families[0].as_string(), Some("Times New Roman"));
assert_eq!(families[1].as_string(), Some("serif"));
}
_ => panic!("Expected font-family to be a list"),
}
}
#[test]
fn test_font_shorthand_minimal() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("12pt Arial"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontVariant).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("Arial")
);
}
#[test]
fn test_font_shorthand_with_weight_only() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("bold 16pt Georgia"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("bold")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(16.0))
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("Georgia")
);
}
#[test]
fn test_font_shorthand_with_numeric_weight() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("700 14pt Helvetica"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("700")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(14.0))
);
}
#[test]
fn test_font_shorthand_with_percentage_size() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("120% sans-serif"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
match props.get(PropertyId::FontSize).unwrap() {
PropertyValue::Percentage(pct) => {
assert_eq!(pct.as_fraction(), 1.2);
}
_ => panic!("Expected percentage"),
}
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("sans-serif")
);
}
#[test]
fn test_font_shorthand_with_px_units() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("16px monospace"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
}
#[test]
fn test_font_shorthand_with_line_height_number() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("12pt/1.5 Verdana"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
assert_eq!(
props.get(PropertyId::LineHeight).unwrap().as_number(),
Some(1.5)
);
}
#[test]
fn test_font_shorthand_with_line_height_percentage() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("10pt/120% Courier"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
match props.get(PropertyId::LineHeight).unwrap() {
PropertyValue::Percentage(pct) => {
assert_eq!(pct.as_fraction(), 1.2);
}
_ => panic!("Expected percentage for line-height"),
}
}
#[test]
fn test_font_shorthand_multiple_families() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(
"14pt Arial, Helvetica, sans-serif",
));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
match props.get(PropertyId::FontFamily).unwrap() {
PropertyValue::List(families) => {
assert_eq!(families.len(), 3);
assert_eq!(families[0].as_string(), Some("Arial"));
assert_eq!(families[1].as_string(), Some("Helvetica"));
assert_eq!(families[2].as_string(), Some("sans-serif"));
}
_ => panic!("Expected font-family to be a list"),
}
}
#[test]
fn test_font_shorthand_inherit() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("inherit"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert!(props.get(PropertyId::FontStyle).is_ok());
assert!(props.get(PropertyId::FontVariant).is_ok());
assert!(props.get(PropertyId::FontWeight).is_ok());
assert!(props.get(PropertyId::FontSize).is_ok());
assert!(props.get(PropertyId::LineHeight).is_ok());
assert!(props.get(PropertyId::FontFamily).is_ok());
}
#[test]
fn test_font_shorthand_initial() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("initial"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontVariant).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_string(),
Some("medium")
);
assert_eq!(
props.get(PropertyId::LineHeight).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("serif")
);
}
#[test]
fn test_font_shorthand_with_oblique() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("oblique 11pt Times"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("oblique")
);
}
#[test]
fn test_font_shorthand_keyword_sizes() {
let sizes = vec![
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large",
];
for size in sizes {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Owned(format!("{} serif", size)));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_string(),
Some(size)
);
}
}
#[test]
fn test_font_shorthand_with_cm_units() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("0.5cm Arial"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_cm(0.5))
);
}
#[test]
fn test_font_shorthand_with_mm_units() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("5mm Courier"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_mm(5.0))
);
}
#[test]
fn test_font_shorthand_complex_example() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed(
"italic 400 18pt/24pt Georgia, Times, serif",
));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("italic")
);
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("400")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(18.0))
);
assert_eq!(
props.get(PropertyId::LineHeight).unwrap().as_length(),
Some(Length::from_pt(24.0))
);
}
#[test]
fn test_margin_three_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(10.0)),
PropertyValue::Length(Length::from_pt(20.0)),
PropertyValue::Length(Length::from_pt(30.0)),
]);
ShorthandExpander::expand(&mut props, "margin", &value).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(30.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
}
#[test]
fn test_padding_two_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(5.0)),
PropertyValue::Length(Length::from_pt(15.0)),
]);
ShorthandExpander::expand(&mut props, "padding", &value).unwrap();
assert_eq!(
props.get(PropertyId::PaddingTop).unwrap().as_length(),
Some(Length::from_pt(5.0))
);
assert_eq!(
props.get(PropertyId::PaddingRight).unwrap().as_length(),
Some(Length::from_pt(15.0))
);
assert_eq!(
props.get(PropertyId::PaddingBottom).unwrap().as_length(),
Some(Length::from_pt(5.0))
);
assert_eq!(
props.get(PropertyId::PaddingLeft).unwrap().as_length(),
Some(Length::from_pt(15.0))
);
}
#[test]
fn test_padding_four_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::Length(Length::from_pt(3.0)),
PropertyValue::Length(Length::from_pt(4.0)),
]);
ShorthandExpander::expand(&mut props, "padding", &value).unwrap();
assert_eq!(
props.get(PropertyId::PaddingTop).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::PaddingRight).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::PaddingBottom).unwrap().as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::PaddingLeft).unwrap().as_length(),
Some(Length::from_pt(4.0))
);
}
#[test]
fn test_border_bottom_style_only() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("dashed"));
ShorthandExpander::expand(&mut props, "border-bottom", &value).unwrap();
assert_eq!(
props
.get(PropertyId::BorderBottomStyle)
.unwrap()
.as_string(),
Some("dashed")
);
}
#[test]
fn test_border_right_width_and_color() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::Color(Color::GREEN),
]);
ShorthandExpander::expand(&mut props, "border-right", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderRightWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::BorderRightColor).unwrap().as_color(),
Some(Color::GREEN)
);
}
#[test]
fn test_border_style_two_values() {
let mut props = PropertyList::new();
let value = PropertyValue::List(vec![
PropertyValue::String(std::borrow::Cow::Borrowed("solid")),
PropertyValue::String(std::borrow::Cow::Borrowed("dashed")),
]);
ShorthandExpander::expand(&mut props, "border-style", &value).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopStyle).unwrap().as_string(),
Some("solid")
);
assert_eq!(
props.get(PropertyId::BorderRightStyle).unwrap().as_string(),
Some("dashed")
);
assert_eq!(
props
.get(PropertyId::BorderBottomStyle)
.unwrap()
.as_string(),
Some("solid")
);
assert_eq!(
props.get(PropertyId::BorderLeftStyle).unwrap().as_string(),
Some("dashed")
);
}
#[test]
fn test_background_none_value() {
let mut props = PropertyList::new();
let value = PropertyValue::None;
let expanded = ShorthandExpander::expand(&mut props, "background", &value).unwrap();
assert!(expanded);
}
#[test]
fn test_font_shorthand_bold_weight_pt_size_family() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("bold 12pt serif"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("bold")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("serif")
);
}
#[test]
fn test_font_shorthand_italic_size_family() {
let mut props = PropertyList::new();
let value = PropertyValue::String(std::borrow::Cow::Borrowed("italic 10pt sans-serif"));
ShorthandExpander::expand(&mut props, "font", &value).unwrap();
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("italic")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("sans-serif")
);
}
#[test]
fn test_shorthand_returns_true_for_known_shorthands() {
for name in &[
"margin",
"padding",
"border",
"border-top",
"border-right",
"border-bottom",
"border-left",
"border-style",
"border-color",
"border-width",
"font",
"background",
] {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(1.0));
let expanded = ShorthandExpander::expand(&mut props, name, &value).unwrap();
assert!(
expanded,
"Expected '{}' to be recognized as a shorthand",
name
);
}
}
#[test]
fn test_shorthand_returns_false_for_non_shorthands() {
for name in &[
"font-size",
"font-weight",
"color",
"text-align",
"line-height",
"letter-spacing",
"word-spacing",
] {
let mut props = PropertyList::new();
let value = PropertyValue::Length(Length::from_pt(1.0));
let expanded = ShorthandExpander::expand(&mut props, name, &value).unwrap();
assert!(!expanded, "Expected '{}' to NOT be a shorthand", name);
}
}
mod tests_extended {
use super::*;
use fop_types::{Color, Length};
#[test]
fn test_margin_one_value() {
let mut props = PropertyList::new();
let v = PropertyValue::Length(Length::from_pt(8.0));
ShorthandExpander::expand(&mut props, "margin", &v).unwrap();
for id in [
PropertyId::MarginTop,
PropertyId::MarginRight,
PropertyId::MarginBottom,
PropertyId::MarginLeft,
] {
assert_eq!(
props.get(id).unwrap().as_length(),
Some(Length::from_pt(8.0)),
"Failed for {:?}",
id
);
}
}
#[test]
fn test_margin_two_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(10.0)),
PropertyValue::Length(Length::from_pt(20.0)),
]);
ShorthandExpander::expand(&mut props, "margin", &v).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(10.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(20.0))
);
}
#[test]
fn test_margin_four_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::Length(Length::from_pt(3.0)),
PropertyValue::Length(Length::from_pt(4.0)),
]);
ShorthandExpander::expand(&mut props, "margin", &v).unwrap();
assert_eq!(
props.get(PropertyId::MarginTop).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::MarginRight).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::MarginBottom).unwrap().as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::MarginLeft).unwrap().as_length(),
Some(Length::from_pt(4.0))
);
}
#[test]
fn test_padding_one_value() {
let mut props = PropertyList::new();
let v = PropertyValue::Length(Length::from_pt(6.0));
ShorthandExpander::expand(&mut props, "padding", &v).unwrap();
for id in [
PropertyId::PaddingTop,
PropertyId::PaddingRight,
PropertyId::PaddingBottom,
PropertyId::PaddingLeft,
] {
assert_eq!(
props.get(id).unwrap().as_length(),
Some(Length::from_pt(6.0))
);
}
}
#[test]
fn test_padding_three_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::Length(Length::from_pt(3.0)),
]);
ShorthandExpander::expand(&mut props, "padding", &v).unwrap();
assert_eq!(
props.get(PropertyId::PaddingTop).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::PaddingRight).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::PaddingBottom).unwrap().as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::PaddingLeft).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
}
#[test]
fn test_border_all_sides_three_components() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::String(std::borrow::Cow::Borrowed("solid")),
PropertyValue::Color(Color::BLACK),
]);
ShorthandExpander::expand(&mut props, "border", &v).unwrap();
for side in [
(
PropertyId::BorderTopWidth,
PropertyId::BorderTopStyle,
PropertyId::BorderTopColor,
),
(
PropertyId::BorderRightWidth,
PropertyId::BorderRightStyle,
PropertyId::BorderRightColor,
),
(
PropertyId::BorderBottomWidth,
PropertyId::BorderBottomStyle,
PropertyId::BorderBottomColor,
),
(
PropertyId::BorderLeftWidth,
PropertyId::BorderLeftStyle,
PropertyId::BorderLeftColor,
),
] {
assert_eq!(
props.get(side.0).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(props.get(side.1).unwrap().as_string(), Some("solid"));
assert_eq!(props.get(side.2).unwrap().as_color(), Some(Color::BLACK));
}
}
#[test]
fn test_border_width_only() {
let mut props = PropertyList::new();
let v = PropertyValue::Length(Length::from_pt(2.0));
ShorthandExpander::expand(&mut props, "border", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props.get(PropertyId::BorderLeftWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
}
#[test]
fn test_border_color_only() {
let mut props = PropertyList::new();
let v = PropertyValue::Color(Color::RED);
ShorthandExpander::expand(&mut props, "border", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::RED)
);
assert_eq!(
props.get(PropertyId::BorderRightColor).unwrap().as_color(),
Some(Color::RED)
);
}
#[test]
fn test_border_top_full() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(3.0)),
PropertyValue::String(std::borrow::Cow::Borrowed("dashed")),
PropertyValue::Color(Color::BLUE),
]);
ShorthandExpander::expand(&mut props, "border-top", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::BorderTopStyle).unwrap().as_string(),
Some("dashed")
);
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::BLUE)
);
assert!(!props.is_explicit(PropertyId::BorderBottomWidth));
}
#[test]
fn test_border_left_width_and_style() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::String(std::borrow::Cow::Borrowed("dotted")),
]);
ShorthandExpander::expand(&mut props, "border-left", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderLeftWidth).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::BorderLeftStyle).unwrap().as_string(),
Some("dotted")
);
}
#[test]
fn test_border_width_four_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Length(Length::from_pt(1.0)),
PropertyValue::Length(Length::from_pt(2.0)),
PropertyValue::Length(Length::from_pt(3.0)),
PropertyValue::Length(Length::from_pt(4.0)),
]);
ShorthandExpander::expand(&mut props, "border-width", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopWidth).unwrap().as_length(),
Some(Length::from_pt(1.0))
);
assert_eq!(
props.get(PropertyId::BorderRightWidth).unwrap().as_length(),
Some(Length::from_pt(2.0))
);
assert_eq!(
props
.get(PropertyId::BorderBottomWidth)
.unwrap()
.as_length(),
Some(Length::from_pt(3.0))
);
assert_eq!(
props.get(PropertyId::BorderLeftWidth).unwrap().as_length(),
Some(Length::from_pt(4.0))
);
}
#[test]
fn test_border_color_four_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Color(Color::RED),
PropertyValue::Color(Color::GREEN),
PropertyValue::Color(Color::BLUE),
PropertyValue::Color(Color::BLACK),
]);
ShorthandExpander::expand(&mut props, "border-color", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopColor).unwrap().as_color(),
Some(Color::RED)
);
assert_eq!(
props.get(PropertyId::BorderRightColor).unwrap().as_color(),
Some(Color::GREEN)
);
assert_eq!(
props.get(PropertyId::BorderBottomColor).unwrap().as_color(),
Some(Color::BLUE)
);
assert_eq!(
props.get(PropertyId::BorderLeftColor).unwrap().as_color(),
Some(Color::BLACK)
);
}
#[test]
fn test_border_color_one_value() {
let mut props = PropertyList::new();
let v = PropertyValue::Color(Color::RED);
ShorthandExpander::expand(&mut props, "border-color", &v).unwrap();
for id in [
PropertyId::BorderTopColor,
PropertyId::BorderRightColor,
PropertyId::BorderBottomColor,
PropertyId::BorderLeftColor,
] {
assert_eq!(props.get(id).unwrap().as_color(), Some(Color::RED));
}
}
#[test]
fn test_border_style_one_value() {
let mut props = PropertyList::new();
let v = PropertyValue::String(std::borrow::Cow::Borrowed("solid"));
ShorthandExpander::expand(&mut props, "border-style", &v).unwrap();
for id in [
PropertyId::BorderTopStyle,
PropertyId::BorderRightStyle,
PropertyId::BorderBottomStyle,
PropertyId::BorderLeftStyle,
] {
assert_eq!(props.get(id).unwrap().as_string(), Some("solid"));
}
}
#[test]
fn test_border_style_four_values() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::String(std::borrow::Cow::Borrowed("solid")),
PropertyValue::String(std::borrow::Cow::Borrowed("dashed")),
PropertyValue::String(std::borrow::Cow::Borrowed("dotted")),
PropertyValue::String(std::borrow::Cow::Borrowed("none")),
]);
ShorthandExpander::expand(&mut props, "border-style", &v).unwrap();
assert_eq!(
props.get(PropertyId::BorderTopStyle).unwrap().as_string(),
Some("solid")
);
assert_eq!(
props.get(PropertyId::BorderRightStyle).unwrap().as_string(),
Some("dashed")
);
assert_eq!(
props
.get(PropertyId::BorderBottomStyle)
.unwrap()
.as_string(),
Some("dotted")
);
assert_eq!(
props.get(PropertyId::BorderLeftStyle).unwrap().as_string(),
Some("none")
);
}
#[test]
fn test_font_shorthand_bold_12pt_arial() {
let mut props = PropertyList::new();
let v = PropertyValue::String(std::borrow::Cow::Borrowed("bold 12pt Arial"));
ShorthandExpander::expand(&mut props, "font", &v).unwrap();
assert_eq!(
props.get(PropertyId::FontWeight).unwrap().as_string(),
Some("bold")
);
assert_eq!(
props.get(PropertyId::FontSize).unwrap().as_length(),
Some(Length::from_pt(12.0))
);
assert_eq!(
props.get(PropertyId::FontFamily).unwrap().as_string(),
Some("Arial")
);
assert_eq!(
props.get(PropertyId::FontStyle).unwrap().as_string(),
Some("normal")
);
assert_eq!(
props.get(PropertyId::FontVariant).unwrap().as_string(),
Some("normal")
);
}
#[test]
fn test_background_color_and_image() {
let mut props = PropertyList::new();
let v = PropertyValue::List(vec![
PropertyValue::Color(Color::WHITE),
PropertyValue::String(std::borrow::Cow::Borrowed("url(banner.png)")),
]);
ShorthandExpander::expand(&mut props, "background", &v).unwrap();
assert_eq!(
props.get(PropertyId::BackgroundColor).unwrap().as_color(),
Some(Color::WHITE)
);
assert_eq!(
props.get(PropertyId::BackgroundImage).unwrap().as_string(),
Some("url(banner.png)")
);
}
#[test]
fn test_expand_returns_false_for_color() {
let mut props = PropertyList::new();
let v = PropertyValue::Color(Color::RED);
let result = ShorthandExpander::expand(&mut props, "color", &v).unwrap();
assert!(!result);
}
#[test]
fn test_expand_returns_false_for_display() {
let mut props = PropertyList::new();
let v = PropertyValue::String(std::borrow::Cow::Borrowed("block"));
let result = ShorthandExpander::expand(&mut props, "display", &v).unwrap();
assert!(!result);
}
#[test]
fn test_expand_returns_false_for_unknown() {
let mut props = PropertyList::new();
let v = PropertyValue::String(std::borrow::Cow::Borrowed("whatever"));
let result = ShorthandExpander::expand(&mut props, "not-a-shorthand", &v).unwrap();
assert!(!result);
}
}