style: add component 'rule' for horizontal file delimiter
Closes #1163 

Adds a new style argument `rule` (open to bikeshedding on the name), which adds a simple horizontal ruled line between files.

This line takes the place of padding (an empty line) that would otherwise be added anyway to delimit files, and is the same color as the grid style.

A couple of questions I had while implementing this:

- Should this style component be enabled by the `full` argument? This PR does not make it enabled by the `full` argument, becuase:
  - I don't think it is semantically correct (in my mind, `rule` is a subset of `grid` already)
  - it looks horrible
  - it would be a breaking change
- ~The snapshot tests do not cover the case of printing multiple files - should they?~
  - ~Currently, coverage of this new feature and the existing feature of `bat` delimiting files with whitespace is not covered. Happy to update the tests to cover this case, but it would probably be better in it's own PR?~
  - It's covered in the integration tests, added a new case there

---

Output examples:

```log
$ bat LICENSE-MIT LICENSE-MIT --style=rule,header,numbers
     File: LICENSE-MIT
   1 Copyright (c) 2018-2020 bat-developers (https://github.com/sharkdp/bat).
   2
...
  18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19 SOFTWARE.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────
     File: LICENSE-MIT
   1 Copyright (c) 2018-2020 bat-developers (https://github.com/sharkdp/bat).
   2
...
  18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19 SOFTWARE.
```

