use html5ever::serialize; use html5ever::serialize::{SerializeOpts, TraversalScope}; use html5ever::QualName; use html5ever::{parse_document, parse_fragment}; use markup5ever::{local_name, namespace_url, ns}; use nos::{Document, SerializableNodeRef}; use tendril::SliceExt; use tendril::StrTendril; use tendril::TendrilSink; fn parse_and_serialize(input: StrTendril) -> StrTendril { let dom = parse_fragment( Document::default(), Default::default(), QualName::new(None, ns!(html), local_name!("body")), vec![], ) .one(input); let root = dom.root(); let inner: SerializableNodeRef = root.first_child().unwrap().into(); let mut result = vec![]; serialize(&mut result, &inner, Default::default()).unwrap(); StrTendril::try_from_byte_slice(&result).unwrap() } macro_rules! test_fn { ($f:ident, $name:ident, $input:expr, $output:expr) => { #[test] fn $name() { assert_eq!($output, &*$f($input.to_tendril())); } }; // Shorthand for $output = $input ($f:ident, $name:ident, $input:expr) => { test_fn!($f, $name, $input, $input); }; } macro_rules! test { ($($t:tt)*) => { test_fn!(parse_and_serialize, $($t)*); }; } test!(empty, r#""#); test!(fuzz, "Hello, World!

"#); test!( misnest, r#"

Hello!

, World!"#, r#"

Hello!

, World!"# ); test!(attr_literal, r#""#); test!(attr_escape_amp, r#""#); test!( attr_escape_amp_2, r#""#, r#""# ); test!( attr_escape_nbsp, "", r#""# ); test!( attr_escape_quot, r#""#, r#""# ); test!( attr_escape_several, r#""#, r#""# ); test!(text_literal, r#"

"'"

"#); test!(text_escape_amp, r#"

&

"#); test!(text_escape_amp_2, r#"

&

"#, r#"

&

"#); test!(text_escape_nbsp, "

x\u{a0}y

", r#"

x y

"#); test!(text_escape_lt, r#"

<

"#); test!(text_escape_gt, r#"

>

"#); test!(text_escape_gt2, r#"

>

"#, r#"

>

"#); test!( script_literal, r#""# ); test!( style_literal, r#""# ); test!(xmp_literal, r#"(x & 1) < 2; y > "foo" + 'bar'"#); test!( iframe_literal, r#""# ); test!( noembed_literal, r#"(x & 1) < 2; y > "foo" + 'bar'"# ); test!( noframes_literal, r#"(x & 1) < 2; y > "foo" + 'bar'"# ); test!(pre_lf_0, "
foo bar
"); test!(pre_lf_1, "
\nfoo bar
", "
foo bar
"); test!(pre_lf_2, "
\n\nfoo bar
", "
\nfoo bar
"); test!(textarea_lf_0, ""); test!( textarea_lf_1, "", "" ); test!( textarea_lf_2, "", "" ); test!(listing_lf_0, "foo bar"); test!( listing_lf_1, "\nfoo bar", "foo bar" ); test!( listing_lf_2, "\n\nfoo bar", "\nfoo bar" ); test!(comment_1, r#"

hi

"#); test!(comment_2, r#"

hi

"#); test!(comment_3, r#"

hi

"#); test!(comment_4, r#"

hi

"#); // FIXME: test serialization of qualified tag/attribute names that can't be // parsed from HTML test!(attr_ns_1, r#""#); test!(attr_ns_2, r#""#); test!(attr_ns_3, r#""#); test!(attr_ns_4, r#""#); #[test] fn doctype() { let dom = parse_document(Document::default(), Default::default()).one(""); let mut result = vec![]; let root = dom.root(); let document: SerializableNodeRef = root.first_child().unwrap().into(); serialize( &mut result, &document, SerializeOpts { scripting_enabled: true, traversal_scope: TraversalScope::IncludeNode, create_missing_parent: false, }, ) .unwrap(); assert_eq!(String::from_utf8(result).unwrap(), ""); }