From faf68ab4abbc9db390b410985644cd2449a06e9d Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Fri, 22 Dec 2023 14:52:18 +1100 Subject: [PATCH] Set up common tests --- minify-html-common/src/lib.rs | 3 +- minify-html-common/src/tests/mod.rs | 659 +++++++++++++-------------- minify-html-onepass/src/tests/mod.rs | 16 + minify-html/src/tests/mod.rs | 16 + 4 files changed, 339 insertions(+), 355 deletions(-) diff --git a/minify-html-common/src/lib.rs b/minify-html-common/src/lib.rs index 1036b166..33da002f 100644 --- a/minify-html-common/src/lib.rs +++ b/minify-html-common/src/lib.rs @@ -1,6 +1,5 @@ pub mod gen; pub mod pattern; pub mod spec; -#[cfg(test)] -mod tests; +pub mod tests; pub mod whitespace; diff --git a/minify-html-common/src/tests/mod.rs b/minify-html-common/src/tests/mod.rs index 64d2b09c..b69b66df 100644 --- a/minify-html-common/src/tests/mod.rs +++ b/minify-html-common/src/tests/mod.rs @@ -1,126 +1,110 @@ -use crate::tests::eval; -use crate::tests::eval_with_css_min; -use crate::tests::eval_with_js_min; +use std::collections::HashMap; -#[test] -fn test_collapse_whitespace() { - eval(b" \n ", b" "); +pub fn create_common_test_data() -> HashMap<&'static [u8], &'static [u8]> { + let mut t = HashMap::<&'static [u8], &'static [u8]>::new(); + + // collapse whitespace + t.insert(b" \n ", b" "); // Tag names should be case insensitive. - eval(b" \n ", b" "); - eval(b" \n ", b" "); -} + t.insert(b" \n ", b" "); + t.insert(b" \n ", b" "); -#[test] -fn test_collapse_and_trim_whitespace() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); + // collapse and trim whitespace + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); // Tag names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_collapse_destroy_whole_and_trim_whitespace() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval( + // collapse destroy whole and trim whitespace + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert( b"", b"", ); - eval( + t.insert( b" ", b"", ); // Tag names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_no_whitespace_minification() { - eval(b"
   \n  \t   
", b"
   \n  \t   
"); - eval( + // no whitespace minification + t.insert(b"
   \n  \t   
", b"
   \n  \t   
"); + t.insert( b"", b"", ); // Tag names should be case insensitive. - eval(b"
   \n  \t   
", b"
   \n  \t   
"); - eval( + t.insert(b"
   \n  \t   
", b"
   \n  \t   
"); + t.insert( b"
    1    2     
", b"
    1    2     
", ); - eval( + t.insert( b"
    1 
\n
2
", b"
    1 
\n
2
", ); - eval( + t.insert( b"
    1 
\n
2
", b"
    1 
\n
2
", ); - eval( + t.insert( br#"
fn main() {
   println!("Hello, world!");
   loop {
     println!("Hello, world!");
   }
-}
 
"#, br#"
fn main() {
   println!("Hello, world!");
   loop {
     println!("Hello, world!");
   }
-}
 
"#, ); -} -#[test] -fn test_parsing_omitted_closing_tag() { - eval(b"", b""); - eval(b" \n", b""); - eval(b" \n", b""); - eval( + // parsing omitted closing tag + t.insert(b"", b""); + t.insert(b" \n", b""); + t.insert(b" \n", b""); + t.insert( b"

Foo

", b"

Foo

", ); -} -#[test] -fn test_self_closing_svg_tag_whitespace_removal() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); -} - -#[test] -fn test_parsing_with_omitted_tags() { - eval(b"", b""); - eval(b"", b""); - eval(b"1
", b"1
"); - eval(b"
", b"
"); - eval(b"", b""); - eval(b"", b""); + // self closing svg tag whitespace removal + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + + // parsing with omitted tags + t.insert(b"
  • 1
  • 2
  • 3
", b"
  • 1
  • 2
  • 3
