Skip to content

Commit

Permalink
feat: add path of failed snapshot on diff report (#69)
Browse files Browse the repository at this point in the history
* chore: misc changes on unit tests

* feat: add path of failed snapshot on diff report
  • Loading branch information
gkampitakis committed Jul 5, 2023
1 parent a3fd6aa commit 31d53b8
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 171 deletions.
24 changes: 23 additions & 1 deletion internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (m MockTestingT) Log(args ...interface{}) {
}

// Equal asserts expected and received have deep equality
func Equal(t *testing.T, expected, received interface{}) {
func Equal[A any](t *testing.T, expected, received A) {
t.Helper()
if !reflect.DeepEqual(expected, received) {
t.Errorf("\n[expected]: %v\n[received]: %v", expected, received)
Expand Down Expand Up @@ -77,6 +77,20 @@ func CreateTempFile(t *testing.T, data string) string {
return path
}

// GetFileContent returns the contents of a file
//
// it errors if file doesn't exist
func GetFileContent(t *testing.T, name string) string {
t.Helper()

content, err := os.ReadFile(name)
if err != nil {
t.Error(err)
}

return string(content)
}

func True(t *testing.T, val bool) {
t.Helper()

Expand All @@ -94,9 +108,17 @@ func False(t *testing.T, val bool) {
}

func Nil(t *testing.T, val interface{}) {
t.Helper()
v := reflect.ValueOf(val)

if val != nil && !v.IsNil() {
t.Errorf("expected nil but got %v", val)
}
}

func NoError(t *testing.T, err error) {
t.Helper()
if err != nil {
t.Errorf("expected no error but got %s", err)
}
}
32 changes: 26 additions & 6 deletions snaps/__snapshots__/diff_test.snap
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@

[TestDiff/should_print_header_consistently - 1]
[TestDiff/should_build_diff_report_consistently - 1]

- Snapshot - 20
+ Received + 10000


mock-diff
at snap/path:10

---

[TestDiff/should_print_header_consistently - 2]
[TestDiff/should_build_diff_report_consistently - 2]

- Snapshot - 10000
+ Received + 20


mock-diff
at snap/path:20

---

[TestDiff/with_color/should_apply_highlights_on_single_line_diff - 1]

- Snapshot - 20
+ Received + 20

- abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd+ abcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcf
- abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd+ abcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcf
at snap/path:10

---

[TestDiff/with_color/multiline_diff - 1]
Expand Down Expand Up @@ -48,7 +54,9 @@
+ Sed lorem felis, condimentum eget vehicula non, sagittis sit amet diam. 
+ Vivamus ut sapien at erat imperdiet suscipit id a lectus.
+ Another Line added.


at snap/path:10

---

[TestDiff/no_color/should_apply_highlights_on_single_line_diff - 1]
Expand All @@ -59,6 +67,8 @@
- abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd
+ abcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcfabcf

at snap/path:10

---

[TestDiff/no_color/multiline_diff - 1]
Expand Down Expand Up @@ -87,4 +97,14 @@
+ Vivamus ut sapien at erat imperdiet suscipit id a lectus.
+ Another Line added.

at snap/path:20

---

[TestDiff/should_not_print_snapshot_line_if_not_provided - 1]

- Snapshot - 2
+ Received + 10

there is a diff here
---
25 changes: 7 additions & 18 deletions snaps/clean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,6 @@ func setupTempExamineFiles(t *testing.T) (map[string]map[string]int, string, str
return tests, dir1, dir2
}

func getFileContent(t *testing.T, name string) string {
t.Helper()

content, err := os.ReadFile(name)
if err != nil {
t.Error(err)
}

return string(content)
}

func TestExamineFiles(t *testing.T) {
t.Run("should parse files", func(t *testing.T) {
tests, dir1, dir2 := setupTempExamineFiles(t)
Expand Down Expand Up @@ -182,7 +171,7 @@ func TestExamineSnaps(t *testing.T) {
obsolete, err := examineSnaps(tests, used, "", shouldUpdate)

test.Equal(t, []string{}, obsolete)
test.Nil(t, err)
test.NoError(t, err)
})

t.Run("should report two obsolete snapshots and not change content", func(t *testing.T) {
Expand All @@ -199,11 +188,11 @@ func TestExamineSnaps(t *testing.T) {
delete(tests[used[1]], "TestDir2_2/TestSimple")

obsolete, err := examineSnaps(tests, used, "", shouldUpdate)
content1 := getFileContent(t, used[0])
content2 := getFileContent(t, used[1])
content1 := test.GetFileContent(t, used[0])
content2 := test.GetFileContent(t, used[1])

test.Equal(t, []string{"TestDir1_3/TestSimple - 2", "TestDir2_2/TestSimple - 1"}, obsolete)
test.Nil(t, err)
test.NoError(t, err)

// Content of snaps is not changed
test.Equal(t, mockSnap1, content1)
Expand All @@ -222,8 +211,8 @@ func TestExamineSnaps(t *testing.T) {
delete(tests[used[1]], "TestDir2_1/TestSimple")

obsolete, err := examineSnaps(tests, used, "", shouldUpdate)
content1 := getFileContent(t, used[0])
content2 := getFileContent(t, used[1])
content1 := test.GetFileContent(t, used[0])
content2 := test.GetFileContent(t, used[1])

expected1 := `
[TestDir1_1/TestSimple - 1]
Expand Down Expand Up @@ -255,7 +244,7 @@ string hello world 2 2 1
},
obsolete,
)
test.Nil(t, err)
test.NoError(t, err)

// Content of snaps is not changed
test.Equal(t, expected1, content1)
Expand Down
97 changes: 56 additions & 41 deletions snaps/diff.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package snaps

import (
"bytes"
"fmt"
"io"
"strconv"
Expand Down Expand Up @@ -72,7 +73,8 @@ func getUnifiedDiff(a, b string) (string, int, int) {
received := strings.Join(aLines[i1:i2], "")

if shouldPrintHighlights(expected, received) {
i, d := singlelineDiff(&s, received, expected)
diff, i, d := singlelineDiff(received, expected)
s.WriteString(diff)
inserted += i
deleted += d

Expand Down Expand Up @@ -113,23 +115,6 @@ func getUnifiedDiff(a, b string) (string, int, int) {
return s.String(), inserted, deleted
}

// header of a diff report
//
// e.g.
// - Snapshot - 10
// - Received - 2
func header(inserted, deleted int) string {
var s strings.Builder
iPadding, dPadding := intPadding(inserted, deleted)

s.WriteString("\n")
colors.FprintDelete(&s, fmt.Sprintf("Snapshot %s- %d\n", dPadding, deleted))
colors.FprintInsert(&s, fmt.Sprintf("Received %s+ %d\n", iPadding, inserted))
s.WriteString("\n")

return s.String()
}

func printRange(w io.Writer, opcodes []difflib.OpCode) {
first, last := opcodes[0], opcodes[len(opcodes)-1]
range1 := difflib.FormatRangeUnified(first.I1, last.I2)
Expand Down Expand Up @@ -161,57 +146,87 @@ func intPadding(inserted, deleted int) (string, string) {
return strings.Repeat(" ", -diff), ""
}

func singlelineDiff(s *strings.Builder, expected, received string) (int, int) {
func singlelineDiff(expected, received string) (string, int, int) {
diffs := dmp.DiffCleanupSemantic(
dmp.DiffMain(expected, received, false),
)
if len(diffs) == 1 && diffs[0].Type == diffEqual {
// -1 means no diffs
return -1, 0
return "", -1, -1
}

var inserted, deleted int
var i strings.Builder
a := &bytes.Buffer{}
b := &bytes.Buffer{}

colors.FprintBg(s, colors.RedBg, colors.Reddiff, "- ")
colors.FprintBg(&i, colors.GreenBG, colors.Greendiff, "+ ")
colors.FprintBg(a, colors.RedBg, colors.Reddiff, "- ")
colors.FprintBg(b, colors.GreenBG, colors.Greendiff, "+ ")

for _, diff := range diffs {
switch diff.Type {
case diffDelete:
deleted++
colors.FprintDeleteBold(s, diff.Text)
colors.FprintDeleteBold(a, diff.Text)
case diffInsert:
inserted++
colors.FprintInsertBold(&i, diff.Text)
colors.FprintInsertBold(b, diff.Text)
case diffEqual:
colors.FprintBg(s, colors.RedBg, colors.Reddiff, diff.Text)
colors.FprintBg(&i, colors.GreenBG, colors.Greendiff, diff.Text)
colors.FprintBg(a, colors.RedBg, colors.Reddiff, diff.Text)
colors.FprintBg(b, colors.GreenBG, colors.Greendiff, diff.Text)
}
}

s.WriteString(i.String())
a.Write(b.Bytes())

return inserted, deleted
return a.String(), inserted, deleted
}

func prettyDiff(expected, received string) string {
if expected == received {
/*
buildDiffReport creates a report with diffs it contains a header the diff body and a footer
header of a diff report
e.g.
- Snapshot - 10
- Received + 2
body contains the diffs
footer contains the relative path of snapshot
e.g. at ../__snapshots__/example_test.snap:25
*/
func buildDiffReport(inserted, deleted int, diff, name string, line int) string {
if diff == "" {
return ""
}
var s strings.Builder
s.Grow(len(diff))

if shouldPrintHighlights(expected, received) {
var diff strings.Builder
if i, d := singlelineDiff(&diff, expected, received); i != -1 {
return header(i, d) + diff.String()
}
iPadding, dPadding := intPadding(inserted, deleted)

return ""
s.WriteString("\n")
colors.FprintDelete(&s, fmt.Sprintf("Snapshot %s- %d\n", dPadding, deleted))
colors.FprintInsert(&s, fmt.Sprintf("Received %s+ %d\n", iPadding, inserted))
s.WriteString("\n")

s.WriteString(diff)

if name != "" {
colors.Fprint(&s, colors.Dim, fmt.Sprintf("\nat %s:%d\n", name, line))
}

if diff, i, d := getUnifiedDiff(expected, received); diff != "" {
return header(i, d) + diff
return s.String()
}

func prettyDiff(expected, received, name string, line int) string {
if expected == received {
return ""
}
differ := getUnifiedDiff
if shouldPrintHighlights(expected, received) {
differ = singlelineDiff
}

return ""
diff, i, d := differ(expected, received)
return buildDiffReport(i, d, diff, name, line)
}
Loading

0 comments on commit 31d53b8

Please sign in to comment.