![image](https://user-images.githubusercontent.com/12255914/95229627-b3842d80-07f8-11eb-96b1-e914287e80d3.png)

I'm not a fan of having my `cat`-alike draw a full-blown table, but I would like to have some visible "end of file, beginning of next file" separation.

Unfortunately, `--style=header,grid` still draws the horizontal lines as if they were part of a table, resulting in two lines where only one is necessary:

![Spectacle J14905](https://user-images.githubusercontent.com/46915/91717467-1989ef00-eb81-11ea-9f23-3664eadc871d.png)

I also get back a full-blown table if I ask for something like line numbers.

What I'd really like is something more minimal than `grid`, which just draws a horizontal line above (or above and below) the `header` to make the change from one file to another more visible when paging through.
Alternative to `grid` for style which only draws a line between files
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b181ff3a39..2a549f9384 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 ## Features
 
 - Adjust pager configuration to comply with `--wrap=never`, see #1255 (@gahag)
+- Added a new `--style` value, `rule`, which adds a simple horizontal ruled line between files, see #1276 (@tommilligan)
 
 ## Bugfixes
 
diff --git a/assets/manual/bat.1.in b/assets/manual/bat.1.in
index a6846b5dd5..65a17fe130 100644
--- a/assets/manual/bat.1.in
+++ b/assets/manual/bat.1.in
@@ -129,7 +129,7 @@ Configure which elements (line numbers, file headers, grid borders, Git modifica
 of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full').
 To set a default style, add the '\-\-style=".."' option to the configuration file or
 export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
-values: *auto*, full, plain, changes, header, grid, numbers, snip.
+values: *auto*, full, plain, changes, header, grid, rule, numbers, snip.
 .HP
 \fB\-r\fR, \fB\-\-line\-range\fR <N:M>...
 .IP
diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs
index 8249e3c93b..8d09618cb4 100644
--- a/src/bin/bat/app.rs
+++ b/src/bin/bat/app.rs
@@ -288,8 +288,8 @@ impl App {
 
     fn style_components(&self) -> Result<StyleComponents> {
         let matches = &self.matches;
-        Ok(StyleComponents(
-            if matches.value_of("decorations") == Some("never") {
+        let mut styled_components =
+            StyleComponents(if matches.value_of("decorations") == Some("never") {
                 HashSet::new()
             } else if matches.is_present("number") {
                 [StyleComponent::LineNumbers].iter().cloned().collect()
@@ -323,7 +323,17 @@ impl App {
                         acc.extend(components.iter().cloned());
                         acc
                     })
-            },
-        ))
+            });
+
+        // If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning.
+        if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) {
+            use ansi_term::Colour::Yellow;
+            eprintln!(
+                "{}: Style 'rule' is a subset of style 'grid', 'rule' will not be visible.",
+                Yellow.paint("[bat warning]"),
+            );
+        }
+
+        Ok(styled_components)
     }
 }
diff --git a/src/bin/bat/clap_app.rs b/src/bin/bat/clap_app.rs
index d04abd8a43..4e642760c8 100644
--- a/src/bin/bat/clap_app.rs
+++ b/src/bin/bat/clap_app.rs
@@ -367,7 +367,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
                 .validator(|val| {
                     let mut invalid_vals = val.split(',').filter(|style| {
                         !&[
-                            "auto", "full", "plain", "header", "grid", "numbers", "snip",
+                            "auto", "full", "plain", "header", "grid", "rule", "numbers", "snip",
                             #[cfg(feature = "git")]
                                 "changes",
                         ]
@@ -382,7 +382,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
                 })
                 .help(
                     "Comma-separated list of style elements to display \
-                     (*auto*, full, plain, changes, header, grid, numbers, snip).",
+                     (*auto*, full, plain, changes, header, grid, rule, numbers, snip).",
                 )
                 .long_help(
                     "Configure which elements (line numbers, file headers, grid \
@@ -400,6 +400,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
                      * header: show filenames before the content.\n  \
                      * grid: vertical/horizontal lines to separate side bar\n          \
                        and the header from the content.\n  \
+                     * rule: horizontal lines to delimit files.\n  \
                      * numbers: show line numbers in the side bar.\n  \
                      * snip: draw separation lines between distinct line ranges.",
                 ),
diff --git a/src/pretty_printer.rs b/src/pretty_printer.rs
index c9530bf405..89745eecd8 100644
--- a/src/pretty_printer.rs
+++ b/src/pretty_printer.rs
@@ -23,6 +23,7 @@ struct ActiveStyleComponents {
     header: bool,
     vcs_modification_markers: bool,
     grid: bool,
+    rule: bool,
     line_numbers: bool,
     snip: bool,
 }
@@ -179,6 +180,12 @@ impl<'a> PrettyPrinter<'a> {
         self
     }
 
+    /// Whether to paint a horizontal rule to delimit files
+    pub fn rule(&mut self, yes: bool) -> &mut Self {
+        self.active_style_components.rule = yes;
+        self
+    }
+
     /// Whether to show modification markers for VCS changes. This has no effect if
     /// the `git` feature is not activated.
     #[cfg_attr(
@@ -285,6 +292,9 @@ impl<'a> PrettyPrinter<'a> {
         if self.active_style_components.grid {
             style_components.push(StyleComponent::Grid);
         }
+        if self.active_style_components.rule {
+            style_components.push(StyleComponent::Rule);
+        }
         if self.active_style_components.header {
             style_components.push(StyleComponent::Header);
         }
diff --git a/src/printer.rs b/src/printer.rs
index 71bf78ee32..e082987489 100644
--- a/src/printer.rs
+++ b/src/printer.rs
@@ -200,13 +200,18 @@ impl<'a> InteractivePrinter<'a> {
         })
     }
 
+    fn print_horizontal_line_term(&mut self, handle: &mut dyn Write, style: Style) -> Result<()> {
+        writeln!(
+            handle,
+            "{}",
+            style.paint("─".repeat(self.config.term_width))
+        )?;
+        Ok(())
+    }
+
     fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> {
         if self.panel_width == 0 {
-            writeln!(
-                handle,
-                "{}",
-                self.colors.grid.paint("─".repeat(self.config.term_width))
-            )?;
+            self.print_horizontal_line_term(handle, self.colors.grid)?;
         } else {
             let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
             let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
@@ -251,6 +256,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
         input: &OpenedInput,
         add_header_padding: bool,
     ) -> Result<()> {
+        if add_header_padding && self.config.style_components.rule() {
+            self.print_horizontal_line_term(handle, self.colors.rule)?;
+        }
+
         if !self.config.style_components.header() {
             if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
                 writeln!(
@@ -279,7 +288,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
                     .paint(if self.panel_width > 0 { "│ " } else { "" }),
             )?;
         } else {
-            if add_header_padding {
+            // Only pad space between files, if we haven't already drawn a horizontal rule
+            if add_header_padding && !self.config.style_components.rule() {
                 writeln!(handle)?;
             }
             write!(handle, "{}", " ".repeat(self.panel_width))?;
@@ -603,6 +613,7 @@ const DEFAULT_GUTTER_COLOR: u8 = 238;
 #[derive(Debug, Default)]
 pub struct Colors {
     pub grid: Style,
+    pub rule: Style,
     pub filename: Style,
     pub git_added: Style,
     pub git_removed: Style,
@@ -624,6 +635,7 @@ impl Colors {
 
         Colors {
             grid: gutter_color.normal(),
+            rule: gutter_color.normal(),
             filename: Style::new().bold(),
             git_added: Green.normal(),
             git_removed: Red.normal(),
diff --git a/src/style.rs b/src/style.rs
index 8d51cbded2..654142068b 100644
--- a/src/style.rs
+++ b/src/style.rs
@@ -9,6 +9,7 @@ pub enum StyleComponent {
     #[cfg(feature = "git")]
     Changes,
     Grid,
+    Rule,
     Header,
     LineNumbers,
     Snip,
@@ -29,6 +30,7 @@ impl StyleComponent {
             #[cfg(feature = "git")]
             StyleComponent::Changes => &[StyleComponent::Changes],
             StyleComponent::Grid => &[StyleComponent::Grid],
+            StyleComponent::Rule => &[StyleComponent::Rule],
             StyleComponent::Header => &[StyleComponent::Header],
             StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
             StyleComponent::Snip => &[StyleComponent::Snip],
@@ -54,6 +56,7 @@ impl FromStr for StyleComponent {
             #[cfg(feature = "git")]
             "changes" => Ok(StyleComponent::Changes),
             "grid" => Ok(StyleComponent::Grid),
+            "rule" => Ok(StyleComponent::Rule),
             "header" => Ok(StyleComponent::Header),
             "numbers" => Ok(StyleComponent::LineNumbers),
             "snip" => Ok(StyleComponent::Snip),
@@ -81,6 +84,10 @@ impl StyleComponents {
         self.0.contains(&StyleComponent::Grid)
     }
 
+    pub fn rule(&self) -> bool {
+        self.0.contains(&StyleComponent::Rule)
+    }
+
     pub fn header(&self) -> bool {
         self.0.contains(&StyleComponent::Header)
     }

diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs
index da0690efcc..f8ff60a59f 100644
--- a/tests/integration_tests.rs
+++ b/tests/integration_tests.rs
@@ -570,6 +570,18 @@ fn empty_file_leads_to_empty_output_with_grid_enabled() {
         .stdout("");
 }
 
+#[test]
+fn empty_file_leads_to_empty_output_with_rule_enabled() {
+    bat()
+        .arg("empty.txt")
+        .arg("--style=rule")
+        .arg("--decorations=always")
+        .arg("--terminal-width=80")
+        .assert()
+        .success()
+        .stdout("");
+}
+
 #[test]
 fn filename_basic() {
     bat()
@@ -668,6 +680,48 @@ fn header_padding() {
         .stderr("");
 }
 
+#[test]
+fn header_padding_rule() {
+    bat()
+        .arg("--decorations=always")
+        .arg("--style=header,rule")
+        .arg("--terminal-width=80")
+        .arg("test.txt")
+        .arg("single-line.txt")
+        .assert()
+        .stdout(
+            "File: test.txt
+hello world
+────────────────────────────────────────────────────────────────────────────────
+File: single-line.txt
+Single Line
+",
+        )
+        .stderr("");
+}
+
+#[test]
+fn grid_overrides_rule() {
+    bat()
+        .arg("--decorations=always")
+        .arg("--style=grid,rule")
+        .arg("--terminal-width=80")
+        .arg("test.txt")
+        .arg("single-line.txt")
+        .assert()
+        .stdout(
+            "\
+────────────────────────────────────────────────────────────────────────────────
+hello world
+────────────────────────────────────────────────────────────────────────────────
+────────────────────────────────────────────────────────────────────────────────
+Single Line
+────────────────────────────────────────────────────────────────────────────────
+",
+        )
+        .stderr("\x1b[33m[bat warning]\x1b[0m: Style 'rule' is a subset of style 'grid', 'rule' will not be visible.\n");
+}
+
 #[cfg(target_os = "linux")]
 #[test]
 fn file_with_invalid_utf8_filename() {
diff --git a/tests/snapshot_tests.rs b/tests/snapshot_tests.rs
index ad41edb25b..8abb841412 100644
--- a/tests/snapshot_tests.rs
+++ b/tests/snapshot_tests.rs
@@ -19,17 +19,27 @@ snapshot_tests! {
     grid:                        "grid",
     header:                      "header",
     numbers:                     "numbers",
+    rule:                        "rule",
     changes_grid:                "changes,grid",
     changes_header:              "changes,header",
     changes_numbers:             "changes,numbers",
+    changes_rule:                "changes,rule",
     grid_header:                 "grid,header",
     grid_numbers:                "grid,numbers",
+    grid_rule:                   "grid,rule",
     header_numbers:              "header,numbers",
+    header_rule:                 "header,rule",
     changes_grid_header:         "changes,grid,header",
     changes_grid_numbers:        "changes,grid,numbers",
+    changes_grid_rule:           "changes,grid,rule",
     changes_header_numbers:      "changes,header,numbers",
+    changes_header_rule:         "changes,header,rule",
     grid_header_numbers:         "grid,header,numbers",
+    grid_header_rule:            "grid,header,rule",
+    header_numbers_rule:         "header,numbers,rule",
     changes_grid_header_numbers: "changes,grid,header,numbers",
+    changes_grid_header_rule:    "changes,grid,header,rule",
+    changes_grid_header_numbers_rule: "changes,grid,header,numbers,rule",
     full:                        "full",
     plain:                       "plain",
 }
diff --git a/tests/snapshots/generate_snapshots.py b/tests/snapshots/generate_snapshots.py
index fd17b28513..bb7d69ba16 100755
--- a/tests/snapshots/generate_snapshots.py
+++ b/tests/snapshots/generate_snapshots.py
@@ -7,7 +7,7 @@
 
 
 def generate_snapshots():
-    single_styles = ["changes", "grid", "header", "numbers"]
+    single_styles = ["changes", "grid", "header", "numbers", "rule"]
     collective_styles = ["full", "plain"]
 
     for num in range(len(single_styles)):
diff --git a/tests/snapshots/output/changes_grid_header_numbers_rule.snapshot.txt b/tests/snapshots/output/changes_grid_header_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..cee4737f4d
--- /dev/null
+++ b/tests/snapshots/output/changes_grid_header_numbers_rule.snapshot.txt
@@ -0,0 +1,26 @@
+───────┬────────────────────────────────────────────────────────────────────────
+       │ 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 + │     println!(r#"This line contains invalid utf8:  "�����"#;
+  14   │ }
+  15   │ 
+  16   │ fn area(rectangle: &Rectangle) -> u32 {
+  17   │     rectangle.width * rectangle.height
+  18   │ }
+  19 + │ 
+  20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 + │     (rectangle.width + rectangle.height) * 2
+  22 + │ }
+───────┴────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/changes_grid_header_rule.snapshot.txt b/tests/snapshots/output/changes_grid_header_rule.snapshot.txt
new file mode 100644
index 0000000000..655b6e248f
--- /dev/null
+++ b/tests/snapshots/output/changes_grid_header_rule.snapshot.txt
@@ -0,0 +1,26 @@
+──┬─────────────────────────────────────────────────────────────────────────────
+  │ 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)
+  │     );
++ │     println!(r#"This line contains invalid utf8:  "�����"#;
+  │ }
+  │ 
+  │ fn area(rectangle: &Rectangle) -> u32 {
+  │     rectangle.width * rectangle.height
+  │ }
++ │ 
++ │ fn perimeter(rectangle: &Rectangle) -> u32 {
++ │     (rectangle.width + rectangle.height) * 2
++ │ }
+──┴─────────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/changes_grid_numbers_rule.snapshot.txt b/tests/snapshots/output/changes_grid_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..7fe7cccfdc
--- /dev/null
+++ b/tests/snapshots/output/changes_grid_numbers_rule.snapshot.txt
@@ -0,0 +1,24 @@
+───────┬────────────────────────────────────────────────────────────────────────
+   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 + │     println!(r#"This line contains invalid utf8:  "�����"#;
+  14   │ }
+  15   │ 
+  16   │ fn area(rectangle: &Rectangle) -> u32 {
+  17   │     rectangle.width * rectangle.height
+  18   │ }
+  19 + │ 
+  20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 + │     (rectangle.width + rectangle.height) * 2
+  22 + │ }
+───────┴────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/changes_grid_rule.snapshot.txt b/tests/snapshots/output/changes_grid_rule.snapshot.txt
new file mode 100644
index 0000000000..04767b8b3a
--- /dev/null
+++ b/tests/snapshots/output/changes_grid_rule.snapshot.txt
@@ -0,0 +1,24 @@
+──┬─────────────────────────────────────────────────────────────────────────────
+  │ 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)
+  │     );
++ │     println!(r#"This line contains invalid utf8:  "�����"#;
+  │ }
+  │ 
+  │ fn area(rectangle: &Rectangle) -> u32 {
+  │     rectangle.width * rectangle.height
+  │ }
++ │ 
++ │ fn perimeter(rectangle: &Rectangle) -> u32 {
++ │     (rectangle.width + rectangle.height) * 2
++ │ }
+──┴─────────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/changes_header_numbers_rule.snapshot.txt b/tests/snapshots/output/changes_header_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..77145eb9b2
--- /dev/null
+++ b/tests/snapshots/output/changes_header_numbers_rule.snapshot.txt
@@ -0,0 +1,23 @@
+       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 +     println!(r#"This line contains invalid utf8:  "�����"#;
+  14   }
+  15   
+  16   fn area(rectangle: &Rectangle) -> u32 {
+  17       rectangle.width * rectangle.height
+  18   }
+  19 + 
+  20 + fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 +     (rectangle.width + rectangle.height) * 2
+  22 + }
diff --git a/tests/snapshots/output/changes_header_rule.snapshot.txt b/tests/snapshots/output/changes_header_rule.snapshot.txt
new file mode 100644
index 0000000000..82fe8c47cb
--- /dev/null
+++ b/tests/snapshots/output/changes_header_rule.snapshot.txt
@@ -0,0 +1,23 @@
+  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)
+      );
++     println!(r#"This line contains invalid utf8:  "�����"#;
+  }
+  
+  fn area(rectangle: &Rectangle) -> u32 {
+      rectangle.width * rectangle.height
+  }
++ 
++ fn perimeter(rectangle: &Rectangle) -> u32 {
++     (rectangle.width + rectangle.height) * 2
++ }
diff --git a/tests/snapshots/output/changes_numbers_rule.snapshot.txt b/tests/snapshots/output/changes_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..bdfe745bff
--- /dev/null
+++ b/tests/snapshots/output/changes_numbers_rule.snapshot.txt
@@ -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 +     println!(r#"This line contains invalid utf8:  "�����"#;
+  14   }
+  15   
+  16   fn area(rectangle: &Rectangle) -> u32 {
+  17       rectangle.width * rectangle.height
+  18   }
+  19 + 
+  20 + fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 +     (rectangle.width + rectangle.height) * 2
+  22 + }
diff --git a/tests/snapshots/output/changes_rule.snapshot.txt b/tests/snapshots/output/changes_rule.snapshot.txt
new file mode 100644
index 0000000000..28d87201f0
--- /dev/null
+++ b/tests/snapshots/output/changes_rule.snapshot.txt
@@ -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)
+      );
++     println!(r#"This line contains invalid utf8:  "�����"#;
+  }
+  
+  fn area(rectangle: &Rectangle) -> u32 {
+      rectangle.width * rectangle.height
+  }
++ 
++ fn perimeter(rectangle: &Rectangle) -> u32 {
++     (rectangle.width + rectangle.height) * 2
++ }
diff --git a/tests/snapshots/output/grid_header_numbers_rule.snapshot.txt b/tests/snapshots/output/grid_header_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..e9f1a9cfe6
--- /dev/null
+++ b/tests/snapshots/output/grid_header_numbers_rule.snapshot.txt
@@ -0,0 +1,26 @@
+─────┬──────────────────────────────────────────────────────────────────────────
+     │ 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 │     println!(r#"This line contains invalid utf8:  "�����"#;
+  14 │ }
+  15 │ 
+  16 │ fn area(rectangle: &Rectangle) -> u32 {
+  17 │     rectangle.width * rectangle.height
+  18 │ }
+  19 │ 
+  20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 │     (rectangle.width + rectangle.height) * 2
+  22 │ }
+─────┴──────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/grid_header_rule.snapshot.txt b/tests/snapshots/output/grid_header_rule.snapshot.txt
new file mode 100644
index 0000000000..50c16941e9
--- /dev/null
+++ b/tests/snapshots/output/grid_header_rule.snapshot.txt
@@ -0,0 +1,26 @@
+────────────────────────────────────────────────────────────────────────────────
+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)
+    );
+    println!(r#"This line contains invalid utf8:  "�����"#;
+}
+
+fn area(rectangle: &Rectangle) -> u32 {
+    rectangle.width * rectangle.height
+}
+
+fn perimeter(rectangle: &Rectangle) -> u32 {
+    (rectangle.width + rectangle.height) * 2
+}
+────────────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/grid_numbers_rule.snapshot.txt b/tests/snapshots/output/grid_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..0961466704
--- /dev/null
+++ b/tests/snapshots/output/grid_numbers_rule.snapshot.txt
@@ -0,0 +1,24 @@
+─────┬──────────────────────────────────────────────────────────────────────────
+   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 │     println!(r#"This line contains invalid utf8:  "�����"#;
+  14 │ }
+  15 │ 
+  16 │ fn area(rectangle: &Rectangle) -> u32 {
+  17 │     rectangle.width * rectangle.height
+  18 │ }
+  19 │ 
+  20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
+  21 │     (rectangle.width + rectangle.height) * 2
+  22 │ }
+─────┴──────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/grid_rule.snapshot.txt b/tests/snapshots/output/grid_rule.snapshot.txt
new file mode 100644
index 0000000000..5b970581f5
--- /dev/null
+++ b/tests/snapshots/output/grid_rule.snapshot.txt
@@ -0,0 +1,24 @@
+────────────────────────────────────────────────────────────────────────────────
+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)
+    );
+    println!(r#"This line contains invalid utf8:  "�����"#;
+}
+
+fn area(rectangle: &Rectangle) -> u32 {
+    rectangle.width * rectangle.height
+}
+
+fn perimeter(rectangle: &Rectangle) -> u32 {
+    (rectangle.width + rectangle.height) * 2
+}
+────────────────────────────────────────────────────────────────────────────────
diff --git a/tests/snapshots/output/header_numbers_rule.snapshot.txt b/tests/snapshots/output/header_numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..a681e6b407
--- /dev/null
+++ b/tests/snapshots/output/header_numbers_rule.snapshot.txt
@@ -0,0 +1,23 @@
+     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     println!(r#"This line contains invalid utf8:  "�����"#;
+  14 }
+  15 
+  16 fn area(rectangle: &Rectangle) -> u32 {
+  17     rectangle.width * rectangle.height
+  18 }
+  19 
+  20 fn perimeter(rectangle: &Rectangle) -> u32 {
+  21     (rectangle.width + rectangle.height) * 2
+  22 }
diff --git a/tests/snapshots/output/header_rule.snapshot.txt b/tests/snapshots/output/header_rule.snapshot.txt
new file mode 100644
index 0000000000..0889edfd32
--- /dev/null
+++ b/tests/snapshots/output/header_rule.snapshot.txt
@@ -0,0 +1,23 @@
+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)
+    );
+    println!(r#"This line contains invalid utf8:  "�����"#;
+}
+
+fn area(rectangle: &Rectangle) -> u32 {
+    rectangle.width * rectangle.height
+}
+
+fn perimeter(rectangle: &Rectangle) -> u32 {
+    (rectangle.width + rectangle.height) * 2
+}
diff --git a/tests/snapshots/output/numbers_rule.snapshot.txt b/tests/snapshots/output/numbers_rule.snapshot.txt
new file mode 100644
index 0000000000..c1341d29df
--- /dev/null
+++ b/tests/snapshots/output/numbers_rule.snapshot.txt
@@ -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     println!(r#"This line contains invalid utf8:  "�����"#;
+  14 }
+  15 
+  16 fn area(rectangle: &Rectangle) -> u32 {
+  17     rectangle.width * rectangle.height
+  18 }
+  19 
+  20 fn perimeter(rectangle: &Rectangle) -> u32 {
+  21     (rectangle.width + rectangle.height) * 2
+  22 }
diff --git a/tests/snapshots/output/rule.snapshot.txt b/tests/snapshots/output/rule.snapshot.txt
new file mode 100644
index 0000000000..dbc49f9fdd
--- /dev/null
+++ b/tests/snapshots/output/rule.snapshot.txt
@@ -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)
+    );
+    println!(r#"This line contains invalid utf8:  "�����"#;
+}
+
+fn area(rectangle: &Rectangle) -> u32 {
+    rectangle.width * rectangle.height
+}
+
+fn perimeter(rectangle: &Rectangle) -> u32 {
+    (rectangle.width + rectangle.height) * 2
+}