"); + t.insert(b"", b""); + t.insert(b"1
", b"1
"); + t.insert(b"
", b"
"); + t.insert(b"", b""); + t.insert(b"", b""); // Tag names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_removal_of_optional_tags() { - eval( + // removal of optional tags + t.insert( b"
  • 1
  • 2
  • 3
", b"
  • 1
  • 2
  • 3
", ); - eval(b"", b""); - eval( + t.insert(b"", b""); + t.insert( b"1
", b"1
", ); - eval(b"
", b"
"); - eval( + t.insert(b"
", b"
"); + t.insert( br#" @@ -133,351 +117,341 @@ fn test_removal_of_optional_tags() { b"", ); // Tag names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_removal_of_optional_closing_p_tag() { - eval(b"

", b"

"); - eval(b"

", b"

"); - eval(b"

", b"

"); - eval( + // removal of optional closing p tag + t.insert(b"

", b"

"); + t.insert(b"

", b"

"); + t.insert(b"

", b"

"); + t.insert( b"

", b"

", ); -} -#[test] -fn test_attr_double_quoted_value_minification() { - eval(b"", b""); - eval(b"", b""); - eval(br#""#, br#""#); - eval(br#""#, br#""#); - eval(b"", b""); - eval(b"", b""); -} + // attr double quoted value minification + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(br#""#, br#""#); + t.insert(br#""#, br#""#); + t.insert(b"", b""); + t.insert(b"", b""); -#[test] -fn test_attr_single_quoted_value_minification() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b"a\">"); - eval( + // attr single quoted value minification + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b"a\">"); + t.insert( b"", b"", ); -} -#[test] -fn test_attr_unquoted_value_minification() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", br#""#); - eval(b"", br#""#); - eval(b"", b""); -} + // attr unquoted value minification + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", br#""#); + t.insert(b"", br#""#); + t.insert(b"", b""); -#[test] -fn test_class_attr_value_minification() { - eval(b"", b""); - eval( + // class attr value minification + t.insert(b"", b""); + t.insert( b"", b"", ); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); // Attribute names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_d_attr_value_minification() { - eval(b"", b""); - eval( + // d attr value minification + t.insert(b"", b""); + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval(b"", b""); + t.insert(b"", b""); // Attribute names should be case insensitive. - eval(b"", b""); -} - -#[test] -fn test_boolean_attr_value_removal() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); + t.insert(b"", b""); + + // boolean attr value removal + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); // Attribute names should be case insensitive. - eval(b"", b""); -} - -#[test] -fn test_empty_attr_removal() { - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); -} - -#[test] -fn test_default_attr_value_removal() { - eval(b"", b""); - eval(b"", b""); - eval(b"", b""); + t.insert(b"", b""); + + // empty attr removal + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + + // default attr value removal + t.insert(b"", b""); + t.insert(b"", b""); + t.insert(b"", b""); // Attribute names should be case insensitive. - eval(b"", b""); -} + t.insert(b"", b""); -#[test] -fn test_script_type_attr_value_removal() { - eval( + // script type attr value removal + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); - eval( + t.insert( b"", b"", ); // Tag and attribute names should be case insensitive. - eval( + t.insert( b"", b"", ); -} - -#[test] -fn test_empty_attr_value_removal() { - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); - eval(b"
", b"
"); -} -#[test] -fn test_hexadecimal_entity_decoding() { - eval(b".", b"."); - eval(b"/", b"/"); - eval(b"/", b"/"); - eval(b"�", b"\0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"ᅑ", b"\xe1\x85\x91"); - eval(b"�", b"\xef\xbf\xbd"); - eval( + // empty attr value removal + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + t.insert(b"
", b"
"); + + // hexadecimal entity decoding + t.insert(b".", b"."); + t.insert(b"/", b"/"); + t.insert(b"/", b"/"); + t.insert(b"�", b"\0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"ᅑ", b"\xe1\x85\x91"); + t.insert(b"�", b"\xef\xbf\xbd"); + t.insert( b"�", b"\xef\xbf\xbd", ); -} -#[test] -fn test_decimal_entity_decoding() { - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"0", b"0"); - eval(b"ᅑ", b"\xe1\x85\x91"); - eval(b"�", b"\xef\xbf\xbd"); - eval( + // decimal entity decoding + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"0", b"0"); + t.insert(b"ᅑ", b"\xe1\x85\x91"); + t.insert(b"�", b"\xef\xbf\xbd"); + t.insert( b"�", b"\xef\xbf\xbd", ); -} -#[test] -fn test_named_entity_decoding() { - eval(b">", b">"); - eval(b">", b">"); - eval(b"&", b"&"); - eval(b"&", b"&"); - eval(b"&xxxyyyzzz", b"&xxxyyyzzz"); - eval(b"&ere", b"&ere"); - eval(b"They & Co.", b"They & Co."); - eval(b"if (this && that)", b"if (this && that)"); + // named entity decoding + t.insert(b">", b">"); + t.insert(b">", b">"); + t.insert(b"&", b"&"); + t.insert(b"&", b"&"); + t.insert(b"&xxxyyyzzz", b"&xxxyyyzzz"); + t.insert(b"&ere", b"&ere"); + t.insert(b"They & Co.", b"They & Co."); + t.insert(b"if (this && that)", b"if (this && that)"); // These entities decode to longer UTF-8 sequences, so we keep them encoded. - eval(b"≪⃒", b"≪⃒"); - eval(b"≪⃒abc", b"≪⃒abc"); - eval(b"≫⃒", b"≫⃒"); + t.insert(b"≪⃒", b"≪⃒"); + t.insert(b"≪⃒abc", b"≪⃒abc"); + t.insert(b"≫⃒", b"≫⃒"); // Named entities not ending with ';' in attr values are not decoded if immediately // followed by an alphanumeric or `=` character. (See parser for more details.) - eval( + t.insert( br#""#, br#""#, ); - eval( + t.insert( br#""#, br#""#, ); - eval( + t.insert( br#""#, br#""#, ); -} - -#[test] -fn test_unintentional_entity_prevention() { - eval(b"&amp", b"&amp"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp", b"&amp"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp", b"&amp"); - eval(b"&amp", b"&amp"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp;", b"&amp;"); - eval(b"&amp;", b"&amp;"); - - eval(b"&lt", b"&lt"); - eval(b"&lt", b"&lt"); - eval(b"&lt;", b"&lt;"); - eval(b"&lt;", b"&lt;"); - eval(b"&lt", b"&lt"); - eval(b"&lt;", b"&lt;"); - - eval(b"&am&amp", b"&am&amp"); - eval(b"&am&amp;", b"&am&amp;"); - - eval(b"&≪⃒", b"&≪⃒"); - eval(b"&am≪⃒", b"&am≪⃒"); - eval(b"&am≪⃒a", b"&am≪⃒a"); - eval(b"&am&nLt", b"&am&nLt"); -} - -#[test] -fn test_left_chevron_in_content() { - eval(b"
<
", b"
<
"); - eval(b"
< 
", b"
< 
"); - eval(b"
 < 
