Skip to content

Commit

Permalink
fix(pact_verifier_cli): Allow transport base-paths to be defined from…
Browse files Browse the repository at this point in the history
… the CLI #418
  • Loading branch information
rholshausen committed Jul 8, 2024
1 parent a5ba0cb commit de31b4e
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 18 deletions.
44 changes: 38 additions & 6 deletions rust/Cargo.lock

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

2 changes: 2 additions & 0 deletions rust/pact_verifier_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ anyhow = "1.0.75"
clap = { version = "4.5.4", features = ["cargo", "env"] }
env_logger = "0.11.2"
junit-report = { version = "0.8.3", optional = true }
lazy_static = "1.5.0"
log = "0.4.20"
maplit = "1.0.2"
pact_models = { version = "~1.2.1", default-features = false }
Expand All @@ -44,4 +45,5 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter", "tracing-lo

[dev-dependencies]
expectest = "0.12.0"
rstest = "0.21.0"
trycmd = "0.15.0"
45 changes: 37 additions & 8 deletions rust/pact_verifier_cli/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::{Arg, ArgAction, ArgGroup, Command, command};
use clap::builder::{FalseyValueParser, NonEmptyStringValueParser, PossibleValuesParser};
use lazy_static::lazy_static;
use regex::Regex;

fn port_value(v: &str) -> Result<u16, String> {
Expand All @@ -20,14 +21,26 @@ fn validate_regex(val: &str) -> Result<String, String> {
}
}

fn transport_value(v: &str) -> Result<(String, u16), String> {
let (transport, port) = v.split_once(':')
.ok_or_else(|| format!("'{}' is not a valid transport, it must be in the form TRANSPORT:PORT", v))?;
if transport.is_empty() {
return Err(format!("'{}' is not a valid transport, the transport part is empty", v));
lazy_static! {
static ref TRANSPORT_VALUE_RE: Regex = Regex::new(r#"^(\w+):(\d+)(\/[^\s]*)?$"#).unwrap();
}

fn transport_value(v: &str) -> Result<(String, u16, Option<String>), String> {
if let Some(result) = TRANSPORT_VALUE_RE.captures(v) {
let transport = if let Some(transport) = result.get(1) {
transport.as_str().to_string()
} else {
return Err(format!("'{}' is not a valid transport, the transport part is empty", v));
};
let port = if let Some(port) = result.get(2) {
port.as_str().parse::<u16>().unwrap() // Ok to unwrap, the regex will only allow digits
} else {
return Err(format!("'{}' is not a valid transport, the port part is empty", v));
};
Ok((transport, port, result.get(3).map(|v| v.as_str().to_string())))
} else {
Err(format!("'{}' is not a valid transport, it must be in the form TRANSPORT:PORT[/path]", v))
}
port.parse::<u16>().map(|port| (transport.to_string(), port))
.map_err(|e| format!("'{}' is not a valid port value: {}", port, e) )
}

pub(crate) fn setup_app() -> Command {
Expand Down Expand Up @@ -334,6 +347,7 @@ pub(crate) fn setup_app() -> Command {
#[cfg(test)]
mod test {
use expectest::prelude::*;
use rstest::rstest;

use crate::args::setup_app;

Expand All @@ -354,12 +368,27 @@ mod test {

#[test]
fn validates_transport_value() {
expect!(transport_value("http:1234")).to(be_ok());
expect!(transport_value("http:1234")).to(be_ok().value(("http".to_string(), 1234, None)));
expect!(transport_value("1234x")).to(be_err());
expect!(transport_value(":1234")).to(be_err());
expect!(transport_value("x:")).to(be_err());
expect!(transport_value("x:x")).to(be_err());
expect!(transport_value("x:1234x")).to(be_err());
expect!(transport_value("x:1234/x")).to(be_ok());
expect!(transport_value("x:1234/p a t h")).to(be_err());
expect!(transport_value("x:1234/p-a%20t%20h")).to(be_ok());
}

#[rstest(
value, expected_value,
case("http:1234/", ("http".to_string(), 1234, Some("/".to_string()))),
case("http:1234/p", ("http".to_string(), 1234, Some("/p".to_string()))),
case("http:1234/p/", ("http".to_string(), 1234, Some("/p/".to_string()))),
case("http:1234/path/2", ("http".to_string(), 1234, Some("/path/2".to_string()))),
case("http:1234/path/2/s%20s", ("http".to_string(), 1234, Some("/path/2/s%20s".to_string())))
)]
fn validates_transport_value_with_path(value: &str, expected_value: (String, u16, Option<String>)) {
expect!(transport_value(value)).to(be_ok().value(expected_value));
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions rust/pact_verifier_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,14 +611,14 @@ fn setup_pretty_log(level: &str, coloured_output: bool) {

#[allow(deprecated)]
pub(crate) fn configure_provider(matches: &ArgMatches) -> ProviderInfo {
// It is ok to unwrap values here, as they have all been validated by the CLI
let transports = matches.get_many::<(String, u16)>("transports")
// It is ok to unwrap values here, as they have all been validated by the CLI parser
let transports = matches.get_many::<(String, u16, Option<String>)>("transports")
.map(|values| {
values.map(|(transport, port)| {
values.map(|(transport, port, base_path)| {
ProviderTransport {
transport: transport.to_string(),
port: Some(*port),
path: None,
path: base_path.clone(),
scheme: None
}
}).collect()
Expand Down

0 comments on commit de31b4e

Please sign in to comment.