This commit is contained in:
eth-p 2018-05-12 14:00:25 -07:00
commit f7e055b6b7
No known key found for this signature in database
GPG Key ID: 1F8DF8091CD46FBC
22 changed files with 572 additions and 0 deletions

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
import itertools
import subprocess
import pathlib
import shutil
def generate_snapshots():
single_styles = ["changes", "grid", "header", "numbers"]
collective_styles = ["full", "plain"]
for num in range(len(single_styles)):
for grouped in itertools.combinations(single_styles, num + 1):
generate_snapshot(",".join(grouped))
for style in collective_styles:
generate_snapshot(style)
def generate_snapshot(option):
command = "../../target/debug/bat --style={0} sample.rs > output/{0}.snapshot.txt".format(
option
)
print("generating snapshot for {}".format(option))
subprocess.call(command, shell=True)
def prepare_output_dir():
shutil.rmtree("output", ignore_errors=True)
pathlib.Path("output").mkdir()
def modify_sample_file():
print("modifying sample.rs to show changes")
shutil.copyfile("sample.modified.rs", "sample.rs")
def undo_sample_file_modification():
print("undoing sample.rs modifications")
subprocess.call("git checkout -- sample.rs", shell=True)
prepare_output_dir()
modify_sample_file()
generate_snapshots()
undo_sample_file_modification()

View File