", b"
 < 
"); - - eval(b"
 <a 
", b"
 <a 
"); - eval(b"
 <a 
", b"
 <a 
"); - eval(b"
 <a 
", b"
 <a 
"); - eval(b"
 <a 
", b"
 <a 
"); - - eval(b"
 <? 
", b"
 <? 
"); - eval(b"
 <? 
", b"
 <? 
"); - eval(b"
 <? 
", b"
 <? 
"); - eval(b"
 <? 
", b"
 <? 
"); - - eval(b"
 </ 
", b"
 </ 
"); - eval(b"
 <! 
", b"
 <! 
"); - - eval(b"<", b"<"); - eval(b"<", b"<"); - eval(b"<;", b"<;"); - eval(b"<;", b"<;"); - eval(b"<;", b"<;"); - eval(b"<", b"<"); - eval(b"<", b"<"); - eval(b"<;", b"<;"); - eval(b"<;", b"<;"); - eval(b"<;", b"<;"); - - eval(b"<a", b"<a"); - eval(b"<a", b"<a"); - eval(b"<a;", b"<a;"); - eval(b"<a;", b"<a;"); - eval(b"<a;", b"<a;"); - eval(b"<a;;", b"<a;;"); - - eval(b"<!", b"<!"); - eval(b"<&", b"<&"); - eval(b"</", b"</"); - eval(b"<?", b"<?"); - eval(b"<@", b"<@"); -} -#[test] -fn test_comments_removal() { - eval( + // unintentional entity prevention + t.insert(b"&amp", b"&amp"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp", b"&amp"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp", b"&amp"); + t.insert(b"&amp", b"&amp"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp;", b"&amp;"); + t.insert(b"&amp;", b"&amp;"); + + t.insert(b"&lt", b"&lt"); + t.insert(b"&lt", b"&lt"); + t.insert(b"&lt;", b"&lt;"); + t.insert(b"&lt;", b"&lt;"); + t.insert(b"&lt", b"&lt"); + t.insert(b"&lt;", b"&lt;"); + + t.insert(b"&am&amp", b"&am&amp"); + t.insert(b"&am&amp;", b"&am&amp;"); + + t.insert(b"&≪⃒", b"&≪⃒"); + t.insert(b"&am≪⃒", b"&am≪⃒"); + t.insert(b"&am≪⃒a", b"&am≪⃒a"); + t.insert(b"&am&nLt", b"&am&nLt"); + + // left chevron in content + t.insert(b"
<
", b"
<
"); + t.insert(b"
< 
", b"
< 
"); + t.insert(b"
 < 
