Skip to content

Commit

Permalink
Add insta-based snapshot tests that cover side-by-side format
Browse files Browse the repository at this point in the history
I'm going to fix inline diff issue #704, and found that the inline format isn't
covered by CLI tests. I could duplicate compare_all.sh to test various formats,
but it's uneasy to review that a new formatting is better than the previous
version. I think snapshot testing will help guarantee the output quality without
increasing maintenance burden too much.

If we like the idea, maybe we can migrate some of compare_all.sh tests to the
insta-based ones.

Note that this will add ~10sec to "cargo test" runs.
  • Loading branch information
yuja committed Jun 13, 2024
1 parent 3649807 commit 902cd93
Show file tree
Hide file tree
Showing 86 changed files with 1,982 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ flamegraph.svg
.idea

sample_files/compare.result
tests/snapshots/*.snap.new

notes.md
9 changes: 9 additions & 0 deletions manual/src/adding_a_parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ $ ./sample_files/compare_all.sh
$ cp sample_files/compare.result sample_files/compare.expected
```

Run the CLI test and [update the snapshots][insta] as well.

```
$ cargo insta test
$ cargo insta accept
```

[insta]: https://insta.rs/docs/quickstart/#reviewing-snapshots

## Maintenance

To update a parser that is already imported, use `git subtree pull`.
Expand Down
37 changes: 37 additions & 0 deletions tests/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::process::Command;
use std::str;

use assert_cmd::prelude::*;
use predicates::prelude::*;
Expand Down Expand Up @@ -259,3 +260,39 @@ fn walk_hidden_items() {
.and(predicate::str::contains("after"));
cmd.assert().stdout(predicate_fn);
}

const MAX_SAMPLE_FILE_SIZE: u64 = 10_000;

#[test]
fn samples_side_by_side() {
insta::glob!("../sample_files", "*_1.*", |left_file| {
let base_dir = left_file.parent().unwrap().parent().unwrap();
let file_name = left_file.file_name().unwrap().to_str().unwrap();
let right_file = left_file.with_file_name(file_name.replace("_1.", "_2."));
// Large sample files are excluded because it's slow to diff with debug
// binary, and the snapshot results wouldn't help review changes.
if left_file.metadata().unwrap().len() > MAX_SAMPLE_FILE_SIZE
|| right_file.metadata().unwrap().len() > MAX_SAMPLE_FILE_SIZE
{
eprintln!("Skipping large sample: {file_name}");
return;
}

let to_path_arg = |path: &Path| {
let short_path = path.strip_prefix(base_dir).unwrap();
let short_str = short_path.to_str().unwrap();
short_str.replace(std::path::MAIN_SEPARATOR, "/")
};
let mut cmd = get_base_command();
let assert = cmd
.arg("--color=always")
.arg("--display=side-by-side")
.arg("--width=160")
.arg(to_path_arg(left_file))
.arg(to_path_arg(&right_file))
.assert()
.success();
let stdout = str::from_utf8(&assert.get_output().stdout).unwrap();
insta::assert_snapshot!(stdout);
});
}
32 changes: 32 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@Session_1.kt.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/Session_1.kt
---
sample_files/Session_2.kt --- 1/2 --- Kotlin
 96  /**  96  /**
 97  * The session's photo URL.  97  * The session's photo URL.
 98  */  98  */
 99  val photoUrl: String?,  99  val photoUrl: String,