{"header_padding_rule": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_grid_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "grid_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header_numbers_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_grid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "no_duplicate_extensions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "full": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "grid_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "grid_overrides_rule": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "changes_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "header_numbers_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "empty_file_leads_to_empty_output_with_rule_enabled": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "changes_grid_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "plain": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"assets::tests::syntax_detection_stdin_filename": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_4_wrapped": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "less::test_parse_less_version_529": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_4": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "does_not_print_unwanted_file_named_cache": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_with_custom_mapping": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_empty_between": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_parse_partial_min": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_multiple_err": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_open_high": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range_last_3": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::default_config_should_include_all_lines": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_is_case_sensitive": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "syntax_mapping::user_can_override_builtin_mappings": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "do_not_detect_different_syntax_for_stdin_and_files": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "input::utf16le": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_stdin": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "pager_disable": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_stdin_binary": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_8_wrapped": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_numbers": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "less::test_parse_less_version_551": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_well_defined_mapping_for_duplicate_extensions": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_parse_single": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "pager_basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_empty_last": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_binary": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "snip": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "header_padding": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_parse_fail": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_same_for_inputkinds": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_all": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "can_print_file_starting_with_cache": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_stdin": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "show_all_mode": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::multi_line": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_parse_partial_max": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_passthrough_wrapped": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_single_line": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_numbers": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "stdin": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range_first_two": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "file_with_invalid_utf8_filename": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "fail_directory": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_simple": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "alias_pager_disable_long_overrides_short": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_for_symlinked_file": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "all_themes_are_present": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "less::test_parse_less_version_wrong_program": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "utf16": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "less::test_parse_less_version_487": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_open_low": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_invalid_utf8": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "syntax_mapping::basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "empty_file_leads_to_empty_output_with_grid_enabled": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "unicode_wrap": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "pager_overwrite": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::comments": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::quotes": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_single_line_empty": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_passthrough": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config_read_arguments_from_file": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "preprocessor::test_try_parse_utf8_char": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_none": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::empty": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_empty_both": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::multiple": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "assets::tests::syntax_detection_first_line": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range_multiple": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "input::basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "alias_pager_disable": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_empty_first_and_last": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_multiple_ok": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::default_config_should_highlight_no_lines": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "syntax_mapping::builtin_mappings": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "fail_non_existing": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_ranges_advanced": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filename_basic": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range_2_3": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "do_not_panic_regression_tests": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "can_print_file_named_cache": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config_location_test": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "do_not_exit_directory": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "can_print_file_named_cache_with_additional_argument": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "tabs_8": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "config::single": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "concatenate_empty_first": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "line_range::test_parse_full": {"run": "PASS", "test": "PASS", "fix": "PASS"}}
{"header_padding_rule": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "grid_overrides_rule": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "empty_file_leads_to_empty_output_with_rule_enabled": {"run": "NONE", "test": "FAIL", "fix": "PASS"}}
{"header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_grid_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "grid_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header_numbers_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_grid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "no_duplicate_extensions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "full": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_grid_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "grid_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_header_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "header_numbers_rule": {"run": "NONE", "test": "NONE", "fix": "PASS"}, "changes_grid_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_numbers": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "changes_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "grid_header": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "plain": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 109, "failed_count": 0, "skipped_count": 0, "passed_tests": ["basic", "tabs_4", "assets::tests::syntax_detection_with_custom_mapping", "header", "filename_multiple_err", "line_range::test_ranges_open_high", "line_range_last_3", "assets::tests::syntax_detection_is_case_sensitive", "syntax_mapping::user_can_override_builtin_mappings", "input::utf16le", "grid_numbers", "pager_disable", "filename_stdin_binary", "tabs_8_wrapped", "line_numbers", "assets::tests::syntax_detection_well_defined_mapping_for_duplicate_extensions", "concatenate_empty_last", "filename_binary", "snip", "header_padding", "line_range::test_parse_fail", "concatenate", "can_print_file_starting_with_cache", "filename_stdin", "show_all_mode", "line_range::test_parse_partial_max", "changes", "changes_grid", "concatenate_single_line", "tabs_numbers", "stdin", "line_range_first_two", "file_with_invalid_utf8_filename", "fail_directory", "less::test_parse_less_version_wrong_program", "line_range::test_ranges_open_low", "assets::tests::syntax_detection_invalid_utf8", "no_duplicate_extensions", "full", "empty_file_leads_to_empty_output_with_grid_enabled", "pager_overwrite", "config::quotes", "concatenate_single_line_empty", "tabs_passthrough", "preprocessor::test_try_parse_utf8_char", "line_range::test_ranges_none", "config::empty", "concatenate_empty_both", "line_range_multiple", "input::basic", "filename_multiple_ok", "config::default_config_should_highlight_no_lines", "line_range::test_ranges_advanced", "filename_basic", "line_range_2_3", "changes_header", "grid_header", "can_print_file_named_cache_with_additional_argument", "tabs_8", "plain", "config::single", "concatenate_empty_first", "line_range::test_parse_full", "assets::tests::syntax_detection_stdin_filename", "tabs_4_wrapped", "less::test_parse_less_version_529", "does_not_print_unwanted_file_named_cache", "concatenate_empty_between", "line_range::test_parse_partial_min", "changes_grid_header", "config::default_config_should_include_all_lines", "do_not_detect_different_syntax_for_stdin_and_files", "concatenate_stdin", "header_numbers", "less::test_parse_less_version_551", "line_range::test_parse_single", "pager_basic", "grid_header_numbers", "assets::tests::syntax_detection_same_for_inputkinds", "line_range::test_ranges_all", "config::multi_line", "tabs_passthrough_wrapped", "line_range::test_ranges_simple", "alias_pager_disable_long_overrides_short", "assets::tests::syntax_detection_for_symlinked_file", "all_themes_are_present", "utf16", "less::test_parse_less_version_487", "numbers", "syntax_mapping::basic", "unicode_wrap", "config::comments", "changes_grid_header_numbers", "config_read_arguments_from_file", "assets::tests::syntax_detection_basic", "config::multiple", "assets::tests::syntax_detection_first_line", "changes_header_numbers", "alias_pager_disable", "concatenate_empty_first_and_last", "syntax_mapping::builtin_mappings", "fail_non_existing", "changes_grid_numbers", "grid", "changes_numbers", "do_not_panic_regression_tests", "can_print_file_named_cache", "config_location_test", "do_not_exit_directory"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 91, "failed_count": 3, "skipped_count": 0, "passed_tests": ["basic", "tabs_4", "assets::tests::syntax_detection_with_custom_mapping", "filename_multiple_err", "line_range::test_ranges_open_high", "line_range_last_3", "assets::tests::syntax_detection_is_case_sensitive", "syntax_mapping::user_can_override_builtin_mappings", "input::utf16le", "pager_disable", "filename_stdin_binary", "tabs_8_wrapped", "line_numbers", "assets::tests::syntax_detection_well_defined_mapping_for_duplicate_extensions", "concatenate_empty_last", "filename_binary", "snip", "header_padding", "line_range::test_parse_fail", "concatenate", "show_all_mode", "can_print_file_starting_with_cache", "filename_stdin", "line_range::test_parse_partial_max", "concatenate_single_line", "tabs_numbers", "stdin", "line_range_first_two", "file_with_invalid_utf8_filename", "fail_directory", "less::test_parse_less_version_wrong_program", "line_range::test_ranges_open_low", "assets::tests::syntax_detection_invalid_utf8", "empty_file_leads_to_empty_output_with_grid_enabled", "pager_overwrite", "config::quotes", "concatenate_single_line_empty", "tabs_passthrough", "line_range::test_ranges_none", "preprocessor::test_try_parse_utf8_char", "config::empty", "concatenate_empty_both", "line_range_multiple", "input::basic", "filename_multiple_ok", "config::default_config_should_highlight_no_lines", "line_range::test_ranges_advanced", "filename_basic", "line_range_2_3", "can_print_file_named_cache_with_additional_argument", "tabs_8", "config::single", "concatenate_empty_first", "line_range::test_parse_full", "assets::tests::syntax_detection_stdin_filename", "tabs_4_wrapped", "less::test_parse_less_version_529", "does_not_print_unwanted_file_named_cache", "concatenate_empty_between", "line_range::test_parse_partial_min", "config::default_config_should_include_all_lines", "do_not_detect_different_syntax_for_stdin_and_files", "concatenate_stdin", "less::test_parse_less_version_551", "line_range::test_parse_single", "pager_basic", "assets::tests::syntax_detection_same_for_inputkinds", "line_range::test_ranges_all", "config::multi_line", "tabs_passthrough_wrapped", "line_range::test_ranges_simple", "alias_pager_disable_long_overrides_short", "assets::tests::syntax_detection_for_symlinked_file", "all_themes_are_present", "utf16", "less::test_parse_less_version_487", "syntax_mapping::basic", "unicode_wrap", "config::comments", "config_read_arguments_from_file", "assets::tests::syntax_detection_basic", "config::multiple", "assets::tests::syntax_detection_first_line", "alias_pager_disable", "concatenate_empty_first_and_last", "syntax_mapping::builtin_mappings", "fail_non_existing", "do_not_panic_regression_tests", "can_print_file_named_cache", "config_location_test", "do_not_exit_directory"], "failed_tests": ["grid_overrides_rule", "empty_file_leads_to_empty_output_with_rule_enabled", "header_padding_rule"], "skipped_tests": []}
{"passed_count": 122, "failed_count": 0, "skipped_count": 0, "passed_tests": ["basic", "tabs_4", "assets::tests::syntax_detection_with_custom_mapping", "header", "filename_multiple_err", "line_range::test_ranges_open_high", "line_range_last_3", "assets::tests::syntax_detection_is_case_sensitive", "syntax_mapping::user_can_override_builtin_mappings", "input::utf16le", "grid_numbers", "changes_header_rule", "pager_disable", "filename_stdin_binary", "tabs_8_wrapped", "line_numbers", "assets::tests::syntax_detection_well_defined_mapping_for_duplicate_extensions", "concatenate_empty_last", "filename_binary", "snip", "header_padding", "line_range::test_parse_fail", "concatenate", "show_all_mode", "filename_stdin", "can_print_file_starting_with_cache", "line_range::test_parse_partial_max", "changes", "changes_grid", "concatenate_single_line", "tabs_numbers", "stdin", "line_range_first_two", "file_with_invalid_utf8_filename", "fail_directory", "less::test_parse_less_version_wrong_program", "line_range::test_ranges_open_low", "assets::tests::syntax_detection_invalid_utf8", "no_duplicate_extensions", "full", "empty_file_leads_to_empty_output_with_grid_enabled", "pager_overwrite", "config::quotes", "concatenate_single_line_empty", "tabs_passthrough", "line_range::test_ranges_none", "preprocessor::test_try_parse_utf8_char", "config::empty", "grid_rule", "concatenate_empty_both", "line_range_multiple", "input::basic", "header_numbers_rule", "filename_multiple_ok", "config::default_config_should_highlight_no_lines", "empty_file_leads_to_empty_output_with_rule_enabled", "line_range::test_ranges_advanced", "filename_basic", "line_range_2_3", "changes_header", "grid_header", "can_print_file_named_cache_with_additional_argument", "tabs_8", "plain", "config::single", "concatenate_empty_first", "line_range::test_parse_full", "assets::tests::syntax_detection_stdin_filename", "tabs_4_wrapped", "less::test_parse_less_version_529", "does_not_print_unwanted_file_named_cache", "concatenate_empty_between", "line_range::test_parse_partial_min", "header_padding_rule", "changes_grid_header", "changes_grid_rule", "config::default_config_should_include_all_lines", "changes_grid_header_rule", "do_not_detect_different_syntax_for_stdin_and_files", "header_rule", "concatenate_stdin", "rule", "header_numbers", "less::test_parse_less_version_551", "line_range::test_parse_single", "pager_basic", "grid_header_numbers", "changes_rule", "assets::tests::syntax_detection_same_for_inputkinds", "line_range::test_ranges_all", "config::multi_line", "changes_grid_header_numbers_rule", "tabs_passthrough_wrapped", "line_range::test_ranges_simple", "alias_pager_disable_long_overrides_short", "assets::tests::syntax_detection_for_symlinked_file", "all_themes_are_present", "utf16", "grid_header_rule", "less::test_parse_less_version_487", "numbers", "syntax_mapping::basic", "unicode_wrap", "config::comments", "changes_grid_header_numbers", "config_read_arguments_from_file", "assets::tests::syntax_detection_basic", "config::multiple", "assets::tests::syntax_detection_first_line", "grid_overrides_rule", "changes_header_numbers", "alias_pager_disable", "concatenate_empty_first_and_last", "syntax_mapping::builtin_mappings", "fail_non_existing", "changes_grid_numbers", "grid", "changes_numbers", "do_not_panic_regression_tests", "can_print_file_named_cache", "config_location_test", "do_not_exit_directory"], "failed_tests": [], "skipped_tests": []}