use parcel_css::{
declaration::DeclarationBlock,
properties::{Property, PropertyId},
stylesheet::{ParserOptions, PrinterOptions},
traits::ToCss,
vendor_prefix::VendorPrefix,
};
fn get_test(decls: &str, property_id: PropertyId, expected: Option<(&str, bool)>) {
let decls = DeclarationBlock::parse_string(decls, ParserOptions::default()).unwrap();
let v = decls.get(&property_id);
if let Some((expected, important)) = expected {
let (value, is_important) = v.unwrap();
assert_eq!(
*value,
Property::parse_string(property_id, expected, ParserOptions::default()).unwrap()
);
assert_eq!(is_important, important);
} else {
assert_eq!(v, None)
}
}
#[test]
fn test_get() {
get_test("color: red", PropertyId::Color, Some(("red", false)));
get_test("color: red !important", PropertyId::Color, Some(("red", true)));
get_test("color: green; color: red", PropertyId::Color, Some(("red", false)));
get_test(
r#"
margin-top: 5px;
margin-bottom: 5px;
margin-left: 5px;
margin-right: 5px;
"#,
PropertyId::Margin,
Some(("5px", false)),
);
get_test(
r#"
margin-top: 5px;
margin-bottom: 5px;
margin-left: 6px;
margin-right: 6px;
"#,
PropertyId::Margin,
Some(("5px 6px", false)),
);
get_test(
r#"
margin-top: 5px;
margin-bottom: 5px;
margin-left: 6px;
margin-right: 6px;
"#,
PropertyId::Margin,
Some(("5px 6px", false)),
);
get_test(
r#"
margin-top: 5px;
margin-bottom: 5px;
"#,
PropertyId::Margin,
None,
);
get_test(
r#"
margin-top: 5px;
margin-bottom: 5px;
margin-left: 5px !important;
margin-right: 5px;
"#,
PropertyId::Margin,
None,
);
get_test(
r#"
margin-top: 5px !important;
margin-bottom: 5px !important;
margin-left: 5px !important;
margin-right: 5px !important;
"#,
PropertyId::Margin,
Some(("5px", true)),
);
get_test(
"margin: 5px 6px 7px 8px",
PropertyId::Margin,
Some(("5px 6px 7px 8px", false)),
);
get_test("margin: 5px 6px 7px 8px", PropertyId::MarginTop, Some(("5px", false)));
get_test(
r#"
border: 1px solid red;
border-color: green;
"#,
PropertyId::Border,
Some(("1px solid green", false)),
);
get_test(
r#"
border: 1px solid red;
border-left-color: green;
"#,
PropertyId::Border,
None,
);
get_test("background: red", PropertyId::Background, Some(("red", false)));
get_test("background: red", PropertyId::BackgroundColor, Some(("red", false)));
get_test(
"background: red url(foo.png)",
PropertyId::BackgroundColor,
Some(("red", false)),
);
get_test(
"background: url(foo.png), url(bar.png) red",
PropertyId::BackgroundColor,
Some(("red", false)),
);
get_test(
"background: url(foo.png) green, url(bar.png) red",
PropertyId::BackgroundColor,
Some(("red", false)),
);
get_test(
"background: linear-gradient(red, green)",
PropertyId::BackgroundImage,
Some(("linear-gradient(red, green)", false)),
);
get_test(
"background: linear-gradient(red, green), linear-gradient(#fff, #000)",
PropertyId::BackgroundImage,
Some(("linear-gradient(red, green), linear-gradient(#fff, #000)", false)),
);
get_test(
"background: linear-gradient(red, green) repeat-x, linear-gradient(#fff, #000) repeat-y",
PropertyId::BackgroundImage,
Some(("linear-gradient(red, green), linear-gradient(#fff, #000)", false)),
);
get_test(
"background: linear-gradient(red, green) repeat-x, linear-gradient(#fff, #000) repeat-y",
PropertyId::BackgroundRepeat,
Some(("repeat-x, repeat-y", false)),
);
get_test(
r#"
background: linear-gradient(red, green);
background-position-x: 20px;
background-position-y: 10px;
background-size: 50px 100px;
background-repeat: repeat no-repeat;
"#,
PropertyId::Background,
Some(("linear-gradient(red, green) 20px 10px / 50px 100px repeat-x", false)),
);
get_test(
r#"
background: linear-gradient(red, green);
background-position-x: 20px;
background-position-y: 10px !important;
background-size: 50px 100px;
background-repeat: repeat no-repeat;
"#,
PropertyId::Background,
None,
);
get_test(
r#"
background: linear-gradient(red, green), linear-gradient(#fff, #000) gray;
background-position-x: right 20px, 10px;
background-position-y: top 20px, 15px;
background-size: 50px 50px, auto;
background-repeat: repeat no-repeat, no-repeat;
"#,
PropertyId::Background,
Some(("linear-gradient(red, green) right 20px top 20px / 50px 50px repeat-x, gray linear-gradient(#fff, #000) 10px 15px no-repeat", false)),
);
get_test(
r#"
background: linear-gradient(red, green);
background-position-x: right 20px, 10px;
background-position-y: top 20px, 15px;
background-size: 50px 50px, auto;
background-repeat: repeat no-repeat, no-repeat;
"#,
PropertyId::Background,
None,
);
get_test(
r#"
background: linear-gradient(red, green);
background-position: 20px 10px;
background-size: 50px 100px;
background-repeat: repeat no-repeat;
"#,
PropertyId::Background,
Some(("linear-gradient(red, green) 20px 10px / 50px 100px repeat-x", false)),
);
get_test(
r#"
background-position-x: 20px;
background-position-y: 10px;
"#,
PropertyId::BackgroundPosition,
Some(("20px 10px", false)),
);
get_test(
r#"
background: linear-gradient(red, green) 20px 10px;
"#,
PropertyId::BackgroundPosition,
Some(("20px 10px", false)),
);
get_test(
r#"
background: linear-gradient(red, green) 20px 10px;
"#,
PropertyId::BackgroundPositionX,
Some(("20px", false)),
);
get_test(
r#"
background: linear-gradient(red, green) 20px 10px;
"#,
PropertyId::BackgroundPositionY,
Some(("10px", false)),
);
get_test(
"mask-border: linear-gradient(red, green) 25",
PropertyId::MaskBorderSource,
Some(("linear-gradient(red, green)", false)),
);
get_test("grid-area: a / b / c / d", PropertyId::GridRowStart, Some(("a", false)));
get_test("grid-area: a / b / c / d", PropertyId::GridRowEnd, Some(("c", false)));
get_test("grid-area: a / b / c / d", PropertyId::GridRow, Some(("a / c", false)));
get_test(
"grid-area: a / b / c / d",
PropertyId::GridColumn,
Some(("b / d", false)),
);
get_test(
r#"
grid-template-rows: auto 1fr;
grid-template-columns: auto 1fr auto;
grid-template-areas: none;
"#,
PropertyId::GridTemplate,
Some(("auto 1fr / auto 1fr auto", false)),
);
get_test(
r#"
grid-template-areas: ". a a ."
". b b .";
grid-template-rows: auto 1fr;
grid-template-columns: 10px 1fr 1fr 10px;
"#,
PropertyId::GridTemplate,
Some((
r#"
". a a ."
". b b ." 1fr
/ 10px 1fr 1fr 10px
"#,
false,
)),
);
get_test(
r#"
grid-template-areas: "a a a"
"b b b";
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr;
"#,
PropertyId::GridTemplate,
None,
);
get_test(
r#"
grid-template-areas: "a a a"
"b b b";
grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
grid-template-columns: auto 1fr auto;
grid-auto-flow: row;
grid-auto-rows: auto;
grid-auto-columns: auto;
"#,
PropertyId::Grid,
Some((
r#"
[header-top] "a a a" [header-bottom]
[main-top] "b b b" 1fr [main-bottom]
/ auto 1fr auto
"#,
false,
)),
);
get_test(
r#"
grid-template-areas: "a a a"
"b b b";
grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
grid-template-columns: auto 1fr auto;
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: 1fr;
"#,
PropertyId::Grid,
None,
);
get_test(
r#"
flex-direction: row;
flex-wrap: wrap;
"#,
PropertyId::FlexFlow(VendorPrefix::None),
Some(("row wrap", false)),
);
get_test(
r#"
-webkit-flex-direction: row;
-webkit-flex-wrap: wrap;
"#,
PropertyId::FlexFlow(VendorPrefix::WebKit),
Some(("row wrap", false)),
);
get_test(
r#"
flex-direction: row;
flex-wrap: wrap;
"#,
PropertyId::FlexFlow(VendorPrefix::WebKit),
None,
);
get_test(
r#"
-webkit-flex-direction: row;
flex-wrap: wrap;
"#,
PropertyId::FlexFlow(VendorPrefix::WebKit),
None,
);
get_test(
r#"
-webkit-flex-direction: row;
flex-wrap: wrap;
"#,
PropertyId::FlexFlow(VendorPrefix::None),
None,
);
get_test(
r#"
-webkit-flex-flow: row;
"#,
PropertyId::FlexDirection(VendorPrefix::WebKit),
Some(("row", false)),
);
get_test(
r#"
-webkit-flex-flow: row;
"#,
PropertyId::FlexDirection(VendorPrefix::None),
None,
);
}
fn set_test(orig: &str, property: &str, value: &str, important: bool, expected: &str) {
let mut decls = DeclarationBlock::parse_string(orig, ParserOptions::default()).unwrap();
decls.set(
Property::parse_string(property.into(), value, ParserOptions::default()).unwrap(),
important,
);
assert_eq!(decls.to_css_string(PrinterOptions::default()).unwrap(), expected);
}
#[test]
fn test_set() {
set_test("color: red", "color", "green", false, "color: green");
set_test("color: red !important", "color", "green", false, "color: green");
set_test("color: red", "color", "green", true, "color: green !important");
set_test("margin: 5px", "margin", "10px", false, "margin: 10px");
set_test("margin: 5px", "margin-top", "8px", false, "margin: 8px 5px 5px");
set_test(
"margin: 5px",
"margin-inline-start",
"8px",
false,
"margin: 5px; margin-inline-start: 8px",
);
set_test(
"margin-inline-start: 5px; margin-top: 10px",
"margin-inline-start",
"8px",
false,
"margin-inline-start: 5px; margin-top: 10px; margin-inline-start: 8px",
);
set_test(
"margin: 5px; margin-inline-start: 8px",
"margin-left",
"10px",
false,
"margin: 5px; margin-inline-start: 8px; margin-left: 10px",
);
set_test(
"border: 1px solid red",
"border-right",
"1px solid green",
false,
"border: 1px solid red; border-right: 1px solid green",
);
set_test(
"border: 1px solid red",
"border-right-color",
"green",
false,
"border: 1px solid red; border-right-color: green",
);
set_test(
"animation: foo 2s",
"animation-name",
"foo, bar",
false,
"animation: foo 2s; animation-name: foo, bar",
);
set_test("animation: foo 2s", "animation-name", "bar", false, "animation: bar 2s");
set_test(
"background: linear-gradient(red, green)",
"background-position-x",
"20px",
false,
"background: linear-gradient(red, green) 20px 0",
);
set_test(
"background: linear-gradient(red, green)",
"background-position",
"20px 10px",
false,
"background: linear-gradient(red, green) 20px 10px",
);
set_test(
"flex-flow: row wrap",
"flex-direction",
"column",
false,
"flex-flow: column wrap",
);
set_test(
"-webkit-flex-flow: row wrap",
"-webkit-flex-direction",
"column",
false,
"-webkit-flex-flow: column wrap",
);
set_test(
"flex-flow: row wrap",
"-webkit-flex-direction",
"column",
false,
"flex-flow: wrap; -webkit-flex-direction: column",
);
}
fn remove_test(orig: &str, property_id: PropertyId, expected: &str) {
let mut decls = DeclarationBlock::parse_string(orig, ParserOptions::default()).unwrap();
decls.remove(&property_id);
assert_eq!(decls.to_css_string(PrinterOptions::default()).unwrap(), expected);
}
#[test]
fn test_remove() {
remove_test("margin-top: 10px", PropertyId::MarginTop, "");
remove_test(
"margin-top: 10px; margin-left: 5px",
PropertyId::MarginTop,
"margin-left: 5px",
);
remove_test(
"margin-top: 10px !important; margin-left: 5px",
PropertyId::MarginTop,
"margin-left: 5px",
);
remove_test(
"margin: 10px",
PropertyId::MarginTop,
"margin-right: 10px; margin-bottom: 10px; margin-left: 10px",
);
remove_test("margin: 10px", PropertyId::Margin, "");
remove_test(
"margin-top: 10px; margin-right: 10px; margin-bottom: 10px; margin-left: 10px",
PropertyId::Margin,
"",
);
remove_test(
"flex-flow: column wrap",
PropertyId::FlexDirection(VendorPrefix::None),
"flex-wrap: wrap",
);
remove_test(
"flex-flow: column wrap",
PropertyId::FlexDirection(VendorPrefix::WebKit),
"flex-flow: column wrap",
);
remove_test(
"-webkit-flex-flow: column wrap",
PropertyId::FlexDirection(VendorPrefix::WebKit),
"-webkit-flex-wrap: wrap",
);
}