", b"
 < 
"); + + t.insert(b"
 <a 
", b"
 <a 
"); + t.insert(b"
 <a 
", b"
 <a 
"); + t.insert(b"
 <a 
", b"
 <a 
"); + t.insert(b"
 <a 
", b"
 <a 
"); + + t.insert(b"
 <? 
", b"
 <? 
"); + t.insert(b"
 <? 
", b"
 <? 
"); + t.insert(b"
 <? 
", b"
 <? 
"); + t.insert(b"
 <? 
", b"
 <? 
"); + + t.insert(b"
 </ 
", b"
 </ 
"); + t.insert(b"
 <! 
", b"
 <! 
"); + + t.insert(b"<", b"<"); + t.insert(b"<", b"<"); + t.insert(b"<;", b"<;"); + t.insert(b"<;", b"<;"); + t.insert(b"<;", b"<;"); + t.insert(b"<", b"<"); + t.insert(b"<", b"<"); + t.insert(b"<;", b"<;"); + t.insert(b"<;", b"<;"); + t.insert(b"<;", b"<;"); + + t.insert(b"<a", b"<a"); + t.insert(b"<a", b"<a"); + t.insert(b"<a;", b"<a;"); + t.insert(b"<a;", b"<a;"); + t.insert(b"<a;", b"<a;"); + t.insert(b"<a;;", b"<a;;"); + + t.insert(b"<!", b"<!"); + t.insert(b"<&", b"<&"); + t.insert(b"</", b"</"); + t.insert(b"<?", b"<?"); + t.insert(b"<@", b"<@"); + + // comments removal + t.insert( b"
a   b
", b"
a   b
", ); - eval(b"&amp", b"&"); - eval( + t.insert(b"&amp", b"&"); + t.insert( b"", b"", ); + + // processing instructions + t.insert(b"> ?>", b"> ?>"); + t.insert(b"avg", b"avg"); + + // self closing svg + t.insert( + b"
", + b"
", + ); + t.insert( + b"
", + b"
", + ); + + t } -#[test] -fn test_processing_instructions() { - eval(b"> ?>", b"> ?>"); - eval(b"avg", b"avg"); +pub fn create_common_css_test_data() -> HashMap<&'static [u8], &'static [u8]> { + let mut t = HashMap::<&'static [u8], &'static [u8]>::new(); + + // style element minification + t.insert( + b"", + b"", + ); + + t } -#[test] -fn test_js_minification() { - eval_with_js_min(b"", b""); - eval_with_js_min( +pub fn create_common_js_test_data() -> HashMap<&'static [u8], &'static [u8]> { + let mut t = HashMap::<&'static [u8], &'static [u8]>::new(); + + // js minification + t.insert(b"", b""); + t.insert( b"", b"", ); - eval_with_js_min( + t.insert( br#" "#, b"", ); - eval_with_js_min( + t.insert( b"", b"", ); - eval_with_js_min( + t.insert( br#" ", ); -} - -/* TODO Reenable once unintentional script closing tag escaping is implemented in minify-js. -#[test] -fn test_js_minification_unintentional_closing_tag() { - eval_with_js_min( - br#""#, - br#""#, - ); - eval_with_js_min( - br#""#, - br#""#, - ); - eval_with_js_min( - br#""#, - br#""#, - ); - eval_with_js_min( - br#""#, - br#""#, - ); -} -*/ -#[test] -fn test_style_element_minification() { - // `", - b"", + // js minification unintentional closing tag + /* TODO Reenable once unintentional script closing tag escaping is implemented in minify-js. + t.insert( + br#""#, + br#""#, ); -} - -#[test] -fn test_self_closing_svg() { - eval( - b"
", - b"
", + t.insert( + br#""#, + br#""#, ); - eval( - b"
", - b"
", + t.insert( + br#""#, + br#""#, + ); + t.insert( + br#""#, + br#""#, ); + */ + + t } diff --git a/minify-html-onepass/src/tests/mod.rs b/minify-html-onepass/src/tests/mod.rs index c6ffc0f6..8e3e764c 100644 --- a/minify-html-onepass/src/tests/mod.rs +++ b/minify-html-onepass/src/tests/mod.rs @@ -2,6 +2,9 @@ use crate::cfg::Cfg; use crate::err::ErrorType; use crate::in_place; use crate::with_friendly_error; +use minify_html_common::tests::create_common_css_test_data; +use minify_html_common::tests::create_common_js_test_data; +use minify_html_common::tests::create_common_test_data; use std::str::from_utf8; pub fn eval_with_cfg(src: &'static [u8], expected: &'static [u8], cfg: &Cfg) { @@ -54,6 +57,19 @@ fn eval_error(src: &'static [u8], expected: ErrorType) -> () { ); } +#[test] +fn test_common() { + for (a, b) in create_common_test_data() { + eval(a, b); + } + for (a, b) in create_common_css_test_data() { + eval_with_css_min(a, b); + } + for (a, b) in create_common_js_test_data() { + eval_with_js_min(a, b); + } +} + #[test] // NOTE: Keep inputs in sync with main variant. Outputs are different as main variant reorders attributes. fn test_space_between_attrs_minification() { diff --git a/minify-html/src/tests/mod.rs b/minify-html/src/tests/mod.rs index 78a200f2..fbf9e555 100644 --- a/minify-html/src/tests/mod.rs +++ b/minify-html/src/tests/mod.rs @@ -1,5 +1,8 @@ use crate::cfg::Cfg; use crate::minify; +use minify_html_common::tests::create_common_css_test_data; +use minify_html_common::tests::create_common_js_test_data; +use minify_html_common::tests::create_common_test_data; use std::str::from_utf8; pub fn eval_with_cfg(src: &'static [u8], expected: &'static [u8], cfg: &Cfg) { @@ -30,6 +33,19 @@ fn eval_without_keep_html_head(src: &'static [u8], expected: &'static [u8]) -> ( eval_with_cfg(src, expected, &Cfg::new()); } +#[test] +fn test_common() { + for (a, b) in create_common_test_data() { + eval(a, b); + } + for (a, b) in create_common_css_test_data() { + eval_with_css_min(a, b); + } + for (a, b) in create_common_js_test_data() { + eval_with_js_min(a, b); + } +} + #[test] fn test_minification_of_doctype() { eval(b"", b"");