Skip to content

Commit

Permalink
feat: add exp/golden (#41)
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
caarlos0 authored Feb 22, 2024
1 parent c6c7abe commit f22b247
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 57 deletions.
15 changes: 12 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ updates:
prefix: "chore"
include: "scope"
- package-ecosystem: "gomod"
directory: "/exp/term"
directory: "/exp/teatest"
schedule:
interval: "daily"
labels:
Expand All @@ -30,7 +30,16 @@ updates:
prefix: "chore"
include: "scope"
- package-ecosystem: "gomod"
directory: "/exp/teatest"
directory: "/exp/golden"
schedule:
interval: "daily"
labels:
- "dependencies"
commit-message:
prefix: "chore"
include: "scope"
- package-ecosystem: "gomod"
directory: "/exp/strings"
schedule:
interval: "daily"
labels:
Expand All @@ -48,7 +57,7 @@ updates:
prefix: "chore"
include: "scope"
- package-ecosystem: "gomod"
directory: "/exp/strings"
directory: "/exp/term"
schedule:
interval: "daily"
labels:
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/golden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# auto-generated by scripts/dependabot. DO NOT EDIT.
name: golden

on:
push:
branches:
- main
pull_request:
paths:
- exp/golden/**
- .github/workflows/golden.yml

jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ./exp/golden
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: ./exp/golden/go.mod
cache: true
cache-dependency-path: ./exp/golden.sum
- run: go build -v ./...
- run: go test -race -v ./...
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ into other repositories.
Currently the following packages are available:

- [`editor`](./editor): open files in text editors
- [`errors`](./errors): `errors.Join` in older Go versions
- [`higherorder`](./exp/higherorder): generic higher order functions
- [`golden`](./exp/golden): verify golden files equality
- [`ordered`](./exp/ordered): generic `min`, `max`, and `clamp` functions for ordered types
- [`slice`](./exp/slice): generic slice utilities
- [`strings`](./exp/strings): utilities for working with strings
- [`teatest`](./exp/teatest): a library for testing [Bubble Tea](https://github.com/charmbracelet/bubbletea) programs
- [`term`](./exp/term): terminal utilities: ansi, termios, conpty

## Feedback

Expand Down
5 changes: 5 additions & 0 deletions exp/golden/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/charmbracelet/x/exp/golden

go 1.19

require github.com/aymanbagabas/go-udiff v0.2.0
2 changes: 2 additions & 0 deletions exp/golden/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
60 changes: 60 additions & 0 deletions exp/golden/golden.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package golden

import (
"bytes"
"flag"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/aymanbagabas/go-udiff"
)

var update = flag.Bool("update", false, "update .golden files")

// RequireEqual is a helper function to assert the given output is
// the expected from the golden files, printing its diff in case it is not.
//
// You can update the golden files by running your tests with the -update flag.
func RequireEqual(tb testing.TB, out []byte) {
tb.Helper()

out = fixLineEndings(out)

golden := filepath.Join("testdata", tb.Name()+".golden")
if *update {
if err := os.MkdirAll(filepath.Dir(golden), 0o755); err != nil { //nolint: gomnd
tb.Fatal(err)
}
if err := os.WriteFile(golden, out, 0o600); err != nil { //nolint: gomnd
tb.Fatal(err)
}
}

path := filepath.Join(tb.TempDir(), tb.Name()+".out")
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { //nolint: gomnd
tb.Fatal(err)
}
if err := os.WriteFile(path, out, 0o600); err != nil { //nolint: gomnd
tb.Fatal(err)
}

goldenBts, err := os.ReadFile(golden)
if err != nil {
tb.Fatal(err)
}

goldenBts = fixLineEndings(goldenBts)
diff := udiff.Unified("golden", "run", string(goldenBts), string(out))
if diff != "" {
tb.Fatalf("output does not match, expected:\n\n%s\n\ngot:\n\n%s\n\ndiff:\n\n%s", string(goldenBts), string(out), diff)
}
}

func fixLineEndings(in []byte) []byte {
if runtime.GOOS != "windows" {
return in
}
return bytes.ReplaceAll(in, []byte("\r\n"), []byte{'\n'})
}
21 changes: 21 additions & 0 deletions exp/golden/golden_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package golden

import "testing"

func TestRequireEqualUpdate(t *testing.T) {
enableUpdate(t)
RequireEqual(t, []byte("test"))
}

func TestRequireEqualNoUpdate(t *testing.T) {
RequireEqual(t, []byte("test"))
}

func enableUpdate(tb testing.TB) {
tb.Helper()
previous := update
*update = true
tb.Cleanup(func() {
update = previous
})
}
1 change: 1 addition & 0 deletions exp/golden/testdata/TestRequireEqualNoUpdate.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
1 change: 1 addition & 0 deletions exp/golden/testdata/TestRequireEqualUpdate.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
7 changes: 2 additions & 5 deletions exp/teatest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ module github.com/charmbracelet/x/exp/teatest

go 1.19

require (
github.com/aymanbagabas/go-udiff v0.2.0
github.com/charmbracelet/bubbletea v0.25.0
)
require github.com/charmbracelet/bubbletea v0.25.0

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
Expand All @@ -20,7 +17,7 @@ require (
github.com/muesli/termenv v0.15.2 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.3.8 // indirect
)
4 changes: 1 addition & 3 deletions exp/teatest/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
Expand Down Expand Up @@ -30,7 +28,7 @@ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
Expand Down
34 changes: 2 additions & 32 deletions exp/teatest/teatest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ package teatest

import (
"bytes"
"flag"
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
"sync"
"syscall"
"testing"
"time"

"github.com/aymanbagabas/go-udiff"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/x/exp/golden"
)

// Program defines the subset of the tea.Program API we need for testing.
Expand Down Expand Up @@ -252,8 +250,6 @@ func (tm *TestModel) Type(s string) {
}
}

var update = flag.Bool("update", false, "update .golden files")

// RequireEqualOutput is a helper function to assert the given output is
// the expected from the golden files, printing its diff in case it is not.
//
Expand All @@ -262,33 +258,7 @@ var update = flag.Bool("update", false, "update .golden files")
// You can update the golden files by running your tests with the -update flag.
func RequireEqualOutput(tb testing.TB, out []byte) {
tb.Helper()

golden := filepath.Join("testdata", tb.Name()+".golden")
if *update {
if err := os.MkdirAll(filepath.Dir(golden), 0o755); err != nil { //nolint: gomnd
tb.Fatal(err)
}
if err := os.WriteFile(golden, out, 0o600); err != nil { //nolint: gomnd
tb.Fatal(err)
}
}

path := filepath.Join(tb.TempDir(), tb.Name()+".out")
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { //nolint: gomnd
tb.Fatal(err)
}
if err := os.WriteFile(path, out, 0o600); err != nil { //nolint: gomnd
tb.Fatal(err)
}

goldenBts, err := os.ReadFile(golden)
if err != nil {
tb.Fatal(err)
}
diff := udiff.Unified("golden", "run", string(goldenBts), string(out))
if diff != "" {
tb.Fatalf("output does not match, diff:\n\n%s", diff)
}
golden.RequireEqual(tb, out)
}

func safe(rw io.ReadWriter) io.ReadWriter {
Expand Down
14 changes: 0 additions & 14 deletions exp/teatest/teatest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ import (
"time"
)

func TestRequireEqualOutputUpdate(t *testing.T) {
enableUpdate(t)
RequireEqualOutput(t, []byte("test"))
}

func TestWaitForErrorReader(t *testing.T) {
err := doWaitFor(iotest.ErrReader(fmt.Errorf("fake")), func(bts []byte) bool {
return true
Expand All @@ -36,12 +31,3 @@ func TestWaitForTimeout(t *testing.T) {
t.Fatalf("unexpected error: %s", err.Error())
}
}

func enableUpdate(tb testing.TB) {
tb.Helper()
previous := update
*update = true
tb.Cleanup(func() {
update = previous
})
}
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ go 1.21
use (
./editor
./errors
./exp/golden
./exp/higherorder
./exp/ordered
./exp/slice
Expand Down
1 change: 1 addition & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
Expand Down

0 comments on commit f22b247

Please sign in to comment.