diff --git a/Cargo.lock b/Cargo.lock index 1b824562fe..89878e045c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,13 +139,12 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.17" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" +checksum = "bcbb6924530aa9e0432442af08bbcafdad182db80d2e560da42a6d442535bf85" dependencies = [ "anstyle", "bstr", - "doc-comment", "libc", "predicates", "predicates-core", @@ -674,9 +673,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -684,9 +683,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -1684,9 +1683,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab69130804d941f8075cfd713bf8848a2c3b3f201a9457a11e6f87e1ab62305" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" dependencies = [ "aho-corasick", "bstr", @@ -1840,13 +1839,12 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d958c2f74b664487a2035fe1dadb032c48718a03b63f3ab0b8537db8549ed4" +checksum = "6452c4751a24e1b99c3260d505eaeee76a050573e61f30ac2c924ddc7236f01e" dependencies = [ "log", "markup5ever", - "match_token", ] [[package]] @@ -1978,9 +1976,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "1744436df46f0bde35af3eda22aeaba453aada65d8f1c171cd8a5f59030bd69f" dependencies = [ "atomic-waker", "bytes", @@ -2006,7 +2004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ "http 1.3.1", - "hyper 1.7.0", + "hyper 1.8.0", "hyper-util", "log", "rustls", @@ -2023,7 +2021,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.7.0", + "hyper 1.8.0", "hyper-util", "pin-project-lite", "tokio", @@ -2051,7 +2049,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.0", "hyper-util", "native-tls", "tokio", @@ -2072,7 +2070,7 @@ dependencies = [ "futures-util", "http 1.3.1", "http-body 1.0.1", - "hyper 1.7.0", + "hyper 1.8.0", "ipnet", "libc", "percent-encoding", @@ -2235,9 +2233,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" dependencies = [ "crossbeam-deque", "globset", @@ -2274,9 +2272,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.18.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e0ddd45fe8e09ee1a607920b12271f8a5528a41ecaf6e1d1440d6493315b6b" +checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" dependencies = [ "console", "portable-atomic", @@ -2572,7 +2570,7 @@ dependencies = [ "html5ever", "html5gum", "http 1.3.1", - "hyper 1.7.0", + "hyper 1.8.0", "ignore", "ip_network", "linkify", @@ -2623,9 +2621,9 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fe69c934650f8f19652b3946075f0fc41ad8757dbb68f1ca14e7900ecc1c3" +checksum = "6c3294c4d74d0742910f8c7b466f44dda9eb2d5742c1e430138df290a1e8451c" dependencies = [ "log", "tendril", @@ -2638,17 +2636,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "match_token" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "matchers" version = "0.2.0" @@ -2808,9 +2795,9 @@ checksum = "f2dcb6053ab98da45585315f79932c5c9821fab8efa4301c0d7b637c91630eb7" [[package]] name = "octocrab" -version = "0.47.0" +version = "0.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0860f9250b6db66c5a4b46e00b381f063c58ad06a90f95f9ef701dd8679bb2c6" +checksum = "76f50b2657b7e31c849c612c4ca71527861631fe3c392f931fb28990b045f972" dependencies = [ "arc-swap", "async-trait", @@ -2824,7 +2811,7 @@ dependencies = [ "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.0", "hyper-rustls", "hyper-timeout", "hyper-util", @@ -2907,9 +2894,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -3016,18 +3003,19 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_shared", + "serde", ] [[package]] name = "phf_codegen" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ "phf_generator", "phf_shared", @@ -3035,19 +3023,19 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ + "fastrand", "phf_shared", - "rand 0.8.5", ] [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ "siphasher", ] @@ -3601,7 +3589,7 @@ dependencies = [ "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.0", "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", @@ -4168,9 +4156,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "string_cache" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", @@ -4181,9 +4169,9 @@ dependencies = [ [[package]] name = "string_cache_codegen" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ "phf_generator", "phf_shared", @@ -5075,9 +5063,9 @@ dependencies = [ [[package]] name = "web_atoms" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" +checksum = "acd0c322f146d0f8aad130ce6c187953889359584497dac6561204c8e17bb43d" dependencies = [ "phf", "phf_codegen", @@ -5460,7 +5448,7 @@ dependencies = [ "futures", "http 1.3.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.0", "hyper-util", "log", "once_cell", diff --git a/fixtures/manpage_examples/README.md b/fixtures/manpage_examples/README.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fixtures/manpage_examples/info.txt b/fixtures/manpage_examples/info.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fixtures/manpage_examples/test.html b/fixtures/manpage_examples/test.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fixtures/manpage_examples/test.md b/fixtures/manpage_examples/test.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lychee-bin/Cargo.toml b/lychee-bin/Cargo.toml index cf0539d3f9..9125c2a1eb 100644 --- a/lychee-bin/Cargo.toml +++ b/lychee-bin/Cargo.toml @@ -19,7 +19,7 @@ lychee-lib = { path = "../lychee-lib", version = "0.21.0", default-features = fa anyhow = "1.0.100" assert-json-diff = "2.0.2" -clap = { version = "4.5.50", features = ["env", "derive", "cargo", "string"] } +clap = { version = "4.5.51", features = ["env", "derive", "cargo", "string"] } clap_mangen = "0.2.31" console = "0.16.1" const_format = "0.2.35" @@ -33,9 +33,9 @@ http-serde = "2.1.1" humantime = "2.3.0" humantime-serde = "1.1.1" numeric-sort = "0.1.5" -indicatif = "0.18.1" +indicatif = "0.18.3" log = "0.4.28" -openssl-sys = { version = "0.9.110", optional = true } +openssl-sys = { version = "0.9.111", optional = true } pad = "0.1.6" regex = "1.12.2" reqwest = { version = "0.12.24", default-features = false, features = [ @@ -62,7 +62,7 @@ url = "2.5.7" [dev-dependencies] -assert_cmd = "2.0.17" +assert_cmd = "2.1.1" cookie_store = "0.22.0" predicates = "3.1.3" pretty_assertions = "1.4.1" diff --git a/lychee-bin/src/commands/generate.rs b/lychee-bin/src/commands/generate.rs index 183123f130..50689c47a3 100644 --- a/lychee-bin/src/commands/generate.rs +++ b/lychee-bin/src/commands/generate.rs @@ -26,7 +26,6 @@ type Commands = &'static [&'static str]; type Example = (Description, Commands); /// Used to render the EXAMPLES section in the man page. -/// Note that the `Commands` are executed and tested. const EXAMPLES: &[Example] = &[ ( "Check all links in supported files by specifying a directory", @@ -143,11 +142,9 @@ fn render_section(title: &str, content: &str, buffer: &mut Vec) -> Result<() #[cfg(test)] mod tests { - use super::{EXAMPLES, man_page}; + use super::man_page; use crate::generate::{CONTRIBUTOR_THANK_NOTE, EXIT_CODE_SECTION}; use anyhow::Result; - use assert_cmd::Command; - use test_utils::{fixtures_path, main_command}; #[test] fn test_man_page() -> Result<()> { @@ -195,43 +192,6 @@ mod tests { Ok(()) } - #[test] - fn test_examples_work() -> Result<()> { - let results: Vec<_> = EXAMPLES - .iter() - .flat_map(|(_, examples)| examples.iter()) - .map(|example| { - let command = example.replace( - "lychee", - main_command!() - .get_program() - .to_str() - .expect("Unable to convert to string"), - ); - - ( - command.clone(), - Command::new("sh") - .arg("-c") - .arg(command) - .current_dir(fixtures_path!().join("manpage_examples")) - .output(), - ) - }) - .collect(); - - for (command, result) in results { - let result = result?; - let output = str::from_utf8(&result.stderr)?; - assert!( - result.status.success(), - "The command '{command}' failed with: {output}", - ); - } - - Ok(()) - } - fn filter_empty_lines(s: &str) -> String { s.lines() .filter(|line| !line.trim().is_empty()) diff --git a/lychee-bin/tests/cli.rs b/lychee-bin/tests/cli.rs index 0f9f8e4708..a27eae8748 100644 --- a/lychee-bin/tests/cli.rs +++ b/lychee-bin/tests/cli.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod cli { use anyhow::anyhow; - use assert_cmd::{Command, assert::Assert, output::OutputOkExt}; + use assert_cmd::{assert::Assert, cargo::cargo_bin_cmd, output::OutputOkExt}; use assert_json_diff::assert_json_include; use http::{Method, StatusCode}; use lychee_lib::{InputSource, ResponseBody}; @@ -22,9 +22,7 @@ mod cli { time::Duration, }; use tempfile::{NamedTempFile, tempdir}; - use test_utils::{ - fixtures_path, main_command, mock_server, redirecting_mock_server, root_path, - }; + use test_utils::{fixtures_path, mock_server, redirecting_mock_server, root_path}; use uuid::Uuid; use wiremock::{ @@ -81,7 +79,7 @@ mod cli { /// Test the output of the JSON format. macro_rules! test_json_output { ($test_file:expr, $expected:expr $(, $arg:expr)*) => {{ - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); let test_path = fixtures_path!().join($test_file); let outfile = format!("{}.json", uuid::Uuid::new_v4()); @@ -124,7 +122,7 @@ mod cli { fn test_compact_output_format_contains_status() -> Result<()> { let test_path = fixtures_path!().join("TEST_INVALID_URLS.html"); - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.arg("--format") .arg("compact") .arg("--mode") @@ -166,7 +164,7 @@ mod cli { async fn test_json_output() -> Result<()> { // Server that returns a bunch of 200 OK responses let mock_server_ok = mock_server!(StatusCode::OK); - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.arg("--format") .arg("json") .arg("-vv") @@ -223,7 +221,7 @@ mod cli { fn test_valid_json_output_to_stdout_on_error() -> Result<()> { let test_path = fixtures_path!().join("TEST_GITHUB_404.md"); - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.arg("--format") .arg("json") .arg(test_path) @@ -242,7 +240,7 @@ mod cli { fn test_detailed_json_output_on_error() -> Result<()> { let test_path = fixtures_path!().join("TEST_DETAILED_JSON_OUTPUT_ERROR.md"); - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.arg("--format") .arg("json") .arg(&test_path) @@ -320,33 +318,29 @@ mod cli { } #[test] - fn test_email_html_with_subject() -> Result<()> { + fn test_email_html_with_subject() { let input = fixtures_path!().join("TEST_EMAIL_QUERY_PARAMS.html"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(input) .arg("--include-mail") .assert() .success() .stdout(contains("hello@example.org?subject=%5BHello%5D")); - - Ok(()) } #[test] - fn test_email_markdown_with_subject() -> Result<()> { + fn test_email_markdown_with_subject() { let input = fixtures_path!().join("TEST_EMAIL_QUERY_PARAMS.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(input) .arg("--include-mail") .assert() .success() .stdout(contains("hello@example.org?subject=%5BHello%5D")); - - Ok(()) } #[test] @@ -381,7 +375,7 @@ mod cli { // Exclude file link because it doesn't exist on the filesystem. // (File URIs are absolute paths, which we don't have.) // Nevertheless, the `file` scheme should be recognized. - main_command!() + cargo_bin_cmd!() .arg(test_schemes_path) .arg("--exclude") .arg("file://") @@ -397,7 +391,7 @@ mod cli { fn test_resolve_paths() { let dir = fixtures_path!().join("resolve_paths"); - main_command!() + cargo_bin_cmd!() .arg("--offline") .arg("--base-url") .arg(&dir) @@ -413,7 +407,7 @@ mod cli { fn test_resolve_paths_from_root_dir() { let dir = fixtures_path!().join("resolve_paths_from_root_dir"); - main_command!() + cargo_bin_cmd!() .arg("--offline") .arg("--include-fragments") .arg("--root-dir") @@ -431,7 +425,7 @@ mod cli { fn test_resolve_paths_from_root_dir_and_base_url() { let dir = fixtures_path!(); - main_command!() + cargo_bin_cmd!() .arg("--offline") .arg("--root-dir") .arg("/resolve_paths") @@ -449,7 +443,7 @@ mod cli { fn test_youtube_quirk() { let url = "https://www.youtube.com/watch?v=NlKuICiT470&list=PLbWDhxwM_45mPVToqaIZNbZeIzFchsKKQ&index=7"; - main_command!() + cargo_bin_cmd!() .write_stdin(url) .arg("--verbose") .arg("--no-progress") @@ -464,7 +458,7 @@ mod cli { fn test_crates_io_quirk() { let url = "https://crates.io/crates/lychee"; - main_command!() + cargo_bin_cmd!() .write_stdin(url) .arg("--verbose") .arg("--no-progress") @@ -482,7 +476,7 @@ mod cli { fn test_ignored_hosts() { let url = "https://twitter.com/zarfeblong/status/1339742840142872577"; - main_command!() + cargo_bin_cmd!() .write_stdin(url) .arg("--verbose") .arg("--no-progress") @@ -501,7 +495,7 @@ mod cli { let mut file = File::create(&file_path)?; writeln!(file, "{}", mock_server.uri())?; - main_command!() + cargo_bin_cmd!() .arg(file_path) .write_stdin(mock_server.uri()) .assert() @@ -515,7 +509,7 @@ mod cli { fn test_schemes() { let test_schemes_path = fixtures_path!().join("TEST_SCHEMES.md"); - main_command!() + cargo_bin_cmd!() .arg(test_schemes_path) .arg("--scheme") .arg("https") @@ -534,7 +528,7 @@ mod cli { // Repetitions in one file shall all be checked and counted only once. let test_schemes_path_1 = fixtures_path!().join("TEST_REPETITION_1.txt"); - main_command!() + cargo_bin_cmd!() .arg(&test_schemes_path_1) .env_clear() .assert() @@ -570,7 +564,7 @@ mod cli { fn test_failure_github_404_no_token() { let test_github_404_path = fixtures_path!().join("TEST_GITHUB_404.md"); - main_command!() + cargo_bin_cmd!() .arg(test_github_404_path) .arg("--no-progress") .env_clear() @@ -589,7 +583,7 @@ mod cli { async fn test_stdin_input() { let mock_server = mock_server!(StatusCode::OK); - main_command!() + cargo_bin_cmd!() .arg("-") .write_stdin(mock_server.uri()) .assert() @@ -600,7 +594,7 @@ mod cli { async fn test_stdin_input_failure() { let mock_server = mock_server!(StatusCode::INTERNAL_SERVER_ERROR); - main_command!() + cargo_bin_cmd!() .arg("-") .write_stdin(mock_server.uri()) .assert() @@ -615,7 +609,7 @@ mod cli { // this behavior (treating multiple `-` as separate inputs) is the same as most CLI tools // that accept `-` as stdin, e.g. `cat`, `bat`, `grep` etc. - main_command!() + cargo_bin_cmd!() .arg("-") .arg("-") .write_stdin(mock_server_a.uri()) @@ -627,7 +621,7 @@ mod cli { #[test] fn test_missing_file_ok_if_skip_missing() { let filename = format!("non-existing-file-{}", uuid::Uuid::new_v4()); - main_command!() + cargo_bin_cmd!() .arg(&filename) .arg("--skip-missing") .assert() @@ -636,20 +630,20 @@ mod cli { #[test] fn test_skips_hidden_files_by_default() { - main_command!() + cargo_bin_cmd!() .arg(fixtures_path!().join("hidden/")) .assert() .success() .stdout(contains("0 Total")); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(fixtures_path!().join("hidden/")) .assert() .stdout("") .success(); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(fixtures_path!().join("hidden/")) .assert() @@ -659,14 +653,14 @@ mod cli { #[test] fn test_include_hidden_file() { - main_command!() + cargo_bin_cmd!() .arg(fixtures_path!().join("hidden/")) .arg("--hidden") .assert() .success() .stdout(contains("1 Total")); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--hidden") .arg(fixtures_path!().join("hidden/")) @@ -674,7 +668,7 @@ mod cli { .stdout(contains("wikipedia.org")) .success(); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg("--hidden") .arg(fixtures_path!().join("hidden/")) @@ -685,20 +679,20 @@ mod cli { #[test] fn test_skips_ignored_files_by_default() { - main_command!() + cargo_bin_cmd!() .arg(fixtures_path!().join("ignore/")) .assert() .success() .stdout(contains("0 Total")); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(fixtures_path!().join("ignore/")) .assert() .success() .stdout(""); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(fixtures_path!().join("ignore/")) .assert() @@ -708,14 +702,14 @@ mod cli { #[test] fn test_include_ignored_file() { - main_command!() + cargo_bin_cmd!() .arg(fixtures_path!().join("ignore/")) .arg("--no-ignore") .assert() .success() .stdout(contains("1 Total")); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--no-ignore") .arg(fixtures_path!().join("ignore/")) @@ -723,7 +717,7 @@ mod cli { .success() .stdout(contains("wikipedia.org")); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg("--no-ignore") .arg(fixtures_path!().join("ignore/")) @@ -743,7 +737,7 @@ mod cli { writeln!(file_a, "{}", mock_server_a.uri().as_str())?; writeln!(file_b, "{}", mock_server_b.uri().as_str())?; - main_command!() + cargo_bin_cmd!() .arg(dir.path().join("*.md")) .arg("--verbose") .assert() @@ -765,7 +759,7 @@ mod cli { writeln!(file_a, "{}", mock_server_a.uri().as_str())?; writeln!(file_b, "{}", mock_server_b.uri().as_str())?; - main_command!() + cargo_bin_cmd!() .arg(dir.path().join("[r]eadme.md")) .arg("--verbose") .arg("--glob-ignore-case") @@ -787,7 +781,7 @@ mod cli { writeln!(file, "{}", mock_server.uri().as_str())?; - main_command!() + cargo_bin_cmd!() .arg(dir.path().join("**/*.md")) // ** should be a recursive glob .arg("--verbose") .assert() @@ -817,7 +811,7 @@ mod cli { let test_path = fixtures_path!().join("TEST.md"); let outfile = format!("{}", Uuid::new_v4()); - main_command!() + cargo_bin_cmd!() .arg("--output") .arg(&outfile) .arg("--dump") @@ -842,7 +836,7 @@ mod cli { fn test_exclude_wildcard() -> Result<()> { let test_path = fixtures_path!().join("TEST.md"); - main_command!() + cargo_bin_cmd!() .arg(test_path) .arg("--exclude") .arg(".*") @@ -857,7 +851,7 @@ mod cli { fn test_exclude_multiple_urls() -> Result<()> { let test_path = fixtures_path!().join("TEST.md"); - main_command!() + cargo_bin_cmd!() .arg(test_path) .arg("--exclude") .arg("https://en.wikipedia.org/*") @@ -874,7 +868,7 @@ mod cli { async fn test_empty_config() { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("empty.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -889,7 +883,7 @@ mod cli { #[test] fn test_invalid_default_config() { let test_path = fixtures_path!().join("configs"); - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.current_dir(test_path) .arg(".") .assert() @@ -904,7 +898,7 @@ mod cli { let mut config = NamedTempFile::new()?; writeln!(config, "include_mail = false")?; - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config.path().to_str().unwrap()) .arg("-") @@ -918,7 +912,7 @@ mod cli { let mut config = NamedTempFile::new()?; writeln!(config, "include_mail = true")?; - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config.path().to_str().unwrap()) .arg("-") @@ -936,7 +930,7 @@ mod cli { async fn test_cache_config() -> Result<()> { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("cache.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -953,7 +947,7 @@ mod cli { #[tokio::test] async fn test_invalid_config() { let config = fixtures_path!().join("configs").join("invalid.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -969,7 +963,7 @@ mod cli { async fn test_config_invalid_keys() { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("invalid-key.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -984,7 +978,7 @@ mod cli { #[tokio::test] async fn test_missing_config_error() { let mock_server = mock_server!(StatusCode::OK); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg("config.does.not.exist.toml") .arg("-") @@ -998,7 +992,7 @@ mod cli { async fn test_config_example() { let mock_server = mock_server!(StatusCode::OK); let config = root_path!().join("lychee.example.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -1011,7 +1005,11 @@ mod cli { #[test] #[cfg(unix)] fn test_all_arguments_in_config() -> Result<()> { - let help_cmd = main_command!().env_clear().arg("--help").assert().success(); + let help_cmd = cargo_bin_cmd!() + .env_clear() + .arg("--help") + .assert() + .success(); let help_text = std::str::from_utf8(&help_cmd.get_output().stdout)?; let regex = test_utils::arg_regex_help!()?; @@ -1053,7 +1051,7 @@ The config file should contain every possible key for documentation purposes." async fn test_config_smoketest() { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("smoketest.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -1067,7 +1065,7 @@ The config file should contain every possible key for documentation purposes." async fn test_config_accept() { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("accept.toml"); - main_command!() + cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -1081,7 +1079,7 @@ The config file should contain every possible key for documentation purposes." #[cfg(unix)] async fn test_config_files_from() { let dir = fixtures_path!().join("configs").join("files_from"); - let result = main_command!() + let result = cargo_bin_cmd!() .current_dir(dir) .arg("/dev/null") // at least one input arg is required. this could be changed in the future .arg("--dump") @@ -1095,7 +1093,7 @@ The config file should contain every possible key for documentation purposes." fn test_lycheeignore_file() -> Result<()> { let test_path = fixtures_path!().join("lycheeignore"); - let cmd = main_command!() + let cmd = cargo_bin_cmd!() .current_dir(test_path) .arg("--dump") .arg("TEST.md") @@ -1116,7 +1114,7 @@ The config file should contain every possible key for documentation purposes." let test_path = fixtures_path!().join("lycheeignore"); let excludes_path = test_path.join("normal-exclude-file"); - main_command!() + cargo_bin_cmd!() .current_dir(test_path) .arg("TEST.md") .arg("--exclude-file") @@ -1156,7 +1154,7 @@ The config file should contain every possible key for documentation purposes." file.sync_all()?; // Create and run command - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.current_dir(&base_path) .arg(&file_path) .arg("--verbose") @@ -1228,7 +1226,7 @@ The config file should contain every possible key for documentation purposes." writeln!(file, "{}", mock_server_no_content.uri().as_str())?; writeln!(file, "{}", mock_server_too_many_requests.uri().as_str())?; - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); let test_cmd = cmd .current_dir(&base_path) .arg(dir.path().join("c.md")) @@ -1291,7 +1289,7 @@ The config file should contain every possible key for documentation purposes." writeln!(file, "{}", mock_server_teapot.uri().as_str())?; writeln!(file, "{}", mock_server_server_error.uri().as_str())?; - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); let test_cmd = cmd .current_dir(&base_path) .arg(dir.path().join("c.md")) @@ -1351,7 +1349,7 @@ The config file should contain every possible key for documentation purposes." async fn test_accept_overrides_defaults_not_additive() -> Result<()> { let mock_server_200 = mock_server!(StatusCode::OK); - main_command!() + cargo_bin_cmd!() .arg("--accept") .arg("404") // ONLY accept 404 - should reject 200 as we overwrite the default .arg("-") @@ -1379,7 +1377,7 @@ The config file should contain every possible key for documentation purposes." let excluded_url = "https://example.com/"; // run first without cache to generate the cache file - main_command!() + cargo_bin_cmd!() .current_dir(&base_path) .write_stdin(format!("{unsupported_url}\n{excluded_url}")) .arg("--cache") @@ -1431,7 +1429,7 @@ The config file should contain every possible key for documentation purposes." let unknown_url = "https://www.linkedin.com/company/corrode"; // run first without cache to generate the cache file - main_command!() + cargo_bin_cmd!() .current_dir(&base_path) .write_stdin(unknown_url.to_string()) .arg("--cache") @@ -1465,7 +1463,7 @@ The config file should contain every possible key for documentation purposes." fn test_verbatim_skipped_by_default() { let input = fixtures_path!().join("TEST_CODE_BLOCKS.md"); - main_command!() + cargo_bin_cmd!() .arg(input) .arg("--dump") .assert() @@ -1477,7 +1475,7 @@ The config file should contain every possible key for documentation purposes." fn test_include_verbatim() { let input = fixtures_path!().join("TEST_CODE_BLOCKS.md"); - main_command!() + cargo_bin_cmd!() .arg("--include-verbatim") .arg(input) .arg("--dump") @@ -1491,7 +1489,7 @@ The config file should contain every possible key for documentation purposes." async fn test_verbatim_skipped_by_default_via_file() { let file = fixtures_path!().join("TEST_VERBATIM.html"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(file) .assert() @@ -1505,7 +1503,7 @@ The config file should contain every possible key for documentation purposes." let body = fs::read_to_string(file).unwrap(); let mock_server = mock_response!(body); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(mock_server.uri()) .assert() @@ -1519,7 +1517,7 @@ The config file should contain every possible key for documentation purposes." let body = fs::read_to_string(file).unwrap(); let mock_server = mock_response!(body); - main_command!() + cargo_bin_cmd!() .arg("--include-verbatim") .arg("--dump") .arg(mock_server.uri()) @@ -1536,9 +1534,9 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_require_https() { let test_path = fixtures_path!().join("TEST_HTTP.html"); - main_command!().arg(&test_path).assert().success(); + cargo_bin_cmd!().arg(&test_path).assert().success(); - main_command!() + cargo_bin_cmd!() .arg("--require-https") .arg(test_path) .assert() @@ -1553,7 +1551,7 @@ The config file should contain every possible key for documentation purposes." fn test_ignore_absolute_local_links_without_base() { let offline_dir = fixtures_path!().join("offline"); - main_command!() + cargo_bin_cmd!() .arg("--offline") .arg(offline_dir.join("index.html")) .env_clear() @@ -1565,7 +1563,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_inputs_without_scheme() { let test_path = fixtures_path!().join("TEST_HTTP.html"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("example.com") .arg(&test_path) @@ -1577,7 +1575,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_print_excluded_links_in_verbose_mode() { let test_path = fixtures_path!().join("TEST_DUMP_EXCLUDE.txt"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--verbose") .arg("--exclude") @@ -1602,7 +1600,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_remap_uri() { - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--remap") .arg("https://example.com http://127.0.0.1:8080") @@ -1622,7 +1620,7 @@ The config file should contain every possible key for documentation purposes." #[test] #[ignore = "Skipping test until https://github.com/robinst/linkify/pull/58 is merged"] fn test_remap_path() { - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--remap") .arg("../../issues https://github.com/usnistgov/OSCAL/issues") @@ -1637,7 +1635,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_remap_capture() { - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--remap") .arg("https://example.com/(.*) http://example.org/$1") @@ -1652,7 +1650,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_remap_named_capture() { - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--remap") .arg("https://github.com/(?P.*)/(?P.*) https://gitlab.com/$org/$repo") @@ -1670,7 +1668,7 @@ The config file should contain every possible key for documentation purposes." let test_path = fixtures_path!().join("exclude-path"); let excluded_path_1 = "\\/excluded?\\/"; // exclude paths containing a directory "exclude" and "excluded" let excluded_path_2 = "(\\.mdx|\\.txt)$"; // exclude .mdx and .txt files - let result = main_command!() + let result = cargo_bin_cmd!() .arg("--exclude-path") .arg(excluded_path_1) .arg("--exclude-path") @@ -1694,7 +1692,7 @@ The config file should contain every possible key for documentation purposes." fn test_handle_relative_paths_as_input() { let test_path = fixtures_path!(); - main_command!() + cargo_bin_cmd!() .current_dir(&test_path) .arg("--verbose") .arg("--exclude") @@ -1711,7 +1709,7 @@ The config file should contain every possible key for documentation purposes." fn test_handle_nonexistent_relative_paths_as_input() { let test_path = fixtures_path!(); - main_command!() + cargo_bin_cmd!() .current_dir(&test_path) .arg("--verbose") .arg("--exclude") @@ -1727,7 +1725,7 @@ The config file should contain every possible key for documentation purposes." fn test_prevent_too_many_redirects() { let url = "https://http.codes/308"; - main_command!() + cargo_bin_cmd!() .write_stdin(url) .arg("--max-redirects") .arg("0") @@ -1743,7 +1741,7 @@ The config file should contain every possible key for documentation purposes." for _ in 0..3 { // This can be flaky. Try up to 3 times - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); let input = fixtures_path!().join("INTERNET_ARCHIVE.md"); cmd.arg("--no-progress").arg("--suggest").arg(input); @@ -1787,7 +1785,7 @@ The config file should contain every possible key for documentation purposes." .await; // Configure the command to use the BasicAuthExtractor - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--basic-auth") .arg(format!("{} {username}:{password}", mock_server.uri())) @@ -1799,7 +1797,7 @@ The config file should contain every possible key for documentation purposes." .stdout(contains("1 OK")); // Websites as direct arguments must also use authentication - main_command!() + cargo_bin_cmd!() .arg(mock_server.uri()) .arg("--verbose") .arg("--basic-auth") @@ -1829,7 +1827,7 @@ The config file should contain every possible key for documentation purposes." .await; // Configure the command to use the BasicAuthExtractor - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--basic-auth") .arg(format!("{} {username1}:{password1}", mock_server1.uri())) @@ -1847,7 +1845,7 @@ The config file should contain every possible key for documentation purposes." async fn test_cookie_jar() -> Result<()> { // Create a random cookie jar file let cookie_jar = NamedTempFile::new()?; - main_command!() + cargo_bin_cmd!() .arg("--cookie-jar") .arg(cookie_jar.path().to_str().unwrap()) .arg("-") @@ -1871,7 +1869,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_does_not_include_duplicates() { let pattern = fixtures_path!().join("dump_inputs/markdown.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(&pattern) .arg(&pattern) @@ -1885,7 +1883,7 @@ The config file should contain every possible key for documentation purposes." let pattern1 = fixtures_path!().join("**/markdown.*"); let pattern2 = fixtures_path!().join("**/*.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(pattern1) .arg(pattern2) @@ -1898,7 +1896,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_glob_md() { let pattern = fixtures_path!().join("**/*.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(pattern) .assert() @@ -1911,7 +1909,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_glob_all() { let pattern = fixtures_path!().join("**/*"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(pattern) .assert() @@ -1927,7 +1925,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_glob_exclude_path() { let pattern = fixtures_path!().join("**/*"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(pattern) .arg("--exclude-path") @@ -1941,7 +1939,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_dump_inputs_url() { - let result = main_command!() + let result = cargo_bin_cmd!() .arg("--dump-inputs") .arg("https://example.com") .assert() @@ -1952,7 +1950,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_dump_inputs_path() { - let result = main_command!() + let result = cargo_bin_cmd!() .arg("--dump-inputs") .arg(fixtures_path!().join("dump_inputs")) .assert() @@ -1978,7 +1976,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_with_extensions() { let test_dir = fixtures_path!().join("dump_inputs"); - let output = main_command!() + let output = cargo_bin_cmd!() .arg("--dump-inputs") .arg("--extensions") .arg("md,txt") @@ -2019,7 +2017,7 @@ The config file should contain every possible key for documentation purposes." let test_dir = fixtures_path!().join("hidden"); // Test default behavior (skip hidden) - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(&test_dir) .assert() @@ -2027,7 +2025,7 @@ The config file should contain every possible key for documentation purposes." .stdout(is_empty()); // Test with --hidden flag - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg("--hidden") .arg(test_dir) @@ -2040,7 +2038,7 @@ The config file should contain every possible key for documentation purposes." fn test_dump_inputs_individual_file() { let test_file = fixtures_path!().join("TEST.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(&test_file) .assert() @@ -2050,7 +2048,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_dump_inputs_stdin() { - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg("-") .assert() @@ -2062,7 +2060,7 @@ The config file should contain every possible key for documentation purposes." fn test_fragments_regression() { let input = fixtures_path!().join("FRAGMENT_REGRESSION.md"); - main_command!() + cargo_bin_cmd!() .arg("--include-fragments") .arg("--verbose") .arg(input) @@ -2074,7 +2072,7 @@ The config file should contain every possible key for documentation purposes." fn test_fragments() { let input = fixtures_path!().join("fragments"); - let mut result = main_command!() + let mut result = cargo_bin_cmd!() .arg("--include-fragments") .arg("--verbose") .arg(input) @@ -2168,7 +2166,7 @@ The config file should contain every possible key for documentation purposes." // it's common for user to accept 429, but let's test with 404 since // triggering 429 may annoy the server - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--accept=200,404") .arg("--include-fragments") @@ -2187,7 +2185,7 @@ The config file should contain every possible key for documentation purposes." fn test_fallback_extensions() { let input = fixtures_path!().join("fallback-extensions"); - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--fallback-extensions=htm,html") .arg(input) @@ -2200,7 +2198,7 @@ The config file should contain every possible key for documentation purposes." fn test_fragments_fallback_extensions() { let input = fixtures_path!().join("fragments-fallback-extensions"); - main_command!() + cargo_bin_cmd!() .arg("--include-fragments") .arg("--fallback-extensions=html") .arg("--no-progress") @@ -2245,7 +2243,7 @@ The config file should contain every possible key for documentation purposes." .mount(&mock_server) .await; - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg(format!("{}/test/index.html", mock_server.uri())) .assert() @@ -2258,7 +2256,7 @@ The config file should contain every possible key for documentation purposes." async fn test_json_format_in_config() -> Result<()> { let mock_server = mock_server!(StatusCode::OK); let config = fixtures_path!().join("configs").join("format.toml"); - let output = main_command!() + let output = cargo_bin_cmd!() .arg("--config") .arg(config) .arg("-") @@ -2281,7 +2279,7 @@ The config file should contain every possible key for documentation purposes." async fn test_redirect_json() { use serde_json::json; redirecting_mock_server!(async |redirect_url: Url, ok_url| { - let output = main_command!() + let output = cargo_bin_cmd!() .arg("-") .arg("--format") .arg("json") @@ -2329,7 +2327,7 @@ The config file should contain every possible key for documentation purposes." .mount(&mock_server) .await; - main_command!() + cargo_bin_cmd!() .arg("-") .write_stdin(mock_server.uri()) .assert() @@ -2347,7 +2345,7 @@ The config file should contain every possible key for documentation purposes." ) .await; - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg(server.uri()) .assert() @@ -2378,7 +2376,7 @@ The config file should contain every possible key for documentation purposes." ) .await; - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--header") .arg("X-Foo: Bar") @@ -2405,7 +2403,7 @@ The config file should contain every possible key for documentation purposes." ) .await; - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--header") .arg("X-Foo: Bar") @@ -2435,7 +2433,7 @@ The config file should contain every possible key for documentation purposes." .await; let config = fixtures_path!().join("configs").join("headers.toml"); - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--config") .arg(config) @@ -2456,7 +2454,7 @@ The config file should contain every possible key for documentation purposes." "https://httpbin.org/status/502", ]; - let cmd = &mut main_command!() + let cmd = &mut cargo_bin_cmd!() .arg("--format") .arg("compact") .arg(fixtures_path!().join(test_files[1])) @@ -2495,7 +2493,7 @@ The config file should contain every possible key for documentation purposes." fn test_extract_url_ending_with_period_file() { let test_path = fixtures_path!().join("LINK_PERIOD.html"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(test_path) .assert() @@ -2508,7 +2506,7 @@ The config file should contain every possible key for documentation purposes." let body = r#"link"#; let mock_server = mock_response!(body); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(mock_server.uri()) .assert() @@ -2520,7 +2518,7 @@ The config file should contain every possible key for documentation purposes." fn test_wikilink_extract_when_specified() { let test_path = fixtures_path!().join("TEST_WIKI.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg("--include-wikilinks") .arg(test_path) @@ -2533,7 +2531,7 @@ The config file should contain every possible key for documentation purposes." fn test_wikilink_dont_extract_when_not_specified() { let test_path = fixtures_path!().join("TEST_WIKI.md"); - main_command!() + cargo_bin_cmd!() .arg("--dump") .arg(test_path) .assert() @@ -2546,7 +2544,7 @@ The config file should contain every possible key for documentation purposes." let input = fixtures_path!().join("filechecker/dir_links.md"); // the dir links in this file all exist. - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--verbose") .assert() @@ -2555,7 +2553,7 @@ The config file should contain every possible key for documentation purposes." // ... but checking fragments will find none, because dirs // have no fragments and no index file given. let dir_links_with_fragment = 2; - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--include-fragments") .assert() @@ -2570,7 +2568,7 @@ The config file should contain every possible key for documentation purposes." // passing `--index-files index.html,index.htm` should reject all links // to /empty_dir because it doesn't have the index file - let result = main_command!() + let result = cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg("index.html,index.htm") @@ -2588,7 +2586,7 @@ The config file should contain every possible key for documentation purposes." // within the error message, formatting of the index file name list should // omit empty names. - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg(",index.html,,,index.htm,") @@ -2603,7 +2601,7 @@ The config file should contain every possible key for documentation purposes." // passing `.` in the index files list should accept a directory // even if no other index file is found. - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg("index.html,.") @@ -2614,7 +2612,7 @@ The config file should contain every possible key for documentation purposes." // checking fragments will accept the index_dir#fragment link, // but reject empty_dir#fragment because empty_dir doesn’t have // index.html. - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg("index.html,.") @@ -2633,7 +2631,7 @@ The config file should contain every possible key for documentation purposes." // passing an empty list to --index-files should reject /all/ // directory links. - let result = main_command!() + let result = cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg("") @@ -2647,7 +2645,7 @@ The config file should contain every possible key for documentation purposes." .stdout(contains("0 OK")); // ... as should passing a number of empty index file names - main_command!() + cargo_bin_cmd!() .arg(&input) .arg("--index-files") .arg(",,,,,") @@ -2663,7 +2661,7 @@ The config file should contain every possible key for documentation purposes." let inputs = fixtures_path!().join("invalid_utf8"); // Run the command with the binary input - let result = main_command!() + let result = cargo_bin_cmd!() .arg("--verbose") .arg(&inputs) .assert() @@ -2692,7 +2690,7 @@ The config file should contain every possible key for documentation purposes." let inputs = fixtures_path!().join("invalid_utf8"); // Run the command with the binary input - main_command!() + cargo_bin_cmd!() .arg("--dump-inputs") .arg(inputs) .assert() @@ -2716,7 +2714,7 @@ The config file should contain every possible key for documentation purposes." // - example.md // - example.html // But the user only specified the .tsx file via the glob pattern. - main_command!() + cargo_bin_cmd!() .arg("--verbose") // Only check ts, js, and html files by default. // However, all files explicitly specified by the user @@ -2735,7 +2733,7 @@ The config file should contain every possible key for documentation purposes." // Make sure all files matching the given extensions are checked // if we specify a directory (and not a glob pattern). - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--extensions=ts,html") .arg(input) @@ -2759,7 +2757,7 @@ The config file should contain every possible key for documentation purposes." let glob_input = fixtures_path!().join("glob_dir/**/*.tsx"); let dir_input = fixtures_path!().join("example_dir"); - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--extensions=html,md") .arg(glob_input) @@ -2788,7 +2786,7 @@ The config file should contain every possible key for documentation purposes." let ts_input_file = fixtures_path!().join("glob_dir/example.ts"); let md_input_file = fixtures_path!().join("glob_dir/example.md"); - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--dump") .arg("--extensions=html,md") @@ -2808,7 +2806,7 @@ The config file should contain every possible key for documentation purposes." fn test_url_inputs_always_get_checked_no_matter_their_extension() { let url_input = "https://example.com/sitemap.xml"; - main_command!() + cargo_bin_cmd!() .arg("--verbose") .arg("--dump") .arg(url_input) @@ -2828,7 +2826,7 @@ The config file should contain every possible key for documentation purposes." fs::write(&test_md, "# Test\n[link](https://example.com)")?; fs::write(&files_list_path, test_md.to_string_lossy().as_ref())?; - main_command!() + cargo_bin_cmd!() .arg("--files-from") .arg(&files_list_path) .arg("--dump-inputs") @@ -2847,7 +2845,7 @@ The config file should contain every possible key for documentation purposes." // Create test file fs::write(&test_md, "# Test\n[link](https://example.com)")?; - main_command!() + cargo_bin_cmd!() .arg("--files-from") .arg("-") .arg("--dump-inputs") @@ -2875,7 +2873,7 @@ The config file should contain every possible key for documentation purposes." ), )?; - main_command!() + cargo_bin_cmd!() .arg("--files-from") .arg(&files_list_path) .arg("--dump-inputs") @@ -2898,7 +2896,7 @@ The config file should contain every possible key for documentation purposes." fs::write(&test_md2, "# Test 2")?; fs::write(&files_list_path, test_md1.to_string_lossy().as_ref())?; - let mut cmd = main_command!(); + let mut cmd = cargo_bin_cmd!(); cmd.arg("--files-from") .arg(&files_list_path) .arg(&test_md2) // Regular input argument @@ -2913,7 +2911,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_files_from_nonexistent_file_error() { - main_command!() + cargo_bin_cmd!() .arg("--files-from") .arg("/nonexistent/file.txt") .arg("--dump-inputs") @@ -2932,7 +2930,7 @@ The config file should contain every possible key for documentation purposes." writeln!(file_without_ext, "[Local](local.md)")?; // Test with --default-extension md - main_command!() + cargo_bin_cmd!() .arg("--default-extension") .arg("md") .arg("--dump") @@ -2951,7 +2949,7 @@ The config file should contain every possible key for documentation purposes." writeln!(html_file_without_ext, "")?; // Test with --default-extension html - main_command!() + cargo_bin_cmd!() .arg("--default-extension") .arg("html") .arg("--dump") @@ -2973,7 +2971,7 @@ The config file should contain every possible key for documentation purposes." // Unknown extensions should fall back to default behavior (plaintext) // and still extract links from the content - main_command!() + cargo_bin_cmd!() .arg("--default-extension") .arg("unknown") .arg("--dump") @@ -2988,7 +2986,7 @@ The config file should contain every possible key for documentation purposes." fn test_input_matching_nothing_warns() -> Result<()> { let empty_dir = tempdir()?; - main_command!() + cargo_bin_cmd!() .arg(format!("{}", empty_dir.path().to_string_lossy())) .arg(format!("{}/*", empty_dir.path().to_string_lossy())) .arg("non-existing-path/*") @@ -3005,7 +3003,7 @@ The config file should contain every possible key for documentation purposes." /// error before link checking. #[test] fn test_invalid_glob_fails_parse() { - main_command!() + cargo_bin_cmd!() .arg("invalid-unmatched-brackets[") .assert() .stderr(contains("Cannot parse input")) @@ -3018,7 +3016,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_pre_cat() { let file = fixtures_path!().join("TEST.md"); - let pre_with_cat = main_command!() + let pre_with_cat = cargo_bin_cmd!() .arg("--preprocess") .arg("cat") .arg("--dump") @@ -3026,7 +3024,7 @@ The config file should contain every possible key for documentation purposes." .assert() .success(); - let no_pre = main_command!() + let no_pre = cargo_bin_cmd!() .arg("--dump") .arg(&file) .assert() @@ -3043,7 +3041,7 @@ The config file should contain every possible key for documentation purposes." #[test] fn test_pre_invalid_command() { let file = fixtures_path!().join("TEST.md"); - main_command!() + cargo_bin_cmd!() .arg("--preprocess") .arg("program does not exist") .arg(file) @@ -3056,7 +3054,7 @@ The config file should contain every possible key for documentation purposes." fn test_pre_error() { let file = fixtures_path!().join("TEST.md"); let script = fixtures_path!().join("pre").join("no_error_message.sh"); - main_command!() + cargo_bin_cmd!() .arg("--preprocess") .arg(&script) .arg(&file) @@ -3067,7 +3065,7 @@ The config file should contain every possible key for documentation purposes." ))); let script = fixtures_path!().join("pre").join("error_message.sh"); - main_command!() + cargo_bin_cmd!() .arg("--preprocess") .arg(&script) .arg(file) diff --git a/lychee-bin/tests/data_uris.rs b/lychee-bin/tests/data_uris.rs index 2427fb4815..96b11ad4d3 100644 --- a/lychee-bin/tests/data_uris.rs +++ b/lychee-bin/tests/data_uris.rs @@ -3,16 +3,10 @@ //! works as expected for normal users. #[cfg(test)] mod cli { - use std::{ - error::Error, - path::{Path, PathBuf}, - }; + use std::path::{Path, PathBuf}; - use assert_cmd::Command; + use assert_cmd::cargo::cargo_bin_cmd; use predicates::str::contains; - use test_utils::main_command; - - type Result = std::result::Result>; fn fixtures_path() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")) @@ -22,11 +16,10 @@ mod cli { } #[test] - fn test_dont_dump_data_uris_by_default() -> Result<()> { - let mut cmd = main_command!(); + fn test_dont_dump_data_uris_by_default() { let input = fixtures_path().join("TEST_DATA_URIS.html"); - let cmd = cmd + let cmd = cargo_bin_cmd!() .arg(input) .arg("--dump") .assert() @@ -36,16 +29,13 @@ mod cli { let output = cmd.get_output(); let output = std::str::from_utf8(&output.stdout).unwrap(); assert_eq!(output.lines().count(), 1); - - Ok(()) } #[test] - fn test_dump_data_uris_in_verbose_mode() -> Result<()> { - let mut cmd = main_command!(); + fn test_dump_data_uris_in_verbose_mode() { let input = fixtures_path().join("TEST_DATA_URIS.html"); - let cmd = cmd + let cmd = cargo_bin_cmd!() .arg(input) .arg("--dump") .arg("--verbose") @@ -62,7 +52,5 @@ mod cli { let output = cmd.get_output(); let output = std::str::from_utf8(&output.stdout).unwrap(); assert_eq!(output.lines().count(), 5); - - Ok(()) } } diff --git a/lychee-bin/tests/example_domains.rs b/lychee-bin/tests/example_domains.rs index 5562255b01..47d61695f0 100644 --- a/lychee-bin/tests/example_domains.rs +++ b/lychee-bin/tests/example_domains.rs @@ -8,9 +8,8 @@ mod cli { path::{Path, PathBuf}, }; - use assert_cmd::Command; + use assert_cmd::cargo::cargo_bin_cmd; use predicates::str::contains; - use test_utils::main_command; type Result = std::result::Result>; @@ -24,10 +23,9 @@ mod cli { #[test] #[cfg(not(feature = "check_example_domains"))] fn test_exclude_example_domains() -> Result<()> { - let mut cmd = main_command!(); let input = fixtures_path().join("TEST_EXAMPLE_DOMAINS.md"); - let cmd = cmd + let cmd = cargo_bin_cmd!() .arg(input) .arg("--include-mail") .arg("--dump") @@ -47,10 +45,9 @@ mod cli { #[test] fn test_do_not_exclude_false_positive_example_domains() -> Result<()> { - let mut cmd = main_command!(); let input = fixtures_path().join("TEST_EXAMPLE_DOMAINS_FALSE_POSITIVES.md"); - let cmd = cmd + let cmd = cargo_bin_cmd!() .arg(input) .arg("--include-mail") .arg("--dump") diff --git a/lychee-bin/tests/local_files.rs b/lychee-bin/tests/local_files.rs index 731ecb2295..febee154dd 100644 --- a/lychee-bin/tests/local_files.rs +++ b/lychee-bin/tests/local_files.rs @@ -2,16 +2,11 @@ mod cli { use std::{error::Error, fs::File, io::Write}; - use assert_cmd::Command; + use assert_cmd::cargo::cargo_bin_cmd; use predicates::str::contains; type Result = std::result::Result>; - fn main_command() -> Command { - // this gets the "main" binary name (e.g. `lychee`) - Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("Couldn't get cargo package name") - } - #[tokio::test] async fn test_local_file() -> Result<()> { let dir = tempfile::tempdir()?; @@ -22,8 +17,8 @@ mod cli { let foo_path = dir.path().join("foo.html"); File::create(foo_path)?; - let mut cmd = main_command(); - cmd.arg(index_path) + cargo_bin_cmd!() + .arg(index_path) .arg("--no-progress") .arg("--verbose") .env_clear() @@ -48,8 +43,8 @@ mod cli { let bar_path = dir.path().join("bar.md"); File::create(bar_path)?; - let mut cmd = main_command(); - cmd.arg(dir.path()) + cargo_bin_cmd!() + .arg(dir.path()) .arg("--no-progress") .arg("--verbose") .env_clear() diff --git a/lychee-bin/tests/usage.rs b/lychee-bin/tests/usage.rs index 073a203c5d..d10bd6d085 100644 --- a/lychee-bin/tests/usage.rs +++ b/lychee-bin/tests/usage.rs @@ -1,10 +1,9 @@ #[cfg(test)] mod readme { - use assert_cmd::Command; + use assert_cmd::cargo::cargo_bin_cmd; use pretty_assertions::assert_eq; use regex::Regex; use test_utils::load_readme_text; - use test_utils::main_command; /// Remove line `[default: lychee/x.y.z]` from the string fn remove_lychee_version_line(string: &str) -> String { @@ -31,9 +30,12 @@ mod readme { #[cfg(unix)] fn test_readme_usage_up_to_date() -> Result<(), Box> { const BEGIN: &str = "```help-message\n"; - let mut cmd = main_command!(); - let help_cmd = cmd.env_clear().arg("--help").assert().success(); + let help_cmd = cargo_bin_cmd!() + .env_clear() + .arg("--help") + .assert() + .success(); let usage_in_help = std::str::from_utf8(&help_cmd.get_output().stdout)?; let usage_in_help = trim_empty_lines(&remove_lychee_version_line(usage_in_help)); @@ -55,8 +57,11 @@ mod readme { #[test] #[cfg(unix)] fn test_arguments_ordered_alphabetically() -> Result<(), Box> { - let mut cmd = main_command!(); - let help_cmd = cmd.env_clear().arg("--help").assert().success(); + let help_cmd = cargo_bin_cmd!() + .env_clear() + .arg("--help") + .assert() + .success(); let help_text = std::str::from_utf8(&help_cmd.get_output().stdout)?; let regex = test_utils::arg_regex_help!()?; diff --git a/lychee-lib/Cargo.toml b/lychee-lib/Cargo.toml index 55ce34d9db..786e89e10f 100644 --- a/lychee-lib/Cargo.toml +++ b/lychee-lib/Cargo.toml @@ -22,16 +22,16 @@ email_address = "0.2.9" futures = "0.3.31" glob = "0.3.3" headers = "0.4.1" -html5ever = "0.35.0" +html5ever = "0.36.1" html5gum = "0.8.0" http = "1.3.1" -hyper = "1.6.0" -ignore = "0.4.24" +hyper = "1.8.0" +ignore = "0.4.25" ip_network = "0.4.1" linkify = "0.10.0" log = "0.4.28" -octocrab = "0.47.0" -openssl-sys = { version = "0.9.110", optional = true } +octocrab = "0.47.1" +openssl-sys = { version = "0.9.111", optional = true } path-clean = "1.0.1" percent-encoding = "2.3.1" pulldown-cmark = "0.13.0" diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 8b0887d065..8294b02466 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -179,14 +179,6 @@ macro_rules! mock_response_body { }}; } -/// Gets the "main" binary name (e.g. `lychee`) -#[macro_export] -macro_rules! main_command { - () => { - Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("Couldn't get cargo package name") - }; -} - /// Capture all CLI flags (e.g. `-a` or `--accept`) from the help message via regex #[macro_export] macro_rules! arg_regex_help {