diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/files/test.html | 7 | ||||
-rw-r--r-- | tests/files/test.out | 17 | ||||
-rw-r--r-- | tests/spans.rs | 89 |
3 files changed, 113 insertions, 0 deletions
diff --git a/tests/files/test.html b/tests/files/test.html new file mode 100644 index 0000000..0dcbdbf --- /dev/null +++ b/tests/files/test.html @@ -0,0 +1,7 @@ +This is a file. + +Here is a tag: <strong >very cool</strong> + +Tags can have attributes: <div id = foo >...</div> + +Attribute values can be quoted: <input name = 'age' type = "number"> diff --git a/tests/files/test.out b/tests/files/test.out new file mode 100644 index 0000000..7127ebc --- /dev/null +++ b/tests/files/test.out @@ -0,0 +1,17 @@ +note: + ┌─ test.html:3:17 + │ +3 │ Here is a tag: <strong >very cool</strong> + │ ^^^^^^ ^^^^^^ EndTag + │ │ + │ StartTag +4 │ +5 │ Tags can have attributes: <div id = foo >...</div> + │ ^^ ^^^ attribute value + │ │ + │ attribute name +6 │ +7 │ Attribute values can be quoted: <input name = 'age' type = "number"> + │ ^^^ ^^^^^^ in double quotes + │ │ + │ in single quotes diff --git a/tests/spans.rs b/tests/spans.rs new file mode 100644 index 0000000..bfa42f6 --- /dev/null +++ b/tests/spans.rs @@ -0,0 +1,89 @@ +#![cfg(feature = "spans")] +use std::include_str; + +use codespan_reporting::{ + self, + diagnostic::{Diagnostic, Label}, + files::SimpleFiles, + term::{self, termcolor::Buffer}, +}; +use html5tokenizer::{ + BufferQueue, Tag, Token, TokenSink, TokenSinkResult, Tokenizer, TokenizerOpts, +}; + +#[derive(Default)] +struct TagSink { + tags: Vec<Tag>, +} + +impl TokenSink for TagSink { + fn process_token(&mut self, token: Token, _line_number: u64) -> TokenSinkResult { + if let Token::TagToken(tag) = token { + self.tags.push(tag); + } + TokenSinkResult::Continue + } +} + +#[test] +fn test() { + let sink = TagSink::default(); + + let mut input = BufferQueue::new(); + let text = include_str!("files/test.html"); + input.push_back(text.to_string()); + + let mut tok = Tokenizer::new(sink, TokenizerOpts::default()); + let _ = tok.feed(&mut input); + + let mut files = SimpleFiles::new(); + let file_id = files.add("test.html", text); + let mut labels = Vec::new(); + + let tags = tok.sink.tags; + for tag in &tags[..2] { + labels.push( + Label::primary(file_id, tag.name_span.clone()).with_message(format!("{:?}", tag.kind)), + ); + } + labels.push( + Label::primary(file_id, tags[2].attrs[0].name_span.clone()).with_message("attribute name"), + ); + labels.push( + Label::primary(file_id, tags[2].attrs[0].value_span.clone()) + .with_message("attribute value"), + ); + labels.push( + Label::primary(file_id, tags[4].attrs[0].value_span.clone()) + .with_message("in single quotes"), + ); + labels.push( + Label::primary(file_id, tags[4].attrs[1].value_span.clone()) + .with_message("in double quotes"), + ); + let diagnostic = Diagnostic::note().with_labels(labels); + + let mut writer = Buffer::no_color(); + let config = codespan_reporting::term::Config::default(); + term::emit(&mut writer, &config, &files, &diagnostic).unwrap(); + + let actual = remove_trailing_spaces(std::str::from_utf8(writer.as_slice()).unwrap()); + let expected = include_str!("files/test.out"); + + if actual != expected { + println!( + "EXPECTED:\n{banner}\n{expected}{banner}\n\nACTUAL OUTPUT:\n{banner}\n{actual}{banner}", + banner = "-".repeat(30), + expected = expected, + actual = actual + ); + panic!("failed"); + } +} + +fn remove_trailing_spaces(text: &str) -> String { + text.lines() + .map(|l| l.trim_end()) + .collect::<Vec<_>>() + .join("\n") +} |