Skip to content

Commit

Permalink
refactor(cli): split up run_command fn (#177)
Browse files Browse the repository at this point in the history
* refactor(cli): move file logic to utility function

* refactor(cli): move variable parsing to utility fn
  • Loading branch information
hougesen authored Feb 12, 2024
1 parent 0c27949 commit 6a5d9a1
Showing 1 changed file with 150 additions and 20 deletions.
170 changes: 150 additions & 20 deletions hitt-cli/src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use crossterm::{style::Print, style::Stylize, QueueableCommand};
use hitt_parser::HittRequest;
use hitt_request::send_request;

use crate::{
Expand All @@ -10,41 +11,170 @@ use crate::{
terminal::handle_response,
};

pub async fn run_command<W: std::io::Write + Send>(
term: &mut W,
args: &RunCommandArguments,
) -> Result<(), HittCliError> {
let http_client = reqwest::Client::new();
fn build_variable_map(
var: &Option<Vec<String>>,
) -> Result<std::collections::HashMap<String, String>, HittCliError> {
let mut vars = std::collections::HashMap::new();

if let Some(arg_variables) = var {
for var in arg_variables {
let (key, value) = parse_variable_argument(var)?;

vars.insert(key, value);
}
}

Ok(vars)
}

#[cfg(test)]
mod test_build_variable_map {
use super::build_variable_map;

#[test]
fn it_should_parse_variables() {
let input = vec![
"name=hougesen".to_owned(),
"host=https://mhouge.dk/?query=asd".to_owned(),
];

let is_dir_path = std::fs::metadata(&args.path).map(|metadata| metadata.is_dir())?;
let x = build_variable_map(&Some(input)).expect("it to return a map");

if is_dir_path && !args.recursive {
assert_eq!(x.len(), 2);

let host_var = x.get("host").expect("it to be some");
assert_eq!(host_var, "https://mhouge.dk/?query=asd");

let name_var = x.get("name").expect("it to be some");
assert_eq!(name_var, "hougesen");
}
}

async fn get_requests(
path: &std::path::Path,
recursive: bool,
var_input: &Option<Vec<String>>,
) -> Result<Vec<(std::path::PathBuf, Vec<HittRequest>)>, HittCliError> {
let is_dir_path = std::fs::metadata(path).map(|metadata| metadata.is_dir())?;

if is_dir_path && !recursive {
return Err(HittCliError::RecursiveNotEnabled);
}

let mut vars = std::collections::HashMap::new();
let vars = build_variable_map(var_input)?;

if let Some(arg_variables) = args.var.clone() {
for var in arg_variables {
let (key, value) = parse_variable_argument(&var)?;
if is_dir_path {
return parse_files(find_http_files(path), vars).await;
}

vars.insert(key, value);
}
parse_file(path, Arc::new(vars)).await.map(|r| vec![r])
}

#[cfg(test)]
mod test_get_requests {
use crate::{commands::run::get_requests, error::HittCliError};

#[tokio::test]
async fn it_should_return_a_list_of_requests() {
let f = tempfile::Builder::new()
.prefix("hitt-")
.rand_bytes(12)
.suffix(".hitt")
.tempfile()
.expect("it to create a file");

let p = f.path();

std::fs::write(p, "GET https://mhouge.dk/").expect("it to write successfully");

let files = get_requests(p, false, &None)
.await
.expect("it to return a list of requests");

assert_eq!(1, files.len());

let file = files.first().expect("it to be some");
let requests = &file.1;

assert_eq!(requests.len(), 1);

let req = requests.first().expect("it to be some");

assert_eq!(req.uri.to_string(), "https://mhouge.dk/");
assert_eq!(req.method, http::Method::GET);
assert!(req.headers.is_empty());
assert!(req.http_version.is_none());
assert!(req.body.is_none());
}

#[tokio::test]
async fn is_should_reject_dir_when_recursive_false() {
let dir = tempfile::Builder::new()
.prefix("hitt-")
.rand_bytes(12)
.suffix(".hitt")
.tempdir()
.expect("it to create a dir");

let p = dir.path();

let err = get_requests(p, false, &None)
.await
.expect_err("expect it to return a missing recursive arg error");

assert!(matches!(err, HittCliError::RecursiveNotEnabled));
}

let parsed_files = if is_dir_path {
parse_files(find_http_files(&args.path), vars).await
} else {
parse_file(&args.path, Arc::new(vars))
#[tokio::test]
async fn it_should_allow_dir_when_recursive_true() {
let dir = tempfile::Builder::new()
.prefix("hitt-")
.rand_bytes(12)
.suffix(".hitt")
.tempdir()
.expect("it to create a file");

let dir_path = dir.path();

let file_path = dir_path.join("file.http");

std::fs::write(&file_path, "GET https://mhouge.dk/").expect("it to write successfully");

let files = get_requests(dir_path, true, &None)
.await
.map(|r| vec![r])
}?;
.expect("it to return a list of requests");

assert_eq!(1, files.len());

let file = files.first().expect("it to be some");

assert_eq!(&file.0, &file_path);

let requests = &file.1;

assert_eq!(requests.len(), 1);

let req = requests.first().expect("it to be some");

assert_eq!(req.uri.to_string(), "https://mhouge.dk/");
assert_eq!(req.method, http::Method::GET);
assert!(req.headers.is_empty());
assert!(req.http_version.is_none());
assert!(req.body.is_none());
}
}

pub async fn run_command<W: std::io::Write + Send>(
term: &mut W,
args: &RunCommandArguments,
) -> Result<(), HittCliError> {
let http_client = reqwest::Client::new();

let timeout = args.timeout.map(core::time::Duration::from_millis);

let mut request_count: u16 = 0;

for (path, file) in parsed_files {
for (path, file) in get_requests(&args.path, args.recursive, &args.var).await? {
if !args.vim {
if request_count > 0 {
term.queue(Print('\n'))?;
Expand Down

0 comments on commit 6a5d9a1

Please sign in to comment.