use skyscraper::html;
#[test]
fn doctype_is_preserved_in_output() {
let text = "<!DOCTYPE html><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert!(
output.starts_with("<!DOCTYPE html>"),
"Output should start with DOCTYPE, got: {:?}",
&output[..std::cmp::min(50, output.len())]
);
}
#[test]
fn doctype_simple_roundtrip() {
let text = "<!DOCTYPE html><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert_eq!(output, text);
}
#[test]
fn comment_before_html_is_preserved() {
let text = "<!DOCTYPE html><!-- test comment --><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert!(
output.contains("<!-- test comment -->"),
"Output should contain the comment, got: {:?}",
&output[..std::cmp::min(100, output.len())]
);
}
#[test]
fn comment_in_initial_mode_is_preserved() {
let text = "<!-- initial comment --><!DOCTYPE html><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert!(
output.starts_with("<!-- initial comment -->"),
"Output should start with the comment, got: {:?}",
&output[..std::cmp::min(80, output.len())]
);
}
#[test]
fn multiple_comments_before_html_preserved() {
let text =
"<!DOCTYPE html><!-- first --><!-- second --><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert_eq!(output, text);
}
#[test]
fn no_doctype_no_doctype_in_output() {
let text = "<html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert_eq!(output, text);
}
#[test]
fn duplicate_doctype_in_before_html_mode_is_ignored() {
let text = "<!DOCTYPE html><!DOCTYPE html><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert_eq!(
output.matches("<!DOCTYPE").count(),
1,
"Only one DOCTYPE should survive; got: {output:?}"
);
assert!(output.contains("<html>"), "Should contain <html>: {output:?}");
}
#[test]
fn unexpected_end_tag_in_before_html_mode_is_ignored() {
let text = "<!DOCTYPE html></div><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert!(
!output.contains("</div>"),
"Stray </div> should not appear in output: {output:?}"
);
assert!(output.contains("<html>"), "Should contain <html>: {output:?}");
assert!(
output.contains("<body></body>"),
"Should contain <body></body>: {output:?}"
);
}
#[test]
fn multiple_unexpected_end_tags_in_before_html_mode_are_ignored() {
let text = "<!DOCTYPE html></span></p></footer><html><head></head><body></body></html>";
let document = html::parse(text).unwrap();
let output = document.to_string();
assert!(
!output.contains("</span>") && !output.contains("</p>") && !output.contains("</footer>"),
"No stray end tags should appear: {output:?}"
);
}