Skip to content

Commit

Permalink
Add unit tests for revalidation selectors.
Browse files Browse the repository at this point in the history
If these break, our cache may be subtly wrong in certain situations, which may
be hard to detect.

MozReview-Commit-ID: AXG2tpGnQ6k
  • Loading branch information
bholley committed Apr 27, 2017
1 parent 25832b9 commit 6e41365
Showing 1 changed file with 106 additions and 1 deletion.
107 changes: 106 additions & 1 deletion tests/unit/style/stylist.rs
Expand Up @@ -4,15 +4,17 @@

use html5ever_atoms::LocalName;
use selectors::parser::LocalName as LocalNameSelector;
use selectors::parser::Selector;
use servo_atoms::Atom;
use std::sync::Arc;
use style::properties::{PropertyDeclarationBlock, PropertyDeclaration};
use style::properties::{longhands, Importance};
use style::rule_tree::CascadeLevel;
use style::selector_parser::SelectorParser;
use style::selector_parser::{SelectorImpl, SelectorParser};
use style::shared_lock::SharedRwLock;
use style::stylesheets::StyleRule;
use style::stylist::{Rule, SelectorMap};
use style::stylist::needs_revalidation;
use style::thread_state;

/// Helper method to get some Rules from selector strings.
Expand Down Expand Up @@ -56,6 +58,109 @@ fn get_mock_map(selectors: &[&str]) -> (SelectorMap, SharedRwLock) {
(map, shared_lock)
}

fn parse_selectors(selectors: &[&str]) -> Vec<Selector<SelectorImpl>> {
selectors.iter()
.map(|x| SelectorParser::parse_author_origin_no_namespace(x).unwrap().0
.into_iter()
.nth(0)
.unwrap())
.collect()
}

#[test]
fn test_revalidation_selectors() {
let test = parse_selectors(&[
// Not revalidation selectors.
"div",
"#bar",
"div:not(.foo)",
"div span",
"div > span",

// Attribute selectors.
"div[foo]",
"div:not([foo])",
"div[foo = \"bar\"]",
"div[foo ~= \"bar\"]",
"div[foo |= \"bar\"]",
"div[foo ^= \"bar\"]",
"div[foo $= \"bar\"]",
"div[foo *= \"bar\"]",
"*|div[foo][bar = \"baz\"]",

// Non-state-based pseudo-classes.
"div:empty",
"div:first-child",
"div:last-child",
"div:only-child",
"div:nth-child(2)",
"div:nth-last-child(2)",
"div:nth-of-type(2)",
"div:nth-last-of-type(2)",
"div:first-of-type",
"div:last-of-type",
"div:only-of-type",

// Note: it would be nice to test :moz-any and the various other non-TS
// pseudo classes supported by gecko, but we don't have access to those
// in these unit tests. :-(

// Sibling combinators.
"span + div",
"span ~ div",

// Revalidation selectors that will get sliced.
"td > h1[dir]",
"td > span + h1[dir]",
"table td > span + div ~ h1[dir]",
]).into_iter()
.filter(|s| needs_revalidation(&s))
.map(|s| s.inner.slice_to_first_ancestor_combinator().complex)
.collect::<Vec<_>>();

let reference = parse_selectors(&[
// Attribute selectors.
"div[foo]",
"div:not([foo])",
"div[foo = \"bar\"]",
"div[foo ~= \"bar\"]",
"div[foo |= \"bar\"]",
"div[foo ^= \"bar\"]",
"div[foo $= \"bar\"]",
"div[foo *= \"bar\"]",
"*|div[foo][bar = \"baz\"]",

// Non-state-based pseudo-classes.
"div:empty",
"div:first-child",
"div:last-child",
"div:only-child",
"div:nth-child(2)",
"div:nth-last-child(2)",
"div:nth-of-type(2)",
"div:nth-last-of-type(2)",
"div:first-of-type",
"div:last-of-type",
"div:only-of-type",

// Sibling combinators.
"span + div",
"span ~ div",

// Revalidation selectors that got sliced.
"h1[dir]",
"span + h1[dir]",
"span + div ~ h1[dir]",
]).into_iter()
.map(|s| s.inner.complex)
.collect::<Vec<_>>();

assert_eq!(test.len(), reference.len());
for (t, r) in test.into_iter().zip(reference.into_iter()) {
assert_eq!(t, r)
}
}

#[test]
fn test_rule_ordering_same_specificity() {
let (rules_list, _) = get_mock_rules(&["a.intro", "img.sidebar"]);
Expand Down

0 comments on commit 6e41365

Please sign in to comment.