Skip to content

Commit

Permalink
feat(pact_consumer): Improve output of mock server errors with ANSI c…
Browse files Browse the repository at this point in the history
…olour
  • Loading branch information
rholshausen committed Jul 11, 2024
1 parent cccd428 commit 57c0bc8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 32 deletions.
11 changes: 9 additions & 2 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion rust/pact_consumer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ exclude = [
]

[features]
default = ["datetime", "xml", "plugins", "multipart", "tls"]
default = ["datetime", "xml", "plugins", "multipart", "tls", "colour"]
datetime = ["pact_models/datetime", "pact_matching/datetime", "pact_mock_server/datetime", "pact-plugin-driver?/datetime"] # Support for date/time matchers and expressions
xml = ["pact_models/xml", "pact_matching/xml", "pact_mock_server/xml", "pact-plugin-driver?/xml"] # support for matching XML documents
plugins = ["dep:pact-plugin-driver", "pact_matching/plugins", "pact_mock_server/plugins"]
multipart = ["pact_matching/multipart", "pact_mock_server/multipart"] # suport for MIME multipart bodies
tls = ["pact_mock_server/tls"]
colour = ["dep:yansi"]

[dependencies]
anyhow = "1.0.82"
Expand All @@ -41,6 +42,7 @@ tracing = "0.1.40"
tracing-core = "0.1.32"
url = "2.5.0"
uuid = { version = "1.8.0", features = ["v4"] }
yansi = { version = "1.0.1", optional = true }

[dev-dependencies]
quickcheck = "1.0.3"
Expand Down
103 changes: 74 additions & 29 deletions rust/pact_consumer/src/mock_server/http_mock_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use pact_models::pact::Pact;
use tracing::{debug, warn};
use url::Url;
use uuid::Uuid;
#[cfg(feature = "colour")] use yansi::Paint;

use pact_matching::metrics::{MetricEvent, send_metrics};
use pact_mock_server::matching::MatchResult;
Expand Down Expand Up @@ -239,40 +240,84 @@ impl ValidatingHttpMockServer {
Ok(())
} else {
// Failure. Format our errors.
let size = termsize::get()
.map(|sz| if sz.cols > 2 { sz.cols - 2 } else { 0 })
.unwrap_or(78);
let pad = "-".repeat(size as usize);
let mut msg = format!(" {} \nMock server {} failed verification:\n", pad, self.description);
for mismatch in mismatches {
match mismatch {
MatchResult::RequestMatch(..) => {
warn!("list of mismatches contains a match");
}
MatchResult::RequestMismatch(request, _, mismatches) => {
let _ = writeln!(&mut msg, "\n - request {}:\n", request);
for m in mismatches {
let _ = writeln!(&mut msg, " - {}", m.description());
}
}
MatchResult::RequestNotFound(request) => {
let _ = writeln!(&mut msg, "\n - received unexpected request {}:\n", short_description(&request));
let debug_str = format!("{:#?}", request);
let _ = writeln!(&mut msg, "{}", debug_str.lines().map(|ln| format!(" {}", ln)).join("\n"));
Err(self.display_errors(mismatches))
}
}

#[cfg(feature = "colour")]
fn display_errors(&self, mismatches: Vec<MatchResult>) -> String {
let size = termsize::get()
.map(|sz| if sz.cols > 2 { sz.cols - 2 } else { 0 })
.unwrap_or(78);
let pad = "-".repeat(size as usize);
let mut msg = format!(" {} \nMock server {} failed verification:\n", pad, self.description.white().bold());
for mismatch in mismatches {
match mismatch {
MatchResult::RequestMatch(..) => {
warn!("list of mismatches contains a match");
}
MatchResult::RequestMismatch(request, _, mismatches) => {
let _ = writeln!(&mut msg, "\n - request {}:\n", request);
for m in mismatches {
let _ = writeln!(&mut msg, " - {}", m.description());
}
MatchResult::MissingRequest(request) => {
let _ = writeln!(
&mut msg,
"\n - request {} expected, but never occurred:\n", short_description(&request),
);
let debug_str = format!("{:#?}", request);
let _ = writeln!(&mut msg, "{}", debug_str.lines().map(|ln| format!(" {}", ln)).join("\n"));
}
MatchResult::RequestNotFound(request) => {
let _ = writeln!(&mut msg, "\n - received unexpected request {}:\n", short_description(&request).white().bold());
let debug_str = format!("{:#?}", request);
let debug_padded = debug_str.lines().map(|ln| format!(" {}", ln)).join("\n");
let _ = writeln!(&mut msg, "{}", debug_padded.italic());
}
MatchResult::MissingRequest(request) => {
let _ = writeln!(
&mut msg,
"\n - request {} expected, but never occurred:\n", short_description(&request).white().bold(),
);
let debug_str = format!("{:#?}", request);
let debug_padded = debug_str.lines().map(|ln| format!(" {}", ln)).join("\n");
let _ = writeln!(&mut msg, "{}", debug_padded.italic());
}
}
}
let _ = writeln!(&mut msg, " {} ", pad);
msg
}

#[cfg(not(feature = "colour"))]
fn display_errors(&self, mismatches: Vec<MatchResult>) -> String {
let size = termsize::get()
.map(|sz| if sz.cols > 2 { sz.cols - 2 } else { 0 })
.unwrap_or(78);
let pad = "-".repeat(size as usize);
let mut msg = format!(" {} \nMock server {} failed verification:\n", pad, self.description);
for mismatch in mismatches {
match mismatch {
MatchResult::RequestMatch(..) => {
warn!("list of mismatches contains a match");
}
MatchResult::RequestMismatch(request, _, mismatches) => {
let _ = writeln!(&mut msg, "\n - request {}:\n", request);
for m in mismatches {
let _ = writeln!(&mut msg, " - {}", m.description());
}
}
MatchResult::RequestNotFound(request) => {
let _ = writeln!(&mut msg, "\n - received unexpected request {}:\n", short_description(&request));
let debug_str = format!("{:#?}", request);
let _ = writeln!(&mut msg, "{}", debug_str.lines().map(|ln| format!(" {}", ln)).join("\n"));
}
MatchResult::MissingRequest(request) => {
let _ = writeln!(
&mut msg,
"\n - request {} expected, but never occurred:\n", short_description(&request),
);
let debug_str = format!("{:#?}", request);
let _ = writeln!(&mut msg, "{}", debug_str.lines().map(|ln| format!(" {}", ln)).join("\n"));
}
}
let _ = writeln!(&mut msg, " {} ", pad);
Err(msg)
}
let _ = writeln!(&mut msg, " {} ", pad);
msg
}
}

Expand Down

0 comments on commit 57c0bc8

Please sign in to comment.