summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Geary <rtgnj42@gmail.com>2020-06-08 14:25:15 -0400
committerRyan Geary <rtgnj42@gmail.com>2020-06-08 22:16:02 -0400
commit1ee01c6de09e8556ece57756ac2d52ba9b28e27b (patch)
treedb1189aa51039f8c222b6fc96c0fe502f1eba618
parent63b9eea62c44182032d86f722e54c11cdc1d9077 (diff)
Add alternate Rust-y range syntax (#11)
Refactor to support choice 'kind' Add ParseRangeError Add rust syntax range parsing tests Implement rust syntax parsing Change parse to not anticipate exclusivity Add choice tests Implement Rust syntax choices Show that there are multiple in opt.choice*s* Refactor repeated code in choice tests Update documentation to reflect Rust range syntax
-rw-r--r--readme.md10
-rw-r--r--src/choice.rs949
-rw-r--r--src/config.rs141
-rw-r--r--src/errors.rs23
-rw-r--r--src/main.rs5
-rw-r--r--src/opt.rs15
-rw-r--r--src/parse.rs270
-rw-r--r--src/parse_error.rs14
8 files changed, 965 insertions, 462 deletions
diff --git a/readme.md b/readme.md
index d226078..cf911a6 100644
--- a/readme.md
+++ b/readme.md
@@ -43,11 +43,11 @@ Please see our guidelines in [contributing.md](contributing.md).
```
$ choose --help
-choose 1.1.1
+choose 1.1.2
`choose` sections from each line of files
USAGE:
- choose [FLAGS] [OPTIONS] <choice>...
+ choose [FLAGS] [OPTIONS] <choices>...
FLAGS:
-c, --character-wise Choose fields by character number
@@ -65,8 +65,10 @@ OPTIONS:
-o, --output-field-separator <output-field-separator> Specify output field separator
ARGS:
- <choice>... Fields to print. Either x, x:, :y, or x:y, where x and y are integers, colons indicate a range,
- and an empty field on either side of the colon continues to the beginning or end of the line.
+ <choices>... Fields to print. Either a, a:b, a..b, or a..=b, where a and b are integers. The beginning or end
+ of a range can be omitted, resulting in including the beginning or end of the line,
+ respectively. a:b is inclusive of b (unless overridden by -x). a..b is exclusive of b and a..=b
+ is inclusive of b
```
### Examples
diff --git a/src/choice.rs b/src/choice.rs
index bf193f6..a2ce12a 100644
--- a/src/choice.rs
+++ b/src/choice.rs
@@ -10,17 +10,27 @@ use crate::writer::WriteReceiver;
pub struct Choice {
pub start: isize,
pub end: isize,
+ pub kind: ChoiceKind,
negative_index: bool,
reversed: bool,
}
+#[derive(Debug, PartialEq)]
+pub enum ChoiceKind {
+ Single,
+ RustExclusiveRange,
+ RustInclusiveRange,
+ ColonRange,
+}
+
impl Choice {
- pub fn new(start: isize, end: isize) -> Self {
+ pub fn new(start: isize, end: isize, kind: ChoiceKind) -> Self {
let negative_index = start < 0 || end < 0;
- let reversed = end < start;
+ let reversed = end < start && !(start >= 0 && end < 0);
Choice {
start,
end,
+ kind,
negative_index,
reversed,
}
@@ -236,35 +246,26 @@ mod tests {
mod print_choice_tests {
use super::*;
- #[test]
- fn print_0() {
- let config = Config::from_iter(vec!["choose", "0"]);
+ fn test_fn(vec: Vec<&str>, input: &str, output: &str) {
+ let config = Config::from_iter(vec);
let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust is pretty cool"),
- &config,
- &mut handle,
- );
+ config.opt.choices[0].print_choice(&String::from(input), &config, &mut handle);
assert_eq!(
- String::from("rust"),
+ String::from(output),
MockStdout::str_from_buf_writer(handle)
);
}
#[test]
- fn print_after_end() {
- let config = Config::from_iter(vec!["choose", "10"]);
- let mut handle = BufWriter::new(MockStdout::new());
-
- config.opt.choice[0].print_choice(
- &String::from("rust is pretty cool"),
- &config,
- &mut handle,
- );
+ fn print_0() {
+ test_fn(vec!["choose", "0"], "rust is pretty cool", "rust");
+ }
- assert_eq!(String::new(), MockStdout::str_from_buf_writer(handle));
+ #[test]
+ fn print_after_end() {
+ test_fn(vec!["choose", "10"], "rust is pretty cool", "");
}
#[test]
@@ -273,7 +274,7 @@ mod tests {
let mut handle = BufWriter::new(MockStdout::new());
let mut handle1 = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
+ config.opt.choices[0].print_choice(
&String::from("rust is pretty cool"),
&config,
&mut handle,
@@ -284,7 +285,7 @@ mod tests {
MockStdout::str_from_buf_writer(handle)
);
- config.opt.choice[1].print_choice(
+ config.opt.choices[1].print_choice(
&String::from("rust is pretty cool"),
&config,
&mut handle1,
@@ -295,460 +296,780 @@ mod tests {
#[test]
fn print_1_to_3_exclusive() {
- let config = Config::from_iter(vec!["choose", "1:3", "-x"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust is pretty cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is pretty"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-x"],
+ "rust is pretty cool",
+ "is pretty",
);
}
#[test]
fn print_1_to_3() {
- let config = Config::from_iter(vec!["choose", "1:3"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust is pretty cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is pretty cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3"],
+ "rust is pretty cool",
+ "is pretty cool",
);
}
#[test]
fn print_1_to_3_separated_by_hashtag() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust#is#pretty#cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is pretty cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-f", "#"],
+ "rust#is#pretty#cool",
+ "is pretty cool",
);
}
#[test]
fn print_1_to_3_separated_by_varying_multiple_hashtag_exclusive() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "#", "-x"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust##is###pretty####cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is pretty"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-f", "#", "-x"],
+ "rust##is###pretty####cool",
+ "is pretty",
);
}
#[test]
fn print_1_to_3_separated_by_varying_multiple_hashtag() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust##is###pretty####cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is pretty cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-f", "#"],
+ "rust##is###pretty####cool",
+ "is pretty cool",
);
}
#[test]
fn print_1_to_3_separated_by_regex_group_vowels_exclusive() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "[aeiou]", "-x"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("the quick brown fox jumped over the lazy dog"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from(" q ck br"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-f", "[aeiou]", "-x"],
+ "the quick brown fox jumped over the lazy dog",
+ " q ck br",
);
}
#[test]
fn print_1_to_3_separated_by_regex_group_vowels() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "[aeiou]"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("the quick brown fox jumped over the lazy dog"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from(" q ck br wn f"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:3", "-f", "[aeiou]"],
+ "the quick brown fox jumped over the lazy dog",
+ " q ck br wn f",
);
}
#[test]
fn print_3_to_1() {
- let config = Config::from_iter(vec!["choose", "3:1"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("pretty is lang"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "3:1"],
+ "rust lang is pretty darn cool",
+ "pretty is lang",
);
}
#[test]
fn print_3_to_1_exclusive() {
- let config = Config::from_iter(vec!["choose", "3:1", "-x"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("is lang"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "3:1", "-x"],
+ "rust lang is pretty darn cool",
+ "is lang",
);
}
#[test]
fn print_1_to_3_nonexistant_field_separator() {
- let config = Config::from_iter(vec!["choose", "1:3", "-f", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
+ test_fn(
+ vec!["choose", "1:3", "-f", "#"],
+ "rust lang is pretty darn cool",
+ "",
);
- assert_eq!(String::from(""), MockStdout::str_from_buf_writer(handle));
}
#[test]
fn print_0_nonexistant_field_separator() {
- let config = Config::from_iter(vec!["choose", "0", "-f", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("rust lang is pretty darn cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "0", "-f", "#"],
+ "rust lang is pretty darn cool",
+ "rust lang is pretty darn cool",
);
}
#[test]
fn print_0_to_3_nonexistant_field_separator() {
- let config = Config::from_iter(vec!["choose", "0:3", "-f", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("rust lang is pretty darn cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "0:3", "-f", "#"],
+ "rust lang is pretty darn cool",
+ "rust lang is pretty darn cool",
);
}
#[test]
fn print_0_with_preceding_separator() {
- let config = Config::from_iter(vec!["choose", "0"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from(" rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("rust"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "0"],
+ " rust lang is pretty darn cool",
+ "rust",
);
}
#[test]
fn print_neg3_to_neg1() {
- let config = Config::from_iter(vec!["choose", "-3:-1"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("pretty darn cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "-3:-1"],
+ "rust lang is pretty darn cool",
+ "pretty darn cool",
);
}
#[test]
fn print_neg1_to_neg3() {
- let config = Config::from_iter(vec!["choose", "-1:-3"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("cool darn pretty"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "-1:-3"],
+ "rust lang is pretty darn cool",
+ "cool darn pretty",
);
}
#[test]
fn print_neg2_to_end() {
- let config = Config::from_iter(vec!["choose", "-2:"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("darn cool"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "-2:"],
+ "rust lang is pretty darn cool",
+ "darn cool",
);
}
#[test]
fn print_start_to_neg3() {
- let config = Config::from_iter(vec!["choose", ":-3"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("rust lang is pretty"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", ":-3"],
+ "rust lang is pretty darn cool",
+ "rust lang is pretty",
);
}
#[test]
fn print_1_to_neg3() {
- let config = Config::from_iter(vec!["choose", "1:-3"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("lang is pretty"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "1:-3"],
+ "rust lang is pretty darn cool",
+ "lang is pretty",
);
}
#[test]
fn print_5_to_neg3_empty() {
- let config = Config::from_iter(vec!["choose", "5:-3"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("rust lang is pretty darn cool"),
- &config,
- &mut handle,
- );
- assert_eq!(String::from(""), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "5:-3"], "rust lang is pretty darn cool", "");
}
#[test]
fn print_0_to_2_greedy() {
- let config = Config::from_iter(vec!["choose", "0:2", "-f", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
- assert_eq!(
- String::from("a b c"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "0:2", "-f", ":"], "a:b::c:::d", "a b c");
}
#[test]
fn print_0_to_2_non_greedy() {
- let config = Config::from_iter(vec!["choose", "0:2", "-n", "-f", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
- assert_eq!(String::from("a b"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "0:2", "-n", "-f", ":"], "a:b::c:::d", "a b");
}
#[test]
fn print_2_to_neg_1_non_greedy_negative() {
- let config = Config::from_iter(vec!["choose", "2:-1", "-n", "-f", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
- assert_eq!(String::from("c d"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "2:-1", "-n", "-f", ":"], "a:b::c:::d", "c d");
}
#[test]
fn print_2_to_0_non_greedy_reversed() {
- let config = Config::from_iter(vec!["choose", "2:0", "-n", "-f", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
- assert_eq!(String::from("b a"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "2:0", "-n", "-f", ":"], "a:b::c:::d", "b a");
}
#[test]
fn print_neg_1_to_neg_3_non_greedy_negative_reversed() {
- let config = Config::from_iter(vec!["choose", "-1:-3", "-n", "-f", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
- assert_eq!(String::from("d"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "-1:-3", "-n", "-f", ":"], "a:b::c:::d", "d");
}
#[test]
fn print_1_to_3_with_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "1:3", "-o", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a b c d"), &config, &mut handle);
- assert_eq!(
- String::from("b#c#d"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "1:3", "-o", "#"], "a b c d", "b#c#d");
}
#[test]
fn print_1_and_3_with_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "1", "3", "-o", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a b c d"), &config, &mut handle);
- handle.write(&config.output_separator).unwrap();
- config.opt.choice[1].print_choice(&String::from("a b c d"), &config, &mut handle);
- assert_eq!(String::from("b#d"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "1", "3", "-o", "#"], "a b c d", "b");
}
#[test]
fn print_2_to_4_with_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "2:4", "-o", "%"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(
- &String::from("Lorem ipsum dolor sit amet, consectetur"),
- &config,
- &mut handle,
- );
- assert_eq!(
- String::from("dolor%sit%amet,"),
- MockStdout::str_from_buf_writer(handle)
+ test_fn(
+ vec!["choose", "2:4", "-o", "%"],
+ "Lorem ipsum dolor sit amet, consectetur",
+ "dolor%sit%amet,",
);
}
#[test]
fn print_3_to_1_with_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "3:1", "-o", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a b c d"), &config, &mut handle);
- assert_eq!(
- String::from("d#c#b"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "3:1", "-o", "#"], "a b c d", "d#c#b");
}
#[test]
fn print_0_to_neg_2_with_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "0:-2", "-o", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a b c d"), &config, &mut handle);
- assert_eq!(
- String::from("a#b#c"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "0:-2", "-o", "#"], "a b c d", "a#b#c");
}
#[test]
fn print_0_to_2_with_empty_output_field_separator() {
- let config = Config::from_iter(vec!["choose", "0:2", "-o", ""]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("a b c d"), &config, &mut handle);
- assert_eq!(String::from("abc"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "0:2", "-o", ""], "a b c d", "abc");
}
#[test]
fn print_0_to_2_character_wise() {
- let config = Config::from_iter(vec!["choose", "0:2", "-c"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("abc"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "0:2", "-c"], "abcd\n", "abc");
}
#[test]
fn print_2_to_end_character_wise() {
- let config = Config::from_iter(vec!["choose", "2:", "-c"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("cd"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "2:", "-c"], "abcd\n", "cd");
}
#[test]
fn print_start_to_2_character_wise() {
- let config = Config::from_iter(vec!["choose", ":2", "-c"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("abc"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", ":2", "-c"], "abcd\n", "abc");
}
#[test]
fn print_0_to_2_character_wise_exclusive() {
- let config = Config::from_iter(vec!["choose", "0:2", "-c", "-x"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("ab"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "0:2", "-c", "-x"], "abcd\n", "ab");
}
#[test]
fn print_0_to_2_character_wise_with_output_delimeter() {
- let config = Config::from_iter(vec!["choose", "0:2", "-c", "-o", ":"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(
- String::from("a:b:c"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "0:2", "-c", "-o", ":"], "abcd\n", "a:b:c");
}
#[test]
fn print_after_end_character_wise() {
- let config = Config::from_iter(vec!["choose", "0:9", "-c"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(
- String::from("abcd"),
- MockStdout::str_from_buf_writer(handle)
- );
+ test_fn(vec!["choose", "0:9", "-c"], "abcd\n", "abcd");
}
#[test]
fn print_2_to_0_character_wise() {
- let config = Config::from_iter(vec!["choose", "2:0", "-c"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("cba"), MockStdout::str_from_buf_writer(handle));
+ test_fn(vec!["choose", "2:0", "-c"], "abcd\n", "cba");
}
#[test]
fn print_neg_2_to_end_character_wise() {
- let config = Config::from_iter(vec!["choose", "-2:", "-c"]);
+ test_fn(vec!["choose", "-2:", "-c"], "abcd\n", "cd");
+ }
+
+ #[test]
+ fn print_1_to_3_exclusive_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-x"],
+ "rust is pretty cool",
+ "is pretty cool",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3"],
+ "rust is pretty cool",
+ "is pretty cool",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_separated_by_hashtag_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "#"],
+ "rust#is#pretty#cool",
+ "is pretty cool",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_separated_by_varying_multiple_hashtag_exclusive_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "#", "-x"],
+ "rust##is###pretty####cool",
+ "is pretty cool",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_separated_by_varying_multiple_hashtag_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "#"],
+ "rust##is###pretty####cool",
+ "is pretty cool",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_separated_by_regex_group_vowels_exclusive_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "[aeiou]", "-x"],
+ "the quick brown fox jumped over the lazy dog",
+ " q ck br wn f",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_separated_by_regex_group_vowels_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "[aeiou]"],
+ "the quick brown fox jumped over the lazy dog",
+ " q ck br wn f",
+ );
+ }
+
+ #[test]
+ fn print_3_to_1_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "3..=1"],
+ "rust lang is pretty darn cool",
+ "pretty is lang",
+ );
+ }
+
+ #[test]
+ fn print_3_to_1_exclusive_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "3..=1", "-x"],
+ "rust lang is pretty darn cool",
+ "pretty is lang",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_nonexistant_field_separator_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=3", "-f", "#"],
+ "rust lang is pretty darn cool",
+ "",
+ );
+ }
+
+ #[test]
+ fn print_0_to_3_nonexistant_field_separator_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "0..=3", "-f", "#"],
+ "rust lang is pretty darn cool",
+ "rust lang is pretty darn cool",
+ );
+ }
+
+ #[test]
+ fn print_neg1_to_neg1_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "-3..=-1"],
+ "rust lang is pretty darn cool",
+ "pretty darn cool",
+ );
+ }
+
+ #[test]
+ fn print_neg1_to_neg3_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "-1..=-3"],
+ "rust lang is pretty darn cool",
+ "cool darn pretty",
+ );
+ }
+
+ #[test]
+ fn print_neg2_to_end_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "-2..="],
+ "rust lang is pretty darn cool",
+ "darn cool",
+ );
+ }
+
+ #[test]
+ fn print_start_to_neg3_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "..=-3"],
+ "rust lang is pretty darn cool",
+ "rust lang is pretty",
+ );
+ }
+
+ #[test]
+ fn print_1_to_neg3_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "1..=-3"],
+ "rust lang is pretty darn cool",
+ "lang is pretty",
+ );
+ }
+
+ #[test]
+ fn print_5_to_neg3_empty_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "5..=-3"],
+ "rust lang is pretty darn cool",
+ "",
+ );
+ }
+
+ #[test]
+ fn print_0_to_2_greedy_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "0..=2", "-f", ":"], "a:b::c:::d", "a b c");
+ }
+
+ #[test]
+ fn print_0_to_2_non_greedy_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "0..=2", "-n", "-f", ":"],
+ "a:b::c:::d",
+ "a b",
+ );
+ }
+
+ #[test]
+ fn print_2_to_neg_1_non_greedy_negative_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "2..=-1", "-n", "-f", ":"],
+ "a:b::c:::d",
+ "c d",
+ );
+ }
+
+ #[test]
+ fn print_2_to_0_non_greedy_reversed_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "2..=0", "-n", "-f", ":"],
+ "a:b::c:::d",
+ "b a",
+ );
+ }
+
+ #[test]
+ fn print_neg_1_to_neg_3_non_greedy_negative_reversed_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "-1..=-3", "-n", "-f", ":"],
+ "a:b::c:::d",
+ "d",
+ );
+ }
+
+ #[test]
+ fn print_1_to_3_with_output_field_separator_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "1..=3", "-o", "#"], "a b c d", "b#c#d");
+ }
+
+ #[test]
+ fn print_1_and_3_with_output_field_separator_rust_syntax_inclusive() {
+ let config = Config::from_iter(vec!["choose", "1", "3", "-o", "#"]);
let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choice[0].print_choice(&String::from("abcd\n"), &config, &mut handle);
- assert_eq!(String::from("cd"), MockStdout::str_from_buf_writer(handle));
+ config.opt.choices[0].print_choice(&String::from("a b c d"), &config, &mut handle);
+ handle.write(&config.output_separator).unwrap();
+ config.opt.choices[1].print_choice(&String::from("a b c d"), &config, &mut handle);
+ assert_eq!(String::from("b#d"), MockStdout::str_from_buf_writer(handle));
+ }
+
+ #[test]
+ fn print_2_to_4_with_output_field_separator_rust_syntax_inclusive() {
+ test_fn(
+ vec!["choose", "2..=4", "-o", "%"],
+ "Lorem ipsum dolor sit amet, consectetur",
+ "dolor%sit%amet,",
+ );
+ }
+
+ #[test]
+ fn print_3_to_1_with_output_field_separator_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "3..=1", "-o", "#"], "a b c d", "d#c#b");
+ }
+
+ #[test]
+ fn print_0_to_neg_2_with_output_field_separator_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "0..=-2", "-o", "#"], "a b c d", "a#b#c");
+ }
+
+ #[test]
+ fn print_0_to_2_with_empty_output_field_separator_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "0..=2", "-o", ""], "a b c d", "abc");
+ }
+
+ #[test]
+ fn print_0_to_2_character_wise_rust_syntax_inclusive() {
+ test_fn(vec!["choose", "0..=2", "-c"], "abcd\n", "abc");
+ }
+
+ #[test]
+ fn print_2_to_end_ch