diff --git a/src/rewritable_units/element.rs b/src/rewritable_units/element.rs index b3e13cf8..85bd1093 100644 --- a/src/rewritable_units/element.rs +++ b/src/rewritable_units/element.rs @@ -1439,7 +1439,11 @@ mod tests { #[test] fn parsed() { test!( - |_| {}, + |el| { + assert_eq!(el.get_attribute("a1").unwrap(), "foo \" baré \" baz"); + assert_eq!(el.get_attribute("a3").unwrap(), "foo/bar"); + assert_eq!(el.get_attribute("a4").unwrap(), ""); + }, r#""# ); } @@ -1523,6 +1527,26 @@ mod tests { assert_eq!(output, r""); } + #[test] + fn value_trailing_slash() { + let mut output = rewrite_element(b"", UTF_8, "img", |el| { + assert_eq!(el.get_attribute("path").unwrap(), "//"); + el.set_attribute("slash", "/").unwrap(); + + assert!(!el.can_have_content()); + }); + + assert_eq!(output, r#""#); + + output = rewrite_element(b"", UTF_8, "img", |el| { + el.remove_attribute("path"); + + assert!(!el.can_have_content()); + }); + + assert_eq!(output, r""); + } + #[test] fn remove_non_existent_attr() { test!( @@ -1537,6 +1561,8 @@ mod tests { fn without_attrs() { test!( |el| { + assert!(el.can_have_content()); + for name in &["a1", "a2", "a3", "a4"] { el.remove_attribute(name); } diff --git a/src/rewritable_units/mod.rs b/src/rewritable_units/mod.rs index 069a3fda..33652866 100644 --- a/src/rewritable_units/mod.rs +++ b/src/rewritable_units/mod.rs @@ -137,7 +137,9 @@ mod test_utils { |c: &[u8]| output.push(c), ); - rewriter.write(html).unwrap(); + for ch in html.chunks(15) { + rewriter.write(ch).unwrap(); + } rewriter.end().unwrap(); } diff --git a/src/rewritable_units/tokens/capturer/text_decoder.rs b/src/rewritable_units/tokens/capturer/text_decoder.rs index 1a81e3e3..33090179 100644 --- a/src/rewritable_units/tokens/capturer/text_decoder.rs +++ b/src/rewritable_units/tokens/capturer/text_decoder.rs @@ -29,7 +29,7 @@ impl TextDecoder { encoding, pending_text_streaming_decoder: None, // TODO make adjustable - text_buffer: String::from_utf8(vec![0u8; 1024]).unwrap(), + text_buffer: "\0".repeat(if cfg!(debug_assertions) { 12 } else { 1024 }), last_text_type: TextType::Data, } } diff --git a/src/rewritable_units/tokens/text_chunk.rs b/src/rewritable_units/tokens/text_chunk.rs index d160f3f9..6afdc53f 100644 --- a/src/rewritable_units/tokens/text_chunk.rs +++ b/src/rewritable_units/tokens/text_chunk.rs @@ -413,15 +413,6 @@ mod tests { }; } - macro_rules! skip_eof_chunk { - ($c:ident) => { - if $c.last_in_text_node() { - assert!($c.as_str().is_empty()); - return; - } - }; - } - #[test] fn parsed() { test!(|_| {}, HTML); @@ -429,15 +420,20 @@ mod tests { #[test] fn with_prepends_and_appends() { + let mut first = true; test!( |c| { - skip_eof_chunk!(c); - c.before("", ContentType::Text); - c.before("
Hey
", ContentType::Html); - c.before("", ContentType::Html); - c.after("", ContentType::Html); - c.after("", ContentType::Html); - c.after("", ContentType::Text); + let is_first = std::mem::replace(&mut first, c.last_in_text_node()); + if is_first { + c.before("", ContentType::Text); + c.before("
Hey
", ContentType::Html); + c.before("", ContentType::Html); + } + if c.last_in_text_node() { + c.after("", ContentType::Html); + c.after("", ContentType::Html); + c.after("", ContentType::Text); + } }, concat!( "<span>
Hey
", @@ -452,17 +448,22 @@ mod tests { #[test] fn removed() { + let mut first = true; test!( |c| { - skip_eof_chunk!(c); + let is_first = std::mem::replace(&mut first, c.last_in_text_node()); assert!(!c.removed()); c.remove(); assert!(c.removed()); - c.before("", ContentType::Html); - c.after("", ContentType::Html); + if is_first { + c.before("", ContentType::Html); + } + if c.last_in_text_node() { + c.after("", ContentType::Html); + } }, "" ); @@ -472,17 +473,20 @@ mod tests { fn replaced_with_text() { test!( |c| { - skip_eof_chunk!(c); - c.before("", ContentType::Html); - c.after("", ContentType::Html); + if c.last_in_text_node() { + c.before("", ContentType::Html); + c.after("", ContentType::Html); - assert!(!c.removed()); + assert!(!c.removed()); - c.replace("
", ContentType::Html); - c.replace("", ContentType::Html); - c.replace("", ContentType::Text); + c.replace("
", ContentType::Html); + c.replace("", ContentType::Html); + c.replace("", ContentType::Text); - assert!(c.removed()); + assert!(c.removed()); + } else { + c.remove(); + } }, "<foo & bar>" ); @@ -492,17 +496,20 @@ mod tests { fn replaced_with_html() { test!( |c| { - skip_eof_chunk!(c); - c.before("", ContentType::Html); - c.after("", ContentType::Html); + if c.last_in_text_node() { + c.before("", ContentType::Html); + c.after("", ContentType::Html); - assert!(!c.removed()); + assert!(!c.removed()); - c.replace("
", ContentType::Html); - c.replace("", ContentType::Html); - c.replace("", ContentType::Html); + c.replace("
", ContentType::Html); + c.replace("", ContentType::Html); + c.replace("", ContentType::Html); - assert!(c.removed()); + assert!(c.removed()); + } else { + c.remove(); + } }, "" );