use specificity::{specificity, specificity_list, Specificity};
fn s(a: u32, b: u32, c: u32) -> Specificity {
Specificity::new(a, b, c)
}
#[test]
fn basics() {
assert_eq!(specificity("#id .cls a"), s(1, 1, 1));
assert_eq!(specificity("*"), s(0, 0, 0));
assert_eq!(specificity("div p"), s(0, 0, 2));
assert_eq!(specificity("a:hover"), s(0, 1, 1));
assert_eq!(specificity("#a#b"), s(2, 0, 0));
assert_eq!(specificity(".x[y].z"), s(0, 3, 0));
assert_eq!(specificity("a.b#c[d]:hover::before"), s(1, 3, 2));
assert_eq!(specificity("input:checked"), s(0, 1, 1));
}
#[test]
fn pseudo_elements() {
assert_eq!(specificity("::before"), s(0, 0, 1));
assert_eq!(specificity(":before"), s(0, 0, 1)); assert_eq!(specificity("::after"), s(0, 0, 1));
assert_eq!(specificity("::first-line"), s(0, 0, 1));
assert_eq!(specificity("::part(x)"), s(0, 0, 1)); assert_eq!(specificity("::slotted(.a)"), s(0, 0, 1));
assert_eq!(specificity("div::before:hover"), s(0, 1, 2));
}
#[test]
fn functional_pseudo_classes() {
assert_eq!(specificity(":is(.a, #b)"), s(1, 0, 0)); assert_eq!(specificity(":not(.a, #b)"), s(1, 0, 0));
assert_eq!(specificity(":has(.a, #b)"), s(1, 0, 0));
assert_eq!(specificity(":where(.a)"), s(0, 0, 0)); assert_eq!(specificity(":not(:is(.a,#b))"), s(1, 0, 0)); assert_eq!(specificity(":host(.x)"), s(0, 1, 0)); }
#[test]
fn nth_child() {
assert_eq!(specificity("li:nth-child(2n+1)"), s(0, 1, 1));
assert_eq!(specificity(":nth-child(odd)"), s(0, 1, 0));
assert_eq!(specificity("li:nth-child(2n of .a, #id)"), s(1, 1, 1));
}
#[test]
fn attributes_and_namespaces() {
assert_eq!(specificity("[href^=\"http\"]"), s(0, 1, 0));
assert_eq!(specificity("[data-x=y i]"), s(0, 1, 0));
assert_eq!(specificity("svg|a"), s(0, 0, 1)); assert_eq!(specificity("*|div"), s(0, 0, 1));
assert_eq!(specificity("|div"), s(0, 0, 1));
assert_eq!(specificity("*|*"), s(0, 0, 0));
}
#[test]
fn combinators_are_ignored() {
assert_eq!(specificity("a > b + c ~ d"), s(0, 0, 4));
assert_eq!(specificity("* + *"), s(0, 0, 0));
assert_eq!(specificity("a || b"), s(0, 0, 2)); }
#[test]
fn escapes() {
assert_eq!(specificity(".foo\\.bar"), s(0, 1, 0)); assert_eq!(specificity("#\\31 23"), s(1, 0, 0)); }
#[test]
fn lists() {
assert_eq!(specificity(".a, #b"), s(1, 0, 0));
assert_eq!(specificity_list(".a, #b"), [s(0, 1, 0), s(1, 0, 0)]);
assert_eq!(
specificity_list("#a, .b, c"),
[s(1, 0, 0), s(0, 1, 0), s(0, 0, 1)]
);
}
#[test]
fn comments_are_stripped() {
assert_eq!(specificity(".a/* #id */"), s(0, 1, 0));
assert_eq!(specificity("/* x */.a.b"), s(0, 2, 0));
assert_eq!(specificity("div/* c */.foo"), s(0, 1, 1));
assert_eq!(specificity_list(".a /* , */ .b"), [s(0, 2, 0)]);
assert_eq!(specificity("[a=\"/*\"]"), s(0, 1, 0));
}
#[test]
fn css_modules_global_local() {
assert_eq!(specificity(":global(#a .b .c)"), s(1, 2, 0));
assert_eq!(specificity(":local(#a)"), s(1, 0, 0));
assert_eq!(specificity(":global(div)"), s(0, 0, 1));
assert_eq!(specificity(":global"), s(0, 0, 0));
assert_eq!(specificity(":local"), s(0, 0, 0));
}
#[test]
fn matches_and_any_are_is_aliases() {
assert_eq!(specificity(":matches(#a)"), s(1, 0, 0));
assert_eq!(specificity(":-webkit-any(.a, #b)"), s(1, 0, 0));
}
#[test]
fn deep_nesting_does_not_overflow() {
let deep = format!("{}{}{}", ":is(".repeat(5000), ".a", &")".repeat(5000));
let _ = specificity(&deep); let ten = format!("{}{}{}", ":is(".repeat(10), "#x", &")".repeat(10));
assert_eq!(specificity(&ten), s(1, 0, 0));
}
#[test]
fn ordering_and_display() {
assert!(specificity("#id") > specificity(".a.b.c"));
assert!(specificity(".a") > specificity("div span"));
assert_eq!(specificity("#a.b c").to_string(), "1,1,1");
assert_eq!(Specificity::default(), s(0, 0, 0));
}