Skip to content
This repository was archived by the owner on Dec 29, 2021. It is now read-only.

Commit 5c1ea8b

Browse files
authored
Merge pull request #13 from killercup/refactor/everything
Assert CLI using a builder instead of complex macro
2 parents 4bf99e7 + 9d81ed8 commit 5c1ea8b

File tree

8 files changed

+481
-374
lines changed

8 files changed

+481
-374
lines changed

.travis.yml

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
sudo: false
22
language: rust
3+
cache: cargo
34
rust:
4-
- nightly
55
- beta
66
- stable
7+
- nightly
78
matrix:
8-
allow_failures:
9-
- rust: nightly
9+
include:
10+
- rust: nightly-2017-03-15
11+
env: CLIPPY=YESPLEASE
12+
script: |
13+
cargo install clippy --vers "0.0.120"
14+
cargo clippy
1015
before_script:
1116
- |
1217
pip install 'travis-cargo<0.2' --user &&
@@ -15,22 +20,14 @@ script:
1520
- |
1621
travis-cargo build &&
1722
travis-cargo test &&
18-
travis-cargo bench &&
19-
travis-cargo --only stable doc
20-
addons:
21-
apt:
22-
packages:
23-
- libcurl4-openssl-dev
24-
- libelf-dev
25-
- libdw-dev
26-
after_success:
27-
- travis-cargo --only stable doc-upload
28-
- rm tests/skeptic.rs # "skip" skeptic doctests for coverage
29-
- travis-cargo coveralls --no-sudo
23+
travis-cargo bench
3024
notifications:
3125
email:
3226
on_success: never
27+
branches:
28+
only:
29+
- master
3330
env:
3431
global:
35-
- TRAVIS_CARGO_NIGHTLY_FEATURE=dev
32+
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
3633
- secure: OUHDuY7h82pYkis1oJW/dO029Rp/HLGT7od5VQJ1eki0M+Oawj7L0tjQPGLKLjj6hA1Sh8XeeelQgrlwVQfkrvwgYLRfmEdbP8z2PclmbxvXmRFysM5R9dN15HYx9AlUsDiHF9otmkNzJPBghlLvvKbzjp7Mlr5cdBaFZ9psafJLOgIWTIpiuHvYhmKhaXG6bIpLw6pi9NWdUYcd5s/gy1n1v5a4oPH/JB9V3Zc8+tv/EPvRynzSRK1jghD7KtppQoRRt92OCQGZ2BYLoTVpkt/bPS50D558xbVoDPyNNgcPM86eSSNbgp8llASJMFVNWWBZYLmbQ5x/219G907YbKWDLbcwMJL0H/JFbtErLarDU5XiEFBELs0Zx2t0S96xOM+ZWxZvWBk3UuKTBaXIKc921JEU+uHHUsPp3zasiMZWN3Rv2ia68HZGvYtwAPG5PWJTeh7BAo6dLGNDISVE/uHhf64E+ZvH3ToEmadx/yimedE7IOBh7kvPTnr1X5RFWNEJYOVSWJ531LoE3WHO9/UKPRLx01fGHzJKXMyWcp2fQjwCsu9zwThk3N4kYQJfi5YNmJw1EiOERiQ0nRckaUC5sA5KE+ZJmEa4ztfe7RMTVceCNagVdsqH8IHWgM+ROKNNKYDjqKbGSiE0RVwUdITUFLeQDWzQYfzsWRQpFV0=

Cargo.toml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "assert_cli"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
authors = ["Pascal Hertleif <killercup@gmail.com>"]
55
repository = "https://github.com/killercup/assert_cli.git"
66
homepage = "https://github.com/killercup/assert_cli"
@@ -10,14 +10,10 @@ documentation = "http://killercup.github.io/assert_cli/"
1010
description = "Test CLI Applications."
1111
build = "build.rs"
1212

13-
[features]
14-
default = []
15-
dev = ["clippy"]
16-
1713
[dependencies]
18-
ansi_term = "0.6.3"
19-
difference = "0.4.0"
20-
clippy = {version = "0.0.23", optional = true}
14+
colored = "1.4"
15+
difference = "1.0"
16+
error-chain = "0.10.0"
2117

2218
[build-dependencies]
2319
skeptic = "0.5"

README.md

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Just add it to your `Cargo.toml`:
1515

1616
```toml
1717
[dependencies]
18-
assert_cli = "0.3"
18+
assert_cli = "0.4"
1919
```
2020

2121
## Example
@@ -24,59 +24,56 @@ Here's a trivial example:
2424

