2020-10-17 08:01:06 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod cli {
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
use std::{
|
2023-02-25 16:57:57 +00:00
|
|
|
collections::{HashMap, HashSet},
|
2022-02-19 00:44:00 +00:00
|
|
|
error::Error,
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
fs::{self, File},
|
|
|
|
|
io::Write,
|
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
|
};
|
2021-04-12 12:40:39 +00:00
|
|
|
|
2020-10-17 08:01:06 +00:00
|
|
|
use assert_cmd::Command;
|
2023-05-05 22:47:32 +00:00
|
|
|
use assert_json_diff::assert_json_include;
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
use http::StatusCode;
|
2023-02-25 16:57:57 +00:00
|
|
|
use lychee_lib::{InputSource, ResponseBody};
|
2022-03-26 09:42:56 +00:00
|
|
|
use predicates::str::{contains, is_empty};
|
2023-02-25 16:57:57 +00:00
|
|
|
use pretty_assertions::assert_eq;
|
2023-05-05 22:47:32 +00:00
|
|
|
use serde::Serialize;
|
|
|
|
|
use serde_json::Value;
|
2020-12-14 00:15:14 +00:00
|
|
|
use uuid::Uuid;
|
2023-06-26 10:06:24 +00:00
|
|
|
use wiremock::{matchers::basic_auth, Mock, ResponseTemplate};
|
2020-12-02 22:28:37 +00:00
|
|
|
|
2022-02-19 00:44:00 +00:00
|
|
|
type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
|
|
|
|
|
2022-07-17 16:40:45 +00:00
|
|
|
// The lychee cache file name is used for some tests.
|
|
|
|
|
// Since it is currently static and can't be overwritten, declare it as a
|
|
|
|
|
// constant.
|
|
|
|
|
const LYCHEE_CACHE_FILE: &str = ".lycheecache";
|
|
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
/// Helper macro to create a mock server which returns a custom status code.
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
macro_rules! mock_server {
|
|
|
|
|
($status:expr $(, $func:tt ($($arg:expr),*))*) => {{
|
|
|
|
|
let mock_server = wiremock::MockServer::start().await;
|
|
|
|
|
let template = wiremock::ResponseTemplate::new(http::StatusCode::from($status));
|
|
|
|
|
let template = template$(.$func($($arg),*))*;
|
|
|
|
|
wiremock::Mock::given(wiremock::matchers::method("GET")).respond_with(template).mount(&mock_server).await;
|
|
|
|
|
mock_server
|
|
|
|
|
}};
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
/// Helper macro to create a mock server which returns a 200 OK and a custom response body.
|
|
|
|
|
macro_rules! mock_response {
|
|
|
|
|
($body:expr) => {{
|
|
|
|
|
let mock_server = wiremock::MockServer::start().await;
|
|
|
|
|
let template = wiremock::ResponseTemplate::new(200).set_body_string($body);
|
|
|
|
|
wiremock::Mock::given(wiremock::matchers::method("GET"))
|
|
|
|
|
.respond_with(template)
|
|
|
|
|
.mount(&mock_server)
|
|
|
|
|
.await;
|
|
|
|
|
mock_server
|
|
|
|
|
}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Gets the "main" binary name (e.g. `lychee`)
|
2020-12-02 22:28:37 +00:00
|
|
|
fn main_command() -> Command {
|
|
|
|
|
Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("Couldn't get cargo package name")
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 19:55:22 +00:00
|
|
|
/// Helper function to get the root path of the project.
|
|
|
|
|
fn root_path() -> PathBuf {
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
|
|
|
.parent()
|
|
|
|
|
.unwrap()
|
2023-03-01 19:55:22 +00:00
|
|
|
.to_path_buf()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Helper function to get the path to the fixtures directory.
|
|
|
|
|
fn fixtures_path() -> PathBuf {
|
|
|
|
|
root_path().join("fixtures")
|
2020-12-02 22:28:37 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-05 22:47:32 +00:00
|
|
|
#[derive(Default, Serialize)]
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
struct MockResponseStats {
|
2023-02-25 16:57:57 +00:00
|
|
|
detailed_stats: bool,
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
total: usize,
|
|
|
|
|
successful: usize,
|
2021-09-08 23:49:25 +00:00
|
|
|
unknown: usize,
|
2023-02-25 16:57:57 +00:00
|
|
|
unsupported: usize,
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
timeouts: usize,
|
|
|
|
|
redirects: usize,
|
|
|
|
|
excludes: usize,
|
|
|
|
|
errors: usize,
|
2022-01-14 14:25:51 +00:00
|
|
|
cached: usize,
|
2023-02-25 16:57:57 +00:00
|
|
|
success_map: HashMap<InputSource, HashSet<ResponseBody>>,
|
|
|
|
|
fail_map: HashMap<InputSource, HashSet<ResponseBody>>,
|
2023-03-27 22:45:06 +00:00
|
|
|
suggestion_map: HashMap<InputSource, HashSet<ResponseBody>>,
|
2023-02-25 16:57:57 +00:00
|
|
|
excluded_map: HashMap<InputSource, HashSet<ResponseBody>>,
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
}
|
2020-10-17 08:01:06 +00:00
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
/// Helper macro to test the output of the JSON format.
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
macro_rules! test_json_output {
|
|
|
|
|
($test_file:expr, $expected:expr $(, $arg:expr)*) => {{
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join($test_file);
|
|
|
|
|
let outfile = format!("{}.json", uuid::Uuid::new_v4());
|
2021-03-29 21:28:17 +00:00
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
cmd$(.arg($arg))*.arg("--output").arg(&outfile).arg("--format").arg("json").arg(test_path).assert().success();
|
|
|
|
|
|
|
|
|
|
let output = std::fs::read_to_string(&outfile)?;
|
|
|
|
|
std::fs::remove_file(outfile)?;
|
2023-05-05 22:47:32 +00:00
|
|
|
|
|
|
|
|
let actual: Value = serde_json::from_str(&output)?;
|
|
|
|
|
let expected: Value = serde_json::to_value(&$expected)?;
|
|
|
|
|
|
|
|
|
|
assert_json_include!(actual: actual, expected: expected);
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
Ok(())
|
|
|
|
|
}};
|
2021-03-29 21:28:17 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-26 22:31:31 +00:00
|
|
|
#[test]
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
fn test_exclude_all_private() -> Result<()> {
|
|
|
|
|
test_json_output!(
|
|
|
|
|
"TEST_ALL_PRIVATE.md",
|
|
|
|
|
MockResponseStats {
|
|
|
|
|
total: 7,
|
|
|
|
|
excludes: 7,
|
|
|
|
|
..MockResponseStats::default()
|
|
|
|
|
},
|
2023-02-25 16:57:57 +00:00
|
|
|
"--exclude-all-private"
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
)
|
|
|
|
|
}
|
2020-10-26 22:31:31 +00:00
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_exclude_email() -> Result<()> {
|
|
|
|
|
test_json_output!(
|
|
|
|
|
"TEST_EMAIL.md",
|
|
|
|
|
MockResponseStats {
|
|
|
|
|
total: 6,
|
|
|
|
|
excludes: 4,
|
|
|
|
|
successful: 2,
|
|
|
|
|
..MockResponseStats::default()
|
|
|
|
|
},
|
|
|
|
|
"--exclude-mail"
|
|
|
|
|
)
|
2020-10-26 22:31:31 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-05 22:40:33 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_email_html_with_subject() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let input = fixtures_path().join("TEST_EMAIL_QUERY_PARAMS.html");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg(input)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("hello@example.org?subject=%5BHello%5D"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_email_markdown_with_subject() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let input = fixtures_path().join("TEST_EMAIL_QUERY_PARAMS.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg(input)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("hello@example.org?subject=%5BHello%5D"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
/// Test that a GitHub link can be checked without specifying the token.
|
2021-02-28 18:09:11 +00:00
|
|
|
#[test]
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
fn test_check_github_no_token() -> Result<()> {
|
|
|
|
|
test_json_output!(
|
|
|
|
|
"TEST_GITHUB.md",
|
|
|
|
|
MockResponseStats {
|
|
|
|
|
total: 1,
|
|
|
|
|
successful: 1,
|
|
|
|
|
..MockResponseStats::default()
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
2021-02-28 18:09:11 +00:00
|
|
|
|
2021-04-26 15:16:58 +00:00
|
|
|
/// Test unsupported URI schemes
|
|
|
|
|
#[test]
|
2023-03-10 21:36:45 +00:00
|
|
|
fn test_unsupported_uri_schemes_are_ignored() {
|
2021-07-04 23:35:36 +00:00
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_schemes_path = fixtures_path().join("TEST_SCHEMES.txt");
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
cmd.arg(test_schemes_path)
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg("file://")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2023-02-27 21:58:03 +00:00
|
|
|
.stdout(contains("3 Total"))
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("1 OK"))
|
|
|
|
|
.stdout(contains("1 Excluded"));
|
2021-04-26 15:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
2021-09-02 23:48:50 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_resolve_paths() {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let offline_dir = fixtures_path().join("offline");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--offline")
|
|
|
|
|
.arg("--base")
|
|
|
|
|
.arg(&offline_dir)
|
|
|
|
|
.arg(&offline_dir.join("index.html"))
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("3 Total"))
|
|
|
|
|
.stdout(contains("3 OK"));
|
2021-09-02 23:48:50 +00:00
|
|
|
}
|
|
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
#[test]
|
2023-03-02 16:26:00 +00:00
|
|
|
fn test_youtube_quirk() {
|
|
|
|
|
let url = "https://www.youtube.com/watch?v=NlKuICiT470&list=PLbWDhxwM_45mPVToqaIZNbZeIzFchsKKQ&index=7";
|
|
|
|
|
|
2023-03-02 16:11:26 +00:00
|
|
|
main_command()
|
2023-03-02 16:26:00 +00:00
|
|
|
.write_stdin(url)
|
2023-03-02 16:11:26 +00:00
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--no-progress")
|
2023-03-02 16:26:00 +00:00
|
|
|
.arg("-")
|
2023-03-02 16:11:26 +00:00
|
|
|
.assert()
|
|
|
|
|
.success()
|
2023-03-02 16:26:00 +00:00
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_cratesio_quirk() {
|
|
|
|
|
let url = "https://crates.io/crates/lychee";
|
|
|
|
|
|
|
|
|
|
main_command()
|
|
|
|
|
.write_stdin(url)
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--no-progress")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[ignore = "Twitter quirk works locally but is flaky on Github (timeout)"]
|
|
|
|
|
fn test_twitter_quirk() {
|
|
|
|
|
let url = "https://twitter.com/zarfeblong/status/1339742840142872577";
|
|
|
|
|
|
|
|
|
|
main_command()
|
|
|
|
|
.write_stdin(url)
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--no-progress")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
2021-02-28 18:09:11 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-02 22:28:37 +00:00
|
|
|
#[tokio::test]
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
async fn test_failure_404_link() -> Result<()> {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::NOT_FOUND);
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
2020-12-02 22:28:37 +00:00
|
|
|
let file_path = dir.path().join("test.txt");
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mut file = File::create(&file_path)?;
|
|
|
|
|
writeln!(file, "{}", mock_server.uri())?;
|
2020-10-26 22:31:31 +00:00
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mut cmd = main_command();
|
2020-12-02 22:28:37 +00:00
|
|
|
cmd.arg(file_path)
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.code(2);
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
2020-10-26 22:31:31 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-26 16:24:54 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_schemes() {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_schemes_path = fixtures_path().join("TEST_SCHEMES.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg(test_schemes_path)
|
|
|
|
|
.arg("--scheme")
|
|
|
|
|
.arg("https")
|
|
|
|
|
.arg("--scheme")
|
|
|
|
|
.arg("http")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("3 Total"))
|
|
|
|
|
.stdout(contains("2 OK"))
|
|
|
|
|
.stdout(contains("1 Excluded"));
|
2021-04-26 16:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
2021-05-04 11:28:39 +00:00
|
|
|
#[test]
|
2021-10-07 16:07:18 +00:00
|
|
|
fn test_caching_single_file() {
|
2021-05-04 11:28:39 +00:00
|
|
|
let mut cmd = main_command();
|
2021-10-07 16:07:18 +00:00
|
|
|
// Repetitions in one file shall all be checked and counted only once.
|
|
|
|
|
let test_schemes_path_1 = fixtures_path().join("TEST_REPETITION_1.txt");
|
2021-05-04 11:28:39 +00:00
|
|
|
|
2021-10-07 16:07:18 +00:00
|
|
|
cmd.arg(&test_schemes_path_1)
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
2021-10-07 16:07:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
// Test that two identical requests don't get executed twice.
|
2022-01-14 14:25:51 +00:00
|
|
|
fn test_caching_across_files() -> Result<()> {
|
|
|
|
|
// Repetitions across multiple files shall all be checked only once.
|
|
|
|
|
let repeated_uris = fixtures_path().join("TEST_REPETITION_*.txt");
|
2021-10-07 16:07:18 +00:00
|
|
|
|
2022-01-14 14:25:51 +00:00
|
|
|
test_json_output!(
|
|
|
|
|
repeated_uris,
|
|
|
|
|
MockResponseStats {
|
|
|
|
|
total: 2,
|
|
|
|
|
cached: 1,
|
|
|
|
|
successful: 2,
|
|
|
|
|
excludes: 0,
|
|
|
|
|
..MockResponseStats::default()
|
|
|
|
|
},
|
|
|
|
|
// Two requests to the same URI may be executed in parallel. As a
|
|
|
|
|
// result, the response might not be cached and the test would be
|
|
|
|
|
// flaky. Therefore limit the concurrency to one request at a time.
|
|
|
|
|
"--max-concurrency",
|
|
|
|
|
"1"
|
|
|
|
|
)
|
2021-05-04 11:28:39 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-26 22:31:31 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_failure_github_404_no_token() {
|
2020-12-02 22:28:37 +00:00
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_github_404_path = fixtures_path().join("TEST_GITHUB_404.md");
|
2020-10-26 22:31:31 +00:00
|
|
|
|
|
|
|
|
cmd.arg(test_github_404_path)
|
2021-02-21 16:19:32 +00:00
|
|
|
.arg("--no-progress")
|
2020-11-24 20:30:06 +00:00
|
|
|
.env_clear()
|
2020-10-26 22:31:31 +00:00
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.code(2)
|
2022-03-03 09:04:55 +00:00
|
|
|
.stdout(contains(
|
2023-02-26 19:12:50 +00:00
|
|
|
"✗ [404] https://github.com/mre/idiomatic-rust-doesnt-exist-man | Failed: Network error: Not Found"
|
2022-03-03 09:04:55 +00:00
|
|
|
))
|
|
|
|
|
.stdout(contains(
|
|
|
|
|
"There were issues with Github URLs. You could try setting a Github token and running lychee again.",
|
|
|
|
|
));
|
2020-10-26 22:31:31 +00:00
|
|
|
}
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_stdin_input() {
|
|
|
|
|
let mut cmd = main_command();
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
cmd.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_stdin_input_failure() {
|
|
|
|
|
let mut cmd = main_command();
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server = mock_server!(StatusCode::INTERNAL_SERVER_ERROR);
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
cmd.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.code(2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_stdin_input_multiple() {
|
|
|
|
|
let mut cmd = main_command();
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server_a = mock_server!(StatusCode::OK);
|
|
|
|
|
let mock_server_b = mock_server!(StatusCode::OK);
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
// this behavior (treating multiple `-` as separate inputs) is the same as most CLI tools
|
|
|
|
|
// that accept `-` as stdin, e.g. `cat`, `bat`, `grep` etc.
|
|
|
|
|
cmd.arg("-")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server_a.uri())
|
|
|
|
|
.write_stdin(mock_server_b.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_missing_file_ok_if_skip_missing() {
|
|
|
|
|
let mut cmd = main_command();
|
2021-11-17 23:44:48 +00:00
|
|
|
let filename = format!("non-existing-file-{}", uuid::Uuid::new_v4());
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
cmd.arg(&filename).arg("--skip-missing").assert().success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_glob() -> Result<()> {
|
|
|
|
|
// using Result to be able to use `?`
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server_a = mock_server!(StatusCode::OK);
|
|
|
|
|
let mock_server_b = mock_server!(StatusCode::OK);
|
2020-12-02 22:28:37 +00:00
|
|
|
let mut file_a = File::create(dir.path().join("a.md"))?;
|
|
|
|
|
let mut file_b = File::create(dir.path().join("b.md"))?;
|
|
|
|
|
|
|
|
|
|
writeln!(file_a, "{}", mock_server_a.uri().as_str())?;
|
|
|
|
|
writeln!(file_b, "{}", mock_server_b.uri().as_str())?;
|
|
|
|
|
|
|
|
|
|
cmd.arg(dir.path().join("*.md"))
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("2 Total"));
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")] // MacOS and Windows have case-insensitive filesystems
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_glob_ignore_case() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server_a = mock_server!(StatusCode::OK);
|
|
|
|
|
let mock_server_b = mock_server!(StatusCode::OK);
|
2020-12-02 22:28:37 +00:00
|
|
|
let mut file_a = File::create(dir.path().join("README.md"))?;
|
|
|
|
|
let mut file_b = File::create(dir.path().join("readme.md"))?;
|
|
|
|
|
|
|
|
|
|
writeln!(file_a, "{}", mock_server_a.uri().as_str())?;
|
|
|
|
|
writeln!(file_b, "{}", mock_server_b.uri().as_str())?;
|
|
|
|
|
|
|
|
|
|
cmd.arg(dir.path().join("[r]eadme.md"))
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--glob-ignore-case")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("2 Total"));
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_glob_recursive() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
|
|
|
|
let subdir_level_1 = tempfile::tempdir_in(&dir)?;
|
|
|
|
|
let subdir_level_2 = tempfile::tempdir_in(&subdir_level_1)?;
|
|
|
|
|
|
Major refactor of codebase (#208)
- The binary component and library component are separated as two
packages in the same workspace.
- `lychee` is the binary component, in `lychee-bin/*`.
- `lychee-lib` is the library component, in `lychee-lib/*`.
- Users can now install only the `lychee-lib`, instead of both
components, that would require fewer dependencies and faster
compilation.
- Dependencies for each component are adjusted and updated. E.g.,
no CLI dependencies for `lychee-lib`.
- CLI tests are only moved to `lychee`, as it has nothing to do
with the library component.
- `Status::Error` is refactored to contain dedicated error enum,
`ErrorKind`.
- The motivation is to delay the formatting of errors to strings.
Note that `e.to_string()` is not necessarily cheap (though
trivial in many cases). The formatting is no delayed until the
error is needed to be displayed to users. So in some cases, if
the error is never used, it means that it won't be formatted at
all.
- Replaced `regex` based matching with one of the following:
- Simple string equality test in the case of 'false positivie'.
- URL parsing based test, in the case of extracting repository and
user name for GitHub links.
- Either cases would be much more efficient than `regex` based
matching. First, there's no need to construct a state machine for
regex. Second, URL is already verified and parsed on its creation,
and extracting its components is fairly cheap. Also, this removes
the dependency on `lazy-static` in `lychee-lib`.
- `types` module now has a sub-directory, and its components are now
separated into their own modules (in that sub-directory).
- `lychee-lib::test_utils` module is only compiled for tests.
- `wiremock` is moved to `dev-dependency` as it's only needed for
`test` modules.
- Dependencies are listed in alphabetical order.
- Imports are organized in the following fashion:
- Imports from `std`
- Imports from 3rd-party crates, and `lychee-lib`.
- Imports from `crate::*` or `super::*`.
- No glob import.
- I followed suggestion from `cargo clippy`, with `clippy::all` and
`clippy:pedantic`.
Co-authored-by: Lucius Hu <lebensterben@users.noreply.github.com>
2021-04-14 23:24:11 +00:00
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
2020-12-02 22:28:37 +00:00
|
|
|
let mut file = File::create(subdir_level_2.path().join("test.md"))?;
|
|
|
|
|
|
|
|
|
|
writeln!(file, "{}", mock_server.uri().as_str())?;
|
|
|
|
|
|
|
|
|
|
// ** should be a recursive glob
|
|
|
|
|
cmd.arg(dir.path().join("**/*.md"))
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("1 Total"));
|
2020-12-02 22:28:37 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2020-12-14 00:15:14 +00:00
|
|
|
|
|
|
|
|
/// Test formatted file output
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_formatted_file_output() -> Result<()> {
|
2023-05-05 22:47:32 +00:00
|
|
|
test_json_output!(
|
|
|
|
|
"TEST.md",
|
|
|
|
|
MockResponseStats {
|
|
|
|
|
total: 11,
|
|
|
|
|
successful: 11,
|
|
|
|
|
..MockResponseStats::default()
|
|
|
|
|
}
|
|
|
|
|
)
|
2020-12-14 00:15:14 +00:00
|
|
|
}
|
2021-09-01 15:37:31 +00:00
|
|
|
|
2022-11-07 23:33:16 +00:00
|
|
|
/// Test writing output of `--dump` command to file
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_dump_to_file() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST.md");
|
|
|
|
|
let outfile = format!("{}", Uuid::new_v4());
|
|
|
|
|
|
|
|
|
|
cmd.arg("--output")
|
|
|
|
|
.arg(&outfile)
|
|
|
|
|
.arg("--dump")
|
|
|
|
|
.arg(test_path)
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
|
|
|
|
|
let output = fs::read_to_string(&outfile)?;
|
|
|
|
|
|
|
|
|
|
// We expect 11 links in the test file
|
|
|
|
|
// Running the command from the command line will print 9 links,
|
|
|
|
|
// because the actual `--dump` command filters out the two
|
|
|
|
|
// http(s)://example.com links
|
|
|
|
|
assert_eq!(output.lines().count(), 11);
|
|
|
|
|
fs::remove_file(outfile)?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-01 15:37:31 +00:00
|
|
|
/// Test excludes
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_exclude_wildcard() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg(test_path)
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg(".*")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("11 Excluded"));
|
2021-09-01 15:37:31 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_exclude_multiple_urls() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg(test_path)
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg("https://en.wikipedia.org/*")
|
|
|
|
|
.arg("https://ldra.com/")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("2 Excluded"));
|
2021-09-01 15:37:31 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_exclude_file() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST.md");
|
|
|
|
|
let excludes_path = fixtures_path().join("TEST_EXCLUDE_1.txt");
|
|
|
|
|
|
|
|
|
|
cmd.arg(test_path)
|
|
|
|
|
.arg("--exclude-file")
|
|
|
|
|
.arg(excludes_path)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("2 Excluded"));
|
2021-09-01 15:37:31 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
2021-09-03 00:12:03 +00:00
|
|
|
}
|
2021-09-01 15:37:31 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_multiple_exclude_files() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST.md");
|
|
|
|
|
let excludes_path1 = fixtures_path().join("TEST_EXCLUDE_1.txt");
|
|
|
|
|
let excludes_path2 = fixtures_path().join("TEST_EXCLUDE_2.txt");
|
|
|
|
|
|
|
|
|
|
cmd.arg(test_path)
|
|
|
|
|
.arg("--exclude-file")
|
|
|
|
|
.arg(excludes_path1)
|
2023-02-26 21:38:49 +00:00
|
|
|
.arg("--exclude-file")
|
2021-09-01 15:37:31 +00:00
|
|
|
.arg(excludes_path2)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("3 Excluded"));
|
2021-09-01 15:37:31 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
2021-09-03 00:12:03 +00:00
|
|
|
}
|
2021-09-04 01:21:54 +00:00
|
|
|
|
2022-02-07 22:17:50 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_empty_config() -> Result<()> {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
|
|
|
|
let config = fixtures_path().join("configs").join("empty.toml");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg(config)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_cache_config() -> Result<()> {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
|
|
|
|
let config = fixtures_path().join("configs").join("cache.toml");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg(config)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_invalid_config() {
|
|
|
|
|
let config = fixtures_path().join("configs").join("invalid.toml");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg(config)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.failure();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 19:55:22 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_missing_config_error() {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg("config.does.not.exist.toml")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.failure();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_config_example() {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
|
|
|
|
let config = root_path().join("lychee.example.toml");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg(config)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 17:05:27 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_config_smoketest() {
|
|
|
|
|
let mock_server = mock_server!(StatusCode::OK);
|
|
|
|
|
let config = fixtures_path().join("configs").join("smoketest.toml");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--config")
|
|
|
|
|
.arg(config)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-23 00:39:53 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_lycheeignore_file() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("ignore");
|
|
|
|
|
|
2022-05-13 16:51:58 +00:00
|
|
|
let cmd = cmd
|
|
|
|
|
.current_dir(test_path)
|
|
|
|
|
.arg("--dump")
|
2021-11-23 00:39:53 +00:00
|
|
|
.arg("TEST.md")
|
|
|
|
|
.assert()
|
2022-05-13 16:51:58 +00:00
|
|
|
.stdout(contains("https://example.com"))
|
|
|
|
|
.stdout(contains("https://example.com/bar"))
|
|
|
|
|
.stdout(contains("https://example.net"));
|
|
|
|
|
|
|
|
|
|
let output = cmd.get_output();
|
|
|
|
|
let output = std::str::from_utf8(&output.stdout).unwrap();
|
|
|
|
|
assert_eq!(output.lines().count(), 3);
|
2021-11-23 00:39:53 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_lycheeignore_and_exclude_file() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("ignore");
|
|
|
|
|
let excludes_path = test_path.join("normal-exclude-file");
|
|
|
|
|
|
|
|
|
|
cmd.current_dir(test_path)
|
|
|
|
|
.arg("TEST.md")
|
|
|
|
|
.arg("--exclude-file")
|
|
|
|
|
.arg(excludes_path)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2022-05-13 16:51:58 +00:00
|
|
|
.stdout(contains("8 Total"))
|
2022-02-18 09:29:49 +00:00
|
|
|
.stdout(contains("6 Excluded"));
|
2021-11-23 00:39:53 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-15 20:45:24 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_lycheecache_file() -> Result<()> {
|
|
|
|
|
let base_path = fixtures_path().join("cache");
|
2022-07-17 16:40:45 +00:00
|
|
|
let cache_file = base_path.join(LYCHEE_CACHE_FILE);
|
|
|
|
|
|
|
|
|
|
// Unconditionally remove cache file if it exists
|
|
|
|
|
let _ = fs::remove_file(&cache_file);
|
2022-07-15 20:45:24 +00:00
|
|
|
|
|
|
|
|
let mock_server_ok = mock_server!(StatusCode::OK);
|
|
|
|
|
let mock_server_err = mock_server!(StatusCode::NOT_FOUND);
|
|
|
|
|
let mock_server_exclude = mock_server!(StatusCode::OK);
|
|
|
|
|
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
|
|
|
|
let mut file = File::create(dir.path().join("c.md"))?;
|
|
|
|
|
|
|
|
|
|
writeln!(file, "{}", mock_server_ok.uri().as_str())?;
|
|
|
|
|
writeln!(file, "{}", mock_server_err.uri().as_str())?;
|
|
|
|
|
writeln!(file, "{}", mock_server_exclude.uri().as_str())?;
|
|
|
|
|
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_cmd = cmd
|
|
|
|
|
.current_dir(&base_path)
|
|
|
|
|
.arg(dir.path().join("c.md"))
|
|
|
|
|
.arg("--verbose")
|
2023-02-27 20:36:39 +00:00
|
|
|
.arg("--no-progress")
|
2022-07-15 20:45:24 +00:00
|
|
|
.arg("--cache")
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg(mock_server_exclude.uri());
|
|
|
|
|
|
|
|
|
|
assert!(
|
|
|
|
|
!cache_file.exists(),
|
|
|
|
|
"cache file should not exist before this test"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// run first without cache to generate the cache file
|
|
|
|
|
test_cmd
|
|
|
|
|
.assert()
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!("[200] {}/\n", mock_server_ok.uri())))
|
|
|
|
|
.stderr(contains(format!(
|
2023-02-27 20:36:39 +00:00
|
|
|
"[404] {}/ | Failed: Network error: Not Found\n",
|
2022-07-15 20:45:24 +00:00
|
|
|
mock_server_err.uri()
|
|
|
|
|
)));
|
|
|
|
|
|
2022-07-17 16:40:45 +00:00
|
|
|
// check content of cache file
|
2022-07-15 20:45:24 +00:00
|
|
|
let data = fs::read_to_string(&cache_file)?;
|
|
|
|
|
assert!(data.contains(&format!("{}/,200", mock_server_ok.uri())));
|
|
|
|
|
assert!(data.contains(&format!("{}/,404", mock_server_err.uri())));
|
|
|
|
|
|
|
|
|
|
// run again to verify cache behavior
|
|
|
|
|
test_cmd
|
|
|
|
|
.assert()
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!(
|
2023-02-27 20:36:39 +00:00
|
|
|
"[200] {}/ | Cached: OK (cached)\n",
|
2022-07-15 20:45:24 +00:00
|
|
|
mock_server_ok.uri()
|
|
|
|
|
)))
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!(
|
2023-02-27 20:36:39 +00:00
|
|
|
"[404] {}/ | Cached: Error (cached)\n",
|
2022-07-15 20:45:24 +00:00
|
|
|
mock_server_err.uri()
|
|
|
|
|
)));
|
|
|
|
|
|
|
|
|
|
// clear the cache file
|
|
|
|
|
fs::remove_file(&cache_file)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-28 11:23:07 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_lycheecache_accept_custom_status_codes() -> Result<()> {
|
2023-02-27 22:27:29 +00:00
|
|
|
let base_path = fixtures_path().join("cache_accept_custom_status_codes");
|
2022-11-28 11:23:07 +00:00
|
|
|
let cache_file = base_path.join(LYCHEE_CACHE_FILE);
|
|
|
|
|
|
|
|
|
|
// Unconditionally remove cache file if it exists
|
|
|
|
|
let _ = fs::remove_file(&cache_file);
|
|
|
|
|
|
|
|
|
|
let mock_server_ok = mock_server!(StatusCode::OK);
|
|
|
|
|
let mock_server_teapot = mock_server!(StatusCode::IM_A_TEAPOT);
|
|
|
|
|
let mock_server_server_error = mock_server!(StatusCode::INTERNAL_SERVER_ERROR);
|
|
|
|
|
|
|
|
|
|
let dir = tempfile::tempdir()?;
|
|
|
|
|
let mut file = File::create(dir.path().join("c.md"))?;
|
|
|
|
|
|
|
|
|
|
writeln!(file, "{}", mock_server_ok.uri().as_str())?;
|
|
|
|
|
writeln!(file, "{}", mock_server_teapot.uri().as_str())?;
|
|
|
|
|
writeln!(file, "{}", mock_server_server_error.uri().as_str())?;
|
|
|
|
|
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_cmd = cmd
|
|
|
|
|
.current_dir(&base_path)
|
|
|
|
|
.arg(dir.path().join("c.md"))
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--cache");
|
|
|
|
|
|
|
|
|
|
assert!(
|
|
|
|
|
!cache_file.exists(),
|
|
|
|
|
"cache file should not exist before this test"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// run first without cache to generate the cache file
|
|
|
|
|
// ignore exit code
|
|
|
|
|
test_cmd
|
|
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.code(2)
|
|
|
|
|
.stdout(contains(format!(
|
2023-04-11 21:43:33 +00:00
|
|
|
"[418] {}/ | Failed: Network error: I\'m a teapot",
|
2022-11-28 11:23:07 +00:00
|
|
|
mock_server_teapot.uri()
|
|
|
|
|
)))
|
|
|
|
|
.stdout(contains(format!(
|
2023-04-11 21:43:33 +00:00
|
|
|
"[500] {}/ | Failed: Network error: Internal Server Error",
|
2022-11-28 11:23:07 +00:00
|
|
|
mock_server_server_error.uri()
|
|
|
|
|
)));
|
|
|
|
|
|
|
|
|
|
// check content of cache file
|
|
|
|
|
let data = fs::read_to_string(&cache_file)?;
|
|
|
|
|
assert!(data.contains(&format!("{}/,200", mock_server_ok.uri())));
|
|
|
|
|
assert!(data.contains(&format!("{}/,418", mock_server_teapot.uri())));
|
|
|
|
|
assert!(data.contains(&format!("{}/,500", mock_server_server_error.uri())));
|
|
|
|
|
|
|
|
|
|
// run again to verify cache behavior
|
|
|
|
|
// this time accept 418 and 500 as valid status codes
|
|
|
|
|
test_cmd
|
|
|
|
|
.arg("--no-progress")
|
|
|
|
|
.arg("--accept")
|
2023-02-22 23:25:53 +00:00
|
|
|
.arg("418,500")
|
2022-11-28 11:23:07 +00:00
|
|
|
.assert()
|
|
|
|
|
.success()
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!(
|
|
|
|
|
"[418] {}/ | Cached: OK (cached)",
|
2022-11-28 11:23:07 +00:00
|
|
|
mock_server_teapot.uri()
|
|
|
|
|
)))
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!(
|
|
|
|
|
"[500] {}/ | Cached: OK (cached)",
|
2022-11-28 11:23:07 +00:00
|
|
|
mock_server_server_error.uri()
|
|
|
|
|
)));
|
|
|
|
|
|
|
|
|
|
// clear the cache file
|
|
|
|
|
fs::remove_file(&cache_file)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 22:27:29 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_skip_cache_unsupported() -> Result<()> {
|
|
|
|
|
let base_path = fixtures_path().join("cache");
|
|
|
|
|
let cache_file = base_path.join(LYCHEE_CACHE_FILE);
|
|
|
|
|
|
|
|
|
|
// Unconditionally remove cache file if it exists
|
|
|
|
|
let _ = fs::remove_file(&cache_file);
|
|
|
|
|
|
|
|
|
|
let unsupported_url = "slack://user".to_string();
|
|
|
|
|
let excluded_url = "https://example.com/";
|
|
|
|
|
|
|
|
|
|
// run first without cache to generate the cache file
|
|
|
|
|
main_command()
|
|
|
|
|
.current_dir(&base_path)
|
|
|
|
|
.write_stdin(format!("{unsupported_url}\n{excluded_url}"))
|
|
|
|
|
.arg("--cache")
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--no-progress")
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg(excluded_url)
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.assert()
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!(
|
2023-03-10 21:36:45 +00:00
|
|
|
"[IGNORED] {unsupported_url} | Unsupported: Error creating request client"
|
2023-02-27 22:27:29 +00:00
|
|
|
)))
|
2023-04-11 21:43:33 +00:00
|
|
|
.stderr(contains(format!("[EXCLUDED] {excluded_url} | Excluded\n")));
|
2023-02-27 22:27:29 +00:00
|
|
|
|
|
|
|
|
// The cache file should be empty, because the only checked URL is
|
|
|
|
|
// unsupported and we don't want to cache that. It might be supported in
|
|
|
|
|
// future versions.
|
|
|
|
|
let buf = fs::read(&cache_file).unwrap();
|
|
|
|
|
assert!(buf.is_empty());
|
|
|
|
|
|
|
|
|
|
// clear the cache file
|
|
|
|
|
fs::remove_file(&cache_file)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-02 00:46:20 +00:00
|
|
|
/// Unknown status codes should be skipped and not cached by default
|
|
|
|
|
/// The reason is that we don't know if they are valid or not
|
|
|
|
|
/// and even if they are invalid, we don't know if they will be valid in the
|
|
|
|
|
/// future.
|
|
|
|
|
///
|
|
|
|
|
/// Since we cannot test this with our mock server (because hyper panics on invalid status codes)
|
|
|
|
|
/// we use LinkedIn as a test target.
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_skip_cache_unknown_status_code() -> Result<()> {
|
|
|
|
|
let base_path = fixtures_path().join("cache");
|
|
|
|
|
let cache_file = base_path.join(LYCHEE_CACHE_FILE);
|
|
|
|
|
|
|
|
|
|
// Unconditionally remove cache file if it exists
|
|
|
|
|
let _ = fs::remove_file(&cache_file);
|
|
|
|
|
|
|
|
|
|
// https://linkedin.com returns 999 for unknown status codes
|
|
|
|
|
// use this as a test target
|
|
|
|
|
let unknown_url = "https://www.linkedin.com/company/corrode";
|
|
|
|
|
|
|
|
|
|
// run first without cache to generate the cache file
|
|
|
|
|
main_command()
|
|
|
|
|
.current_dir(&base_path)
|
|
|
|
|
.write_stdin(unknown_url.to_string())
|
|
|
|
|
.arg("--cache")
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--no-progress")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.assert()
|
|
|
|
|
.stderr(contains(format!("[999] {unknown_url} | Unknown status")));
|
|
|
|
|
|
|
|
|
|
// The cache file should be empty, because the only checked URL is
|
|
|
|
|
// unsupported and we don't want to cache that. It might be supported in
|
|
|
|
|
// future versions.
|
|
|
|
|
let buf = fs::read(&cache_file).unwrap();
|
|
|
|
|
assert!(buf.is_empty());
|
|
|
|
|
|
|
|
|
|
// clear the cache file
|
|
|
|
|
fs::remove_file(&cache_file)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_verbatim_skipped_by_default() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let input = fixtures_path().join("TEST_CODE_BLOCKS.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg(input)
|
|
|
|
|
.arg("--dump")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(is_empty());
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-26 09:42:56 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_include_verbatim() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let input = fixtures_path().join("TEST_CODE_BLOCKS.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--include-verbatim")
|
|
|
|
|
.arg(input)
|
|
|
|
|
.arg("--dump")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("http://127.0.0.1/block"))
|
|
|
|
|
.stdout(contains("http://127.0.0.1/inline"))
|
|
|
|
|
.stdout(contains("http://127.0.0.1/bash"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2023-03-11 14:18:25 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_verbatim_skipped_by_default_via_file() -> Result<()> {
|
|
|
|
|
let file = fixtures_path().join("TEST_VERBATIM.html");
|
|
|
|
|
|
|
|
|
|
main_command()
|
|
|
|
|
.arg("--dump")
|
|
|
|
|
.arg(file)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(is_empty());
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-03-26 09:42:56 +00:00
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_verbatim_skipped_by_default_via_remote_url() -> Result<()> {
|
2022-03-26 09:42:56 +00:00
|
|
|
let mut cmd = main_command();
|
2023-01-03 23:38:19 +00:00
|
|
|
let file = fixtures_path().join("TEST_VERBATIM.html");
|
|
|
|
|
let body = fs::read_to_string(file)?;
|
|
|
|
|
let mock_server = mock_response!(body);
|
2022-03-26 09:42:56 +00:00
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg(mock_server.uri())
|
2022-03-26 09:42:56 +00:00
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(is_empty());
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-03 23:38:19 +00:00
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_include_verbatim_via_remote_url() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let file = fixtures_path().join("TEST_VERBATIM.html");
|
|
|
|
|
let body = fs::read_to_string(file)?;
|
|
|
|
|
let mock_server = mock_response!(body);
|
|
|
|
|
|
|
|
|
|
cmd.arg("--include-verbatim")
|
|
|
|
|
.arg("--dump")
|
|
|
|
|
.arg(mock_server.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("http://www.example.com/pre"))
|
|
|
|
|
.stdout(contains("http://www.example.com/code"))
|
|
|
|
|
.stdout(contains("http://www.example.com/samp"))
|
|
|
|
|
.stdout(contains("http://www.example.com/kbd"))
|
|
|
|
|
.stdout(contains("http://www.example.com/var"))
|
|
|
|
|
.stdout(contains("http://www.example.com/script"));
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-04 01:21:54 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_require_https() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let test_path = fixtures_path().join("TEST_HTTP.html");
|
|
|
|
|
cmd.arg(&test_path).assert().success();
|
|
|
|
|
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
cmd.arg("--require-https").arg(test_path).assert().failure();
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2021-09-20 09:13:30 +00:00
|
|
|
|
|
|
|
|
/// If base-dir is not set, don't throw an error in case we encounter
|
|
|
|
|
/// an absolute local link within a file (e.g. `/about`).
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_ignore_absolute_local_links_without_base() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
let offline_dir = fixtures_path().join("offline");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--offline")
|
|
|
|
|
.arg(&offline_dir.join("index.html"))
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
2021-11-17 23:44:48 +00:00
|
|
|
.stdout(contains("0 Total"));
|
2021-09-20 09:13:30 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-03-27 00:27:27 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_inputs_without_scheme() -> Result<()> {
|
|
|
|
|
let test_path = fixtures_path().join("TEST_HTTP.html");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("example.com")
|
|
|
|
|
.arg(&test_path)
|
|
|
|
|
.arg("https://example.org")
|
|
|
|
|
.assert()
|
|
|
|
|
.success();
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-05-13 16:53:16 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_print_excluded_links_in_verbose_mode() -> Result<()> {
|
|
|
|
|
let test_path = fixtures_path().join("TEST_DUMP_EXCLUDE.txt");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--exclude")
|
2022-05-29 19:41:22 +00:00
|
|
|
.arg("example.com")
|
2022-05-13 16:53:16 +00:00
|
|
|
.arg("--")
|
|
|
|
|
.arg(&test_path)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains(format!(
|
|
|
|
|
"https://example.com/ ({}) [excluded]",
|
|
|
|
|
test_path.display()
|
|
|
|
|
)))
|
|
|
|
|
.stdout(contains(format!(
|
|
|
|
|
"https://example.org/ ({})",
|
|
|
|
|
test_path.display()
|
|
|
|
|
)))
|
|
|
|
|
.stdout(contains(format!(
|
|
|
|
|
"https://example.com/foo/bar ({}) [excluded]",
|
|
|
|
|
test_path.display()
|
|
|
|
|
)));
|
2022-05-29 19:41:22 +00:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_remap_uri() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("--remap")
|
|
|
|
|
.arg("https://example.com http://127.0.0.1:8080")
|
|
|
|
|
.arg("--remap")
|
|
|
|
|
.arg("https://example.org https://staging.example.com")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
2023-02-27 20:22:43 +00:00
|
|
|
.write_stdin("https://example.com\nhttps://example.org\nhttps://example.net\n")
|
2022-05-29 19:41:22 +00:00
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("http://127.0.0.1:8080/"))
|
|
|
|
|
.stdout(contains("https://staging.example.com/"))
|
|
|
|
|
.stdout(contains("https://example.net/"));
|
2022-05-13 16:53:16 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-05-29 15:27:09 +00:00
|
|
|
|
2023-02-27 20:22:43 +00:00
|
|
|
#[test]
|
|
|
|
|
#[ignore = "Skipping test until https://github.com/robinst/linkify/pull/58 is merged"]
|
|
|
|
|
fn test_remap_path() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("--remap")
|
|
|
|
|
.arg("../../issues https://github.com/usnistgov/OSCAL/issues")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin("../../issues\n")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("https://github.com/usnistgov/OSCAL/issues"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 13:05:19 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_remap_capture() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("--remap")
|
|
|
|
|
.arg("https://example.com/(.*) http://example.org/$1")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin("https://example.com/foo\n")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("http://example.org/foo"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_remap_named_capture() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--dump")
|
|
|
|
|
.arg("--remap")
|
|
|
|
|
.arg("https://github.com/(?P<org>.*)/(?P<repo>.*) https://gitlab.com/$org/$repo")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin("https://github.com/lycheeverse/lychee\n")
|
|
|
|
|
.env_clear()
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("https://gitlab.com/lycheeverse/lychee"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-29 15:27:09 +00:00
|
|
|
#[test]
|
|
|
|
|
fn test_excluded_paths() -> Result<()> {
|
|
|
|
|
let test_path = fixtures_path().join("exclude-path");
|
|
|
|
|
|
|
|
|
|
let excluded_path1 = test_path.join("dir1");
|
|
|
|
|
let excluded_path2 = test_path.join("dir2").join("subdir");
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.arg("--exclude-path")
|
|
|
|
|
.arg(&excluded_path1)
|
2023-02-26 13:28:07 +00:00
|
|
|
.arg("--exclude-path")
|
2022-05-29 15:27:09 +00:00
|
|
|
.arg(&excluded_path2)
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg(&test_path)
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
// Links in excluded files are not taken into account in the total
|
|
|
|
|
// number of links.
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-07-22 15:15:55 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_handle_relative_paths_as_input() -> Result<()> {
|
|
|
|
|
let test_path = fixtures_path();
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.current_dir(&test_path)
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg("example.*")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("./TEST_DUMP_EXCLUDE.txt")
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("3 Total"))
|
|
|
|
|
.stdout(contains("3 Excluded"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_handle_nonexistent_relative_paths_as_input() -> Result<()> {
|
|
|
|
|
let test_path = fixtures_path();
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
|
|
|
|
|
cmd.current_dir(&test_path)
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--exclude")
|
|
|
|
|
.arg("example.*")
|
|
|
|
|
.arg("--")
|
|
|
|
|
.arg("./NOT-A-REAL-TEST-FIXTURE.md")
|
|
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.stderr(contains(
|
|
|
|
|
"Cannot find local file ./NOT-A-REAL-TEST-FIXTURE.md",
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2023-03-10 14:15:37 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_prevent_too_many_redirects() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let url = "https://httpstat.us/308";
|
|
|
|
|
|
|
|
|
|
cmd.write_stdin(url)
|
|
|
|
|
.arg("--max-redirects")
|
|
|
|
|
.arg("0")
|
|
|
|
|
.arg("-")
|
|
|
|
|
.assert()
|
|
|
|
|
.failure();
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2023-05-11 18:20:27 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_suggests_url_alternatives() -> Result<()> {
|
|
|
|
|
let mut cmd = main_command();
|
|
|
|
|
let input = fixtures_path().join("INTERNET_ARCHIVE.md");
|
|
|
|
|
|
|
|
|
|
cmd.arg("--suggest")
|
|
|
|
|
.arg(input)
|
|
|
|
|
.assert()
|
|
|
|
|
.failure()
|
|
|
|
|
.code(2)
|
|
|
|
|
.stdout(contains("Suggestions"))
|
|
|
|
|
.stdout(contains("http://web.archive.org/web/"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2023-06-26 10:06:24 +00:00
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_basic_auth() -> Result<()> {
|
|
|
|
|
let username = "username";
|
|
|
|
|
let password = "password123";
|
|
|
|
|
|
|
|
|
|
let mock_server = wiremock::MockServer::start().await;
|
|
|
|
|
Mock::given(basic_auth(username, password))
|
|
|
|
|
.respond_with(ResponseTemplate::new(200))
|
|
|
|
|
.mount(&mock_server)
|
|
|
|
|
.await;
|
|
|
|
|
|
|
|
|
|
// Configure the command to use the BasicAuthExtractor
|
|
|
|
|
main_command()
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--basic-auth")
|
|
|
|
|
.arg(format!("{} {username}:{password}", mock_server.uri()))
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(mock_server.uri())
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("1 Total"))
|
|
|
|
|
.stdout(contains("1 OK"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn test_multi_basic_auth() -> Result<()> {
|
|
|
|
|
let username1 = "username";
|
|
|
|
|
let password1 = "password123";
|
|
|
|
|
let mock_server1 = wiremock::MockServer::start().await;
|
|
|
|
|
Mock::given(basic_auth(username1, password1))
|
|
|
|
|
.respond_with(ResponseTemplate::new(200))
|
|
|
|
|
.mount(&mock_server1)
|
|
|
|
|
.await;
|
|
|
|
|
|
|
|
|
|
let username2 = "admin_user";
|
|
|
|
|
let password2 = "admin_pw";
|
|
|
|
|
let mock_server2 = wiremock::MockServer::start().await;
|
|
|
|
|
|
|
|
|
|
Mock::given(basic_auth(username2, password2))
|
|
|
|
|
.respond_with(ResponseTemplate::new(200))
|
|
|
|
|
.mount(&mock_server2)
|
|
|
|
|
.await;
|
|
|
|
|
|
|
|
|
|
// Configure the command to use the BasicAuthExtractor
|
|
|
|
|
main_command()
|
|
|
|
|
.arg("--verbose")
|
|
|
|
|
.arg("--basic-auth")
|
|
|
|
|
.arg(format!("{} {username1}:{password1}", mock_server1.uri()))
|
|
|
|
|
.arg("--basic-auth")
|
|
|
|
|
.arg(format!("{} {username2}:{password2}", mock_server2.uri()))
|
|
|
|
|
.arg("-")
|
|
|
|
|
.write_stdin(format!("{}\n{}", mock_server1.uri(), mock_server2.uri()))
|
|
|
|
|
.assert()
|
|
|
|
|
.success()
|
|
|
|
|
.stdout(contains("2 Total"))
|
|
|
|
|
.stdout(contains("2 OK"));
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2020-10-17 08:01:06 +00:00
|
|
|
}
|