@ -0,0 +1,25 @@
───────┬────────────────────────────────────────────────────────────────────────
│ File: sample.rs
───────┼────────────────────────────────────────────────────────────────────────
1 │ struct Rectangle {
2 │ width: u32,
3 │ height: u32,
4 │ }
5 │
6 _ │ fn main() {
7 │ let rect1 = Rectangle { width: 30, height: 50 };
8 │
9 │ println!(
10 ~ │ "The perimeter of the rectangle is {} pixels.",
11 ~ │ perimeter(&rect1)
12 │ );
13 │ }
14 │
15 │ fn area(rectangle: &Rectangle) -> u32 {
16 │ rectangle.width * rectangle.height
17 │ }
18 + │
19 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
20 + │ (rectangle.width + rectangle.height) * 2
21 + │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,25 @@
───────┬────────────────────────────────────────────────────────────────────────
│ File: sample.rs
───────┼────────────────────────────────────────────────────────────────────────
│ struct Rectangle {
│ width: u32,
│ height: u32,
│ }
_ │ fn main() {
│ let rect1 = Rectangle { width: 30, height: 50 };
│ println!(
~ │ "The perimeter of the rectangle is {} pixels.",
~ │ perimeter(&rect1)
│ );
│ }
│ fn area(rectangle: &Rectangle) -> u32 {
│ rectangle.width * rectangle.height
│ }
+ │
+ │ fn perimeter(rectangle: &Rectangle) -> u32 {
+ │ (rectangle.width + rectangle.height) * 2
+ │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
1 │ struct Rectangle {
2 │ width: u32,
3 │ height: u32,
4 │ }
5 │
6 _ │ fn main() {
7 │ let rect1 = Rectangle { width: 30, height: 50 };
8 │
9 │ println!(
10 ~ │ "The perimeter of the rectangle is {} pixels.",
11 ~ │ perimeter(&rect1)
12 │ );
13 │ }
14 │
15 │ fn area(rectangle: &Rectangle) -> u32 {
16 │ rectangle.width * rectangle.height
17 │ }
18 + │
19 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
20 + │ (rectangle.width + rectangle.height) * 2
21 + │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
│ struct Rectangle {
│ width: u32,
│ height: u32,
│ }
_ │ fn main() {
│ let rect1 = Rectangle { width: 30, height: 50 };
│ println!(
~ │ "The perimeter of the rectangle is {} pixels.",
~ │ perimeter(&rect1)
│ );
│ }
│ fn area(rectangle: &Rectangle) -> u32 {
│ rectangle.width * rectangle.height
│ }
+ │
+ │ fn perimeter(rectangle: &Rectangle) -> u32 {
+ │ (rectangle.width + rectangle.height) * 2
+ │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
File: sample.rs
1 struct Rectangle {
2 width: u32,
3 height: u32,
4 }
5
6 _ fn main() {
7 let rect1 = Rectangle { width: 30, height: 50 };
8
9 println!(
10 ~ "The perimeter of the rectangle is {} pixels.",
11 ~ perimeter(&rect1)
12 );
13 }
14
15 fn area(rectangle: &Rectangle) -> u32 {
16 rectangle.width * rectangle.height
17 }
18 +
19 + fn perimeter(rectangle: &Rectangle) -> u32 {
20 + (rectangle.width + rectangle.height) * 2
21 + }

View File

@ -0,0 +1,22 @@
File: sample.rs
struct Rectangle {
width: u32,
height: u32,
}
_ fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
~ "The perimeter of the rectangle is {} pixels.",
~ perimeter(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
+
+ fn perimeter(rectangle: &Rectangle) -> u32 {
+ (rectangle.width + rectangle.height) * 2
+ }

View File

@ -0,0 +1,21 @@
1 struct Rectangle {
2 width: u32,
3 height: u32,
4 }
5
6 _ fn main() {
7 let rect1 = Rectangle { width: 30, height: 50 };
8
9 println!(
10 ~ "The perimeter of the rectangle is {} pixels.",
11 ~ perimeter(&rect1)
12 );
13 }
14
15 fn area(rectangle: &Rectangle) -> u32 {
16 rectangle.width * rectangle.height
17 }
18 +
19 + fn perimeter(rectangle: &Rectangle) -> u32 {
20 + (rectangle.width + rectangle.height) * 2
21 + }

View File

@ -0,0 +1,21 @@
struct Rectangle {
width: u32,
height: u32,
}
_ fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
~ "The perimeter of the rectangle is {} pixels.",
~ perimeter(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
+
+ fn perimeter(rectangle: &Rectangle) -> u32 {
+ (rectangle.width + rectangle.height) * 2
+ }

View File

@ -0,0 +1,25 @@
───────┬────────────────────────────────────────────────────────────────────────
│ File: sample.rs
───────┼────────────────────────────────────────────────────────────────────────
1 │ struct Rectangle {
2 │ width: u32,
3 │ height: u32,
4 │ }
5 │
6 _ │ fn main() {
7 │ let rect1 = Rectangle { width: 30, height: 50 };
8 │
9 │ println!(
10 ~ │ "The perimeter of the rectangle is {} pixels.",
11 ~ │ perimeter(&rect1)
12 │ );
13 │ }
14 │
15 │ fn area(rectangle: &Rectangle) -> u32 {
16 │ rectangle.width * rectangle.height
17 │ }
18 + │
19 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
20 + │ (rectangle.width + rectangle.height) * 2
21 + │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,25 @@
───────┬────────────────────────────────────────────────────────────────────────
│ File: sample.rs
───────┼────────────────────────────────────────────────────────────────────────
1 │ struct Rectangle {
2 │ width: u32,
3 │ height: u32,
4 │ }
5 │
6 │ fn main() {
7 │ let rect1 = Rectangle { width: 30, height: 50 };
8 │
9 │ println!(
10 │ "The perimeter of the rectangle is {} pixels.",
11 │ perimeter(&rect1)
12 │ );
13 │ }
14 │
15 │ fn area(rectangle: &Rectangle) -> u32 {
16 │ rectangle.width * rectangle.height
17 │ }
18 │
19 │ fn perimeter(rectangle: &Rectangle) -> u32 {
20 │ (rectangle.width + rectangle.height) * 2
21 │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,25 @@
───────┬────────────────────────────────────────────────────────────────────────
│ File: sample.rs
───────┼────────────────────────────────────────────────────────────────────────
│ struct Rectangle {
│ width: u32,
│ height: u32,
│ }
│ fn main() {
│ let rect1 = Rectangle { width: 30, height: 50 };
│ println!(
│ "The perimeter of the rectangle is {} pixels.",
│ perimeter(&rect1)
│ );
│ }
│ fn area(rectangle: &Rectangle) -> u32 {
│ rectangle.width * rectangle.height
│ }
│ fn perimeter(rectangle: &Rectangle) -> u32 {
│ (rectangle.width + rectangle.height) * 2
│ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
1 │ struct Rectangle {
2 │ width: u32,
3 │ height: u32,
4 │ }
5 │
6 │ fn main() {
7 │ let rect1 = Rectangle { width: 30, height: 50 };
8 │
9 │ println!(
10 │ "The perimeter of the rectangle is {} pixels.",
11 │ perimeter(&rect1)
12 │ );
13 │ }
14 │
15 │ fn area(rectangle: &Rectangle) -> u32 {
16 │ rectangle.width * rectangle.height
17 │ }
18 │
19 │ fn perimeter(rectangle: &Rectangle) -> u32 {
20 │ (rectangle.width + rectangle.height) * 2
21 │ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
│ struct Rectangle {
│ width: u32,
│ height: u32,
│ }
│ fn main() {
│ let rect1 = Rectangle { width: 30, height: 50 };
│ println!(
│ "The perimeter of the rectangle is {} pixels.",
│ perimeter(&rect1)
│ );
│ }
│ fn area(rectangle: &Rectangle) -> u32 {
│ rectangle.width * rectangle.height
│ }
│ fn perimeter(rectangle: &Rectangle) -> u32 {
│ (rectangle.width + rectangle.height) * 2
│ }
───────┴────────────────────────────────────────────────────────────────────────

View File

@ -0,0 +1,22 @@
File: sample.rs
1 struct Rectangle {
2 width: u32,
3 height: u32,
4 }
5
6 fn main() {
7 let rect1 = Rectangle { width: 30, height: 50 };
8
9 println!(
10 "The perimeter of the rectangle is {} pixels.",
11 perimeter(&rect1)
12 );
13 }
14
15 fn area(rectangle: &Rectangle) -> u32 {
16 rectangle.width * rectangle.height
17 }
18
19 fn perimeter(rectangle: &Rectangle) -> u32 {
20 (rectangle.width + rectangle.height) * 2
21 }

View File

@ -0,0 +1,22 @@
File: sample.rs
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
"The perimeter of the rectangle is {} pixels.",
perimeter(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
fn perimeter(rectangle: &Rectangle) -> u32 {
(rectangle.width + rectangle.height) * 2
}

View File

@ -0,0 +1,21 @@
1 struct Rectangle {
2 width: u32,
3 height: u32,
4 }
5
6 fn main() {
7 let rect1 = Rectangle { width: 30, height: 50 };
8
9 println!(
10 "The perimeter of the rectangle is {} pixels.",
11 perimeter(&rect1)
12 );
13 }
14
15 fn area(rectangle: &Rectangle) -> u32 {
16 rectangle.width * rectangle.height
17 }
18
19 fn perimeter(rectangle: &Rectangle) -> u32 {
20 (rectangle.width + rectangle.height) * 2
21 }

View File

@ -0,0 +1,21 @@
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
"The perimeter of the rectangle is {} pixels.",
perimeter(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
fn perimeter(rectangle: &Rectangle) -> u32 {
(rectangle.width + rectangle.height) * 2
}

View File

@ -0,0 +1,21 @@
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
"The perimeter of the rectangle is {} pixels.",
perimeter(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
fn perimeter(rectangle: &Rectangle) -> u32 {
(rectangle.width + rectangle.height) * 2
}

18
tests/snapshots/sample.rs Normal file
View File

@ -0,0 +1,18 @@
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
// width and height of a rectangle can be different
let rect1 = Rectangle { width: 30, height: 50 };
println!(
"The area of the rectangle is {} square pixels.",
area(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}

75
tests/tester.rs Normal file
View File

@ -0,0 +1,75 @@
use std::env;
use std::fs::{self, File};
use std::io::Read;
use std::path::PathBuf;
use std::process::Command;
pub struct BatTester {
exe: PathBuf,
}
impl BatTester {
pub fn new() -> Self {
modify_sample_file();
// Lifted from fd :)
let root = env::current_exe()
.expect("tests executable")
.parent()
.expect("tests executable directory")
.parent()
.expect("bat executable directory")
.to_path_buf();
let exe_name = if cfg!(windows) { "bat.exe" } else { "bat" };
BatTester {
exe: root.join(exe_name),
}
}
pub fn test_snapshot(&self, style: &str) {
let output = Command::new(&self.exe)
.args(&[
"tests/snapshots/sample.rs",
&format!("--style={}", style),
])
.output()
.expect("bat failed");
// have to do the replace because the filename in the header changes based on the current working directory
let actual = String::from_utf8_lossy(&output.stdout)
.as_ref()
.replace("tests/snapshots/", "");
let mut expected = String::new();
let mut file = File::open(format!("tests/snapshots/output/{}.snapshot.txt", style))
.expect("snapshot file missing");
file.read_to_string(&mut expected)
.expect("could not read snapshot file");
assert_eq!(expected, actual);
}
}
impl Drop for BatTester {
fn drop(&mut self) {
undo_sample_file_modification();
}
}
fn modify_sample_file() {
fs::copy(
"tests/snapshots/sample.modified.rs",
"tests/snapshots/sample.rs",
).expect("generating modified sample file failed");
}
fn undo_sample_file_modification() {
let output = Command::new("git")
.args(&["checkout", "--", "tests/snapshots/sample.rs"])
.output()
.expect("git checkout failed");
if !output.status.success() {
panic!("undoing modified sample changes failed")
}
}

33
tests/tests.rs Normal file
View File

@ -0,0 +1,33 @@
mod tester;
use tester::BatTester;
static STYLES: &'static [&'static str] = &[
"changes",
"grid",
"header",
"numbers",
"changes,grid",
"changes,header",
"changes,numbers",
"grid,header",
"grid,numbers",
"header,numbers",
"changes,grid,header",
"changes,grid,numbers",
"changes,header,numbers",
"grid,header,numbers",
"changes,grid,header,numbers",
"full",
"plain",
];
#[test]
fn test_snapshots() {
let bat_tester = BatTester::new();
for style in STYLES {
println!("testing {}", style);
bat_tester.test_snapshot(&*style);
}
}