2525
```rust
2626
extern crate assert_cli;
27+
2728
fn main() {
28-
assert_cli::assert_cli_output("echo", &["42"], "42").unwrap();
29+
assert_cli::Assert::command(&["echo", "42"]).prints("42").unwrap();
2930
}
3031
```
3132

3233
Or if you'd rather use the macro:
3334

34-
```rust,ignore
35+
```rust
3536
#[macro_use] extern crate assert_cli;
36-
fn main() {
37-
assert_cli!("echo", &["42"] => Success, "42").unwrap();
38-
assert_cli!("black-box", &["--special"] => Error 42, "error no 42\n").unwrap()
39-
}
40-
```
41-
42-
And here is one that will fail:
4337

44-
```rust,should_panic
45-
extern crate assert_cli;
4638
fn main() {
47-
assert_cli::assert_cli_output("echo", &["42"], "1337").unwrap();
39+
assert_cmd!(echo 42).succeeds().and().prints("42").unwrap();
4840
}
4941
```
5042

51-
this will show a nice, colorful diff in your terminal, like this:
52-
53-
```diff
54-
-1337
55-
+42
56-
```
57-
58-
If you'd prefer to not check the output:
43+
And here is one that will fail (which also shows `execute` which returns a
44+
`Result` and can be used instead of `unwrap`):
5945

6046
```rust
6147
#[macro_use] extern crate assert_cli;
48+
6249
fn main() {
63-
assert_cli::assert_cli("echo", &["42"]).unwrap();
64-
assert_cli!("echo", &["42"] => Success).unwrap();
50+
let test = assert_cmd!(grep amet Cargo.toml)
51+
.fails_with(1)
52+
.execute();
53+
assert!(test.is_err());
6554
}
6655
```
6756

68-
All exported functions and the macro return a `Result` containing the
69-
`Output` of the process, allowing you to do further custom assertions:
57+
If you want to check for the program's output, you can use `print` or
58+
`print_exactly`:
7059

71-
```rust
60+
```rust,should_panic="Assert CLI failure"
7261
#[macro_use] extern crate assert_cli;
62+
7363
fn main() {
74-
let output = assert_cli!("echo", &["Number 42"] => Success).unwrap();
75-
let stdout = std::str::from_utf8(&output.stdout).unwrap();
76-
assert!(stdout.contains("42"));
64+
assert_cmd!("wc" "README.md")
65+
.prints_exactly("1337 README.md")
66+
.unwrap();
7767
}
7868
```
7969

70+
this will show a nice, colorful diff in your terminal, like this:
71+
72+
```diff
73+
-1337
74+
+92
75+
```
76+
8077
## License
8178

8279
Licensed under either of

src/cli_error.rs

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/diff.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,46 @@
1-
use std::fmt;
1+
extern crate colored;
2+
use self::colored::Colorize;
23

3-
use difference::Difference;
4-
use ansi_term::Colour::{Green, Red};
4+
use difference::{Difference, Changeset};
5+
use std::fmt::Write;
56

