Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions fixtures/double-count/home.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Navbar

* [Resource 1](resource-1.md)
* [Resource 2](resource-2.md)
* [Resource 3](resource-3.md)
5 changes: 5 additions & 0 deletions fixtures/double-count/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Navbar

* [Resource 1](resource-1.md)
* [Resource 2](resource-2.md)
* [Resource 3](resource-3.md)
1 change: 1 addition & 0 deletions fixtures/double-count/resource-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# First resource
1 change: 1 addition & 0 deletions fixtures/double-count/resource-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Second resource
1 change: 1 addition & 0 deletions fixtures/double-count/resource-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Third resource
3 changes: 2 additions & 1 deletion lychee-bin/src/formatters/stats/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ impl Display for CompactResponseStats {

color!(f, NORMAL, "🔍 {} Total", stats.total)?;
color!(f, DIM, " (in {})", format_duration(stats.duration))?;
color!(f, NORMAL, " 🔗 {} Unique", stats.unique)?;
color!(f, BOLD_GREEN, " ✅ {} OK", stats.successful)?;

let total_errors = stats.errors;
Expand Down Expand Up @@ -181,7 +182,7 @@ mod tests {
ℹ Suggestions
https://original.dev/ --> https://suggestion.dev/

🔍 2 Total (in 0s) ✅ 0 OK 🚫 1 Error ⏳ 1 Timeouts 🔀 1 Redirects
🔍 2 Total (in 0s) 🔗 2 Unique ✅ 0 OK 🚫 1 Error ⏳ 1 Timeouts 🔀 1 Redirects

📊 Per-host Statistics
────────────────────────────────────────────────────────────
Expand Down
2 changes: 2 additions & 0 deletions lychee-bin/src/formatters/stats/detailed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl Display for DetailedResponseStats {
writeln!(f, "📝 Summary")?;
writeln!(f, "{separator}")?;
write_stat(f, "🔍 Total", stats.total, true)?;
write_stat(f, "🔗 Unique", stats.unique, true)?;
write_stat(f, "✅ Successful", stats.successful, true)?;
write_stat(f, "⏳ Timeouts", stats.timeouts, true)?;
write_stat(f, "🔀 Redirected", stats.redirects, true)?;
Expand Down Expand Up @@ -136,6 +137,7 @@ mod tests {
"📝 Summary
---------------------
🔍 Total............2
🔗 Unique...........2
✅ Successful.......0
⏳ Timeouts.........1
🔀 Redirected.......1
Expand Down
1 change: 1 addition & 0 deletions lychee-bin/src/formatters/stats/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mod tests {

const EXPECTED_JSON: &str = r#"{
"total": 2,
"unique": 2,
"successful": 0,
"unknown": 0,
"unsupported": 0,
Expand Down
6 changes: 6 additions & 0 deletions lychee-bin/src/formatters/stats/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ fn stats_table(stats: &ResponseStats) -> String {
status: "🔍 Total",
count: stats.total,
},
StatsTableEntry {
status: "🔗 Unique",
count: stats.unique,
},
StatsTableEntry {
status: "✅ Successful",
count: stats.successful,
Expand Down Expand Up @@ -244,6 +248,7 @@ mod tests {
let expected = "| Status | Count |
|----------------|-------|
| 🔍 Total | 0 |
| 🔗 Unique | 0 |
| ✅ Successful | 0 |
| ⏳ Timeouts | 0 |
| 🔀 Redirected | 0 |
Expand All @@ -262,6 +267,7 @@ mod tests {
| Status | Count |
|----------------|-------|
| 🔍 Total | 2 |
| 🔗 Unique | 2 |
| ✅ Successful | 0 |
| ⏳ Timeouts | 1 |
| 🔀 Redirected | 1 |
Expand Down
2 changes: 2 additions & 0 deletions lychee-bin/src/formatters/stats/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ fn get_dummy_stats() -> OutputStats {

let response_stats = ResponseStats {
total: 2,
unique: 2,
successful: 0,
errors: 1,
unknown: 0,
Expand All @@ -189,6 +190,7 @@ fn get_dummy_stats() -> OutputStats {
excluded_map: HashMap::default(),
timeout_map,
detailed_stats: true,
seen_responses: HashSet::new(),
};

let host_stats = Some(HostStatsMap::from(HashMap::from([(
Expand Down
12 changes: 11 additions & 1 deletion lychee-bin/src/formatters/stats/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
time::Duration,
};

use lychee_lib::{CacheStatus, InputSource, Response, ResponseBody, Status};
use lychee_lib::{CacheStatus, InputSource, Response, ResponseBody, Status, Uri};
use serde::Serialize;

use crate::formatters::suggestion::Suggestion;
Expand All @@ -24,6 +24,8 @@ use crate::formatters::suggestion::Suggestion;
pub(crate) struct ResponseStats {
/// Total number of responses
pub(crate) total: usize,
/// Number of unique responses (i.e. responses with a unique URI)
pub(crate) unique: usize,
/// Number of successful responses
pub(crate) successful: usize,
/// Number of responses with an unknown status
Expand Down Expand Up @@ -56,6 +58,9 @@ pub(crate) struct ResponseStats {
pub(crate) duration: Duration,
/// Also track successful and excluded responses
pub(crate) detailed_stats: bool,
/// Set for counting unique responses
#[serde(skip)]
pub(crate) seen_responses: HashSet<Uri>,
}

impl ResponseStats {
Expand All @@ -65,6 +70,7 @@ impl ResponseStats {
pub(crate) fn extended() -> Self {
Self {
detailed_stats: true,
seen_responses: HashSet::new(),
..Default::default()
}
}
Expand Down Expand Up @@ -113,6 +119,10 @@ impl ResponseStats {

/// Update the stats with a new response
pub(crate) fn add(&mut self, response: Response) {
if self.seen_responses.insert(response.body().uri.clone()) {
self.unique += 1;
}

self.total += 1;
self.increment_status_counters(response.status());
self.add_response_status(response);
Expand Down
22 changes: 22 additions & 0 deletions lychee-bin/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3667,4 +3667,26 @@ https://lychee.cli.rs/guides/cli/#fragments-ignored
.assert()
.success();
}

#[test]
fn test_no_double_count() {
let test_file_1 = fixtures_path!().join("double-count/index.md");
let test_file_2 = fixtures_path!().join("double-count/home.md");

cargo_bin_cmd!()
.arg(&test_file_1)
.arg(&test_file_2)
.assert()
.success()
.stdout(contains("6 Total"))
.stdout(contains("3 Unique"));

cargo_bin_cmd!()
.arg("--dump")
.arg(&test_file_1)
.arg(&test_file_2)
.assert()
.success()
.stdout(contains("resource-1.md").count(2));
}
}