100  100 
101  /** 101  /**
102  * IDs of the sessions related to this session. 102  * IDs of the sessions related to this session.
sample_files/Session_2.kt --- 2/2 --- Kotlin
114  return startTime <= now && endTime >= now 114  return startTime <= now && endTime >= now
115  } 115  }
...  116 
...  117  val hasPhoto inline get() = photoUrl.isNotEmpty()
116  118 
117  /** 119  /**
118  * Returns whether the session has a video or not. A session could be l 120  * Returns whether the session has a video or not. A session could be l
... ive streaming or have a ... ive streaming or have a
119  * recorded session. Both live stream and recorded videos are stored in 121  * recorded session. Both live stream and recorded videos are stored in
...  [Session.youTubeUrl]. ...  [Session.youTubeUrl].
120  */ 122  */
121  fun hasVideo() = youTubeUrl.isNotEmpty() 123  val hasVideo inline get() = youTubeUrl.isNotEmpty()
...  124 
...  125  val hasPhotoOrVideo inline get() = hasPhoto || hasVideo
122  126 
123  /** 127  /**
124  * The year the session was held. 128  * The year the session was held.
14 changes: 14 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@ada_1.adb.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/ada_1.adb
---
sample_files/ada_2.adb --- Ada
1  with Ada.Text_IO; use Ada.Text_IO; procedure Hello is begin Put_Line ("Hello 1 with Ada.Text_IO;
.  WORLD!"); end Hello; . 
.  2 
.  3 procedure Hello is
.  4  package TIO renames Ada.Text_IO;
.  5 begin
.  6  TIO.Put_Line ("Hello World!");
.  7 end Hello;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/added_line_1.txt
---
sample_files/added_line_2.txt --- Text
1 1 potato
2 2 tomato
 3 legato
10 changes: 10 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@align_footer_1.txt.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/align_footer_1.txt
---
sample_files/align_footer_2.txt --- Text
1 before 1 before
2  foo x 2  x
3 y . 
4 after 3 after
7 changes: 7 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@apex_1.cls.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/apex_1.cls
---
sample_files/apex_2.cls --- Apex
No syntactic changes.
33 changes: 33 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@bad_combine_1.rs.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/bad_combine_1.rs
---
sample_files/bad_combine_2.rs --- 1/2 --- Rust
 1  . 
 2 fn column_widths( . 
 3  hunks: &[Hunk], . 
 4  lhs_mps: &[MatchedPos], . 
 5  rhs_mps: &[MatchedPos], . 
 6  max_lhs_src_line: LineNumber, . 
 7  max_rhs_src_line: LineNumber, . 
 8 ) { . 
 9 } . 
10  . 
11 fn display_line_nums( 1 fn display_line_nums(
12 ) -> (String, String) { 2 ) -> (String, String) {
13  let display_rhs_line_num: String = match rhs_line_num { 3  let display_rhs_line_num: String = match rhs_line_num {
14  Some(line_num) => { 4  Some(line_num) => {
15  let s = format_line_num_padded(line_num, rhs_column_width); 5  let s = format_line_num_padded(line_num, widths.rhs_line_nums);
16  if rhs_lines_with_novel.contains(&line_num) { 6  if rhs_lines_with_novel.contains(&line_num) {
17  s.bright_green().to_string() 7  s.bright_green().to_string()
18  } else { 8  } else {

sample_files/bad_combine_2.rs --- 2/2 --- Rust
21  } 11  }
22  None => format_missing_line_num( 12  None => format_missing_line_num(
23  prev_rhs_line_num.unwrap_or_else(|| 10.into()), 13  prev_rhs_line_num.unwrap_or_else(|| 10.into()),
24  rhs_column_width, 14  widths.rhs_line_nums,
25  ), 15  ),
26  }; 16  };
27  17 
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/change_outer_1.el
---
sample_files/change_outer_2.el --- Emacs Lisp
1 (lhs comma rhs) 1 [(lhs) comma rhs]
35 changes: 35 additions & 0 deletions tests/snapshots/cli__samples_side_by_side@chinese_1.po.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
source: tests/cli.rs
expression: stdout
input_file: sample_files/chinese_1.po
---
sample_files/chinese_2.po --- 1/3 --- Text
File permissions changed from 100755 to 100644.
1 #: ../errors.h:589 1 #: ../errors.h:589
2 # reorder if possible 2 # reorder if possible
3 #, fuzzy, c-format 3 #, fuzzy, c-format
4 msgid "E244: Illegal %s name \"%s\" in font name \"%s\"" 4 # msgid "E244: Illegal %s name \"%s\" in font name \"%s\""
5 msgstr "E244: 字体名 \"%3$s\" 中有非法 %1$s 名称 \"%2$s\"" 5 # msgstr "E244: 字体名 \"%3$s\" 中有非法 %1$s 名称 \"%2$s\""
6  6 
7 #: ../errors.h:591 7 #: ../errors.h:591
8 #, c-format 8 #, c-format

sample_files/chinese_2.po --- 2/3 --- Text
21 #: ../errors.h:788 21 #: ../errors.h:788
22 # reorder if possible 22 # reorder if possible
23 #, fuzzy, c-format 23 #, fuzzy, c-format
24 msgid "E316: ml_get: Cannot find line %ld in buffer %d %s" 24 # msgid "E316: ml_get: Cannot find line %ld in buffer %d %s"
25 msgstr "E316: ml_get: 在缓冲区 %2$d %3$s 中找不到第 %1$ld 行" 25 # msgstr "E316: ml_get: 在缓冲区 %2$d %3$s 中找不到第 %1$ld 行"
26  26 
27 #: ../errors.h:790 27 #: ../errors.h:790
28 msgid "E317: Pointer block id wrong" 28 msgid "E317: Pointer block id wrong"

sample_files/chinese_2.po --- 3/3 --- Text
43 #: ../errors.h:2705 43 #: ../errors.h:2705
44 # reorder if possible 44 # reorder if possible
45 #, fuzzy, c-format 45 #, fuzzy, c-format
46 msgid "E1037: Cannot use \"%s\" with %s" 46 # msgid "E1037: Cannot use \"%s\" with %s"
47 msgstr "E1037: 不能对 %2$s 使用 \"%1$s\"" 47 # msgstr "E1037: 不能对 %2$s 使用 \"%1$s\""
48  48 
49 #: ../errors.h:2707 49 #: ../errors.h:2707
50 msgid "E1038: \"vim9script\" can only be used in a script" 50 msgid "E1038: \"vim9script\" can only be used in a script"
Loading

0 comments on commit 902cd93

Please sign in to comment.