From 090d64739003de3e92c46b4f518ca4f01749ec09 Mon Sep 17 00:00:00 2001 From: Sunshine Date: Sat, 23 May 2020 03:49:04 -0400 Subject: [PATCH] group all tests into either passing or failing groups --- src/tests/cli.rs | 1002 ++++++++++++----------- src/tests/css/embed_css.rs | 620 +++++++------- src/tests/css/enquote.rs | 77 +- src/tests/html/get_node_name.rs | 71 +- src/tests/html/is_icon.rs | 72 +- src/tests/html/stringify_document.rs | 345 ++++---- src/tests/html/walk_and_embed_assets.rs | 824 +++++++++---------- src/tests/js/attr_is_event_handler.rs | 56 +- src/tests/utils/clean_url.rs | 75 +- src/tests/utils/data_to_data_url.rs | 37 +- src/tests/utils/data_url_to_data.rs | 163 ++-- src/tests/utils/detect_media_type.rs | 268 +++--- src/tests/utils/file_url_to_fs_path.rs | 57 +- src/tests/utils/get_url_fragment.rs | 31 +- src/tests/utils/is_data_url.rs | 56 +- src/tests/utils/is_file_url.rs | 108 +-- src/tests/utils/is_http_url.rs | 76 +- src/tests/utils/resolve_url.rs | 427 +++++----- src/tests/utils/retrieve_asset.rs | 200 ++--- src/tests/utils/url_has_protocol.rs | 120 +-- 20 files changed, 2399 insertions(+), 2286 deletions(-) diff --git a/src/tests/cli.rs b/src/tests/cli.rs index 2d19c32..34dc9fd 100644 --- a/src/tests/cli.rs +++ b/src/tests/cli.rs @@ -1,9 +1,3 @@ -use assert_cmd::prelude::*; -use std::env; -use std::io::Write; -use std::process::Command; -use tempfile::NamedTempFile; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -11,519 +5,527 @@ use tempfile::NamedTempFile; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_print_version() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd.arg("-V").output().unwrap(); - - // STDOUT should contain program name and version - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - format!("{} {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_bad_input_empty_target() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd.arg("").output().unwrap(); - - // STDOUT should be empty - assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); - - // STDERR should contain error description - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - "No target specified\n" - ); - - // The exit code should be 1 - out.assert().code(1); - - Ok(()) -} - -#[test] -fn passing_bad_input_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap(); - - // STDOUT should contain HTML - assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); - - // STDERR should contain error description - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - "Unsupported data URL media type\n" - ); - - // The exit code should be 1 - out.assert().code(1); - - Ok(()) -} - -#[test] -fn passing_isolate_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-I") - .arg("data:text/html,Hello%2C%20World!") - .output() - .unwrap(); - - // STDOUT should contain isolated HTML - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\ -\ -Hello, World!\n" - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_remove_css_from_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-c") - .arg("data:text/html,Hello") - .output() - .unwrap(); - - // STDOUT should contain HTML with no CSS - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\ -\ -\ -Hello\n" - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_remove_frames_from_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-f") - .arg("data:text/html,Hi") - .output() - .unwrap(); - - // STDOUT should contain HTML with no iframes - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\ -\ -Hi\n" - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_remove_images_from_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-i") - .arg("data:text/html,Hi") - .output() - .unwrap(); - - // STDOUT should contain HTML with no images - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - format!( - "\ -\ -\ -\ -\ -\ -Hi\ -\ -\n", - empty_image = empty_image!() - ) - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_remove_js_from_data_url() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-j") - .arg("data:text/html,Hi") - .output() - .unwrap(); - - // STDOUT should contain HTML with no JS - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\ -\ -\ -\ -Hi\ -\n" - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_local_file_target_input() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let cwd_normalized: String = - str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); - let out = cmd - .arg("-M") - .arg(if cfg!(windows) { - "src\\tests\\data\\basic\\local-file.html" - } else { - "src/tests/data/basic/local-file.html" - }) - .output() - .unwrap(); - let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; - - // STDOUT should contain HTML from the local file - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\ -\n \ -\n \ -Local HTML file\n \ -\n \ -\n\n\n\n \ -\"\"\n \ -Tricky href\n \ -Remote URL\n \ -\n\n\n\n\ -\n\ -" - ); - - // STDERR should contain list of retrieved file URLs - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - format!( - "\ -{file}{cwd}/src/tests/data/basic/local-file.html\n\ -{file}{cwd}/src/tests/data/basic/local-style.css\n\ -{file}{cwd}/src/tests/data/basic/local-script.js\n\ -", - file = file_url_protocol, - cwd = cwd_normalized - ) - ); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_local_file_target_input_absolute_target_path() -> Result<(), Box> -{ - let cwd = env::current_dir().unwrap(); - let cwd_normalized: String = - str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("-jciI") - .arg(if cfg!(windows) { - format!( - "{cwd}\\src\\tests\\data\\basic\\local-file.html", - cwd = cwd.to_str().unwrap() - ) - } else { +#[cfg(test)] +mod passing { + use assert_cmd::prelude::*; + use std::env; + use std::io::Write; + use std::process::Command; + use tempfile::NamedTempFile; + + #[test] + fn print_version() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd.arg("-V").output().unwrap(); + + // STDOUT should contain program name and version + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + format!("{} {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn bad_input_empty_target() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd.arg("").output().unwrap(); + + // STDOUT should be empty + assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); + + // STDERR should contain error description + assert_eq!( + std::str::from_utf8(&out.stderr).unwrap(), + "No target specified\n" + ); + + // The exit code should be 1 + out.assert().code(1); + + Ok(()) + } + + #[test] + fn bad_input_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap(); + + // STDOUT should contain HTML + assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); + + // STDERR should contain error description + assert_eq!( + std::str::from_utf8(&out.stderr).unwrap(), + "Unsupported data URL media type\n" + ); + + // The exit code should be 1 + out.assert().code(1); + + Ok(()) + } + + #[test] + fn isolate_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-I") + .arg("data:text/html,Hello%2C%20World!") + .output() + .unwrap(); + + // STDOUT should contain isolated HTML + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "\ + \ + Hello, World!\n" + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn remove_css_from_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-c") + .arg("data:text/html,Hello") + .output() + .unwrap(); + + // STDOUT should contain HTML with no CSS + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "\ + \ + \ + Hello\n" + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn remove_frames_from_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-f") + .arg("data:text/html,Hi") + .output() + .unwrap(); + + // STDOUT should contain HTML with no iframes + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "\ + \ + Hi\n" + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn remove_images_from_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-i") + .arg("data:text/html,Hi") + .output() + .unwrap(); + + // STDOUT should contain HTML with no images + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), format!( - "{cwd}/src/tests/data/basic/local-file.html", - cwd = cwd.to_str().unwrap() + "\ + \ + \ + \ + \ + \ + Hi\ + \ + \n", + empty_image = empty_image!() ) - }) - .output() - .unwrap(); - let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; - - // STDOUT should contain HTML from the local file - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - format!( + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn remove_js_from_data_url() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-j") + .arg("data:text/html,Hi") + .output() + .unwrap(); + + // STDOUT should contain HTML with no JS + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "\ + \ + \ + \ + Hi\ + \n" + ); + + // STDERR should be empty + assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn local_file_target_input() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let cwd_normalized: String = + str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); + let out = cmd + .arg("-M") + .arg(if cfg!(windows) { + "src\\tests\\data\\basic\\local-file.html" + } else { + "src/tests/data/basic/local-file.html" + }) + .output() + .unwrap(); + let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; + + // STDOUT should contain HTML from the local file + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), "\ -\ -\n \ -\n \ -Local HTML file\n \ -\n \ -\n\n\n\n \ -\"\"\n \ -Tricky href\n \ -Remote URL\n \ -\n\n\n\n\ -\n\ -", - empty_image = empty_image!() - ) - ); - - // STDERR should contain only the target file - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - format!( - "{file}{cwd}/src/tests/data/basic/local-file.html\n", - file = file_url_protocol, - cwd = cwd_normalized, - ) - ); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_local_file_url_target_input() -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let cwd_normalized: String = - str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); - let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; - let out = cmd - .arg("-M") - .arg("-cji") - .arg(if cfg!(windows) { + \n \ + \n \ + Local HTML file\n \ + \n \ + \n\n\n\n \ + \"\"\n \ + Tricky href\n \ + Remote URL\n \ + \n\n\n\n\ + \n\ + " + ); + + // STDERR should contain list of retrieved file URLs + assert_eq!( + std::str::from_utf8(&out.stderr).unwrap(), format!( - "{file}{cwd}/src/tests/data/basic/local-file.html", + "\ + {file}{cwd}/src/tests/data/basic/local-file.html\n\ + {file}{cwd}/src/tests/data/basic/local-style.css\n\ + {file}{cwd}/src/tests/data/basic/local-script.js\n\ + ", file = file_url_protocol, - cwd = cwd_normalized, + cwd = cwd_normalized ) - } else { + ); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn local_file_target_input_absolute_target_path() -> Result<(), Box> { + let cwd = env::current_dir().unwrap(); + let cwd_normalized: String = + str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let out = cmd + .arg("-M") + .arg("-jciI") + .arg(if cfg!(windows) { + format!( + "{cwd}\\src\\tests\\data\\basic\\local-file.html", + cwd = cwd.to_str().unwrap() + ) + } else { + format!( + "{cwd}/src/tests/data/basic/local-file.html", + cwd = cwd.to_str().unwrap() + ) + }) + .output() + .unwrap(); + let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; + + // STDOUT should contain HTML from the local file + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), format!( - "{file}{cwd}/src/tests/data/basic/local-file.html", - file = file_url_protocol, - cwd = cwd_normalized, + "\ + \ + \n \ + \n \ + Local HTML file\n \ + \n \ + \n\n\n\n \ + \"\"\n \ + Tricky href\n \ + Remote URL\n \ + \n\n\n\n\ + \n\ + ", + empty_image = empty_image!() ) - }) - .output() - .unwrap(); - - // STDOUT should contain HTML from the local file - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - format!( - "\ -\ -\n \ -\n \ -Local HTML file\n \ -\n \ -\n\n\n\n \ -\"\"\n \ -Tricky href\n \ -Remote URL\n \ -\n\n\n\n\ -\n\ -", - empty_image = empty_image!() - ) - ); - - // STDERR should contain list of retrieved file URLs - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - if cfg!(windows) { + ); + + // STDERR should contain only the target file + assert_eq!( + std::str::from_utf8(&out.stderr).unwrap(), format!( "{file}{cwd}/src/tests/data/basic/local-file.html\n", file = file_url_protocol, cwd = cwd_normalized, ) - } else { + ); + + // The exit code should be 0 + out.assert().code(0); + + Ok(()) + } + + #[test] + fn local_file_url_target_input() -> Result<(), Box> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let cwd_normalized: String = + str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); + let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; + let out = cmd + .arg("-M") + .arg("-cji") + .arg(if cfg!(windows) { + format!( + "{file}{cwd}/src/tests/data/basic/local-file.html", + file = file_url_protocol, + cwd = cwd_normalized, + ) + } else { + format!( + "{file}{cwd}/src/tests/data/basic/local-file.html", + file = file_url_protocol, + cwd = cwd_normalized, + ) + }) + .output() + .unwrap(); + + // STDOUT should contain HTML from the local file + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), format!( - "{file}{cwd}/src/tests/data/basic/local-file.html\n", - file = file_url_protocol, - cwd = cwd_normalized, + "\ + \ + \n \ + \n \ + Local HTML file\n \ + \n \ + \n\n\n\n \ + \"\"\n \ + Tricky href\n \ + Remote URL\n \ + \n\n\n\n\ + \n\ + ", + empty_image = empty_image!() ) - } - ); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_security_disallow_local_assets_within_data_url_targets( -) -> Result<(), Box> { - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let out = cmd - .arg("-M") - .arg("data:text/html,%3Cscript%20src=\"src/tests/data/basic/local-script.js\"%3E%3C/script%3E") - .output() - .unwrap(); - - // STDOUT should contain HTML with no JS in it - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\n" - ); - - // STDERR should be empty - assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_embed_file_url_local_asset_within_style_attribute( -) -> Result<(), Box> { - let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" }; - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let mut file_svg = NamedTempFile::new()?; - writeln!(file_svg, "\ -\ -\ -SVG\ -\n")?; - let mut file_html = NamedTempFile::new()?; - writeln!( - file_html, - "
\n", - file = file_url_prefix, - path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"), - )?; - let out = cmd.arg("-M").arg(file_html.path()).output().unwrap(); - - // STDOUT should contain HTML with date URL for background-image in it - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "
\n", file = file_url_prefix, - html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"), - svg_path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"), - ) - ); - - // The exit code should be 0 - out.assert().code(0); - - Ok(()) -} - -#[test] -fn passing_css_import_string() -> Result<(), Box> { - let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" }; - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; - let mut file_css = NamedTempFile::new()?; - writeln!(file_css, "body{{background-color:#000;color:#fff}}")?; - let mut file_html = NamedTempFile::new()?; - writeln!( - file_html, - "\ -\n\ -", - file = file_url_prefix, - css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"), - )?; - let out = cmd.arg("-M").arg(file_html.path()).output().unwrap(); - - // STDOUT should contain embedded CSS url()'s - assert_eq!( - std::str::from_utf8(&out.stdout).unwrap(), - "\n\n\n" - ); - - // STDERR should list temporary files that got retrieved - assert_eq!( - std::str::from_utf8(&out.stderr).unwrap(), - format!( + path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"), + )?; + let out = cmd.arg("-M").arg(file_html.path()).output().unwrap(); + + // STDOUT should contain HTML with date URL for background-image in it + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "
\n\ + ", file = file_url_prefix, - html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"), css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"), - ) - ); + )?; + let out = cmd.arg("-M").arg(file_html.path()).output().unwrap(); + + // STDOUT should contain embedded CSS url()'s + assert_eq!( + std::str::from_utf8(&out.stdout).unwrap(), + "\n\n\n" + ); + + // STDERR should list temporary files that got retrieved + assert_eq!( + std::str::from_utf8(&out.stderr).unwrap(), + format!( + "\ + {file}{html_path}\n\ + {file}{css_path}\n\ + {file}{css_path}\n\ + {file}{css_path}\n\ + ", + file = file_url_prefix, + html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"), + css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"), + ) + ); - // The exit code should be 0 - out.assert().code(0); + // The exit code should be 0 + out.assert().code(0); - Ok(()) + Ok(()) + } } diff --git a/src/tests/css/embed_css.rs b/src/tests/css/embed_css.rs index f3d036b..b34aea6 100644 --- a/src/tests/css/embed_css.rs +++ b/src/tests/css/embed_css.rs @@ -1,8 +1,3 @@ -use reqwest::blocking::Client; -use std::collections::HashMap; - -use crate::css; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -10,308 +5,315 @@ use crate::css; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_empty_input() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - assert_eq!( - css::embed_css(cache, &client, "", "", false, false, false,), - "" - ); -} - -#[test] -fn passing_style_exclude_unquoted_images() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const STYLE: &str = "/* border: none;*/\ -background-image: url(https://somewhere.com/bg.png); \ -list-style: url(/assets/images/bullet.svg);\ -width:99.998%; \ -margin-top: -20px; \ -line-height: -1; \ -height: calc(100vh - 10pt)"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &STYLE, - false, - true, - true, - ), - format!( - "/* border: none;*/\ -background-image: url('{empty_image}'); \ -list-style: url('{empty_image}');\ -width:99.998%; \ -margin-top: -20px; \ -line-height: -1; \ -height: calc(100vh - 10pt)", - empty_image = empty_image!() - ) - ); -} - -#[test] -fn passing_style_exclude_single_quoted_images() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const STYLE: &str = "/* border: none;*/\ -background-image: url('https://somewhere.com/bg.png'); \ -list-style: url('/assets/images/bullet.svg');\ -width:99.998%; \ -margin-top: -20px; \ -line-height: -1; \ -height: calc(100vh - 10pt)"; - - assert_eq!( - css::embed_css(cache, &client, "", &STYLE, false, true, true,), - format!( - "/* border: none;*/\ -background-image: url('{empty_image}'); \ -list-style: url('{empty_image}');\ -width:99.998%; \ -margin-top: -20px; \ -line-height: -1; \ -height: calc(100vh - 10pt)", - empty_image = empty_image!() - ) - ); -} - -#[test] -fn passing_style_block() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -#id.class-name:not(:nth-child(3n+0)) {\n \ - // border: none;\n \ - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');\n\ -}\n\ -\n\ -html > body {}"; - - assert_eq!( - css::embed_css(cache, &client, "file:///", &CSS, false, false, true,), - CSS - ); -} - -#[test] -fn passing_attribute_selectors() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -[data-value] { - /* Attribute exists */ -} - -[data-value='foo'] { - /* Attribute has this exact value */ -} - -[data-value*='foo'] { - /* Attribute value contains this value somewhere in it */ -} - -[data-value~='foo'] { - /* Attribute has this value in a space-separated list somewhere */ -} - -[data-value^='foo'] { - /* Attribute value starts with this */ -} - -[data-value|='foo'] { - /* Attribute value starts with this in a dash-separated list */ -} - -[data-value$='foo'] { - /* Attribute value ends with this */ -} -"; - - assert_eq!( - css::embed_css(cache, &client, "", &CSS, false, false, false,), - CSS - ); -} - -#[test] -fn passing_import_string() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -@charset 'UTF-8';\n\ -\n\ -@import 'data:text/css,html{background-color:%23000}';\n\ -\n\ -@import url('data:text/css,html{color:%23fff}')\n\ -"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &CSS, - false, - false, - true, - ), - "\ -@charset 'UTF-8';\n\ -\n\ -@import 'data:text/css;base64,aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiMwMDB9';\n\ -\n\ -@import url('data:text/css;base64,aHRtbHtjb2xvcjojZmZmfQ==')\n\ -" - ); -} - -#[test] -fn passing_hash_urls() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -body {\n \ - behavior: url(#default#something);\n\ -}\n\ -\n\ -.scissorHalf {\n \ - offset-path: url(#somePath);\n\ -}\n\ -"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &CSS, - false, - false, - true, - ), - CSS - ); -} - -#[test] -fn passing_transform_percentages_and_degrees() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -div {\n \ - transform: translate(-50%, -50%) rotate(-45deg);\n\ - transform: translate(50%, 50%) rotate(45deg);\n\ - transform: translate(+50%, +50%) rotate(+45deg);\n\ -}\n\ -"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &CSS, - false, - false, - true, - ), - CSS - ); -} - -#[test] -fn passing_unusual_indents() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -.is\\:good:hover {\n \ - color: green\n\ -}\n\ -\n\ -#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\+\\=\\,\\.\\/\\\\\\'\\\"\\;\\:\\?\\>\\<\\[\\]\\{\\}\\|\\`\\# {\n \ - color: black\n\ -}\n\ -"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &CSS, - false, - false, - true, - ), - CSS - ); -} - -#[test] -fn passing_exclude_fonts() { - let cache = &mut HashMap::new(); - let client = Client::new(); - - const CSS: &str = "\ -@font-face {\n \ - font-family: 'My Font';\n \ - src: url(my_font.woff);\n\ -}\n\ -\n\ -#identifier {\n \ - font-family: 'My Font' Arial\n\ -}\n\ -\n\ -@font-face {\n \ - font-family: 'My Font';\n \ - src: url(my_font.woff);\n\ -}\n\ -\n\ -div {\n \ - font-family: 'My Font' Verdana\n\ -}\n\ -"; - - const CSS_OUT: &str = " \ -\n\ -\n\ -#identifier {\n \ - font-family: 'My Font' Arial\n\ -}\n\ -\n \ -\n\ -\n\ -div {\n \ - font-family: 'My Font' Verdana\n\ -}\n\ -"; - - assert_eq!( - css::embed_css( - cache, - &client, - "https://doesntmatter.local/", - &CSS, - true, - false, - true, - ), - CSS_OUT - ); +#[cfg(test)] +mod passing { + use crate::css; + use reqwest::blocking::Client; + use std::collections::HashMap; + + #[test] + fn empty_input() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + assert_eq!( + css::embed_css(cache, &client, "", "", false, false, false,), + "" + ); + } + + #[test] + fn style_exclude_unquoted_images() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const STYLE: &str = "/* border: none;*/\ + background-image: url(https://somewhere.com/bg.png); \ + list-style: url(/assets/images/bullet.svg);\ + width:99.998%; \ + margin-top: -20px; \ + line-height: -1; \ + height: calc(100vh - 10pt)"; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &STYLE, + false, + true, + true, + ), + format!( + "/* border: none;*/\ + background-image: url('{empty_image}'); \ + list-style: url('{empty_image}');\ + width:99.998%; \ + margin-top: -20px; \ + line-height: -1; \ + height: calc(100vh - 10pt)", + empty_image = empty_image!() + ) + ); + } + + #[test] + fn style_exclude_single_quoted_images() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const STYLE: &str = "/* border: none;*/\ + background-image: url('https://somewhere.com/bg.png'); \ + list-style: url('/assets/images/bullet.svg');\ + width:99.998%; \ + margin-top: -20px; \ + line-height: -1; \ + height: calc(100vh - 10pt)"; + + assert_eq!( + css::embed_css(cache, &client, "", &STYLE, false, true, true,), + format!( + "/* border: none;*/\ + background-image: url('{empty_image}'); \ + list-style: url('{empty_image}');\ + width:99.998%; \ + margin-top: -20px; \ + line-height: -1; \ + height: calc(100vh - 10pt)", + empty_image = empty_image!() + ) + ); + } + + #[test] + fn style_block() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + #id.class-name:not(:nth-child(3n+0)) {\n \ + // border: none;\n \ + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');\n\ + }\n\ + \n\ + html > body {}"; + + assert_eq!( + css::embed_css(cache, &client, "file:///", &CSS, false, false, true,), + CSS + ); + } + + #[test] + fn attribute_selectors() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + [data-value] { + /* Attribute exists */ + } + + [data-value='foo'] { + /* Attribute has this exact value */ + } + + [data-value*='foo'] { + /* Attribute value contains this value somewhere in it */ + } + + [data-value~='foo'] { + /* Attribute has this value in a space-separated list somewhere */ + } + + [data-value^='foo'] { + /* Attribute value starts with this */ + } + + [data-value|='foo'] { + /* Attribute value starts with this in a dash-separated list */ + } + + [data-value$='foo'] { + /* Attribute value ends with this */ + } + "; + + assert_eq!( + css::embed_css(cache, &client, "", &CSS, false, false, false,), + CSS + ); + } + + #[test] + fn import_string() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + @charset 'UTF-8';\n\ + \n\ + @import 'data:text/css,html{background-color:%23000}';\n\ + \n\ + @import url('data:text/css,html{color:%23fff}')\n\ + "; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &CSS, + false, + false, + true, + ), + "\ + @charset 'UTF-8';\n\ + \n\ + @import 'data:text/css;base64,aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiMwMDB9';\n\ + \n\ + @import url('data:text/css;base64,aHRtbHtjb2xvcjojZmZmfQ==')\n\ + " + ); + } + + #[test] + fn hash_urls() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + body {\n \ + behavior: url(#default#something);\n\ + }\n\ + \n\ + .scissorHalf {\n \ + offset-path: url(#somePath);\n\ + }\n\ + "; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &CSS, + false, + false, + true, + ), + CSS + ); + } + + #[test] + fn transform_percentages_and_degrees() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + div {\n \ + transform: translate(-50%, -50%) rotate(-45deg);\n\ + transform: translate(50%, 50%) rotate(45deg);\n\ + transform: translate(+50%, +50%) rotate(+45deg);\n\ + }\n\ + "; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &CSS, + false, + false, + true, + ), + CSS + ); + } + + #[test] + fn unusual_indents() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + .is\\:good:hover {\n \ + color: green\n\ + }\n\ + \n\ + #\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\+\\=\\,\\.\\/\\\\\\'\\\"\\;\\:\\?\\>\\<\\[\\]\\{\\}\\|\\`\\# {\n \ + color: black\n\ + }\n\ + "; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &CSS, + false, + false, + true, + ), + CSS + ); + } + + #[test] + fn exclude_fonts() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + const CSS: &str = "\ + @font-face {\n \ + font-family: 'My Font';\n \ + src: url(my_font.woff);\n\ + }\n\ + \n\ + #identifier {\n \ + font-family: 'My Font' Arial\n\ + }\n\ + \n\ + @font-face {\n \ + font-family: 'My Font';\n \ + src: url(my_font.woff);\n\ + }\n\ + \n\ + div {\n \ + font-family: 'My Font' Verdana\n\ + }\n\ + "; + + const CSS_OUT: &str = " \ + \n\ + \n\ + #identifier {\n \ + font-family: 'My Font' Arial\n\ + }\n\ + \n \ + \n\ + \n\ + div {\n \ + font-family: 'My Font' Verdana\n\ + }\n\ + "; + + assert_eq!( + css::embed_css( + cache, + &client, + "https://doesntmatter.local/", + &CSS, + true, + false, + true, + ), + CSS_OUT + ); + } } diff --git a/src/tests/css/enquote.rs b/src/tests/css/enquote.rs index 21304b0..d02a868 100644 --- a/src/tests/css/enquote.rs +++ b/src/tests/css/enquote.rs @@ -1,5 +1,3 @@ -use crate::css; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,44 +5,49 @@ use crate::css; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_empty_input_single_quotes() { - assert_eq!(css::enquote(str!(""), false), "''"); -} +#[cfg(test)] +mod passing { + use crate::css; -#[test] -fn passing_empty_input_double_quotes() { - assert_eq!(css::enquote(str!(""), true), "\"\""); -} + #[test] + fn empty_input_single_quotes() { + assert_eq!(css::enquote(str!(""), false), "''"); + } -#[test] -fn passing_apostrophes_single_quotes() { - assert_eq!( - css::enquote(str!("It's a lovely day, don't you think?"), false), - "'It\\'s a lovely day, don\\'t you think?'" - ); -} + #[test] + fn empty_input_double_quotes() { + assert_eq!(css::enquote(str!(""), true), "\"\""); + } -#[test] -fn passing_apostrophes_double_quotes() { - assert_eq!( - css::enquote(str!("It's a lovely day, don't you think?"), true), - "\"It's a lovely day, don't you think?\"" - ); -} + #[test] + fn apostrophes_single_quotes() { + assert_eq!( + css::enquote(str!("It's a lovely day, don't you think?"), false), + "'It\\'s a lovely day, don\\'t you think?'" + ); + } -#[test] -fn passing_feet_and_inches_single_quotes() { - assert_eq!( - css::enquote(str!("5'2\", 6'5\""), false), - "'5\\'2\", 6\\'5\"'" - ); -} + #[test] + fn apostrophes_double_quotes() { + assert_eq!( + css::enquote(str!("It's a lovely day, don't you think?"), true), + "\"It's a lovely day, don't you think?\"" + ); + } + + #[test] + fn feet_and_inches_single_quotes() { + assert_eq!( + css::enquote(str!("5'2\", 6'5\""), false), + "'5\\'2\", 6\\'5\"'" + ); + } -#[test] -fn passing_feet_and_inches_double_quotes() { - assert_eq!( - css::enquote(str!("5'2\", 6'5\""), true), - "\"5'2\\\", 6'5\\\"\"" - ); + #[test] + fn feet_and_inches_double_quotes() { + assert_eq!( + css::enquote(str!("5'2\", 6'5\""), true), + "\"5'2\\\", 6'5\\\"\"" + ); + } } diff --git a/src/tests/html/get_node_name.rs b/src/tests/html/get_node_name.rs index dfd4b08..94c9234 100644 --- a/src/tests/html/get_node_name.rs +++ b/src/tests/html/get_node_name.rs @@ -1,6 +1,3 @@ -use crate::html; -use html5ever::rcdom::{Handle, NodeData}; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -8,42 +5,48 @@ use html5ever::rcdom::{Handle, NodeData}; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn get_node_name() { - let html = "

"; - let dom = html::html_to_dom(&html); - let mut count = 0; +#[cfg(test)] +mod passing { + use crate::html; + use html5ever::rcdom::{Handle, NodeData}; - fn test_walk(node: &Handle, i: &mut i8) { - *i += 1; + #[test] + fn get_node_name() { + let html = "

"; + let dom = html::html_to_dom(&html); + let mut count = 0; - match &node.data { - NodeData::Document => { - for child in node.children.borrow().iter() { - test_walk(child, &mut *i); - } - } - NodeData::Element { ref name, .. } => { - let node_name = name.local.as_ref().to_string(); - let parent = html::get_parent_node(node); - let parent_node_name = html::get_node_name(&parent); - if node_name == "head" || node_name == "body" { - assert_eq!(parent_node_name, Some("html")); - } else if node_name == "div" { - assert_eq!(parent_node_name, Some("body")); - } else if node_name == "p" { - assert_eq!(parent_node_name, Some("div")); + fn test_walk(node: &Handle, i: &mut i8) { + *i += 1; + + match &node.data { + NodeData::Document => { + for child in node.children.borrow().iter() { + test_walk(child, &mut *i); + } } + NodeData::Element { ref name, .. } => { + let node_name = name.local.as_ref().to_string(); + let parent = html::get_parent_node(node); + let parent_node_name = html::get_node_name(&parent); + if node_name == "head" || node_name == "body" { + assert_eq!(parent_node_name, Some("html")); + } else if node_name == "div" { + assert_eq!(parent_node_name, Some("body")); + } else if node_name == "p" { + assert_eq!(parent_node_name, Some("div")); + } - for child in node.children.borrow().iter() { - test_walk(child, &mut *i); + for child in node.children.borrow().iter() { + test_walk(child, &mut *i); + } } - } - _ => (), - }; - } + _ => (), + }; + } - test_walk(&dom.document, &mut count); + test_walk(&dom.document, &mut count); - assert_eq!(count, 7); + assert_eq!(count, 7); + } } diff --git a/src/tests/html/is_icon.rs b/src/tests/html/is_icon.rs index 334cec4..a187356 100644 --- a/src/tests/html/is_icon.rs +++ b/src/tests/html/is_icon.rs @@ -1,5 +1,3 @@ -use crate::html; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,29 +5,34 @@ use crate::html; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_icon() { - assert!(html::is_icon("icon")); -} - -#[test] -fn passing_shortcut_icon_capitalized() { - assert!(html::is_icon("Shortcut Icon")); -} - -#[test] -fn passing_icon_uppercase() { - assert!(html::is_icon("ICON")); -} - -#[test] -fn passing_mask_icon() { - assert!(html::is_icon("mask-icon")); -} - -#[test] -fn passing_fluid_icon() { - assert!(html::is_icon("fluid-icon")); +#[cfg(test)] +mod passing { + use crate::html; + + #[test] + fn icon() { + assert!(html::is_icon("icon")); + } + + #[test] + fn shortcut_icon_capitalized() { + assert!(html::is_icon("Shortcut Icon")); + } + + #[test] + fn icon_uppercase() { + assert!(html::is_icon("ICON")); + } + + #[test] + fn mask_icon() { + assert!(html::is_icon("mask-icon")); + } + + #[test] + fn fluid_icon() { + assert!(html::is_icon("fluid-icon")); + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -39,12 +42,17 @@ fn passing_fluid_icon() { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_stylesheet() { - assert!(!html::is_icon("stylesheet")); -} +#[cfg(test)] +mod failing { + use crate::html; + + #[test] + fn stylesheet() { + assert!(!html::is_icon("stylesheet")); + } -#[test] -fn failing_empty_string() { - assert!(!html::is_icon("")); + #[test] + fn empty_string() { + assert!(!html::is_icon("")); + } } diff --git a/src/tests/html/stringify_document.rs b/src/tests/html/stringify_document.rs index 2089996..45bced9 100644 --- a/src/tests/html/stringify_document.rs +++ b/src/tests/html/stringify_document.rs @@ -1,5 +1,3 @@ -use crate::html; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,182 +5,187 @@ use crate::html; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_div_as_root_element() { - let html = "
"; - let dom = html::html_to_dom(&html); - - let opt_no_css: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_isolate: bool = false; - - assert_eq!( - html::stringify_document( - &dom.document, - opt_no_css, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_isolate, - ), - "
" - ); -} - -#[test] -fn passing_full_page_with_no_html_head_or_body() { - let html = "Isolated document\ - \ - \ -
"; - let dom = html::html_to_dom(&html); - - let opt_no_css: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_isolate: bool = true; - - assert_eq!( - html::stringify_document( - &dom.document, - opt_no_css, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_isolate, - ), - "\ - \ - \ - Isolated document\ - \ - \ - \ - \ -
\ - \ -
\ - \ - " - ); -} - -#[test] -fn passing_doctype_and_the_rest_no_html_head_or_body() { - let html = "\ - Unstyled document\ - \ -
"; - let dom = html::html_to_dom(&html); - - let opt_no_css: bool = true; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_isolate: bool = false; - - assert_eq!( - html::stringify_document( - &dom.document, - opt_no_css, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_isolate, - ), - "\ - \ - \ - \ - Unstyled document\ - \ - \ -
\ - " - ); -} - -#[test] -fn passing_doctype_and_the_rest_no_html_head_or_body_forbid_frames() { - let html = "\ - Frameless document\ - \ -
"; - let dom = html::html_to_dom(&html); - - let opt_no_css: bool = false; - let opt_no_frames: bool = true; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_isolate: bool = false; - - assert_eq!( - html::stringify_document( - &dom.document, - opt_no_css, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_isolate, - ), - "\ - \ - \ - \ - Frameless document\ - \ - \ -
\ - " - ); -} - -#[test] -fn passing_doctype_and_the_rest_all_forbidden() { - let html = "\ - no-frame no-css no-js no-image isolated document\ - \ - \ -
\ - \ - \ - \ -
"; - let dom = html::html_to_dom(&html); - - let opt_isolate: bool = true; - let opt_no_css: bool = true; - let opt_no_frames: bool = true; - let opt_no_js: bool = true; - let opt_no_images: bool = true; - - assert_eq!( - html::stringify_document( - &dom.document, - opt_no_css, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_isolate, - ), - "\ - \ +#[cfg(test)] +mod passing { + use crate::html; + + #[test] + fn div_as_root_element() { + let html = "
"; + let dom = html::html_to_dom(&html); + + let opt_no_css: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_isolate: bool = false; + + assert_eq!( + html::stringify_document( + &dom.document, + opt_no_css, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_isolate, + ), + "
" + ); + } + + #[test] + fn full_page_with_no_html_head_or_body() { + let html = "Isolated document\ + \ + \ +
"; + let dom = html::html_to_dom(&html); + + let opt_no_css: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_isolate: bool = true; + + assert_eq!( + html::stringify_document( + &dom.document, + opt_no_css, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_isolate, + ), + "\ \ - \ - no-frame no-css no-js no-image isolated document\ + \ + Isolated document\ + \ \ - \ \ \
\ \ - \ - \
\ \ " - ); + ); + } + + #[test] + fn doctype_and_the_rest_no_html_head_or_body() { + let html = "\ + Unstyled document\ + \ +
"; + let dom = html::html_to_dom(&html); + + let opt_no_css: bool = true; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_isolate: bool = false; + + assert_eq!( + html::stringify_document( + &dom.document, + opt_no_css, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_isolate, + ), + "\ + \ + \ + \ + Unstyled document\ + \ + \ +
\ + " + ); + } + + #[test] + fn doctype_and_the_rest_no_html_head_or_body_forbid_frames() { + let html = "\ + Frameless document\ + \ +
"; + let dom = html::html_to_dom(&html); + + let opt_no_css: bool = false; + let opt_no_frames: bool = true; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_isolate: bool = false; + + assert_eq!( + html::stringify_document( + &dom.document, + opt_no_css, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_isolate, + ), + "\ + \ + \ + \ + Frameless document\ + \ + \ +
\ + " + ); + } + + #[test] + fn doctype_and_the_rest_all_forbidden() { + let html = "\ + no-frame no-css no-js no-image isolated document\ + \ + \ +
\ + \ + \ + \ +
"; + let dom = html::html_to_dom(&html); + + let opt_isolate: bool = true; + let opt_no_css: bool = true; + let opt_no_frames: bool = true; + let opt_no_js: bool = true; + let opt_no_images: bool = true; + + assert_eq!( + html::stringify_document( + &dom.document, + opt_no_css, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_isolate, + ), + "\ + \ + \ + \ + no-frame no-css no-js no-image isolated document\ + \ + \ + \ + \ +
\ + \ + \ + \ +
\ + \ + " + ); + } } diff --git a/src/tests/html/walk_and_embed_assets.rs b/src/tests/html/walk_and_embed_assets.rs index 00397e5..9dbec0c 100644 --- a/src/tests/html/walk_and_embed_assets.rs +++ b/src/tests/html/walk_and_embed_assets.rs @@ -1,8 +1,3 @@ -use crate::html; -use html5ever::serialize::{serialize, SerializeOpts}; -use reqwest::blocking::Client; -use std::collections::HashMap; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -10,410 +5,419 @@ use std::collections::HashMap; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_basic() { - let cache = &mut HashMap::new(); - - let html = "

"; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "

" - ); -} - -#[test] -fn passing_ensure_no_recursive_iframe() { - let html = "

"; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "

" - ); -} - -#[test] -fn passing_ensure_no_recursive_frame() { - let html = ""; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "" - ); -} - -#[test] -fn passing_no_css() { - let html = "\ - \ -
"; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = true; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "\ - \ - \ - \ - \ - \ -
\ - \ - " - ); -} - -#[test] -fn passing_no_images() { - let html = "\ -
"; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = true; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - format!( +#[cfg(test)] +mod passing { + use crate::html; + use html5ever::serialize::{serialize, SerializeOpts}; + use reqwest::blocking::Client; + use std::collections::HashMap; + + #[test] + fn basic() { + let cache = &mut HashMap::new(); + + let html = "

"; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "

" + ); + } + + #[test] + fn ensure_no_recursive_iframe() { + let html = "

"; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "

" + ); + } + + #[test] + fn ensure_no_recursive_frame() { + let html = ""; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "" + ); + } + + #[test] + fn no_css() { + let html = "\ + \ +
"; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = true; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), "\ - \ - \ - \ - \ -
\ - \ -
\ - \ - ", - empty_image = empty_image!() - ) - ); -} - -#[test] -fn passing_no_body_background_images() { - let html = ""; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = false; - let opt_no_images: bool = true; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "" - ); -} - -#[test] -fn passing_no_frames() { - let html = ""; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = true; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "" - ); -} - -#[test] -fn passing_no_iframes() { - let html = ""; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = true; - let opt_no_js: bool = false; - let opt_no_images: bool = false; - let opt_silent = true; - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "" - ); -} - -#[test] -fn passing_no_js() { - let html = "
\ - \ - \ -
"; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - - let opt_no_css: bool = false; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = false; - let opt_no_js: bool = true; - let opt_no_images: bool = false; - let opt_silent = true; - - let client = Client::new(); - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "
\ -
" - ); -} - -#[test] -fn passing_with_no_integrity() { - let html = "No integrity\ - \ - "; - let dom = html::html_to_dom(&html); - let url = "http://localhost"; - let cache = &mut HashMap::new(); - let client = Client::new(); - let opt_no_css: bool = true; - let opt_no_fonts: bool = false; - let opt_no_frames: bool = true; - let opt_no_js: bool = true; - let opt_no_images: bool = true; - let opt_silent = true; - - html::walk_and_embed_assets( - cache, - &client, - &url, - &dom.document, - opt_no_css, - opt_no_fonts, - opt_no_frames, - opt_no_js, - opt_no_images, - opt_silent, - ); - - let mut buf: Vec = Vec::new(); - serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); - - assert_eq!( - buf.iter().map(|&c| c as char).collect::(), - "\ - No integrity\ - \ - " - ); + \ + \ + \ + \ + \ +
\ + \ + " + ); + } + + #[test] + fn no_images() { + let html = "\ +
"; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = true; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + format!( + "\ + \ + \ + \ + \ +
\ + \ +
\ + \ + ", + empty_image = empty_image!() + ) + ); + } + + #[test] + fn no_body_background_images() { + let html = + ""; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = true; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "" + ); + } + + #[test] + fn no_frames() { + let html = ""; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = true; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "" + ); + } + + #[test] + fn no_iframes() { + let html = ""; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = true; + let opt_no_js: bool = false; + let opt_no_images: bool = false; + let opt_silent = true; + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "" + ); + } + + #[test] + fn no_js() { + let html = "
\ + \ + \ +
"; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = true; + let opt_no_images: bool = false; + let opt_silent = true; + + let client = Client::new(); + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "
\ +
" + ); + } + + #[test] + fn with_no_integrity() { + let html = "No integrity\ + \ + "; + let dom = html::html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + let client = Client::new(); + let opt_no_css: bool = true; + let opt_no_fonts: bool = false; + let opt_no_frames: bool = true; + let opt_no_js: bool = true; + let opt_no_images: bool = true; + let opt_silent = true; + + html::walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_fonts, + opt_no_frames, + opt_no_js, + opt_no_images, + opt_silent, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "\ + No integrity\ + \ + " + ); + } } diff --git a/src/tests/js/attr_is_event_handler.rs b/src/tests/js/attr_is_event_handler.rs index fbc2146..a64604d 100644 --- a/src/tests/js/attr_is_event_handler.rs +++ b/src/tests/js/attr_is_event_handler.rs @@ -1,5 +1,3 @@ -use crate::js; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,19 +5,24 @@ use crate::js; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_onblur_camelcase() { - assert!(js::attr_is_event_handler("onBlur")); -} +#[cfg(test)] +mod passing { + use crate::js; -#[test] -fn passing_onclick_lowercase() { - assert!(js::attr_is_event_handler("onclick")); -} + #[test] + fn onblur_camelcase() { + assert!(js::attr_is_event_handler("onBlur")); + } + + #[test] + fn onclick_lowercase() { + assert!(js::attr_is_event_handler("onclick")); + } -#[test] -fn passing_onclick_camelcase() { - assert!(js::attr_is_event_handler("onClick")); + #[test] + fn onclick_camelcase() { + assert!(js::attr_is_event_handler("onClick")); + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -29,17 +32,22 @@ fn passing_onclick_camelcase() { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_href() { - assert!(!js::attr_is_event_handler("href")); -} +#[cfg(test)] +mod failing { + use crate::js; -#[test] -fn failing_empty_string() { - assert!(!js::attr_is_event_handler("")); -} + #[test] + fn href() { + assert!(!js::attr_is_event_handler("href")); + } + + #[test] + fn empty_string() { + assert!(!js::attr_is_event_handler("")); + } -#[test] -fn failing_class() { - assert!(!js::attr_is_event_handler("class")); + #[test] + fn class() { + assert!(!js::attr_is_event_handler("class")); + } } diff --git a/src/tests/utils/clean_url.rs b/src/tests/utils/clean_url.rs index eaec4fd..9e3b9f7 100644 --- a/src/tests/utils/clean_url.rs +++ b/src/tests/utils/clean_url.rs @@ -1,5 +1,3 @@ -use crate::utils; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,42 +5,47 @@ use crate::utils; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_removes_fragment() { - assert_eq!( - utils::clean_url("https://somewhere.com/font.eot#iefix"), - "https://somewhere.com/font.eot" - ); -} +#[cfg(test)] +mod passing { + use crate::utils; -#[test] -fn passing_removes_empty_fragment() { - assert_eq!( - utils::clean_url("https://somewhere.com/font.eot#"), - "https://somewhere.com/font.eot" - ); -} + #[test] + fn removes_fragment() { + assert_eq!( + utils::clean_url("https://somewhere.com/font.eot#iefix"), + "https://somewhere.com/font.eot" + ); + } -#[test] -fn passing_removes_empty_query_and_empty_fragment() { - assert_eq!( - utils::clean_url("https://somewhere.com/font.eot?#"), - "https://somewhere.com/font.eot" - ); -} + #[test] + fn removes_empty_fragment() { + assert_eq!( + utils::clean_url("https://somewhere.com/font.eot#"), + "https://somewhere.com/font.eot" + ); + } -#[test] -fn passing_removes_empty_query_amp_and_empty_fragment() { - assert_eq!( - utils::clean_url("https://somewhere.com/font.eot?a=b&#"), - "https://somewhere.com/font.eot?a=b" - ); -} + #[test] + fn removes_empty_query_and_empty_fragment() { + assert_eq!( + utils::clean_url("https://somewhere.com/font.eot?#"), + "https://somewhere.com/font.eot" + ); + } + + #[test] + fn removes_empty_query_amp_and_empty_fragment() { + assert_eq!( + utils::clean_url("https://somewhere.com/font.eot?a=b&#"), + "https://somewhere.com/font.eot?a=b" + ); + } -#[test] -fn passing_keeps_credentials() { - assert_eq!( - utils::clean_url("https://cookie:monster@gibson.internet/"), - "https://cookie:monster@gibson.internet/" - ); + #[test] + fn keeps_credentials() { + assert_eq!( + utils::clean_url("https://cookie:monster@gibson.internet/"), + "https://cookie:monster@gibson.internet/" + ); + } } diff --git a/src/tests/utils/data_to_data_url.rs b/src/tests/utils/data_to_data_url.rs index 0ee0604..9b4b4f6 100644 --- a/src/tests/utils/data_to_data_url.rs +++ b/src/tests/utils/data_to_data_url.rs @@ -1,5 +1,3 @@ -use crate::utils; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,22 +5,27 @@ use crate::utils; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_encode_string_with_specific_media_type() { - let mime = "application/javascript"; - let data = "var word = 'hello';\nalert(word);\n"; - let data_url = utils::data_to_data_url(mime, data.as_bytes(), "", ""); +#[cfg(test)] +mod passing { + use crate::utils; - assert_eq!( - &data_url, - "data:application/javascript;base64,dmFyIHdvcmQgPSAnaGVsbG8nOwphbGVydCh3b3JkKTsK" - ); -} + #[test] + fn encode_string_with_specific_media_type() { + let mime = "application/javascript"; + let data = "var word = 'hello';\nalert(word);\n"; + let data_url = utils::data_to_data_url(mime, data.as_bytes(), "", ""); + + assert_eq!( + &data_url, + "data:application/javascript;base64,dmFyIHdvcmQgPSAnaGVsbG8nOwphbGVydCh3b3JkKTsK" + ); + } -#[test] -fn passing_encode_append_fragment() { - let data = "\n"; - let data_url = utils::data_to_data_url("text/css", data.as_bytes(), "", "fragment"); + #[test] + fn encode_append_fragment() { + let data = "\n"; + let data_url = utils::data_to_data_url("text/css", data.as_bytes(), "", "fragment"); - assert_eq!(&data_url, "data:text/css;base64,PHN2Zz48L3N2Zz4K#fragment"); + assert_eq!(&data_url, "data:text/css;base64,PHN2Zz48L3N2Zz4K#fragment"); + } } diff --git a/src/tests/utils/data_url_to_data.rs b/src/tests/utils/data_url_to_data.rs index b239574..7d8b766 100644 --- a/src/tests/utils/data_url_to_data.rs +++ b/src/tests/utils/data_url_to_data.rs @@ -1,5 +1,3 @@ -use crate::utils; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,76 +5,82 @@ use crate::utils; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_parse_text_html_base64() { - let (media_type, data) = utils::data_url_to_data("data:text/html;base64,V29yayBleHBhbmRzIHNvIGFzIHRvIGZpbGwgdGhlIHRpbWUgYXZhaWxhYmxlIGZvciBpdHMgY29tcGxldGlvbg=="); - - assert_eq!(media_type, "text/html"); - assert_eq!( - String::from_utf8_lossy(&data), - "Work expands so as to fill the time available for its completion" - ); -} - -#[test] -fn passing_parse_text_html_utf8() { - let (media_type, data) = utils::data_url_to_data( - "data:text/html;utf8,Work expands so as to fill the time available for its completion", - ); - - assert_eq!(media_type, "text/html"); - assert_eq!( - String::from_utf8_lossy(&data), - "Work expands so as to fill the time available for its completion" - ); -} - -#[test] -fn passing_parse_text_html_plaintext() { - let (media_type, data) = utils::data_url_to_data( - "data:text/html,Work expands so as to fill the time available for its completion", - ); - - assert_eq!(media_type, "text/html"); - assert_eq!( - String::from_utf8_lossy(&data), - "Work expands so as to fill the time available for its completion" - ); -} - -#[test] -fn passing_parse_text_html_charset_utf_8_between_two_whitespaces() { - let (media_type, data) = utils::data_url_to_data(" data:text/html;charset=utf-8,Work expands so as to fill the time available for its completion "); - - assert_eq!(media_type, "text/html"); - assert_eq!( - String::from_utf8_lossy(&data), - "Work expands so as to fill the time available for its completion" - ); -} - -#[test] -fn passing_parse_text_css_url_encoded() { - let (media_type, data) = utils::data_url_to_data("data:text/css,div{background-color:%23000}"); - - assert_eq!(media_type, "text/css"); - assert_eq!(String::from_utf8_lossy(&data), "div{background-color:#000}"); -} - -#[test] -fn passing_parse_no_media_type_base64() { - let (media_type, data) = utils::data_url_to_data("data:;base64,dGVzdA=="); - - assert_eq!(media_type, ""); - assert_eq!(String::from_utf8_lossy(&data), "test"); -} - -#[test] -fn passing_parse_no_media_type_no_encoding() { - let (media_type, data) = utils::data_url_to_data("data:;,test%20test"); - - assert_eq!(media_type, ""); - assert_eq!(String::from_utf8_lossy(&data), "test test"); +#[cfg(test)] +mod passing { + use crate::utils; + + #[test] + fn parse_text_html_base64() { + let (media_type, data) = utils::data_url_to_data("data:text/html;base64,V29yayBleHBhbmRzIHNvIGFzIHRvIGZpbGwgdGhlIHRpbWUgYXZhaWxhYmxlIGZvciBpdHMgY29tcGxldGlvbg=="); + + assert_eq!(media_type, "text/html"); + assert_eq!( + String::from_utf8_lossy(&data), + "Work expands so as to fill the time available for its completion" + ); + } + + #[test] + fn parse_text_html_utf8() { + let (media_type, data) = utils::data_url_to_data( + "data:text/html;utf8,Work expands so as to fill the time available for its completion", + ); + + assert_eq!(media_type, "text/html"); + assert_eq!( + String::from_utf8_lossy(&data), + "Work expands so as to fill the time available for its completion" + ); + } + + #[test] + fn parse_text_html_plaintext() { + let (media_type, data) = utils::data_url_to_data( + "data:text/html,Work expands so as to fill the time available for its completion", + ); + + assert_eq!(media_type, "text/html"); + assert_eq!( + String::from_utf8_lossy(&data), + "Work expands so as to fill the time available for its completion" + ); + } + + #[test] + fn parse_text_html_charset_utf_8_between_two_whitespaces() { + let (media_type, data) = utils::data_url_to_data(" data:text/html;charset=utf-8,Work expands so as to fill the time available for its completion "); + + assert_eq!(media_type, "text/html"); + assert_eq!( + String::from_utf8_lossy(&data), + "Work expands so as to fill the time available for its completion" + ); + } + + #[test] + fn parse_text_css_url_encoded() { + let (media_type, data) = + utils::data_url_to_data("data:text/css,div{background-color:%23000}"); + + assert_eq!(media_type, "text/css"); + assert_eq!(String::from_utf8_lossy(&data), "div{background-color:#000}"); + } + + #[test] + fn parse_no_media_type_base64() { + let (media_type, data) = utils::data_url_to_data("data:;base64,dGVzdA=="); + + assert_eq!(media_type, ""); + assert_eq!(String::from_utf8_lossy(&data), "test"); + } + + #[test] + fn parse_no_media_type_no_encoding() { + let (media_type, data) = utils::data_url_to_data("data:;,test%20test"); + + assert_eq!(media_type, ""); + assert_eq!(String::from_utf8_lossy(&data), "test test"); + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -86,10 +90,15 @@ fn passing_parse_no_media_type_no_encoding() { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_just_word_data() { - let (media_type, data) = utils::data_url_to_data("data"); +#[cfg(test)] +mod failing { + use crate::utils; + + #[test] + fn just_word_data() { + let (media_type, data) = utils::data_url_to_data("data"); - assert_eq!(media_type, ""); - assert_eq!(String::from_utf8_lossy(&data), ""); + assert_eq!(media_type, ""); + assert_eq!(String::from_utf8_lossy(&data), ""); + } } diff --git a/src/tests/utils/detect_media_type.rs b/src/tests/utils/detect_media_type.rs index 6dee71c..b024525 100644 --- a/src/tests/utils/detect_media_type.rs +++ b/src/tests/utils/detect_media_type.rs @@ -1,5 +1,3 @@ -use crate::utils; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,131 +5,136 @@ use crate::utils; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_image_gif87() { - assert_eq!(utils::detect_media_type(b"GIF87a", ""), "image/gif"); -} - -#[test] -fn passing_image_gif89() { - assert_eq!(utils::detect_media_type(b"GIF89a", ""), "image/gif"); -} - -#[test] -fn passing_image_jpeg() { - assert_eq!(utils::detect_media_type(b"\xFF\xD8\xFF", ""), "image/jpeg"); -} - -#[test] -fn passing_image_png() { - assert_eq!( - utils::detect_media_type(b"\x89PNG\x0D\x0A\x1A\x0A", ""), - "image/png" - ); -} - -#[test] -fn passing_image_svg() { - assert_eq!(utils::detect_media_type(b" Result<(), ParseError> { - let resolved_url = utils::resolve_url("https://www.kernel.org", "../category/signatures.html")?; - - assert_eq!( - resolved_url.as_str(), - "https://www.kernel.org/category/signatures.html" - ); - - Ok(()) -} - -#[test] -fn passing_from_just_filename_to_full_https_url() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "saved_page.htm", - "https://www.kernel.org/category/signatures.html", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://www.kernel.org/category/signatures.html" - ); - - Ok(()) -} - -#[test] -fn passing_from_https_url_to_url_with_no_protocol() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "https://www.kernel.org", - "//www.kernel.org/theme/images/logos/tux.png", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://www.kernel.org/theme/images/logos/tux.png" - ); - - Ok(()) -} - -#[test] -fn passing_from_https_url_to_url_with_no_protocol_and_on_different_hostname( -) -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "https://www.kernel.org", - "//another-host.org/theme/images/logos/tux.png", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://another-host.org/theme/images/logos/tux.png" - ); - - Ok(()) -} - -#[test] -fn passing_from_https_url_to_relative_root_path() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "https://www.kernel.org/category/signatures.html", - "/theme/images/logos/tux.png", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://www.kernel.org/theme/images/logos/tux.png" - ); - - Ok(()) -} - -#[test] -fn passing_from_https_to_just_filename() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "https://www.w3schools.com/html/html_iframe.asp", - "default.asp", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://www.w3schools.com/html/default.asp" - ); - - Ok(()) -} - -#[test] -fn passing_from_data_url_to_https() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", - "https://www.kernel.org/category/signatures.html", - )?; - - assert_eq!( - resolved_url.as_str(), - "https://www.kernel.org/category/signatures.html" - ); - - Ok(()) -} - -#[test] -fn passing_from_data_url_to_data_url() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", - "data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K", - )?; - - assert_eq!( - resolved_url.as_str(), - "data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K" - ); - - Ok(()) -} - -#[test] -fn passing_from_file_url_to_relative_path() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "file:///home/user/Websites/my-website/index.html", - "assets/images/logo.png", - ) - .unwrap_or(str!()); - - assert_eq!( - resolved_url.as_str(), - "file:///home/user/Websites/my-website/assets/images/logo.png" - ); - - Ok(()) -} - -#[test] -fn passing_from_file_url_to_relative_path_with_backslashes() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "file:\\\\\\home\\user\\Websites\\my-website\\index.html", - "assets\\images\\logo.png", - ) - .unwrap_or(str!()); - - assert_eq!( - resolved_url.as_str(), - "file:///home/user/Websites/my-website/assets/images/logo.png" - ); - - Ok(()) -} - -#[test] -fn passing_from_data_url_to_file_url() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", - "file:///etc/passwd", - ) - .unwrap_or(str!()); - - assert_eq!(resolved_url.as_str(), "file:///etc/passwd"); - - Ok(()) -} - -#[test] -fn passing_preserve_fragment() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "http://doesnt-matter.local/", - "css/fonts/fontmarvelous.svg#fontmarvelous", - ) - .unwrap_or(str!()); - - assert_eq!( - resolved_url.as_str(), - "http://doesnt-matter.local/css/fonts/fontmarvelous.svg#fontmarvelous" - ); - - Ok(()) -} - -#[test] -fn passing_resolve_from_file_url_to_file_url() -> Result<(), ParseError> { - let resolved_url = if cfg!(windows) { - utils::resolve_url("file:///c:/index.html", "file:///c:/image.png").unwrap_or(str!()) - } else { - utils::resolve_url("file:///tmp/index.html", "file:///tmp/image.png").unwrap_or(str!()) - }; - - assert_eq!( - resolved_url.as_str(), - if cfg!(windows) { - "file:///c:/image.png" +#[cfg(test)] +mod passing { + use crate::utils; + use url::ParseError; + + #[test] + fn from_https_to_level_up_relative() -> Result<(), ParseError> { + let resolved_url = + utils::resolve_url("https://www.kernel.org", "../category/signatures.html")?; + + assert_eq!( + resolved_url.as_str(), + "https://www.kernel.org/category/signatures.html" + ); + + Ok(()) + } + + #[test] + fn from_just_filename_to_full_https_url() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "saved_page.htm", + "https://www.kernel.org/category/signatures.html", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://www.kernel.org/category/signatures.html" + ); + + Ok(()) + } + + #[test] + fn from_https_url_to_url_with_no_protocol() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "https://www.kernel.org", + "//www.kernel.org/theme/images/logos/tux.png", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://www.kernel.org/theme/images/logos/tux.png" + ); + + Ok(()) + } + + #[test] + fn from_https_url_to_url_with_no_protocol_and_on_different_hostname() -> Result<(), ParseError> + { + let resolved_url = utils::resolve_url( + "https://www.kernel.org", + "//another-host.org/theme/images/logos/tux.png", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://another-host.org/theme/images/logos/tux.png" + ); + + Ok(()) + } + + #[test] + fn from_https_url_to_relative_root_path() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "https://www.kernel.org/category/signatures.html", + "/theme/images/logos/tux.png", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://www.kernel.org/theme/images/logos/tux.png" + ); + + Ok(()) + } + + #[test] + fn from_https_to_just_filename() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "https://www.w3schools.com/html/html_iframe.asp", + "default.asp", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://www.w3schools.com/html/default.asp" + ); + + Ok(()) + } + + #[test] + fn from_data_url_to_https() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", + "https://www.kernel.org/category/signatures.html", + )?; + + assert_eq!( + resolved_url.as_str(), + "https://www.kernel.org/category/signatures.html" + ); + + Ok(()) + } + + #[test] + fn from_data_url_to_data_url() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", + "data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K", + )?; + + assert_eq!( + resolved_url.as_str(), + "data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K" + ); + + Ok(()) + } + + #[test] + fn from_file_url_to_relative_path() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "file:///home/user/Websites/my-website/index.html", + "assets/images/logo.png", + ) + .unwrap_or(str!()); + + assert_eq!( + resolved_url.as_str(), + "file:///home/user/Websites/my-website/assets/images/logo.png" + ); + + Ok(()) + } + + #[test] + fn from_file_url_to_relative_path_with_backslashes() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "file:\\\\\\home\\user\\Websites\\my-website\\index.html", + "assets\\images\\logo.png", + ) + .unwrap_or(str!()); + + assert_eq!( + resolved_url.as_str(), + "file:///home/user/Websites/my-website/assets/images/logo.png" + ); + + Ok(()) + } + + #[test] + fn from_data_url_to_file_url() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", + "file:///etc/passwd", + ) + .unwrap_or(str!()); + + assert_eq!(resolved_url.as_str(), "file:///etc/passwd"); + + Ok(()) + } + + #[test] + fn preserve_fragment() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "http://doesnt-matter.local/", + "css/fonts/fontmarvelous.svg#fontmarvelous", + ) + .unwrap_or(str!()); + + assert_eq!( + resolved_url.as_str(), + "http://doesnt-matter.local/css/fonts/fontmarvelous.svg#fontmarvelous" + ); + + Ok(()) + } + + #[test] + fn resolve_from_file_url_to_file_url() -> Result<(), ParseError> { + let resolved_url = if cfg!(windows) { + utils::resolve_url("file:///c:/index.html", "file:///c:/image.png").unwrap_or(str!()) } else { - "file:///tmp/image.png" - } - ); - - Ok(()) + utils::resolve_url("file:///tmp/index.html", "file:///tmp/image.png").unwrap_or(str!()) + }; + + assert_eq!( + resolved_url.as_str(), + if cfg!(windows) { + "file:///c:/image.png" + } else { + "file:///tmp/image.png" + } + ); + + Ok(()) + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -215,15 +218,21 @@ fn passing_resolve_from_file_url_to_file_url() -> Result<(), ParseError> { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_from_data_url_to_url_with_no_protocol() -> Result<(), ParseError> { - let resolved_url = utils::resolve_url( - "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", - "//www.w3schools.com/html/html_iframe.asp", - ) - .unwrap_or(str!()); +#[cfg(test)] +mod failing { + use crate::utils; + use url::ParseError; + + #[test] + fn from_data_url_to_url_with_no_protocol() -> Result<(), ParseError> { + let resolved_url = utils::resolve_url( + "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h", + "//www.w3schools.com/html/html_iframe.asp", + ) + .unwrap_or(str!()); - assert_eq!(resolved_url.as_str(), ""); + assert_eq!(resolved_url.as_str(), ""); - Ok(()) + Ok(()) + } } diff --git a/src/tests/utils/retrieve_asset.rs b/src/tests/utils/retrieve_asset.rs index c834beb..4aeeb5b 100644 --- a/src/tests/utils/retrieve_asset.rs +++ b/src/tests/utils/retrieve_asset.rs @@ -1,8 +1,3 @@ -use crate::utils; -use reqwest::blocking::Client; -use std::collections::HashMap; -use std::env; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -10,66 +5,74 @@ use std::env; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_read_data_url() { - let cache = &mut HashMap::new(); - let client = Client::new(); +#[cfg(test)] +mod passing { + use crate::utils; + use reqwest::blocking::Client; + use std::collections::HashMap; + use std::env; - // If both source and target are data URLs, - // ensure the result contains target data URL - let (data, final_url, media_type) = utils::retrieve_asset( - cache, - &client, - "data:text/html;base64,c291cmNl", - "data:text/html;base64,dGFyZ2V0", - false, - ) - .unwrap(); - assert_eq!( - utils::data_to_data_url(&media_type, &data, &final_url, ""), - utils::data_to_data_url("text/html", "target".as_bytes(), "", "") - ); - assert_eq!( - final_url, - utils::data_to_data_url("text/html", "target".as_bytes(), "", "") - ); - assert_eq!(&media_type, "text/html"); -} + #[test] + fn read_data_url() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + // If both source and target are data URLs, + // ensure the result contains target data URL + let (data, final_url, media_type) = utils::retrieve_asset( + cache, + &client, + "data:text/html;base64,c291cmNl", + "data:text/html;base64,dGFyZ2V0", + false, + ) + .unwrap(); + assert_eq!( + utils::data_to_data_url(&media_type, &data, &final_url, ""), + utils::data_to_data_url("text/html", "target".as_bytes(), "", "") + ); + assert_eq!( + final_url, + utils::data_to_data_url("text/html", "target".as_bytes(), "", "") + ); + assert_eq!(&media_type, "text/html"); + } -#[test] -fn passing_read_local_file_with_file_url_parent() { - let cache = &mut HashMap::new(); - let client = Client::new(); + #[test] + fn read_local_file_with_file_url_parent() { + let cache = &mut HashMap::new(); + let client = Client::new(); - let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; + let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; - // Inclusion of local assets from local sources should be allowed - let cwd = env::current_dir().unwrap(); - let (data, final_url, _media_type) = utils::retrieve_asset( - cache, - &client, - &format!( - "{file}{cwd}/src/tests/data/basic/local-file.html", - file = file_url_protocol, - cwd = cwd.to_str().unwrap() - ), - &format!( - "{file}{cwd}/src/tests/data/basic/local-script.js", - file = file_url_protocol, - cwd = cwd.to_str().unwrap() - ), - false, - ) - .unwrap(); - assert_eq!(utils::data_to_data_url("application/javascript", &data, &final_url, ""), "data:application/javascript;base64,ZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiZ3JlZW4iOwpkb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gInJlZCI7Cg=="); - assert_eq!( - &final_url, - &format!( - "{file}{cwd}/src/tests/data/basic/local-script.js", - file = file_url_protocol, - cwd = cwd.to_str().unwrap() + // Inclusion of local assets from local sources should be allowed + let cwd = env::current_dir().unwrap(); + let (data, final_url, _media_type) = utils::retrieve_asset( + cache, + &client, + &format!( + "{file}{cwd}/src/tests/data/basic/local-file.html", + file = file_url_protocol, + cwd = cwd.to_str().unwrap() + ), + &format!( + "{file}{cwd}/src/tests/data/basic/local-script.js", + file = file_url_protocol, + cwd = cwd.to_str().unwrap() + ), + false, ) - ); + .unwrap(); + assert_eq!(utils::data_to_data_url("application/javascript", &data, &final_url, ""), "data:application/javascript;base64,ZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiZ3JlZW4iOwpkb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gInJlZCI7Cg=="); + assert_eq!( + &final_url, + &format!( + "{file}{cwd}/src/tests/data/basic/local-script.js", + file = file_url_protocol, + cwd = cwd.to_str().unwrap() + ) + ); + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -79,46 +82,53 @@ fn passing_read_local_file_with_file_url_parent() { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_read_local_file_with_data_url_parent() { - let cache = &mut HashMap::new(); - let client = Client::new(); +#[cfg(test)] +mod failing { + use crate::utils; + use reqwest::blocking::Client; + use std::collections::HashMap; - // Inclusion of local assets from data URL sources should not be allowed - match utils::retrieve_asset( - cache, - &client, - "data:text/html;base64,SoUrCe", - "file:///etc/passwd", - false, - ) { - Ok((..)) => { - assert!(false); - } - Err(_) => { - assert!(true); + #[test] + fn read_local_file_with_data_url_parent() { + let cache = &mut HashMap::new(); + let client = Client::new(); + + // Inclusion of local assets from data URL sources should not be allowed + match utils::retrieve_asset( + cache, + &client, + "data:text/html;base64,SoUrCe", + "file:///etc/passwd", + false, + ) { + Ok((..)) => { + assert!(false); + } + Err(_) => { + assert!(true); + } } } -} -#[test] -fn failing_read_local_file_with_https_parent() { - let cache = &mut HashMap::new(); - let client = Client::new(); + #[test] + fn read_local_file_with_https_parent() { + let cache = &mut HashMap::new(); + let client = Client::new(); - // Inclusion of local assets from remote sources should not be allowed - match utils::retrieve_asset( - cache, - &client, - "https://kernel.org/", - "file:///etc/passwd", - false, - ) { - Ok((..)) => { - assert!(false); - } - Err(_) => { - assert!(true); + // Inclusion of local assets from remote sources should not be allowed + match utils::retrieve_asset( + cache, + &client, + "https://kernel.org/", + "file:///etc/passwd", + false, + ) { + Ok((..)) => { + assert!(false); + } + Err(_) => { + assert!(true); + } } } } diff --git a/src/tests/utils/url_has_protocol.rs b/src/tests/utils/url_has_protocol.rs index 1c6e213..3c03619 100644 --- a/src/tests/utils/url_has_protocol.rs +++ b/src/tests/utils/url_has_protocol.rs @@ -1,5 +1,3 @@ -use crate::utils; - // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ @@ -7,50 +5,55 @@ use crate::utils; // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn passing_mailto() { - assert!(utils::url_has_protocol( - "mailto:somebody@somewhere.com?subject=hello" - )); -} +#[cfg(test)] +mod passing { + use crate::utils; -#[test] -fn passing_tel() { - assert!(utils::url_has_protocol("tel:5551234567")); -} + #[test] + fn mailto() { + assert!(utils::url_has_protocol( + "mailto:somebody@somewhere.com?subject=hello" + )); + } -#[test] -fn passing_ftp_no_slashes() { - assert!(utils::url_has_protocol("ftp:some-ftp-server.com")); -} + #[test] + fn tel() { + assert!(utils::url_has_protocol("tel:5551234567")); + } -#[test] -fn passing_ftp_with_credentials() { - assert!(utils::url_has_protocol( - "ftp://user:password@some-ftp-server.com" - )); -} + #[test] + fn ftp_no_slashes() { + assert!(utils::url_has_protocol("ftp:some-ftp-server.com")); + } -#[test] -fn passing_javascript() { - assert!(utils::url_has_protocol("javascript:void(0)")); -} + #[test] + fn ftp_with_credentials() { + assert!(utils::url_has_protocol( + "ftp://user:password@some-ftp-server.com" + )); + } -#[test] -fn passing_http() { - assert!(utils::url_has_protocol("http://news.ycombinator.com")); -} + #[test] + fn javascript() { + assert!(utils::url_has_protocol("javascript:void(0)")); + } -#[test] -fn passing_https() { - assert!(utils::url_has_protocol("https://github.com")); -} + #[test] + fn http() { + assert!(utils::url_has_protocol("http://news.ycombinator.com")); + } + + #[test] + fn https() { + assert!(utils::url_has_protocol("https://github.com")); + } -#[test] -fn passing_mailto_uppercase() { - assert!(utils::url_has_protocol( - "MAILTO:somebody@somewhere.com?subject=hello" - )); + #[test] + fn mailto_uppercase() { + assert!(utils::url_has_protocol( + "MAILTO:somebody@somewhere.com?subject=hello" + )); + } } // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ @@ -60,24 +63,29 @@ fn passing_mailto_uppercase() { // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ -#[test] -fn failing_url_with_no_protocol() { - assert!(!utils::url_has_protocol( - "//some-hostname.com/some-file.html" - )); -} +#[cfg(test)] +mod failing { + use crate::utils; -#[test] -fn failing_relative_path() { - assert!(!utils::url_has_protocol("some-hostname.com/some-file.html")); -} + #[test] + fn url_with_no_protocol() { + assert!(!utils::url_has_protocol( + "//some-hostname.com/some-file.html" + )); + } -#[test] -fn failing_relative_to_root_path() { - assert!(!utils::url_has_protocol("/some-file.html")); -} + #[test] + fn relative_path() { + assert!(!utils::url_has_protocol("some-hostname.com/some-file.html")); + } + + #[test] + fn relative_to_root_path() { + assert!(!utils::url_has_protocol("/some-file.html")); + } -#[test] -fn failing_empty_string() { - assert!(!utils::url_has_protocol("")); + #[test] + fn empty_string() { + assert!(!utils::url_has_protocol("")); + } }