From 79cf2b09e84faaf4237e42a8783a19734fa288a0 Mon Sep 17 00:00:00 2001 From: Keith Wade Date: Fri, 23 Oct 2020 19:10:27 -0500 Subject: [PATCH 1/5] Run cargo fmt, enforce cargo fmt in build --- .github/workflows/ci.yaml | 1 + tests/args.rs | 36 ++++++++---------- tests/common.rs | 10 ++--- tests/filter_identity.rs | 79 +++++++++++++++++++-------------------- tests/piping.rs | 54 ++++++++++++-------------- 5 files changed, 85 insertions(+), 95 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0b9c831..8d15b93 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,5 +10,6 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + - run: cargo fmt -- --check - run: cargo test - run: cargo build --release --all-features diff --git a/tests/args.rs b/tests/args.rs index fdc0d54..2d6ba4a 100644 --- a/tests/args.rs +++ b/tests/args.rs @@ -5,34 +5,30 @@ mod common; #[test] fn file_arg_invalid_location() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("should-not-exist.toml")) - .arg("."); + cmd.arg("--file") + .arg(common::get_fixture_path("should-not-exist.toml")) + .arg("."); - cmd - .assert() - .failure() - .stderr(predicate::str::contains("Failed to open file:")); + cmd.assert() + .failure() + .stderr(predicate::str::contains("Failed to open file:")); - Ok(()) + Ok(()) } #[test] fn file_arg_not_valid_toml() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("test_01.json")) - .arg("."); + cmd.arg("--file") + .arg(common::get_fixture_path("test_01.json")) + .arg("."); - cmd - .assert() - .failure() - .stderr(predicate::str::contains("File is not valid TOML.")); + cmd.assert() + .failure() + .stderr(predicate::str::contains("File is not valid TOML.")); - Ok(()) + Ok(()) } diff --git a/tests/common.rs b/tests/common.rs index 13a5647..6d92487 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,8 +1,8 @@ // Testing utility functions pub fn get_fixture_path(file_name: &str) -> String { - format!( - "{project_root}/tests/fixtures/{file_name}", - project_root = env!("CARGO_MANIFEST_DIR"), - file_name = file_name - ) + format!( + "{project_root}/tests/fixtures/{file_name}", + project_root = env!("CARGO_MANIFEST_DIR"), + file_name = file_name + ) } diff --git a/tests/filter_identity.rs b/tests/filter_identity.rs index f68693e..0ec81e7 100644 --- a/tests/filter_identity.rs +++ b/tests/filter_identity.rs @@ -6,54 +6,53 @@ mod common; #[test] fn test_identity_filter_file_arg() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg("."); + cmd.arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg("."); - cmd.assert().success().stdout(predicate::str::contains( - "[cool]\n\ + cmd.assert().success().stdout(predicate::str::contains( + "[cool]\n\ yes = true", - )); + )); - Ok(()) + Ok(()) } #[test] fn test_identity_filter_stdin() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; - - let process = match cmd - .arg(".") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - { - Err(why) => panic!("couldn't spawn tq: {}", why), - Ok(process) => process, - }; - - let toml_str = std::fs::read_to_string(common::get_fixture_path("test_01.toml"))?; - let toml_bytes = toml_str.into_bytes(); - - match process.stdin.unwrap().write_all(&toml_bytes) { - Err(why) => panic!("couldn't write to tq stdin: {}", why), - Ok(_) => println!("sent toml bytes to tq"), - } - - let mut s = String::new(); - match process.stdout.unwrap().read_to_string(&mut s) { - Err(why) => panic!("couldn't read tq stdout: {}", why), - Ok(_) => print!("tq responded with:\n{}", s), - } - - assert_eq!( - s, - "[cool]\n\ + let mut cmd = Command::cargo_bin("tq")?; + + let process = match cmd + .arg(".") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + { + Err(why) => panic!("couldn't spawn tq: {}", why), + Ok(process) => process, + }; + + let toml_str = std::fs::read_to_string(common::get_fixture_path("test_01.toml"))?; + let toml_bytes = toml_str.into_bytes(); + + match process.stdin.unwrap().write_all(&toml_bytes) { + Err(why) => panic!("couldn't write to tq stdin: {}", why), + Ok(_) => println!("sent toml bytes to tq"), + } + + let mut s = String::new(); + match process.stdout.unwrap().read_to_string(&mut s) { + Err(why) => panic!("couldn't read tq stdout: {}", why), + Ok(_) => print!("tq responded with:\n{}", s), + } + + assert_eq!( + s, + "[cool]\n\ yes = true\n\n" - ); + ); - Ok(()) + Ok(()) } diff --git a/tests/piping.rs b/tests/piping.rs index 26d7aae..4b23926 100644 --- a/tests/piping.rs +++ b/tests/piping.rs @@ -5,51 +5,45 @@ mod common; #[test] fn test_basic_pipe_context() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | .cool"); + cmd.arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | .cool"); - cmd - .assert() - .success() - .stdout(predicate::str::contains("yes = true")); + cmd.assert() + .success() + .stdout(predicate::str::contains("yes = true")); - Ok(()) + Ok(()) } #[test] fn filter_identity_piping_scope() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | . | . | .cool"); + cmd.arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | . | . | .cool"); - cmd - .assert() - .success() - .stdout(predicate::str::contains("yes = true")); + cmd.assert() + .success() + .stdout(predicate::str::contains("yes = true")); - Ok(()) + Ok(()) } #[test] fn filter_identity_piping_right_hand() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd - .arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | .cool | .yes"); + cmd.arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | .cool | .yes"); - cmd - .assert() - .success() - .stdout(predicate::str::contains("true")); + cmd.assert() + .success() + .stdout(predicate::str::contains("true")); - Ok(()) + Ok(()) } From cac3d267ddedcaf495bfe792efc1c1ec2fbffb34 Mon Sep 17 00:00:00 2001 From: Keith Wade Date: Fri, 23 Oct 2020 19:15:25 -0500 Subject: [PATCH 2/5] Fix clippy warnings, enforce clippy --- .github/workflows/ci.yaml | 1 + src/load_toml.rs | 1 - src/main.rs | 10 ++++------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8d15b93..1770071 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,5 +11,6 @@ jobs: with: toolchain: stable - run: cargo fmt -- --check + - run: cargo clippy -- -D warnings - run: cargo test - run: cargo build --release --all-features diff --git a/src/load_toml.rs b/src/load_toml.rs index d4fd39b..769097b 100644 --- a/src/load_toml.rs +++ b/src/load_toml.rs @@ -1,6 +1,5 @@ use std::fs::File; use std::io::{self, Read}; -use toml; use crate::errors::*; diff --git a/src/main.rs b/src/main.rs index be440b9..b5a1feb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -use toml; - fn main() { let matches = tq::read_args(); @@ -61,16 +59,16 @@ fn main() { // Step 3: handle various piping scenarios // Step 4: output let full_filter_string = matches.value_of("filter").unwrap(); - let filter_pass = full_filter_string.split("|"); + let filter_pass = full_filter_string.split('|'); - let mut value: toml::Value = toml_file.clone(); + let mut value: toml::Value = toml_file; for filter_str in filter_pass { if filter_str.trim() == "." { continue; } - let keys = filter_str.split("."); - let _count = filter_str.split(".").count(); + let keys = filter_str.split('.'); + let _count = filter_str.split('.').count(); let mut val: toml::Value = value; for key in keys { From b413504dbafa5340a00ddd94f64b8069d768a79c Mon Sep 17 00:00:00 2001 From: Keith Wade Date: Fri, 23 Oct 2020 19:18:23 -0500 Subject: [PATCH 3/5] Give steps names --- .github/workflows/ci.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1770071..5179bb7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,11 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable - - run: cargo fmt -- --check - - run: cargo clippy -- -D warnings - - run: cargo test - - run: cargo build --release --all-features + - name: Format + run: cargo fmt -- --check + - name: Lint + run: cargo clippy -- -D warnings + - name: Test + run: cargo test + - name: Build + run: cargo build --release --all-features From 049c30ab1a14e08a51cc437dc09474f86071acf5 Mon Sep 17 00:00:00 2001 From: Keith Wade Date: Fri, 23 Oct 2020 19:21:21 -0500 Subject: [PATCH 4/5] Bump patch to v0.1.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de62fd9..9f5dde7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,7 +293,7 @@ dependencies = [ [[package]] name = "tq" -version = "0.1.3" +version = "0.1.4" dependencies = [ "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index a2b5cd5..36225ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ authors = ["Brandon Slinkard "] edition = "2018" name = "tq" -version = "0.1.3" +version = "0.1.4" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 5df832e38e43994e2bbc6cad7027d43bf857ad42 Mon Sep 17 00:00:00 2001 From: Keith Wade Date: Fri, 23 Oct 2020 19:37:42 -0500 Subject: [PATCH 5/5] Set fmt tab_spaces to 2 Requested by @slinkardbrandon --- rustfmt.toml | 1 + src/lib.rs | 40 +++++------ src/load_toml.rs | 16 ++--- src/main.rs | 152 +++++++++++++++++++-------------------- tests/args.rs | 36 +++++----- tests/common.rs | 10 +-- tests/filter_identity.rs | 79 ++++++++++---------- tests/piping.rs | 54 +++++++------- 8 files changed, 200 insertions(+), 188 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..b196eaa --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +tab_spaces = 2 diff --git a/src/lib.rs b/src/lib.rs index 4cf9ec0..fc99032 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,29 +6,29 @@ extern crate error_chain; use clap::{App, Arg, ArgMatches}; pub mod errors { - error_chain! {} + error_chain! {} } pub mod load_toml; pub fn read_args() -> ArgMatches<'static> { - App::new(crate_name!()) - .version(crate_version!()) - .author(crate_authors!()) - .about(crate_description!()) - .arg( - Arg::with_name("file") - .short("f") - .long("file") - .value_name("TOML_FILE") - .help("TOML file to ingest") - .takes_value(true), - ) - .arg( - Arg::with_name("filter") - .help("Applies to the TOML input and produces filter results as TOML on standard output.") - .required(true) - .index(1), - ) - .get_matches() + App::new(crate_name!()) + .version(crate_version!()) + .author(crate_authors!()) + .about(crate_description!()) + .arg( + Arg::with_name("file") + .short("f") + .long("file") + .value_name("TOML_FILE") + .help("TOML file to ingest") + .takes_value(true), + ) + .arg( + Arg::with_name("filter") + .help("Applies to the TOML input and produces filter results as TOML on standard output.") + .required(true) + .index(1), + ) + .get_matches() } diff --git a/src/load_toml.rs b/src/load_toml.rs index 769097b..662650f 100644 --- a/src/load_toml.rs +++ b/src/load_toml.rs @@ -4,21 +4,21 @@ use std::io::{self, Read}; use crate::errors::*; pub fn load_toml_from_file(name: &str) -> Result { - let mut file = File::open(name).chain_err(|| format!("Failed to open file: {:?}", &name))?; - let mut contents = String::new(); - let _ = file.read_to_string(&mut contents); + let mut file = File::open(name).chain_err(|| format!("Failed to open file: {:?}", &name))?; + let mut contents = String::new(); + let _ = file.read_to_string(&mut contents); - toml::from_str(&contents).chain_err(|| "File is not valid TOML.") + toml::from_str(&contents).chain_err(|| "File is not valid TOML.") } pub fn load_toml_from_stdin() -> Result { - let mut content = String::new(); - let _ = io::stdin().lock().read_to_string(&mut content); + let mut content = String::new(); + let _ = io::stdin().lock().read_to_string(&mut content); - toml::from_str(&content).chain_err(|| "File is not valid TOML.") + toml::from_str(&content).chain_err(|| "File is not valid TOML.") } #[test] fn load_toml_from_file_without_crash() { - let _foo = load_toml_from_file("../tests/fixtures/test_01.toml"); + let _foo = load_toml_from_file("../tests/fixtures/test_01.toml"); } diff --git a/src/main.rs b/src/main.rs index b5a1feb..794a4b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,88 +1,88 @@ fn main() { - let matches = tq::read_args(); + let matches = tq::read_args(); - let toml_file: toml::Value = match matches.value_of("file") { - Some(file) => tq::load_toml::load_toml_from_file(file).unwrap(), - None => tq::load_toml::load_toml_from_stdin().unwrap(), - }; + let toml_file: toml::Value = match matches.value_of("file") { + Some(file) => tq::load_toml::load_toml_from_file(file).unwrap(), + None => tq::load_toml::load_toml_from_stdin().unwrap(), + }; - /*** - * One of the first things we'll want to do is deal with filters - * and how to pipe results from one filter to another. From the JQ manual: - * "Generally, things that would be done with loops and iteration in other languages are just done by gluing filters together in jq." - * The same can be said for tq. - * - * It's important to remember that every filter has an input and an output. - * Even literals like "hello" or 42 are filters - they take an input but - * always produce the same literal as output. Operations that combine two - * filters, like addition, generally feed the same input to both and combine - * the results. So, you can implement an averaging filter as add / length - - * feeding the input array both to the add filter and the length filter - * and then performing the division. - */ + /*** + * One of the first things we'll want to do is deal with filters + * and how to pipe results from one filter to another. From the JQ manual: + * "Generally, things that would be done with loops and iteration in other languages are just done by gluing filters together in jq." + * The same can be said for tq. + * + * It's important to remember that every filter has an input and an output. + * Even literals like "hello" or 42 are filters - they take an input but + * always produce the same literal as output. Operations that combine two + * filters, like addition, generally feed the same input to both and combine + * the results. So, you can implement an averaging filter as add / length - + * feeding the input array both to the add filter and the length filter + * and then performing the division. + */ - /*** - * Basic filters: - * - * Identity: . - * - The absolute simplest filter is: . - * This is a filter that takes its input and produces it unchanged as output. That is, this is the identity operator. - * - * Object Identifier-Index: .foo, .foo.bar - * - The simplest useful filter is: .foo - * When given TOML as an input, it gets the value in the table row "foo" - * - * Optional Object Identifier Index: .foo? - * - Just like .foo, but does not output even an error when . is not an array or an object. - * - * Generic Object Index: .[] - * - You can also look up fields of an object using syntax like .["foo"] - * (.foo above is a shorthand version of this, but only for identifier-like strings). - * - * Array Index: .[2] - * When the index value is an integer, .[] can index arrays. Arrays are zero-based, so .[2] returns the third element. - * - * Pipe: | - * Combines two filters by feeding the output(s) of the one on the left into - * the input of the one on the right. It's pretty much the same as the Unix shell's - * pipe, if you're used to that. If the one on the left produces multiple results, - * the one on the right will be run for each of those results. So, the expression - * .[] | .foo retrieves the "foo" field of each element of the input array. Note - * that .a.b.c is the same as .a | .b | .c. Note too that . is the input value at - * the particular stage in a "pipeline", specifically: where the . expression - * appears. Thus .a | . | .b is the same as .a.b, as the . in the middle refers - * to whatever value .a produced. - */ + /*** + * Basic filters: + * + * Identity: . + * - The absolute simplest filter is: . + * This is a filter that takes its input and produces it unchanged as output. That is, this is the identity operator. + * + * Object Identifier-Index: .foo, .foo.bar + * - The simplest useful filter is: .foo + * When given TOML as an input, it gets the value in the table row "foo" + * + * Optional Object Identifier Index: .foo? + * - Just like .foo, but does not output even an error when . is not an array or an object. + * + * Generic Object Index: .[] + * - You can also look up fields of an object using syntax like .["foo"] + * (.foo above is a shorthand version of this, but only for identifier-like strings). + * + * Array Index: .[2] + * When the index value is an integer, .[] can index arrays. Arrays are zero-based, so .[2] returns the third element. + * + * Pipe: | + * Combines two filters by feeding the output(s) of the one on the left into + * the input of the one on the right. It's pretty much the same as the Unix shell's + * pipe, if you're used to that. If the one on the left produces multiple results, + * the one on the right will be run for each of those results. So, the expression + * .[] | .foo retrieves the "foo" field of each element of the input array. Note + * that .a.b.c is the same as .a | .b | .c. Note too that . is the input value at + * the particular stage in a "pipeline", specifically: where the . expression + * appears. Thus .a | . | .b is the same as .a.b, as the . in the middle refers + * to whatever value .a produced. + */ - // Step 1, read the input string, determine execution order - // Step 2: access the toml_file to get strings, tables, etc - // Step 3: handle various piping scenarios - // Step 4: output - let full_filter_string = matches.value_of("filter").unwrap(); - let filter_pass = full_filter_string.split('|'); + // Step 1, read the input string, determine execution order + // Step 2: access the toml_file to get strings, tables, etc + // Step 3: handle various piping scenarios + // Step 4: output + let full_filter_string = matches.value_of("filter").unwrap(); + let filter_pass = full_filter_string.split('|'); - let mut value: toml::Value = toml_file; - for filter_str in filter_pass { - if filter_str.trim() == "." { - continue; - } - - let keys = filter_str.split('.'); - let _count = filter_str.split('.').count(); + let mut value: toml::Value = toml_file; + for filter_str in filter_pass { + if filter_str.trim() == "." { + continue; + } - let mut val: toml::Value = value; - for key in keys { - let trimmed_key = key.trim(); - if trimmed_key == "" { - continue; - } + let keys = filter_str.split('.'); + let _count = filter_str.split('.').count(); - val = val.get(trimmed_key).unwrap().clone(); - } + let mut val: toml::Value = value; + for key in keys { + let trimmed_key = key.trim(); + if trimmed_key == "" { + continue; + } - value = val; + val = val.get(trimmed_key).unwrap().clone(); } - println!("{}", &value); - std::process::exit(0); + value = val; + } + + println!("{}", &value); + std::process::exit(0); } diff --git a/tests/args.rs b/tests/args.rs index 2d6ba4a..fdc0d54 100644 --- a/tests/args.rs +++ b/tests/args.rs @@ -5,30 +5,34 @@ mod common; #[test] fn file_arg_invalid_location() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("should-not-exist.toml")) - .arg("."); + cmd + .arg("--file") + .arg(common::get_fixture_path("should-not-exist.toml")) + .arg("."); - cmd.assert() - .failure() - .stderr(predicate::str::contains("Failed to open file:")); + cmd + .assert() + .failure() + .stderr(predicate::str::contains("Failed to open file:")); - Ok(()) + Ok(()) } #[test] fn file_arg_not_valid_toml() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("test_01.json")) - .arg("."); + cmd + .arg("--file") + .arg(common::get_fixture_path("test_01.json")) + .arg("."); - cmd.assert() - .failure() - .stderr(predicate::str::contains("File is not valid TOML.")); + cmd + .assert() + .failure() + .stderr(predicate::str::contains("File is not valid TOML.")); - Ok(()) + Ok(()) } diff --git a/tests/common.rs b/tests/common.rs index 6d92487..13a5647 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,8 +1,8 @@ // Testing utility functions pub fn get_fixture_path(file_name: &str) -> String { - format!( - "{project_root}/tests/fixtures/{file_name}", - project_root = env!("CARGO_MANIFEST_DIR"), - file_name = file_name - ) + format!( + "{project_root}/tests/fixtures/{file_name}", + project_root = env!("CARGO_MANIFEST_DIR"), + file_name = file_name + ) } diff --git a/tests/filter_identity.rs b/tests/filter_identity.rs index 0ec81e7..f68693e 100644 --- a/tests/filter_identity.rs +++ b/tests/filter_identity.rs @@ -6,53 +6,54 @@ mod common; #[test] fn test_identity_filter_file_arg() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg("."); + cmd + .arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg("."); - cmd.assert().success().stdout(predicate::str::contains( - "[cool]\n\ + cmd.assert().success().stdout(predicate::str::contains( + "[cool]\n\ yes = true", - )); + )); - Ok(()) + Ok(()) } #[test] fn test_identity_filter_stdin() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; - - let process = match cmd - .arg(".") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - { - Err(why) => panic!("couldn't spawn tq: {}", why), - Ok(process) => process, - }; - - let toml_str = std::fs::read_to_string(common::get_fixture_path("test_01.toml"))?; - let toml_bytes = toml_str.into_bytes(); - - match process.stdin.unwrap().write_all(&toml_bytes) { - Err(why) => panic!("couldn't write to tq stdin: {}", why), - Ok(_) => println!("sent toml bytes to tq"), - } - - let mut s = String::new(); - match process.stdout.unwrap().read_to_string(&mut s) { - Err(why) => panic!("couldn't read tq stdout: {}", why), - Ok(_) => print!("tq responded with:\n{}", s), - } - - assert_eq!( - s, - "[cool]\n\ + let mut cmd = Command::cargo_bin("tq")?; + + let process = match cmd + .arg(".") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + { + Err(why) => panic!("couldn't spawn tq: {}", why), + Ok(process) => process, + }; + + let toml_str = std::fs::read_to_string(common::get_fixture_path("test_01.toml"))?; + let toml_bytes = toml_str.into_bytes(); + + match process.stdin.unwrap().write_all(&toml_bytes) { + Err(why) => panic!("couldn't write to tq stdin: {}", why), + Ok(_) => println!("sent toml bytes to tq"), + } + + let mut s = String::new(); + match process.stdout.unwrap().read_to_string(&mut s) { + Err(why) => panic!("couldn't read tq stdout: {}", why), + Ok(_) => print!("tq responded with:\n{}", s), + } + + assert_eq!( + s, + "[cool]\n\ yes = true\n\n" - ); + ); - Ok(()) + Ok(()) } diff --git a/tests/piping.rs b/tests/piping.rs index 4b23926..26d7aae 100644 --- a/tests/piping.rs +++ b/tests/piping.rs @@ -5,45 +5,51 @@ mod common; #[test] fn test_basic_pipe_context() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | .cool"); + cmd + .arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | .cool"); - cmd.assert() - .success() - .stdout(predicate::str::contains("yes = true")); + cmd + .assert() + .success() + .stdout(predicate::str::contains("yes = true")); - Ok(()) + Ok(()) } #[test] fn filter_identity_piping_scope() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | . | . | .cool"); + cmd + .arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | . | . | .cool"); - cmd.assert() - .success() - .stdout(predicate::str::contains("yes = true")); + cmd + .assert() + .success() + .stdout(predicate::str::contains("yes = true")); - Ok(()) + Ok(()) } #[test] fn filter_identity_piping_right_hand() -> Result<(), Box> { - let mut cmd = Command::cargo_bin("tq")?; + let mut cmd = Command::cargo_bin("tq")?; - cmd.arg("--file") - .arg(common::get_fixture_path("test_01.toml")) - .arg(". | .cool | .yes"); + cmd + .arg("--file") + .arg(common::get_fixture_path("test_01.toml")) + .arg(". | .cool | .yes"); - cmd.assert() - .success() - .stdout(predicate::str::contains("true")); + cmd + .assert() + .success() + .stdout(predicate::str::contains("true")); - Ok(()) + Ok(()) }