summaryrefslogtreecommitdiff
path: root/tests/src/collect.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/collect.rs')
-rw-r--r--tests/src/collect.rs60
1 files changed, 43 insertions, 17 deletions
diff --git a/tests/src/collect.rs b/tests/src/collect.rs
index 5c7327f1..c6deba77 100644
--- a/tests/src/collect.rs
+++ b/tests/src/collect.rs
@@ -23,9 +23,9 @@ pub fn collect() -> Result<(Vec<Test>, usize), Vec<TestParseError>> {
pub struct Test {
pub pos: FilePos,
pub name: EcoString,
+ pub attrs: Vec<Attr>,
pub source: Source,
pub notes: Vec<Note>,
- pub large: bool,
}
impl Display for Test {
@@ -57,6 +57,14 @@ impl Display for FilePos {
}
}
+/// A test attribute, given after the test name.
+#[derive(Clone, Debug, PartialEq)]
+pub enum Attr {
+ Html,
+ Render,
+ Large,
+}
+
/// The size of a file.
pub struct FileSize(pub usize);
@@ -109,8 +117,7 @@ impl Display for NoteKind {
struct Collector {
tests: Vec<Test>,
errors: Vec<TestParseError>,
- seen: HashMap<EcoString, FilePos>,
- large: HashSet<EcoString>,
+ seen: HashMap<EcoString, (FilePos, Vec<Attr>)>,
skipped: usize,
}
@@ -121,7 +128,6 @@ impl Collector {
tests: vec![],
errors: vec![],
seen: HashMap::new(),
- large: HashSet::new(),
skipped: 0,
}
}
@@ -156,7 +162,7 @@ impl Collector {
}
}
- /// Walks through all reference images and ensure that a test exists for
+ /// Walks through all reference output and ensures that a test exists for
/// each one.
fn walk_references(&mut self) {
for entry in walkdir::WalkDir::new(crate::REF_PATH).sort_by_file_name() {
@@ -169,20 +175,20 @@ impl Collector {
let stem = path.file_stem().unwrap().to_string_lossy();
let name = &*stem;
- let Some(pos) = self.seen.get(name) else {
+ let Some((pos, attrs)) = self.seen.get(name) else {
self.errors.push(TestParseError {
pos: FilePos::new(path, 0),
- message: "dangling reference image".into(),
+ message: "dangling reference output".into(),
});
continue;
};
let len = path.metadata().unwrap().len() as usize;
- if !self.large.contains(name) && len > crate::REF_LIMIT {
+ if !attrs.contains(&Attr::Large) && len > crate::REF_LIMIT {
self.errors.push(TestParseError {
pos: pos.clone(),
message: format!(
- "reference image size exceeds {}, but the test is not marked as `// LARGE`",
+ "reference output size exceeds {}, but the test is not marked as `large`",
FileSize(crate::REF_LIMIT),
),
});
@@ -218,6 +224,7 @@ impl<'a> Parser<'a> {
while !self.s.done() {
let mut name = EcoString::new();
+ let mut attrs = Vec::new();
let mut notes = vec![];
if self.s.eat_if("---") {
self.s.eat_while(' ');
@@ -228,8 +235,8 @@ impl<'a> Parser<'a> {
self.error("expected test name");
} else if !is_ident(&name) {
self.error(format!("test name `{name}` is not a valid identifier"));
- } else if !self.s.eat_if("---") {
- self.error("expected closing ---");
+ } else {
+ attrs = self.parse_attrs();
}
} else {
self.error("expected opening ---");
@@ -247,7 +254,7 @@ impl<'a> Parser<'a> {
self.test_start_line = self.line;
let pos = FilePos::new(self.path, self.test_start_line);
- self.collector.seen.insert(name.clone(), pos.clone());
+ self.collector.seen.insert(name.clone(), (pos.clone(), attrs.clone()));
while !self.s.done() && !self.s.at("---") {
self.s.eat_until(is_newline);
@@ -257,10 +264,6 @@ impl<'a> Parser<'a> {
}
let text = self.s.from(start);
- let large = text.starts_with("// LARGE");
- if large {
- self.collector.large.insert(name.clone());
- }
if !selected(&name, self.path.canonicalize().unwrap()) {
self.collector.skipped += 1;
@@ -285,8 +288,31 @@ impl<'a> Parser<'a> {
}
}
- self.collector.tests.push(Test { pos, name, source, notes, large });
+ self.collector.tests.push(Test { pos, name, source, notes, attrs });
+ }
+ }
+
+ fn parse_attrs(&mut self) -> Vec<Attr> {
+ let mut attrs = vec![];
+ while !self.s.eat_if("---") {
+ let attr = match self.s.eat_until(char::is_whitespace) {
+ "large" => Attr::Large,
+ "html" => Attr::Html,
+ "render" => Attr::Render,
+ found => {
+ self.error(format!(
+ "expected attribute or closing ---, found `{found}`"
+ ));
+ break;
+ }
+ };
+ if attrs.contains(&attr) {
+ self.error(format!("duplicate attribute {attr:?}"));
+ }
+ attrs.push(attr);
+ self.s.eat_while(' ');
}
+ attrs
}
/// Skips the preamble of a test.