6-
pub fn render(changeset: &[Difference]) -> Result<String, fmt::Error> {
7-
use std::fmt::Write;
7+
use errors::*;
88

9+
pub fn render(&Changeset { ref diffs, .. }: &Changeset) -> Result<String> {
910
let mut t = String::new();
1011

11-
for change in changeset {
12-
match *change {
12+
for (i, diff) in diffs.iter().enumerate() {
13+
match *diff {
1314
Difference::Same(ref x) => {
14-
for line in x.lines() {
15-
try!(writeln!(t, " {}", line));
16-
}
17-
}
18-
Difference::Add(ref x) => {
19-
try!(write!(t, "{}", Green.paint("+")));
20-
try!(writeln!(t, "{}", Green.paint(x)));
15+
writeln!(t, " {}", x)?;
2116
}
2217
Difference::Rem(ref x) => {
23-
try!(write!(t, "{}", Red.paint("-")));
24-
try!(writeln!(t, "{}", Red.paint(x)));
18+
writeln!(t, "{}", format!("-{}", x).red())?;
19+
}
20+
Difference::Add(ref x) => {
21+
match diffs[i - 1] {
22+
Difference::Rem(ref y) => {
23+
write!(t, "{}", "+".green())?;
24+
let Changeset { diffs, .. } = Changeset::new(y, x, " ");
25+
for c in diffs {
26+
match c {
27+
Difference::Same(ref z) if !z.is_empty() => {
28+
write!(t, "{}", z.green())?;
29+
write!(t, " ")?;
30+
}
31+
Difference::Add(ref z) if !z.is_empty() => {
32+
write!(t, "{}", z.green().reverse())?;
33+
write!(t, " ")?;
34+
}
35+
_ => (),
36+
}
37+
}
38+
writeln!(t, "")?;
39+
}
40+
_ => {
41+
writeln!(t, "{}", format!("+{}", x).green().dimmed())?;
42+
}
43+
};
2544
}
2645
}
2746
}
@@ -31,20 +50,19 @@ pub fn render(changeset: &[Difference]) -> Result<String, fmt::Error> {
3150

3251
#[cfg(test)]
3352
mod tests {
34-
use difference::diff;
3553
use super::*;
3654

3755
#[test]
3856
fn basic_diff() {
39-
let (_, diff) = diff("lol", "yay", "\n");
57+
let diff = Changeset::new("lol", "yay", "\n");
58+
println!("{}", render(&diff).unwrap());
4059
assert_eq!(render(&diff).unwrap(),
41-
"\u{1b}[31m-\u{1b}[0m\u{1b}[31mlol\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[32myay\
42-
\u{1b}[0m\n")
60+
" \n\u{1b}[31m-lol\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[7;32myay\u{1b}[0m \n")
4361
}
4462

4563
#[test]
4664
fn multiline_diff() {
47-
let (_, diff) = diff("Lorem ipsum dolor sit amet, consectetur adipisicing elit,
65+
let diff = Changeset::new("Lorem ipsum dolor sit amet, consectetur adipisicing elit,
4866
sed do eiusmod tempor incididunt ut labore et dolore magna
4967
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
5068
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
@@ -53,6 +71,7 @@ sed do eiusmod tempor **incididunt** ut labore et dolore magna
5371
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
5472
ullamco laboris nisi ut aliquip ex ea commodo consequat.",
5573
"\n");
56-
assert_eq!(render(&diff).unwrap(), " Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n\u{1b}[31m-\u{1b}[0m\u{1b}[31msed do eiusmod tempor incididunt ut labore et dolore magna\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[32msed do eiusmod tempor **incididunt** ut labore et dolore magna\u{1b}[0m\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation\n ullamco laboris nisi ut aliquip ex ea commodo consequat.\n");
74+
println!("{}", render(&diff).unwrap());
75+
assert_eq!(render(&diff).unwrap(), " Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n\u{1b}[31m-sed do eiusmod tempor incididunt ut labore et dolore magna\u{1b}[0m\n\u{1b}[32m+\u{1b}[0m\u{1b}[32msed do eiusmod tempor\u{1b}[0m \u{1b}[7;32m**incididunt**\u{1b}[0m \u{1b}[32mut labore et dolore magna\u{1b}[0m \n aliqua. Ut enim ad minim veniam, quis nostrud exercitation\nullamco laboris nisi ut aliquip ex ea commodo consequat.\n");
5776
}
5877
}

src/errors.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error_chain! {
2+
foreign_links {
3+
Io(::std::io::Error);
4+
Fmt(::std::fmt::Error);
5+
}
6+
errors {
7+
StatusMismatch(cmd: Vec<String>, expected: bool) {
8+
description("Wrong status")
9+
display(
10+
"Command {:?} {got} but expected it to {expected}",
11+
cmd.join(" "),
12+
got = if *expected { "failed" } else { "succeed" },
13+
expected = if *expected { "succeed" } else { "failed" },
14+
)
15+
}
16+
ExitCodeMismatch(cmd: Vec<String>, expected: Option<i32>, got: Option<i32>) {
17+
description("Wrong exit code")
18+
display(
19+
"Command {:?} exited with code {:?} but expected it to be {:?}",
20+
cmd.join(" "), got, expected,
21+
)
22+
}
23+
OutputMismatch(expected: String, got: String) {
24+
description("Output was not as expected")
25+
display(
26+
"Expected output to contain\n{}\nbut could not find it in\n{}",
27+
expected,
28+
got,
29+
)
30+
}
31+
ExactOutputMismatch(diff: String) {
32+
description("Output was not as expected")
33+
display("{}", diff)
34+
}
35+
ErrorOutputMismatch(expected: String, got: String) {
36+
description("Stderr output was not as expected")
37+
display(
38+
"Expected stderr output to contain\n{}\nbut could not find it in\n{}",
39+
expected,
40+
got,
41+
)
42+
}
43+
ExactErrorOutputMismatch(diff: String) {
44+
description("Stderr output was not as expected")
45+
display("{}", diff)
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)