mirror of
https://github.com/jimeh/go-golden.git
synced 2026-02-19 03:16:38 +00:00
Merge pull request #1 from jimeh/refactor-things
refactor: get closer to "stable"
This commit is contained in:
26
.github/workflows/ci.yml
vendored
26
.github/workflows/ci.yml
vendored
@@ -32,6 +32,32 @@ jobs:
|
|||||||
- name: Check if mods are tidy
|
- name: Check if mods are tidy
|
||||||
run: make check-tidy
|
run: make check-tidy
|
||||||
|
|
||||||
|
cov:
|
||||||
|
name: Coverage
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.15
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- name: Publish coverage
|
||||||
|
uses: paambaati/codeclimate-action@v2.7.4
|
||||||
|
env:
|
||||||
|
VERBOSE: "true"
|
||||||
|
GOMAXPROCS: 4
|
||||||
|
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||||
|
with:
|
||||||
|
coverageCommand: make cov
|
||||||
|
prefix: github.com/${{ github.repository }}
|
||||||
|
coverageLocations: |
|
||||||
|
${{ github.workspace }}/coverage.out:gocov
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test
|
name: Test
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
bin/*
|
bin/*
|
||||||
testdata/*
|
|
||||||
coverage.out
|
coverage.out
|
||||||
|
|
||||||
|
testdata/*
|
||||||
|
!testdata/TestExample*
|
||||||
|
|||||||
14
Makefile
14
Makefile
@@ -88,6 +88,18 @@ format: $(TOOLDIR)/goimports $(TOOLDIR)/gofumpt
|
|||||||
bench:
|
bench:
|
||||||
go test $(V) -count=1 -bench=$(BENCH) $(TESTARGS) ./...
|
go test $(V) -count=1 -bench=$(BENCH) $(TESTARGS) ./...
|
||||||
|
|
||||||
|
.PHONY: golden-update
|
||||||
|
golden-update:
|
||||||
|
GOLDEN_UPDATE=1 $(MAKE) test
|
||||||
|
|
||||||
|
.PHONY: golden-clean
|
||||||
|
golden-clean:
|
||||||
|
find . -type f -name '*.golden' -path '*/testdata/*' -delete
|
||||||
|
find . -type d -empty -path '*/testdata/*' -delete
|
||||||
|
|
||||||
|
.PHONY: golden-regen
|
||||||
|
golden-regen: golden-clean golden-update
|
||||||
|
|
||||||
#
|
#
|
||||||
# Code Generation
|
# Code Generation
|
||||||
#
|
#
|
||||||
@@ -171,7 +183,7 @@ check-tidy:
|
|||||||
|
|
||||||
# Serve docs
|
# Serve docs
|
||||||
.PHONY: docs
|
.PHONY: docs
|
||||||
docs: godoc
|
docs: $(TOOLDIR)/godoc
|
||||||
$(info serviing docs on http://127.0.0.1:6060/pkg/$(GOMODNAME)/)
|
$(info serviing docs on http://127.0.0.1:6060/pkg/$(GOMODNAME)/)
|
||||||
@godoc -http=127.0.0.1:6060
|
@godoc -http=127.0.0.1:6060
|
||||||
|
|
||||||
|
|||||||
81
README.md
81
README.md
@@ -1,5 +1,80 @@
|
|||||||
# go-golden
|
<h1 align="center">
|
||||||
|
go-golden
|
||||||
|
</h1>
|
||||||
|
|
||||||
Yet another Go package for working with `*.golden` test files.
|
<p align="center">
|
||||||
|
<strong>
|
||||||
|
Yet another Go package for working with `*.golden` test files, with a focus
|
||||||
|
on simplicity through it's default behavior.
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
Currently a work in progress.
|
<p align="center">
|
||||||
|
<a href="https://pkg.go.dev/github.com/jimeh/go-golden">
|
||||||
|
<img src="https://img.shields.io/badge/%E2%80%8B-reference-387b97.svg?logo=go&logoColor=white"
|
||||||
|
alt="Go Reference">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/jimeh/go-golden/actions">
|
||||||
|
<img src="https://img.shields.io/github/workflow/status/jimeh/go-golden/CI.svg?logo=github" alt="Actions Status">
|
||||||
|
</a>
|
||||||
|
<a href="https://codeclimate.com/github/jimeh/go-golden">
|
||||||
|
<img src="https://img.shields.io/codeclimate/coverage/jimeh/go-golden.svg?logo=code%20climate" alt="Coverage">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/jimeh/go-golden/issues">
|
||||||
|
<img src="https://img.shields.io/github/issues-raw/jimeh/go-golden.svg?style=flat&logo=github&logoColor=white"
|
||||||
|
alt="GitHub issues">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/jimeh/go-golden/pulls">
|
||||||
|
<img src="https://img.shields.io/github/issues-pr-raw/jimeh/go-golden.svg?style=flat&logo=github&logoColor=white" alt="GitHub pull requests">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/jimeh/go-golden/blob/master/LICENSE">
|
||||||
|
<img src="https://img.shields.io/github/license/jimeh/go-golden.svg?style=flat" alt="License Status">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Golden file names are based on the name of the test function and any subtest
|
||||||
|
names by calling t.Name(). File names are sanitized to ensure they're compatible
|
||||||
|
with Linux, macOS and Windows systems regardless of what crazy characters might
|
||||||
|
be in a subtest's name.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
```
|
||||||
|
import "github.com/jimeh/go-golden"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Typical usage should look something like this:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TestExampleMyStruct(t *testing.T) {
|
||||||
|
got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if golden.Update() {
|
||||||
|
golden.Set(t, got)
|
||||||
|
}
|
||||||
|
want := golden.Get(t)
|
||||||
|
|
||||||
|
assert.Equal(t, want, got)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above example will read/write to:
|
||||||
|
|
||||||
|
testdata/TestExampleMyStruct.golden
|
||||||
|
|
||||||
|
To update the golden file (have `golden.Update()` return true), simply set the
|
||||||
|
`GOLDEN_UPDATE` environment variable to one of `1`, `y`, `t`, `yes`, `on`, or
|
||||||
|
`true` when running tests.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Please see the
|
||||||
|
[Go Reference](https://pkg.go.dev/github.com/jimeh/go-golden#section-documentation)
|
||||||
|
for documentation and examples.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](https://github.com/jimeh/go-golden/blob/master/LICENSE)
|
||||||
|
|||||||
108
example_test.go
Normal file
108
example_test.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package golden_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jimeh/go-golden"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyStruct struct {
|
||||||
|
Foo string `json:"foo,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExampleMyStruct reads/writes the following golden file:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStruct.golden
|
||||||
|
//
|
||||||
|
func TestExampleMyStruct(t *testing.T) {
|
||||||
|
got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if golden.Update() {
|
||||||
|
golden.Set(t, got)
|
||||||
|
}
|
||||||
|
want := golden.Get(t)
|
||||||
|
|
||||||
|
assert.Equal(t, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExampleMyStructTabular reads/writes the following golden files:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||||
|
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||||
|
//
|
||||||
|
func TestExampleMyStructTabular(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
obj *MyStruct
|
||||||
|
}{
|
||||||
|
{name: "empty struct", obj: &MyStruct{}},
|
||||||
|
{name: "full struct", obj: &MyStruct{Foo: "Bar"}},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := json.Marshal(tt.obj)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if golden.Update() {
|
||||||
|
golden.Set(t, got)
|
||||||
|
}
|
||||||
|
want := golden.Get(t)
|
||||||
|
|
||||||
|
assert.Equal(t, want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExampleMyStructP reads/writes the following golden file:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructP/json.golden
|
||||||
|
// testdata/TestExampleMyStructP/xml.golden
|
||||||
|
//
|
||||||
|
func TestExampleMyStructP(t *testing.T) {
|
||||||
|
gotJSON, _ := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
gotXML, _ := xml.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
|
||||||
|
if golden.Update() {
|
||||||
|
golden.SetP(t, "json", gotJSON)
|
||||||
|
golden.SetP(t, "xml", gotXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||||
|
assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExampleMyStructTabularP reads/writes the following golden file:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructTabularP/empty_struct/json.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/empty_struct/xml.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/full_struct/json.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/full_struct/xml.golden
|
||||||
|
//
|
||||||
|
func TestExampleMyStructTabularP(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
obj *MyStruct
|
||||||
|
}{
|
||||||
|
{name: "empty struct", obj: &MyStruct{}},
|
||||||
|
{name: "full struct", obj: &MyStruct{Foo: "Bar"}},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotJSON, _ := json.Marshal(tt.obj)
|
||||||
|
gotXML, _ := xml.Marshal(tt.obj)
|
||||||
|
|
||||||
|
if golden.Update() {
|
||||||
|
golden.SetP(t, "json", gotJSON)
|
||||||
|
golden.SetP(t, "xml", gotXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||||
|
assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
49
global.go
49
global.go
@@ -1,49 +0,0 @@
|
|||||||
package golden
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
var global = New()
|
|
||||||
|
|
||||||
// Updating returns true when golden is set to update golden files. Used to
|
|
||||||
// determine if golden.Set() should be called or not.
|
|
||||||
func Updating() bool {
|
|
||||||
return global.Updating()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the content of the default golden file for the given *testing.T
|
|
||||||
// instance as determined by t.Name(). If no golden file can be found/read, it
|
|
||||||
// will fail the test with t.Fatal().
|
|
||||||
func Get(t *testing.T) []byte {
|
|
||||||
return global.Get(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set writes given data of the default golden file for the given *testing.T
|
|
||||||
// instance as determined by t.Name(). If writing fails it will fail the test
|
|
||||||
// with t.Fatal() detailing the error.
|
|
||||||
func Set(t *testing.T, data []byte) {
|
|
||||||
global.Set(t, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// File returns the filename for the default golden file for the given
|
|
||||||
// *testing.T instance as determined by t.Name().
|
|
||||||
func File(t *testing.T) string {
|
|
||||||
return global.File(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNamed return the content of the specifically named golden file belonging
|
|
||||||
// to the given *testing.T instance as determined by t.Name(). If no golden file
|
|
||||||
// can be found/read, it will fail the test with t.Fatal().
|
|
||||||
func GetNamed(t *testing.T, name string) []byte {
|
|
||||||
return global.GetNamed(t, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNamed writes given data of the specifically named golden file belonging to
|
|
||||||
// the given *testing.T instance as determined by t.Name(). If writing fails it
|
|
||||||
// will fail the test with t.Fatal() detailing the error.
|
|
||||||
func SetNamed(t *testing.T, name string, data []byte) {
|
|
||||||
global.SetNamed(t, name, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NamedFile(t *testing.T, name string) string {
|
|
||||||
return global.NamedFile(t, name)
|
|
||||||
}
|
|
||||||
358
golden.go
358
golden.go
@@ -1,10 +1,132 @@
|
|||||||
// Package golden is yet another package for working with *.golden test files.
|
// Package golden is yet another package for working with *.golden test files,
|
||||||
|
// with a focus on simplicity through it's default behavior.
|
||||||
|
//
|
||||||
|
// Golden file names are based on the name of the test function and any subtest
|
||||||
|
// names by calling t.Name(). File names are sanitized to ensure they're
|
||||||
|
// compatible with Linux, macOS and Windows systems regardless of what crazy
|
||||||
|
// characters might be in a subtest's name.
|
||||||
|
//
|
||||||
|
// Usage
|
||||||
|
//
|
||||||
|
// Typical usage should look something like this:
|
||||||
|
//
|
||||||
|
// func TestExampleMyStruct(t *testing.T) {
|
||||||
|
// got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
// require.NoError(t, err)
|
||||||
|
//
|
||||||
|
// if golden.Update() {
|
||||||
|
// golden.Set(t, got)
|
||||||
|
// }
|
||||||
|
// want := golden.Get(t)
|
||||||
|
//
|
||||||
|
// assert.Equal(t, want, got)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The above example will read/write to:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStruct.golden
|
||||||
|
//
|
||||||
|
// To update the golden file (have golden.Update() return true), simply set the
|
||||||
|
// GOLDEN_UPDATE environment variable to one of "1", "y", "t", "yes", "on", or
|
||||||
|
// "true" when running tests.
|
||||||
|
//
|
||||||
|
// Sub-Tests
|
||||||
|
//
|
||||||
|
// As the golden filename is based on t.Name(), it works with sub-tests too,
|
||||||
|
// ensuring each sub-test gets it's own golden file. For example:
|
||||||
|
//
|
||||||
|
// func TestExampleMyStructTabular(t *testing.T) {
|
||||||
|
// tests := []struct {
|
||||||
|
// name string
|
||||||
|
// obj *MyStruct
|
||||||
|
// }{
|
||||||
|
// {name: "empty struct", obj: &MyStruct{}},
|
||||||
|
// {name: "full struct", obj: &MyStruct{Foo: "Bar"}},
|
||||||
|
// }
|
||||||
|
// for _, tt := range tests {
|
||||||
|
// t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// got, err := json.Marshal(tt.obj)
|
||||||
|
// require.NoError(t, err)
|
||||||
|
//
|
||||||
|
// if golden.Update() {
|
||||||
|
// golden.Set(t, got)
|
||||||
|
// }
|
||||||
|
// want := golden.Get(t)
|
||||||
|
//
|
||||||
|
// assert.Equal(t, want, got)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The above example will read/write to:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||||
|
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||||
|
//
|
||||||
|
// Multiple Golden Files in a Single Test
|
||||||
|
//
|
||||||
|
// The "P" suffixed methods, GetP(), SetP(), and FileP(), all take a name
|
||||||
|
// argument which allows using specific golden files within a given *testing.T
|
||||||
|
// instance.
|
||||||
|
//
|
||||||
|
// func TestExampleMyStructP(t *testing.T) {
|
||||||
|
// gotJSON, _ := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
// gotXML, _ := xml.Marshal(&MyStruct{Foo: "Bar"})
|
||||||
|
//
|
||||||
|
// if golden.Update() {
|
||||||
|
// golden.SetP(t, "json", gotJSON)
|
||||||
|
// golden.SetP(t, "xml", gotXML)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||||
|
// assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The above example will read/write to:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructP/json.golden
|
||||||
|
// testdata/TestExampleMyStructP/xml.golden
|
||||||
|
//
|
||||||
|
// This works with tabular tests too of course:
|
||||||
|
//
|
||||||
|
// func TestExampleMyStructTabularP(t *testing.T) {
|
||||||
|
// tests := []struct {
|
||||||
|
// name string
|
||||||
|
// obj *MyStruct
|
||||||
|
// }{
|
||||||
|
// {name: "empty struct", obj: &MyStruct{}},
|
||||||
|
// {name: "full struct", obj: &MyStruct{Foo: "Bar"}},
|
||||||
|
// }
|
||||||
|
// for _, tt := range tests {
|
||||||
|
// t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// gotJSON, _ := json.Marshal(tt.obj)
|
||||||
|
// gotXML, _ := xml.Marshal(tt.obj)
|
||||||
|
//
|
||||||
|
// if golden.Update() {
|
||||||
|
// golden.SetP(t, "json", gotJSON)
|
||||||
|
// golden.SetP(t, "xml", gotXML)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||||
|
// assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The above example will read/write to:
|
||||||
|
//
|
||||||
|
// testdata/TestExampleMyStructTabularP/empty_struct/json.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/empty_struct/xml.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/full_struct/json.golden
|
||||||
|
// testdata/TestExampleMyStructTabularP/full_struct/xml.golden
|
||||||
|
//
|
||||||
package golden
|
package golden
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,54 +137,190 @@ const (
|
|||||||
DefaultDirname = "testdata"
|
DefaultDirname = "testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Golden struct {
|
var DefaultUpdateFunc = EnvUpdateFunc
|
||||||
DirMode os.FileMode
|
|
||||||
FileMode os.FileMode
|
var global = New()
|
||||||
Suffix string
|
|
||||||
Dirname string
|
// File returns the filename of the golden file for the given *testing.T
|
||||||
UpdatingFunc UpdatingFunc
|
// instance as determined by t.Name().
|
||||||
|
func File(t *testing.T) string {
|
||||||
|
return global.File(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get returns the content of the golden file for the given *testing.T instance
|
||||||
|
// as determined by t.Name(). If no golden file can be found/read, it will fail
|
||||||
|
// the test by calling t.Fatal().
|
||||||
|
func Get(t *testing.T) []byte {
|
||||||
|
return global.Get(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set writes given data to the golden file for the given *testing.T instance as
|
||||||
|
// determined by t.Name(). If writing fails it will fail the test by calling
|
||||||
|
// t.Fatal() with error details.
|
||||||
|
func Set(t *testing.T, data []byte) {
|
||||||
|
global.Set(t, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileP returns the filename of the specifically named golden file for the
|
||||||
|
// given *testing.T instance as determined by t.Name().
|
||||||
|
func FileP(t *testing.T, name string) string {
|
||||||
|
return global.FileP(t, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetP returns the content of the specifically named golden file belonging
|
||||||
|
// to the given *testing.T instance as determined by t.Name(). If no golden file
|
||||||
|
// can be found/read, it will fail the test with t.Fatal().
|
||||||
|
//
|
||||||
|
// This is very similar to Get(), but it allows multiple different golden files
|
||||||
|
// to be used within the same one *testing.T instance.
|
||||||
|
func GetP(t *testing.T, name string) []byte {
|
||||||
|
return global.GetP(t, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetP writes given data of the specifically named golden file belonging to
|
||||||
|
// the given *testing.T instance as determined by t.Name(). If writing fails it
|
||||||
|
// will fail the test with t.Fatal() detailing the error.
|
||||||
|
//
|
||||||
|
// This is very similar to Set(), but it allows multiple different golden files
|
||||||
|
// to be used within the same one *testing.T instance.
|
||||||
|
func SetP(t *testing.T, name string, data []byte) {
|
||||||
|
global.SetP(t, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update returns true when golden is set to update golden files. Used to
|
||||||
|
// determine if golden.Set() or golden.Write() should be called or not.
|
||||||
|
//
|
||||||
|
// Default behavior uses EnvUpdateFunc() to check if the "GOLDEN_UPDATE"
|
||||||
|
// environment variable is set to a truthy value. To customize create a custom
|
||||||
|
// *Golden instance with New() and set a new UpdateFunc value.
|
||||||
|
func Update() bool {
|
||||||
|
return global.Update()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Golden handles all interactions with golden files. The top-level package
|
||||||
|
// functions all just proxy through to a default global *Golden instance.
|
||||||
|
type Golden struct {
|
||||||
|
// DirMode determines the file system permissions of any folders created to
|
||||||
|
// hold golden files.
|
||||||
|
DirMode os.FileMode
|
||||||
|
|
||||||
|
// FileMode determines the file system permissions of any created or updated
|
||||||
|
// golden files written to disk.
|
||||||
|
FileMode os.FileMode
|
||||||
|
|
||||||
|
// Suffix determines the filename suffix for all golden files. Typically
|
||||||
|
// this should be ".golden", but can be changed here if needed.
|
||||||
|
Suffix string
|
||||||
|
|
||||||
|
// Dirname is the name of the top-level directory at the root of the package
|
||||||
|
// which holds all golden files. Typically this should "testdata", but can
|
||||||
|
// be changed here if needed.
|
||||||
|
Dirname string
|
||||||
|
|
||||||
|
// UpdateFunc is used to determine if golden files should be updated or
|
||||||
|
// not. Its boolean return value is returned by Update().
|
||||||
|
UpdateFunc UpdateFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new *Golden instance with default values correctly
|
||||||
|
// populated. This is ideally how you should create a custom *Golden, and then
|
||||||
|
// modify the relevant fields as you see fit.
|
||||||
func New() *Golden {
|
func New() *Golden {
|
||||||
return &Golden{
|
return &Golden{
|
||||||
DirMode: DefaultDirMode,
|
DirMode: DefaultDirMode,
|
||||||
FileMode: DefaultFileMode,
|
FileMode: DefaultFileMode,
|
||||||
Suffix: DefaultSuffix,
|
Suffix: DefaultSuffix,
|
||||||
Dirname: DefaultDirname,
|
Dirname: DefaultDirname,
|
||||||
UpdatingFunc: EnvVarUpdatingFunc,
|
UpdateFunc: DefaultUpdateFunc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating returns true when the function assigned to UpdatingFunc returns
|
// File returns the filename of the golden file for the given *testing.T
|
||||||
// true.
|
// instance as determined by t.Name().
|
||||||
func (s *Golden) Updating() bool {
|
|
||||||
return s.UpdatingFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the content of the default golden file for the given *testing.T
|
|
||||||
// instance as determined by t.Name(). If no golden file can be found/read, it
|
|
||||||
// will fail the test with t.Fatal().
|
|
||||||
func (s *Golden) Get(t *testing.T) []byte {
|
|
||||||
return s.GetNamed(t, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set writes given data of the default golden file for the given *testing.T
|
|
||||||
// instance as determined by t.Name(). If writing fails it will fail the test
|
|
||||||
// with t.Fatal() detailing the error.
|
|
||||||
func (s *Golden) Set(t *testing.T, data []byte) {
|
|
||||||
s.SetNamed(t, "", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Golden) File(t *testing.T) string {
|
func (s *Golden) File(t *testing.T) string {
|
||||||
return s.NamedFile(t, "")
|
return s.file(t, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Golden) GetNamed(t *testing.T, name string) []byte {
|
// Get returns the content of the golden file for the given *testing.T instance
|
||||||
if t == nil {
|
// as determined by t.Name(). If no golden file can be found/read, it will fail
|
||||||
|
// the test by calling t.Fatal().
|
||||||
|
func (s *Golden) Get(t *testing.T) []byte {
|
||||||
|
return s.get(t, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set writes given data to the golden file for the given *testing.T instance as
|
||||||
|
// determined by t.Name(). If writing fails it will fail the test by calling
|
||||||
|
// t.Fatal() with error details.
|
||||||
|
func (s *Golden) Set(t *testing.T, data []byte) {
|
||||||
|
s.set(t, "", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileP returns the filename of the specifically named golden file for the
|
||||||
|
// given *testing.T instance as determined by t.Name().
|
||||||
|
func (s *Golden) FileP(t *testing.T, name string) string {
|
||||||
|
if name == "" {
|
||||||
|
if t != nil {
|
||||||
|
t.Fatal("golden: name cannot be empty")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.file(t, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetP returns the content of the specifically named golden file belonging
|
||||||
|
// to the given *testing.T instance as determined by t.Name(). If no golden file
|
||||||
|
// can be found/read, it will fail the test with t.Fatal().
|
||||||
|
//
|
||||||
|
// This is very similar to Get(), but it allows multiple different golden files
|
||||||
|
// to be used within the same one *testing.T instance.
|
||||||
|
func (s *Golden) GetP(t *testing.T, name string) []byte {
|
||||||
|
if name == "" {
|
||||||
|
t.Fatal("golden: name cannot be empty")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
f := s.NamedFile(t, name)
|
return s.get(t, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetP writes given data of the specifically named golden file belonging to
|
||||||
|
// the given *testing.T instance as determined by t.Name(). If writing fails it
|
||||||
|
// will fail the test with t.Fatal() detailing the error.
|
||||||
|
//
|
||||||
|
// This is very similar to Set(), but it allows multiple different golden files
|
||||||
|
// to be used within the same one *testing.T instance.
|
||||||
|
func (s *Golden) SetP(t *testing.T, name string, data []byte) {
|
||||||
|
if name == "" {
|
||||||
|
t.Fatal("golden: name cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.set(t, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Golden) file(t *testing.T, name string) string {
|
||||||
|
if t.Name() == "" {
|
||||||
|
t.Fatalf("golden: could not determine filename for: %+v", t)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
base := []string{s.Dirname, filepath.FromSlash(t.Name())}
|
||||||
|
if name != "" {
|
||||||
|
base = append(base, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := filepath.Clean(filepath.Join(base...) + s.Suffix)
|
||||||
|
|
||||||
|
dirty := strings.Split(f, string(os.PathSeparator))
|
||||||
|
clean := make([]string, 0, len(dirty))
|
||||||
|
for _, s := range dirty {
|
||||||
|
clean = append(clean, sanitizeFilename(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(clean, string(os.PathSeparator))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Golden) get(t *testing.T, name string) []byte {
|
||||||
|
f := s.file(t, name)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(f)
|
b, err := ioutil.ReadFile(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -72,12 +330,8 @@ func (s *Golden) GetNamed(t *testing.T, name string) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Golden) SetNamed(t *testing.T, name string, data []byte) {
|
func (s *Golden) set(t *testing.T, name string, data []byte) {
|
||||||
if t == nil {
|
f := s.file(t, name)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f := s.NamedFile(t, name)
|
|
||||||
dir := filepath.Dir(f)
|
dir := filepath.Dir(f)
|
||||||
|
|
||||||
t.Logf("golden: writing .golden file: %s", f)
|
t.Logf("golden: writing .golden file: %s", f)
|
||||||
@@ -94,16 +348,12 @@ func (s *Golden) SetNamed(t *testing.T, name string, data []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Golden) NamedFile(t *testing.T, name string) string {
|
// Update returns true when golden is set to update golden files. Used to
|
||||||
if t == nil || t.Name() == "" {
|
// determine if golden.Set() or golden.Write() should be called or not.
|
||||||
t.Fatalf("golden: could not determine filename for: %+v", t)
|
//
|
||||||
return ""
|
// Default behavior uses EnvUpdateFunc() to check if the "GOLDEN_UPDATE"
|
||||||
}
|
// environment variable is set to a truthy value. To customize set a new
|
||||||
|
// UpdateFunc value on *Golden.
|
||||||
base := []string{s.Dirname, filepath.FromSlash(t.Name())}
|
func (s *Golden) Update() bool {
|
||||||
if name != "" {
|
return s.UpdateFunc()
|
||||||
base = append(base, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Clean(filepath.Join(base...) + s.Suffix)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,98 +11,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpdating(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
env map[string]string
|
|
||||||
want bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE not set",
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to 0",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "0"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to 1",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "1"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to 2",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "2"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to y",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "y"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to n",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "n"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to t",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "t"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to f",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "f"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to yes",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "yes"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to no",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "no"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to on",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "on"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to off",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "off"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to true",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "true"},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to false",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "false"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GOLDEN_UPDATE set to foobarnopebbq",
|
|
||||||
env: map[string]string{"GOLDEN_UPDATE": "foobarnopebbq"},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
envctl.WithClean(tt.env, func() {
|
|
||||||
got := Updating()
|
|
||||||
|
|
||||||
assert.Equal(t, tt.want, got)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFile(t *testing.T) {
|
func TestFile(t *testing.T) {
|
||||||
got := File(t)
|
got := File(t)
|
||||||
|
|
||||||
@@ -122,11 +30,11 @@ func TestFile(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
want: filepath.Join("testdata", "TestFile", "foo/bar.golden"),
|
want: filepath.Join("testdata", "TestFile", "foo", "bar.golden"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `"foobar"`,
|
name: `"foobar"`,
|
||||||
want: filepath.Join("testdata", "TestFile", "\"foobar\".golden"),
|
want: filepath.Join("testdata", "TestFile", "_foobar_.golden"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -140,9 +48,9 @@ func TestFile(t *testing.T) {
|
|||||||
|
|
||||||
func TestGet(t *testing.T) {
|
func TestGet(t *testing.T) {
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
err := os.RemoveAll(filepath.Join("testdata", t.Name()))
|
err := os.RemoveAll(filepath.Join("testdata", "TestGet"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = os.Remove(filepath.Join("testdata", t.Name()+".golden"))
|
err = os.Remove(filepath.Join("testdata", "TestGet.golden"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -188,7 +96,7 @@ func TestGet(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "thing: it's a thing!",
|
name: "thing: it's a thing!",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGet", "thing:_it's_a_thing!.golden",
|
"testdata", "TestGet", "thing__it's_a_thing!.golden",
|
||||||
),
|
),
|
||||||
want: []byte("A thing? Really? Are we getting lazy? :P"),
|
want: []byte("A thing? Really? Are we getting lazy? :P"),
|
||||||
},
|
},
|
||||||
@@ -214,9 +122,9 @@ func TestGet(t *testing.T) {
|
|||||||
|
|
||||||
func TestSet(t *testing.T) {
|
func TestSet(t *testing.T) {
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
err := os.RemoveAll(filepath.Join("testdata", t.Name()))
|
err := os.RemoveAll(filepath.Join("testdata", "TestSet"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = os.Remove(filepath.Join("testdata", t.Name()+".golden"))
|
err = os.Remove(filepath.Join("testdata", "TestSet.golden"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -258,7 +166,7 @@ func TestSet(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "thing: it's a thing!",
|
name: "thing: it's a thing!",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSet", "thing:_it's_a_thing!.golden",
|
"testdata", "TestSet", "thing__it's_a_thing!.golden",
|
||||||
),
|
),
|
||||||
content: []byte("A thing? Really? Are we getting lazy? :P"),
|
content: []byte("A thing? Really? Are we getting lazy? :P"),
|
||||||
},
|
},
|
||||||
@@ -278,34 +186,74 @@ func TestSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNamed(t *testing.T) {
|
func TestFileP(t *testing.T) {
|
||||||
|
got := FileP(t, "sub-name")
|
||||||
|
assert.Equal(t,
|
||||||
|
filepath.Join("testdata", "TestFileP", "sub-name.golden"), got,
|
||||||
|
)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
named string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
named: "sub-thing",
|
||||||
|
want: filepath.Join(
|
||||||
|
"testdata", "TestFileP", "#00", "sub-thing.golden",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fozbaz",
|
||||||
|
named: "email",
|
||||||
|
want: filepath.Join(
|
||||||
|
"testdata", "TestFileP", "fozbaz", "email.golden",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fozbaz",
|
||||||
|
named: "json",
|
||||||
|
want: filepath.Join(
|
||||||
|
"testdata", "TestFileP", "fozbaz#01", "json.golden",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "foo/bar",
|
||||||
|
named: "hello/world",
|
||||||
|
want: filepath.Join(
|
||||||
|
"testdata", "TestFileP",
|
||||||
|
"foo", "bar",
|
||||||
|
"hello", "world.golden",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := FileP(t, tt.named)
|
||||||
|
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetP(t *testing.T) {
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
err := os.RemoveAll(filepath.Join("testdata", t.Name()))
|
err := os.RemoveAll(filepath.Join("testdata", "TestGetP"))
|
||||||
require.NoError(t, err)
|
|
||||||
err = os.Remove(filepath.Join("testdata", t.Name()+".golden"))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
err := os.MkdirAll(filepath.Join("testdata", "TestGetNamed"), 0o755)
|
err := os.MkdirAll(filepath.Join("testdata", "TestGetP"), 0o755)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
content := []byte("this is the default golden file for TestGetNamed")
|
content := []byte("this is the named golden file for TestGetP")
|
||||||
err = ioutil.WriteFile( //nolint:gosec
|
err = ioutil.WriteFile( //nolint:gosec
|
||||||
filepath.Join("testdata", "TestGetNamed.golden"), content, 0o644,
|
filepath.Join("testdata", "TestGetP", "sub-name.golden"),
|
||||||
)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
got := GetNamed(t, "")
|
|
||||||
assert.Equal(t, content, got)
|
|
||||||
|
|
||||||
content = []byte("this is the named golden file for TestGetNamed")
|
|
||||||
err = ioutil.WriteFile( //nolint:gosec
|
|
||||||
filepath.Join("testdata", "TestGetNamed", "sub-name.golden"),
|
|
||||||
content, 0o644,
|
content, 0o644,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
got = GetNamed(t, "sub-name")
|
got := GetP(t, "sub-name")
|
||||||
assert.Equal(t, content, got)
|
assert.Equal(t, content, got)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@@ -314,16 +262,11 @@ func TestGetNamed(t *testing.T) {
|
|||||||
file string
|
file string
|
||||||
want []byte
|
want []byte
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
file: filepath.Join("testdata", "TestGetNamed", "#00.golden"),
|
|
||||||
want: []byte("number double-zero here"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
named: "sub-zero-one",
|
named: "sub-zero-one",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "#01/sub-zero-one.golden",
|
"testdata", "TestGetP", "#00", "sub-zero-one.golden",
|
||||||
),
|
),
|
||||||
want: []byte("number zero-one here"),
|
want: []byte("number zero-one here"),
|
||||||
},
|
},
|
||||||
@@ -331,7 +274,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "foobar",
|
name: "foobar",
|
||||||
named: "email",
|
named: "email",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "foobar/email.golden",
|
"testdata", "TestGetP", "foobar", "email.golden",
|
||||||
),
|
),
|
||||||
want: []byte("foobar email here"),
|
want: []byte("foobar email here"),
|
||||||
},
|
},
|
||||||
@@ -339,7 +282,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "foobar",
|
name: "foobar",
|
||||||
named: "json",
|
named: "json",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "foobar#01/json.golden",
|
"testdata", "TestGetP", "foobar#01", "json.golden",
|
||||||
),
|
),
|
||||||
want: []byte("foobar json here"),
|
want: []byte("foobar json here"),
|
||||||
},
|
},
|
||||||
@@ -347,7 +290,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
named: "hello/world",
|
named: "hello/world",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed",
|
"testdata", "TestGetP",
|
||||||
"foo", "bar",
|
"foo", "bar",
|
||||||
"hello", "world.golden",
|
"hello", "world.golden",
|
||||||
),
|
),
|
||||||
@@ -357,7 +300,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "john's lost flip-flop",
|
name: "john's lost flip-flop",
|
||||||
named: "left",
|
named: "left",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "john's_lost_flip-flop",
|
"testdata", "TestGetP", "john's_lost_flip-flop",
|
||||||
"left.golden",
|
"left.golden",
|
||||||
),
|
),
|
||||||
want: []byte("Did John lose his left flip-flop again?"),
|
want: []byte("Did John lose his left flip-flop again?"),
|
||||||
@@ -366,7 +309,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "john's lost flip-flop",
|
name: "john's lost flip-flop",
|
||||||
named: "right",
|
named: "right",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "john's_lost_flip-flop#01",
|
"testdata", "TestGetP", "john's_lost_flip-flop#01",
|
||||||
"right.golden",
|
"right.golden",
|
||||||
),
|
),
|
||||||
want: []byte("Did John lose his right flip-flop again?"),
|
want: []byte("Did John lose his right flip-flop again?"),
|
||||||
@@ -375,14 +318,14 @@ func TestGetNamed(t *testing.T) {
|
|||||||
name: "thing: it's",
|
name: "thing: it's",
|
||||||
named: "a thing!",
|
named: "a thing!",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestGetNamed", "thing:_it's", "a thing!.golden",
|
"testdata", "TestGetP", "thing__it's", "a_thing!.golden",
|
||||||
),
|
),
|
||||||
want: []byte("A thing? Really? Are we getting lazy? :P"),
|
want: []byte("A thing? Really? Are we getting lazy? :P"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
f := NamedFile(t, tt.named)
|
f := FileP(t, tt.named)
|
||||||
dir := filepath.Dir(f)
|
dir := filepath.Dir(f)
|
||||||
|
|
||||||
err := os.MkdirAll(dir, 0o755)
|
err := os.MkdirAll(dir, 0o755)
|
||||||
@@ -391,7 +334,7 @@ func TestGetNamed(t *testing.T) {
|
|||||||
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
|
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
got := GetNamed(t, tt.named)
|
got := GetP(t, tt.named)
|
||||||
|
|
||||||
assert.Equal(t, filepath.FromSlash(tt.file), f)
|
assert.Equal(t, filepath.FromSlash(tt.file), f)
|
||||||
assert.Equal(t, tt.want, got)
|
assert.Equal(t, tt.want, got)
|
||||||
@@ -399,27 +342,17 @@ func TestGetNamed(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetNamed(t *testing.T) {
|
func TestSetP(t *testing.T) {
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
err := os.RemoveAll(filepath.Join("testdata", t.Name()))
|
err := os.RemoveAll(filepath.Join("testdata", "TestSetP"))
|
||||||
require.NoError(t, err)
|
|
||||||
err = os.Remove(filepath.Join("testdata", t.Name()+".golden"))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
content := []byte("This is the default golden file for TestSetNamed ^_^")
|
content := []byte("This is the named golden file for TestSetP ^_^")
|
||||||
SetNamed(t, "", content)
|
SetP(t, "sub-name", content)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(filepath.Join("testdata", "TestSetNamed.golden"))
|
b, err := ioutil.ReadFile(
|
||||||
require.NoError(t, err)
|
filepath.Join("testdata", "TestSetP", "sub-name.golden"),
|
||||||
|
|
||||||
assert.Equal(t, content, b)
|
|
||||||
|
|
||||||
content = []byte("This is the named golden file for TestSetNamed ^_^")
|
|
||||||
SetNamed(t, "sub-name", content)
|
|
||||||
|
|
||||||
b, err = ioutil.ReadFile(
|
|
||||||
filepath.Join("testdata", "TestSetNamed", "sub-name.golden"),
|
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -431,16 +364,11 @@ func TestSetNamed(t *testing.T) {
|
|||||||
file string
|
file string
|
||||||
content []byte
|
content []byte
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
file: filepath.Join("testdata", "TestSetNamed", "#00.golden"),
|
|
||||||
content: []byte("number double-zero strikes again"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
named: "sub-zero-one",
|
named: "sub-zero-one",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "#01", "sub-zero-one.golden",
|
"testdata", "TestSetP", "#00", "sub-zero-one.golden",
|
||||||
),
|
),
|
||||||
content: []byte("number zero-one sub-zero-one strikes again"),
|
content: []byte("number zero-one sub-zero-one strikes again"),
|
||||||
},
|
},
|
||||||
@@ -448,7 +376,7 @@ func TestSetNamed(t *testing.T) {
|
|||||||
name: "foobar",
|
name: "foobar",
|
||||||
named: "email",
|
named: "email",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "foobar", "email.golden",
|
"testdata", "TestSetP", "foobar", "email.golden",
|
||||||
),
|
),
|
||||||
content: []byte("foobar here"),
|
content: []byte("foobar here"),
|
||||||
},
|
},
|
||||||
@@ -456,22 +384,15 @@ func TestSetNamed(t *testing.T) {
|
|||||||
name: "foobar",
|
name: "foobar",
|
||||||
named: "json",
|
named: "json",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "foobar#01", "json.golden",
|
"testdata", "TestSetP", "foobar#01", "json.golden",
|
||||||
),
|
),
|
||||||
content: []byte("foobar here"),
|
content: []byte("foobar here"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "foo/bar",
|
|
||||||
file: filepath.Join(
|
|
||||||
"testdata", "TestSetNamed", "foo", "bar.golden",
|
|
||||||
),
|
|
||||||
content: []byte("foo/bar style sub-sub-folders works too"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "john's lost flip-flop",
|
name: "john's lost flip-flop",
|
||||||
named: "left",
|
named: "left",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "john's_lost_flip-flop",
|
"testdata", "TestSetP", "john's_lost_flip-flop",
|
||||||
"left.golden",
|
"left.golden",
|
||||||
),
|
),
|
||||||
content: []byte("Did John lose his left flip-flop again?"),
|
content: []byte("Did John lose his left flip-flop again?"),
|
||||||
@@ -480,7 +401,7 @@ func TestSetNamed(t *testing.T) {
|
|||||||
name: "john's lost flip-flop",
|
name: "john's lost flip-flop",
|
||||||
named: "right",
|
named: "right",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "john's_lost_flip-flop#01",
|
"testdata", "TestSetP", "john's_lost_flip-flop#01",
|
||||||
"right.golden",
|
"right.golden",
|
||||||
),
|
),
|
||||||
content: []byte("Did John lose his right flip-flop again?"),
|
content: []byte("Did John lose his right flip-flop again?"),
|
||||||
@@ -489,16 +410,16 @@ func TestSetNamed(t *testing.T) {
|
|||||||
name: "thing: it's",
|
name: "thing: it's",
|
||||||
named: "a thing!",
|
named: "a thing!",
|
||||||
file: filepath.Join(
|
file: filepath.Join(
|
||||||
"testdata", "TestSetNamed", "thing:_it's", "a thing!.golden",
|
"testdata", "TestSetP", "thing__it's", "a_thing!.golden",
|
||||||
),
|
),
|
||||||
content: []byte("A thing? Really? Are we getting lazy? :P"),
|
content: []byte("A thing? Really? Are we getting lazy? :P"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
f := NamedFile(t, tt.named)
|
f := FileP(t, tt.named)
|
||||||
|
|
||||||
SetNamed(t, tt.named, tt.content)
|
SetP(t, tt.named, tt.content)
|
||||||
|
|
||||||
got, err := ioutil.ReadFile(f)
|
got, err := ioutil.ReadFile(f)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -509,53 +430,14 @@ func TestSetNamed(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNamedFile(t *testing.T) {
|
func TestUpdate(t *testing.T) {
|
||||||
got := NamedFile(t, "")
|
for _, tt := range envUpdateFuncTestCases {
|
||||||
assert.Equal(t, "testdata/TestNamedFile.golden", got)
|
|
||||||
|
|
||||||
got = NamedFile(t, "sub-name")
|
|
||||||
assert.Equal(t, "testdata/TestNamedFile/sub-name.golden", got)
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
named string
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
named: "",
|
|
||||||
want: "testdata/TestNamedFile/#00.golden",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
named: "sub-thing",
|
|
||||||
want: "testdata/TestNamedFile/#01/sub-thing.golden",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "foobar",
|
|
||||||
want: "testdata/TestNamedFile/foobar.golden",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "fozbaz",
|
|
||||||
named: "email",
|
|
||||||
want: "testdata/TestNamedFile/fozbaz/email.golden",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "fozbaz",
|
|
||||||
named: "json",
|
|
||||||
want: "testdata/TestNamedFile/fozbaz#01/json.golden",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "foo/bar",
|
|
||||||
named: "hello/world",
|
|
||||||
want: "testdata/TestNamedFile/foo/bar/hello/world.golden",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got := NamedFile(t, tt.named)
|
envctl.WithClean(tt.env, func() {
|
||||||
|
got := Update()
|
||||||
|
|
||||||
assert.Equal(t, tt.want, got)
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
34
sanitize.go
Normal file
34
sanitize.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package golden
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
whitespaceChars = regexp.MustCompile(`\s`)
|
||||||
|
illegalChars = regexp.MustCompile(`[\/\?<>\\:\*\|"]`)
|
||||||
|
controlChars = regexp.MustCompile(`[\x00-\x1f\x80-\x9f]`)
|
||||||
|
reservedNames = regexp.MustCompile(`^\.+$`)
|
||||||
|
winReserved = regexp.MustCompile(
|
||||||
|
`(?i)^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$`,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
func sanitizeFilename(name string) string {
|
||||||
|
if reservedNames.MatchString(name) || winReserved.MatchString(name) {
|
||||||
|
var b []byte
|
||||||
|
for i := 0; i < len(name); i++ {
|
||||||
|
b = append(b, byte('_'))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := strings.TrimRight(name, ". ")
|
||||||
|
r = whitespaceChars.ReplaceAllString(r, "_")
|
||||||
|
r = illegalChars.ReplaceAllString(r, "_")
|
||||||
|
r = controlChars.ReplaceAllString(r, "_")
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
124
sanitize_test.go
Normal file
124
sanitize_test.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
package golden
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_sanitizeFilename(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
filename string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
filename: "",
|
||||||
|
want: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".",
|
||||||
|
filename: ".",
|
||||||
|
want: "_",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "..",
|
||||||
|
filename: "..",
|
||||||
|
want: "__",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "...",
|
||||||
|
filename: "...",
|
||||||
|
want: "___",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "clean",
|
||||||
|
filename: "foo-bar-nope.golden",
|
||||||
|
want: "foo-bar-nope.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with spaces",
|
||||||
|
filename: "foo bar nope.golden",
|
||||||
|
want: "foo__bar_nope.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "illegal chars",
|
||||||
|
filename: `foo/?<>\:*|"bar.golden`,
|
||||||
|
want: "foo_________bar.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "control chars",
|
||||||
|
filename: "foo\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" +
|
||||||
|
"\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a" +
|
||||||
|
"\x1b\x1c\x1d\x1e\x1fbar.golden",
|
||||||
|
want: "foo________________________________bar.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trailing whitespace",
|
||||||
|
filename: "foobar.golden ",
|
||||||
|
want: "foobar.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trailing dots",
|
||||||
|
filename: "foobar.golden......",
|
||||||
|
want: "foobar.golden",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trailing whitespace and dots",
|
||||||
|
filename: "foobar.golden .. .. .. ",
|
||||||
|
want: "foobar.golden",
|
||||||
|
},
|
||||||
|
{name: "con", filename: "con", want: "___"},
|
||||||
|
{name: "prn", filename: "prn", want: "___"},
|
||||||
|
{name: "aux", filename: "aux", want: "___"},
|
||||||
|
{name: "nul", filename: "nul", want: "___"},
|
||||||
|
{name: "com1", filename: "com1", want: "____"},
|
||||||
|
{name: "com2", filename: "com2", want: "____"},
|
||||||
|
{name: "com3", filename: "com3", want: "____"},
|
||||||
|
{name: "com4", filename: "com4", want: "____"},
|
||||||
|
{name: "com5", filename: "com5", want: "____"},
|
||||||
|
{name: "com6", filename: "com6", want: "____"},
|
||||||
|
{name: "com7", filename: "com7", want: "____"},
|
||||||
|
{name: "com8", filename: "com8", want: "____"},
|
||||||
|
{name: "com9", filename: "com9", want: "____"},
|
||||||
|
{name: "lpt1", filename: "lpt1", want: "____"},
|
||||||
|
{name: "lpt2", filename: "lpt2", want: "____"},
|
||||||
|
{name: "lpt3", filename: "lpt3", want: "____"},
|
||||||
|
{name: "lpt4", filename: "lpt4", want: "____"},
|
||||||
|
{name: "lpt5", filename: "lpt5", want: "____"},
|
||||||
|
{name: "lpt6", filename: "lpt6", want: "____"},
|
||||||
|
{name: "lpt7", filename: "lpt7", want: "____"},
|
||||||
|
{name: "lpt8", filename: "lpt8", want: "____"},
|
||||||
|
{name: "lpt9", filename: "lpt9", want: "____"},
|
||||||
|
{name: "CON", filename: "CON", want: "___"},
|
||||||
|
{name: "PRN", filename: "PRN", want: "___"},
|
||||||
|
{name: "AUX", filename: "AUX", want: "___"},
|
||||||
|
{name: "NUL", filename: "NUL", want: "___"},
|
||||||
|
{name: "COM1", filename: "COM1", want: "____"},
|
||||||
|
{name: "COM2", filename: "COM2", want: "____"},
|
||||||
|
{name: "COM3", filename: "COM3", want: "____"},
|
||||||
|
{name: "COM4", filename: "COM4", want: "____"},
|
||||||
|
{name: "COM5", filename: "COM5", want: "____"},
|
||||||
|
{name: "COM6", filename: "COM6", want: "____"},
|
||||||
|
{name: "COM7", filename: "COM7", want: "____"},
|
||||||
|
{name: "COM8", filename: "COM8", want: "____"},
|
||||||
|
{name: "COM9", filename: "COM9", want: "____"},
|
||||||
|
{name: "LPT1", filename: "LPT1", want: "____"},
|
||||||
|
{name: "LPT2", filename: "LPT2", want: "____"},
|
||||||
|
{name: "LPT3", filename: "LPT3", want: "____"},
|
||||||
|
{name: "LPT4", filename: "LPT4", want: "____"},
|
||||||
|
{name: "LPT5", filename: "LPT5", want: "____"},
|
||||||
|
{name: "LPT6", filename: "LPT6", want: "____"},
|
||||||
|
{name: "LPT7", filename: "LPT7", want: "____"},
|
||||||
|
{name: "LPT8", filename: "LPT8", want: "____"},
|
||||||
|
{name: "LPT9", filename: "LPT9", want: "____"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := sanitizeFilename(tt.filename)
|
||||||
|
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
1
testdata/TestExampleMyStruct.golden
vendored
Normal file
1
testdata/TestExampleMyStruct.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"foo":"Bar"}
|
||||||
1
testdata/TestExampleMyStructP/json.golden
vendored
Normal file
1
testdata/TestExampleMyStructP/json.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"foo":"Bar"}
|
||||||
1
testdata/TestExampleMyStructP/xml.golden
vendored
Normal file
1
testdata/TestExampleMyStructP/xml.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<MyStruct><Foo>Bar</Foo></MyStruct>
|
||||||
1
testdata/TestExampleMyStructTabular/empty_struct.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabular/empty_struct.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
testdata/TestExampleMyStructTabular/full_struct.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabular/full_struct.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"foo":"Bar"}
|
||||||
1
testdata/TestExampleMyStructTabularP/empty_struct/json.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabularP/empty_struct/json.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
testdata/TestExampleMyStructTabularP/empty_struct/xml.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabularP/empty_struct/xml.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<MyStruct><Foo></Foo></MyStruct>
|
||||||
1
testdata/TestExampleMyStructTabularP/full_struct/json.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabularP/full_struct/json.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"foo":"Bar"}
|
||||||
1
testdata/TestExampleMyStructTabularP/full_struct/xml.golden
vendored
Normal file
1
testdata/TestExampleMyStructTabularP/full_struct/xml.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<MyStruct><Foo>Bar</Foo></MyStruct>
|
||||||
@@ -4,11 +4,14 @@ import "os"
|
|||||||
|
|
||||||
var truthyStrings = []string{"1", "y", "t", "yes", "on", "true"}
|
var truthyStrings = []string{"1", "y", "t", "yes", "on", "true"}
|
||||||
|
|
||||||
type UpdatingFunc func() bool
|
type UpdateFunc func() bool
|
||||||
|
|
||||||
// EnvVarUpdateFunc checks if the GOLDEN_UPDATE environment variable is set to
|
// EnvUpdateFunc checks if the GOLDEN_UPDATE environment variable is set to
|
||||||
// one of "1", "y", "t", "yes", "on", or "true".
|
// one of "1", "y", "t", "yes", "on", or "true".
|
||||||
func EnvVarUpdatingFunc() bool {
|
//
|
||||||
|
// This is also the default UpdateFunc used to determine the return value of
|
||||||
|
// Update().
|
||||||
|
func EnvUpdateFunc() bool {
|
||||||
env := os.Getenv("GOLDEN_UPDATE")
|
env := os.Getenv("GOLDEN_UPDATE")
|
||||||
for _, v := range truthyStrings {
|
for _, v := range truthyStrings {
|
||||||
if env == v {
|
if env == v {
|
||||||
106
update_test.go
Normal file
106
update_test.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package golden
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jimeh/envctl"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var envUpdateFuncTestCases = []struct {
|
||||||
|
name string
|
||||||
|
env map[string]string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE not set",
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to empty string",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": ""},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to 0",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "0"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to 1",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "1"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to 2",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "2"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to y",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "y"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to n",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "n"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to t",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "t"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to f",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "f"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to yes",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "yes"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to no",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "no"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to on",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "on"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to off",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "off"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to true",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "true"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to false",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "false"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GOLDEN_UPDATE set to foobarnopebbq",
|
||||||
|
env: map[string]string{"GOLDEN_UPDATE": "foobarnopebbq"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvUpdateFunc(t *testing.T) {
|
||||||
|
for _, tt := range envUpdateFuncTestCases {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
envctl.WithClean(tt.env, func() {
|
||||||
|
got := EnvUpdateFunc()
|
||||||
|
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user