mirror of
https://github.com/jimeh/go-golden.git
synced 2026-02-19 11:16:47 +00:00
Compare commits
12 Commits
improve-te
...
v0.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e17b04717f | ||
| 550ba17fb0 | |||
|
|
8a88e5174b | ||
| bc86ba7a6d | |||
| 62e8344ff3 | |||
| e46dc124ff | |||
| 6817ec6101 | |||
| 8f4d3d4170 | |||
| b2112ca475 | |||
|
27e0134701
|
|||
| 85ae6e9ae3 | |||
| f5a03af9ce |
3
.github/.release-please-manifest.json
vendored
Normal file
3
.github/.release-please-manifest.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
".": "0.2.1"
|
||||
}
|
||||
15
.github/release-please-config.json
vendored
Normal file
15
.github/release-please-config.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"bootstrap-sha": "edb189f0863fddd94211a5b4c5b5bcf7a90fbd10",
|
||||
"packages": {
|
||||
".": {
|
||||
"release-type": "go",
|
||||
"changelog-path": "CHANGELOG.md",
|
||||
"bump-minor-pre-major": true,
|
||||
"bump-patch-for-minor-pre-major": true,
|
||||
"always-update": true,
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}
|
||||
},
|
||||
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
|
||||
}
|
||||
73
.github/workflows/ci.yml
vendored
73
.github/workflows/ci.yml
vendored
@@ -6,29 +6,28 @@ jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
version: v1.42
|
||||
env:
|
||||
VERBOSE: "true"
|
||||
go-version: stable
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: v1.64
|
||||
|
||||
tidy:
|
||||
name: Tidy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
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-
|
||||
go-version-file: go.mod
|
||||
- name: Check if mods are tidy
|
||||
run: make check-tidy
|
||||
|
||||
@@ -36,18 +35,12 @@ jobs:
|
||||
name: Coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
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-
|
||||
go-version-file: go.mod
|
||||
- name: Publish coverage
|
||||
uses: paambaati/codeclimate-action@v2.7.4
|
||||
uses: paambaati/codeclimate-action@v9.0.0
|
||||
env:
|
||||
VERBOSE: "true"
|
||||
GOMAXPROCS: 4
|
||||
@@ -68,20 +61,30 @@ jobs:
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
go_version:
|
||||
- "1.15"
|
||||
- "1.16"
|
||||
- "1.17"
|
||||
- "1.18"
|
||||
- "1.19"
|
||||
- "1.20"
|
||||
- "stable"
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go_version }}
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
check-latest: true
|
||||
- name: Run tests
|
||||
run: go test -v -count=1 -race ./...
|
||||
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
outputs:
|
||||
release_created: ${{ steps.release-please.outputs.release_created }}
|
||||
version: ${{ steps.release-please.outputs.version }}
|
||||
steps:
|
||||
- uses: jimeh/release-please-manifest-action@v2
|
||||
id: release-please
|
||||
with:
|
||||
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -4,18 +4,13 @@ linters-settings:
|
||||
statements: 150
|
||||
gocyclo:
|
||||
min-complexity: 20
|
||||
golint:
|
||||
min-confidence: 0
|
||||
govet:
|
||||
check-shadowing: true
|
||||
enable-all: true
|
||||
disable:
|
||||
- fieldalignment
|
||||
lll:
|
||||
line-length: 80
|
||||
tab-width: 4
|
||||
maligned:
|
||||
suggest-new: true
|
||||
misspell:
|
||||
locale: US
|
||||
|
||||
@@ -24,13 +19,11 @@ linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- copyloopvar
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errorlint
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- funlen
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
@@ -58,13 +51,10 @@ linters:
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- tparallel
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- wastedassign
|
||||
- whitespace
|
||||
|
||||
|
||||
22
CHANGELOG.md
22
CHANGELOG.md
@@ -2,6 +2,28 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [0.2.1](https://github.com/jimeh/go-golden/compare/v0.2.0...v0.2.1) (2025-04-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **options:** add optional Options arguments to New() function ([#14](https://github.com/jimeh/go-golden/issues/14)) ([550ba17](https://github.com/jimeh/go-golden/commit/550ba17fb0be76372eab83f2494ee4ffff804fa6))
|
||||
|
||||
## [0.2.0](https://github.com/jimeh/go-golden/compare/v0.1.0...v0.2.0) (2025-03-24)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **go:** Go 1.17 or later is now required, up from Go 1.15.
|
||||
|
||||
### Features
|
||||
|
||||
* **defaults:** expose a Default *Golden instance ([#9](https://github.com/jimeh/go-golden/issues/9)) ([e46dc12](https://github.com/jimeh/go-golden/commit/e46dc124ff22e52dfc050174c7b3de980c980912))
|
||||
* **do:** add new Do function to simplify golden usage ([#11](https://github.com/jimeh/go-golden/issues/11)) ([bc86ba7](https://github.com/jimeh/go-golden/commit/bc86ba7a6d9f4374c9fb15f78e51eedf50df04d2))
|
||||
* **go:** upgrade to Go 1.17 (from 1.15) ([#6](https://github.com/jimeh/go-golden/issues/6)) ([85ae6e9](https://github.com/jimeh/go-golden/commit/85ae6e9ae3c4222d68faee0c44a1fd105a2e04b4))
|
||||
* **interface:** use TestingT interface intead of *testing.T in function signatures ([#13](https://github.com/jimeh/go-golden/issues/13)) ([62e8344](https://github.com/jimeh/go-golden/commit/62e8344ff33dccf0a5666e94361a143d34558bf0))
|
||||
* **update:** make default GOLDEN_UPDATE env var check case-insensitive ([#10](https://github.com/jimeh/go-golden/issues/10)) ([6817ec6](https://github.com/jimeh/go-golden/commit/6817ec6101558b3914984d4ee3fe816d534f87bb))
|
||||
|
||||
## 0.1.0 (2021-10-28)
|
||||
|
||||
|
||||
|
||||
35
Makefile
35
Makefile
@@ -34,23 +34,19 @@ SHELL := env \
|
||||
# Tools
|
||||
#
|
||||
|
||||
TOOLS += $(TOOLDIR)/gobin
|
||||
$(TOOLDIR)/gobin:
|
||||
GO111MODULE=off go get -u github.com/myitcv/gobin
|
||||
|
||||
# external tool
|
||||
define tool # 1: binary-name, 2: go-import-path
|
||||
TOOLS += $(TOOLDIR)/$(1)
|
||||
|
||||
$(TOOLDIR)/$(1): $(TOOLDIR)/gobin Makefile
|
||||
gobin $(V) "$(2)"
|
||||
$(TOOLDIR)/$(1): Makefile
|
||||
GOBIN="$(CURDIR)/$(TOOLDIR)" go install "$(2)"
|
||||
endef
|
||||
|
||||
$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc))
|
||||
$(eval $(call tool,gofumpt,mvdan.cc/gofumpt))
|
||||
$(eval $(call tool,goimports,golang.org/x/tools/cmd/goimports))
|
||||
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/cmd/golangci-lint@v1.42))
|
||||
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod))
|
||||
$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc@latest))
|
||||
$(eval $(call tool,gofumpt,mvdan.cc/gofumpt@latest))
|
||||
$(eval $(call tool,goimports,golang.org/x/tools/cmd/goimports@latest))
|
||||
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64))
|
||||
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod@latest))
|
||||
|
||||
.PHONY: tools
|
||||
tools: $(TOOLS)
|
||||
@@ -186,20 +182,3 @@ check-tidy:
|
||||
docs: $(TOOLDIR)/godoc
|
||||
$(info serviing docs on http://127.0.0.1:6060/pkg/$(GOMODNAME)/)
|
||||
@godoc -http=127.0.0.1:6060
|
||||
|
||||
#
|
||||
# Release
|
||||
#
|
||||
|
||||
.PHONY: new-version
|
||||
new-version: check-npx
|
||||
npx standard-version
|
||||
|
||||
.PHONY: next-version
|
||||
next-version: check-npx
|
||||
npx standard-version --dry-run
|
||||
|
||||
.PHONY: check-npx
|
||||
check-npx:
|
||||
$(if $(shell which npx),,\
|
||||
$(error No npx found in PATH, please install NodeJS))
|
||||
|
||||
46
README.md
46
README.md
@@ -10,26 +10,12 @@
|
||||
</p>
|
||||
|
||||
<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>
|
||||
<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/actions/workflow/status/jimeh/go-golden/ci.yml?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>
|
||||
|
||||
## Import
|
||||
@@ -42,15 +28,12 @@ import "github.com/jimeh/go-golden"
|
||||
|
||||
```go
|
||||
func TestExampleMyStruct(t *testing.T) {
|
||||
got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||
require.NoError(t, err)
|
||||
got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||
require.NoError(t, err)
|
||||
|
||||
if golden.Update() {
|
||||
golden.Set(t, got)
|
||||
}
|
||||
want := golden.Get(t)
|
||||
want := golden.Do(t, got)
|
||||
|
||||
assert.Equal(t, want, got)
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -58,6 +41,15 @@ The above example will read/write to:
|
||||
|
||||
- `testdata/TestExampleMyStruct.golden`
|
||||
|
||||
The call to `golden.Do()` is equivalent to:
|
||||
|
||||
```go
|
||||
if golden.Update() {
|
||||
golden.Set(t, got)
|
||||
}
|
||||
want := golden.Get(t)
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
@@ -10,31 +10,29 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// The tests in this file are examples from the README and the package-level Go
|
||||
// documentation.
|
||||
|
||||
type MyStruct struct {
|
||||
Foo string `json:"foo,omitempty"`
|
||||
}
|
||||
|
||||
// TestExampleMyStruct reads/writes the following golden file:
|
||||
//
|
||||
// testdata/TestExampleMyStruct.golden
|
||||
//
|
||||
// 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)
|
||||
want := golden.Do(t, got)
|
||||
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
|
||||
// TestExampleMyStructTabular reads/writes the following golden files:
|
||||
//
|
||||
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||
//
|
||||
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||
func TestExampleMyStructTabular(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -48,10 +46,7 @@ func TestExampleMyStructTabular(t *testing.T) {
|
||||
got, err := json.Marshal(tt.obj)
|
||||
require.NoError(t, err)
|
||||
|
||||
if golden.Update() {
|
||||
golden.Set(t, got)
|
||||
}
|
||||
want := golden.Get(t)
|
||||
want := golden.Do(t, got)
|
||||
|
||||
assert.Equal(t, want, got)
|
||||
})
|
||||
@@ -60,29 +55,25 @@ func TestExampleMyStructTabular(t *testing.T) {
|
||||
|
||||
// TestExampleMyStructP reads/writes the following golden file:
|
||||
//
|
||||
// testdata/TestExampleMyStructP/json.golden
|
||||
// testdata/TestExampleMyStructP/xml.golden
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
wantJSON := golden.DoP(t, "json", gotJSON)
|
||||
wantXML := golden.DoP(t, "xml", gotXML)
|
||||
|
||||
assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||
assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||
assert.Equal(t, wantJSON, gotJSON)
|
||||
assert.Equal(t, wantXML, 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
|
||||
//
|
||||
// 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
|
||||
@@ -96,13 +87,11 @@ func TestExampleMyStructTabularP(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)
|
||||
}
|
||||
wantJSON := golden.DoP(t, "json", gotJSON)
|
||||
wantXML := golden.DoP(t, "xml", gotXML)
|
||||
|
||||
assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||
assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||
assert.Equal(t, wantJSON, gotJSON)
|
||||
assert.Equal(t, wantXML, gotXML)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
9
go.mod
9
go.mod
@@ -1,8 +1,11 @@
|
||||
module github.com/jimeh/go-golden
|
||||
|
||||
go 1.15
|
||||
go 1.17
|
||||
|
||||
require github.com/stretchr/testify v1.10.0
|
||||
|
||||
require (
|
||||
github.com/jimeh/envctl v0.1.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
19
go.sum
19
go.sum
@@ -1,14 +1,19 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/jimeh/envctl v0.1.0 h1:KTv3D+pi5M4/PgFVE/W8ssWqiZP3pDJ8Cga50L+1avo=
|
||||
github.com/jimeh/envctl v0.1.0/go.mod h1:aM27ffBbO1yUBKUzgJGCUorS4z+wyh+qhQe1ruxXZZo=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
337
golden.go
337
golden.go
@@ -1,178 +1,200 @@
|
||||
// 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
|
||||
// Golden file names are based on the name of the test function and any sub-test
|
||||
// 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.
|
||||
// characters might be in a sub-test's name.
|
||||
//
|
||||
// Usage
|
||||
// # Usage
|
||||
//
|
||||
// Typical usage should look something like this:
|
||||
//
|
||||
// func TestExampleMyStruct(t *testing.T) {
|
||||
// got, err := json.Marshal(&MyStruct{Foo: "Bar"})
|
||||
// require.NoError(t, err)
|
||||
// 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)
|
||||
// want := golden.Do(t, got)
|
||||
//
|
||||
// assert.Equal(t, want, got)
|
||||
// }
|
||||
// assert.Equal(t, want, got)
|
||||
// }
|
||||
//
|
||||
// The above example will read/write to:
|
||||
//
|
||||
// testdata/TestExampleMyStruct.golden
|
||||
// testdata/TestExampleMyStruct.golden
|
||||
//
|
||||
// The call to golden.Do() is equivalent to:
|
||||
//
|
||||
// if golden.Update() {
|
||||
// golden.Set(t, got)
|
||||
// }
|
||||
// want := golden.Get(t)
|
||||
//
|
||||
// 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
|
||||
// # 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:
|
||||
// ensuring each sub-test gets its 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)
|
||||
// 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)
|
||||
// want := golden.Do(t, got)
|
||||
//
|
||||
// assert.Equal(t, want, got)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// assert.Equal(t, want, got)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// The above example will read/write to:
|
||||
//
|
||||
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||
// testdata/TestExampleMyStructTabular/empty_struct.golden
|
||||
// testdata/TestExampleMyStructTabular/full_struct.golden
|
||||
//
|
||||
// Multiple Golden Files in a Single Test
|
||||
// # 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"})
|
||||
// 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)
|
||||
// }
|
||||
// wantJSON := golden.DoP(t, "json", gotJSON)
|
||||
// wantXML := golden.DoP(t, "xml", gotXML)
|
||||
//
|
||||
// assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||
// assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||
// }
|
||||
// assert.Equal(t, wantJSON, gotJSON)
|
||||
// assert.Equal(t, wantXML, gotXML)
|
||||
// }
|
||||
//
|
||||
// The above example will read/write to:
|
||||
//
|
||||
// testdata/TestExampleMyStructP/json.golden
|
||||
// testdata/TestExampleMyStructP/xml.golden
|
||||
// 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)
|
||||
// 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)
|
||||
// }
|
||||
// wantJSON := golden.DoP(t, "json", gotJSON)
|
||||
// wantXML := golden.DoP(t, "xml", gotXML)
|
||||
//
|
||||
// assert.Equal(t, golden.GetP(t, "json"), gotJSON)
|
||||
// assert.Equal(t, golden.GetP(t, "xml"), gotXML)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// assert.Equal(t, wantJSON, gotJSON)
|
||||
// assert.Equal(t, wantXML, 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
|
||||
//
|
||||
// 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
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultDirMode = 0o755
|
||||
DefaultFileMode = 0o644
|
||||
DefaultSuffix = ".golden"
|
||||
DefaultDirname = "testdata"
|
||||
var (
|
||||
// Default is the default *Golden instance. All package-level functions use
|
||||
// the Default instance.
|
||||
Default = New()
|
||||
|
||||
// DefaultDirMode is the default DirMode value used by New().
|
||||
DefaultDirMode = os.FileMode(0o755)
|
||||
|
||||
// DefaultFileMode is the default FileMode value used by New().
|
||||
DefaultFileMode = os.FileMode(0o644)
|
||||
|
||||
// DefaultSuffix is the default Suffix value used by New().
|
||||
DefaultSuffix = ".golden"
|
||||
|
||||
// DefaultDirname is the default Dirname value used by New().
|
||||
DefaultDirname = "testdata"
|
||||
|
||||
// DefaultUpdateFunc is the default UpdateFunc value used by New().
|
||||
DefaultUpdateFunc = EnvUpdateFunc
|
||||
)
|
||||
|
||||
var DefaultUpdateFunc = EnvUpdateFunc
|
||||
// Do is a convenience function for calling Update(), Set(), and Get() in a
|
||||
// single call. If Update() returns true, data will be written to the golden
|
||||
// file using Set(), before reading it back with Get().
|
||||
func Do(t TestingT, data []byte) []byte {
|
||||
t.Helper()
|
||||
|
||||
var global = New()
|
||||
return Default.Do(t, data)
|
||||
}
|
||||
|
||||
// File returns the filename of the golden file for the given *testing.T
|
||||
// instance as determined by t.Name().
|
||||
func File(t *testing.T) string {
|
||||
func File(t TestingT) string {
|
||||
t.Helper()
|
||||
|
||||
return global.File(t)
|
||||
return Default.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 {
|
||||
func Get(t TestingT) []byte {
|
||||
t.Helper()
|
||||
|
||||
return global.Get(t)
|
||||
return Default.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) {
|
||||
func Set(t TestingT, data []byte) {
|
||||
t.Helper()
|
||||
|
||||
global.Set(t, data)
|
||||
Default.Set(t, data)
|
||||
}
|
||||
|
||||
// DoP is a convenience function for calling Update(), SetP(), and GetP() in a
|
||||
// single call. If Update() returns true, data will be written to the golden
|
||||
// file using SetP(), before reading it back with GetP().
|
||||
func DoP(t TestingT, name string, data []byte) []byte {
|
||||
t.Helper()
|
||||
|
||||
return Default.DoP(t, name, 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 {
|
||||
func FileP(t TestingT, name string) string {
|
||||
t.Helper()
|
||||
|
||||
return global.FileP(t, name)
|
||||
return Default.FileP(t, name)
|
||||
}
|
||||
|
||||
// GetP returns the content of the specifically named golden file belonging
|
||||
@@ -181,10 +203,10 @@ func FileP(t *testing.T, name string) string {
|
||||
//
|
||||
// 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 {
|
||||
func GetP(t TestingT, name string) []byte {
|
||||
t.Helper()
|
||||
|
||||
return global.GetP(t, name)
|
||||
return Default.GetP(t, name)
|
||||
}
|
||||
|
||||
// SetP writes given data of the specifically named golden file belonging to
|
||||
@@ -193,10 +215,10 @@ func GetP(t *testing.T, name string) []byte {
|
||||
//
|
||||
// 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) {
|
||||
func SetP(t TestingT, name string, data []byte) {
|
||||
t.Helper()
|
||||
|
||||
global.SetP(t, name, data)
|
||||
Default.SetP(t, name, data)
|
||||
}
|
||||
|
||||
// Update returns true when golden is set to update golden files. Should be used
|
||||
@@ -206,7 +228,7 @@ func SetP(t *testing.T, name string, data []byte) {
|
||||
// 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()
|
||||
return Default.Update()
|
||||
}
|
||||
|
||||
// Golden handles all interactions with golden files. The top-level package
|
||||
@@ -221,7 +243,7 @@ type Golden struct {
|
||||
FileMode os.FileMode
|
||||
|
||||
// Suffix determines the filename suffix for all golden files. Typically
|
||||
// this should be ".golden", but can be changed here if needed.
|
||||
// this would be ".golden".
|
||||
Suffix string
|
||||
|
||||
// Dirname is the name of the top-level directory at the root of the package
|
||||
@@ -234,48 +256,87 @@ type Golden struct {
|
||||
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 {
|
||||
return &Golden{
|
||||
// New returns a new *Golden instance with default values correctly populated.
|
||||
// It accepts zero or more Option functions that can modify the default values.
|
||||
func New(opts ...Option) *Golden {
|
||||
g := &Golden{
|
||||
DirMode: DefaultDirMode,
|
||||
FileMode: DefaultFileMode,
|
||||
Suffix: DefaultSuffix,
|
||||
Dirname: DefaultDirname,
|
||||
UpdateFunc: DefaultUpdateFunc,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(g)
|
||||
}
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
// Do is a convenience function for calling Update(), Set(), and Get() in a
|
||||
// single call. If Update() returns true, data will be written to the golden
|
||||
// file using Set(), before reading it back with Get().
|
||||
func (s *Golden) Do(t TestingT, data []byte) []byte {
|
||||
t.Helper()
|
||||
|
||||
if s.Update() {
|
||||
s.Set(t, data)
|
||||
}
|
||||
|
||||
return s.Get(t)
|
||||
}
|
||||
|
||||
// File returns the filename of the golden file for the given *testing.T
|
||||
// instance as determined by t.Name().
|
||||
func (s *Golden) File(t *testing.T) string {
|
||||
func (s *Golden) File(t TestingT) string {
|
||||
t.Helper()
|
||||
|
||||
return s.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 (s *Golden) Get(t *testing.T) []byte {
|
||||
func (s *Golden) Get(t TestingT) []byte {
|
||||
t.Helper()
|
||||
|
||||
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) {
|
||||
func (s *Golden) Set(t TestingT, data []byte) {
|
||||
t.Helper()
|
||||
|
||||
s.set(t, "", data)
|
||||
}
|
||||
|
||||
// DoP is a convenience function for calling Update(), SetP(), and GetP() in a
|
||||
// single call. If Update() returns true, data will be written to the golden
|
||||
// file using SetP(), before reading it back with GetP().
|
||||
func (s *Golden) DoP(t TestingT, name string, data []byte) []byte {
|
||||
t.Helper()
|
||||
|
||||
if name == "" {
|
||||
t.Fatalf("golden: name cannot be empty")
|
||||
}
|
||||
|
||||
if s.Update() {
|
||||
s.SetP(t, name, data)
|
||||
}
|
||||
|
||||
return s.GetP(t, name)
|
||||
}
|
||||
|
||||
// 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")
|
||||
}
|
||||
func (s *Golden) FileP(t TestingT, name string) string {
|
||||
t.Helper()
|
||||
|
||||
return ""
|
||||
if name == "" {
|
||||
t.Fatalf("golden: name cannot be empty")
|
||||
}
|
||||
|
||||
return s.file(t, name)
|
||||
@@ -287,11 +348,11 @@ func (s *Golden) FileP(t *testing.T, name string) string {
|
||||
//
|
||||
// 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")
|
||||
func (s *Golden) GetP(t TestingT, name string) []byte {
|
||||
t.Helper()
|
||||
|
||||
return nil
|
||||
if name == "" {
|
||||
t.Fatalf("golden: name cannot be empty")
|
||||
}
|
||||
|
||||
return s.get(t, name)
|
||||
@@ -303,19 +364,29 @@ func (s *Golden) GetP(t *testing.T, name string) []byte {
|
||||
//
|
||||
// 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) {
|
||||
func (s *Golden) SetP(t TestingT, name string, data []byte) {
|
||||
t.Helper()
|
||||
|
||||
if name == "" {
|
||||
t.Fatal("golden: name cannot be empty")
|
||||
t.Fatalf("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)
|
||||
// Update returns true when golden is set to update golden files. Should be used
|
||||
// to determine if golden.Set() or golden.SetP() 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 set a new
|
||||
// UpdateFunc value on *Golden.
|
||||
func (s *Golden) Update() bool {
|
||||
return s.UpdateFunc()
|
||||
}
|
||||
|
||||
return ""
|
||||
func (s *Golden) file(t TestingT, name string) string {
|
||||
if t.Name() == "" {
|
||||
t.Fatalf("golden: could not determine filename")
|
||||
}
|
||||
|
||||
base := []string{s.Dirname, filepath.FromSlash(t.Name())}
|
||||
@@ -334,10 +405,10 @@ func (s *Golden) file(t *testing.T, name string) string {
|
||||
return strings.Join(clean, string(os.PathSeparator))
|
||||
}
|
||||
|
||||
func (s *Golden) get(t *testing.T, name string) []byte {
|
||||
func (s *Golden) get(t TestingT, name string) []byte {
|
||||
f := s.file(t, name)
|
||||
|
||||
b, err := ioutil.ReadFile(f)
|
||||
b, err := os.ReadFile(f)
|
||||
if err != nil {
|
||||
t.Fatalf("golden: failed reading %s: %s", f, err.Error())
|
||||
}
|
||||
@@ -345,7 +416,7 @@ func (s *Golden) get(t *testing.T, name string) []byte {
|
||||
return b
|
||||
}
|
||||
|
||||
func (s *Golden) set(t *testing.T, name string, data []byte) {
|
||||
func (s *Golden) set(t TestingT, name string, data []byte) {
|
||||
f := s.file(t, name)
|
||||
dir := filepath.Dir(f)
|
||||
|
||||
@@ -354,22 +425,10 @@ func (s *Golden) set(t *testing.T, name string, data []byte) {
|
||||
err := os.MkdirAll(dir, s.DirMode)
|
||||
if err != nil {
|
||||
t.Fatalf("golden: failed to create directory: %s", err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(f, data, s.FileMode)
|
||||
err = os.WriteFile(f, data, s.FileMode)
|
||||
if err != nil {
|
||||
t.Fatalf("golden: filed to write file: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Update returns true when golden is set to update golden files. Should be used
|
||||
// to determine if golden.Set() or golden.SetP() 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 set a new
|
||||
// UpdateFunc value on *Golden.
|
||||
func (s *Golden) Update() bool {
|
||||
return s.UpdateFunc()
|
||||
}
|
||||
|
||||
405
golden_test.go
405
golden_test.go
@@ -1,16 +1,296 @@
|
||||
package golden
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/jimeh/envctl"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// assertSameFunc asserts that two functions are the same by comparing their
|
||||
// function names via reflection.
|
||||
func assertSameFunc(t *testing.T, want, got interface{}) {
|
||||
t.Helper()
|
||||
|
||||
// Verify both arguments are functions
|
||||
wantType := reflect.TypeOf(want)
|
||||
gotType := reflect.TypeOf(got)
|
||||
|
||||
if wantType.Kind() != reflect.Func {
|
||||
t.Fatalf(
|
||||
"assertSameFunc: 'want' argument is not a function, got %s",
|
||||
wantType.Kind(),
|
||||
)
|
||||
}
|
||||
|
||||
if gotType.Kind() != reflect.Func {
|
||||
t.Fatalf(
|
||||
"assertSameFunc: 'got' argument is not a function, got %s",
|
||||
gotType.Kind(),
|
||||
)
|
||||
}
|
||||
|
||||
gotFP := reflect.ValueOf(got).Pointer()
|
||||
gotFuncName := runtime.FuncForPC(gotFP).Name()
|
||||
wantFP := reflect.ValueOf(want).Pointer()
|
||||
wantFuncName := runtime.FuncForPC(wantFP).Name()
|
||||
|
||||
assert.Equal(t, wantFuncName, gotFuncName)
|
||||
}
|
||||
|
||||
func TestDefaults(t *testing.T) {
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
assert.IsType(t, &Golden{}, Default)
|
||||
|
||||
assert.Equal(t, DefaultDirMode, Default.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, Default.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, Default.Suffix)
|
||||
assert.Equal(t, DefaultDirname, Default.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, Default.UpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("DefaultDirMode", func(t *testing.T) {
|
||||
assert.Equal(t, os.FileMode(0o755), DefaultDirMode)
|
||||
})
|
||||
|
||||
t.Run("DefaultFileMode", func(t *testing.T) {
|
||||
assert.Equal(t, os.FileMode(0o644), DefaultFileMode)
|
||||
})
|
||||
|
||||
t.Run("DefaultSuffix", func(t *testing.T) {
|
||||
assert.Equal(t, ".golden", DefaultSuffix)
|
||||
})
|
||||
|
||||
t.Run("DefaultDirname", func(t *testing.T) {
|
||||
assert.Equal(t, "testdata", DefaultDirname)
|
||||
})
|
||||
|
||||
t.Run("DefaultUpdateFunc", func(t *testing.T) {
|
||||
assertSameFunc(t, EnvUpdateFunc, DefaultUpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("customized Default* variables", func(t *testing.T) {
|
||||
// Capture the default values before we change them.
|
||||
defaultDirMode := DefaultDirMode
|
||||
defaultFileMode := DefaultFileMode
|
||||
defaultSuffix := DefaultSuffix
|
||||
defaultDirname := DefaultDirname
|
||||
defaultUpdateFunc := DefaultUpdateFunc
|
||||
|
||||
// Restore the default values after the test.
|
||||
t.Cleanup(func() {
|
||||
DefaultDirMode = defaultDirMode
|
||||
DefaultFileMode = defaultFileMode
|
||||
DefaultSuffix = defaultSuffix
|
||||
DefaultDirname = defaultDirname
|
||||
DefaultUpdateFunc = defaultUpdateFunc
|
||||
})
|
||||
|
||||
// Set all the default values to new values.
|
||||
DefaultDirMode = os.FileMode(0o700)
|
||||
DefaultFileMode = os.FileMode(0o600)
|
||||
DefaultSuffix = ".gold"
|
||||
DefaultDirname = "goldenfiles"
|
||||
|
||||
updateFunc := func() bool { return true }
|
||||
DefaultUpdateFunc = updateFunc
|
||||
|
||||
// Create a new Golden instance with the new values.
|
||||
got := New()
|
||||
|
||||
assert.Equal(t, DefaultDirMode, got.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, got.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, got.Suffix)
|
||||
assert.Equal(t, DefaultDirname, got.Dirname)
|
||||
assertSameFunc(t, updateFunc, got.UpdateFunc)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
t.Run("defaults (no options)", func(t *testing.T) {
|
||||
g := New()
|
||||
assert.Equal(t, DefaultDirMode, g.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, g.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, g.Suffix)
|
||||
assert.Equal(t, DefaultDirname, g.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
// Test each option individually
|
||||
t.Run("WithDirMode", func(t *testing.T) {
|
||||
customMode := os.FileMode(0o700)
|
||||
g := New(WithDirMode(customMode))
|
||||
assert.Equal(t, customMode, g.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, g.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, g.Suffix)
|
||||
assert.Equal(t, DefaultDirname, g.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("WithFileMode", func(t *testing.T) {
|
||||
customMode := os.FileMode(0o600)
|
||||
g := New(WithFileMode(customMode))
|
||||
assert.Equal(t, DefaultDirMode, g.DirMode)
|
||||
assert.Equal(t, customMode, g.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, g.Suffix)
|
||||
assert.Equal(t, DefaultDirname, g.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("WithSuffix", func(t *testing.T) {
|
||||
customSuffix := ".my-suffix"
|
||||
g := New(WithSuffix(customSuffix))
|
||||
assert.Equal(t, DefaultDirMode, g.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, g.FileMode)
|
||||
assert.Equal(t, customSuffix, g.Suffix)
|
||||
assert.Equal(t, DefaultDirname, g.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("WithDirname", func(t *testing.T) {
|
||||
customDirname := "fixtures/generated"
|
||||
g := New(WithDirname(customDirname))
|
||||
assert.Equal(t, DefaultDirMode, g.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, g.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, g.Suffix)
|
||||
assert.Equal(t, customDirname, g.Dirname)
|
||||
assertSameFunc(t, EnvUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
t.Run("WithUpdateFunc", func(t *testing.T) {
|
||||
customUpdateFunc := func() bool { return true }
|
||||
g := New(WithUpdateFunc(customUpdateFunc))
|
||||
assert.Equal(t, DefaultDirMode, g.DirMode)
|
||||
assert.Equal(t, DefaultFileMode, g.FileMode)
|
||||
assert.Equal(t, DefaultSuffix, g.Suffix)
|
||||
assert.Equal(t, DefaultDirname, g.Dirname)
|
||||
assertSameFunc(t, customUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
|
||||
// Test multiple options at once
|
||||
t.Run("MultipleOptions", func(t *testing.T) {
|
||||
customDirMode := os.FileMode(0o700)
|
||||
customFileMode := os.FileMode(0o600)
|
||||
customSuffix := ".fixture"
|
||||
customDirname := "fixtures"
|
||||
customUpdateFunc := func() bool { return true }
|
||||
|
||||
g := New(
|
||||
WithDirMode(customDirMode),
|
||||
WithFileMode(customFileMode),
|
||||
WithSuffix(customSuffix),
|
||||
WithDirname(customDirname),
|
||||
WithUpdateFunc(customUpdateFunc),
|
||||
)
|
||||
|
||||
assert.Equal(t, customDirMode, g.DirMode)
|
||||
assert.Equal(t, customFileMode, g.FileMode)
|
||||
assert.Equal(t, customSuffix, g.Suffix)
|
||||
assert.Equal(t, customDirname, g.Dirname)
|
||||
assertSameFunc(t, customUpdateFunc, g.UpdateFunc)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDo(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
err := os.RemoveAll(filepath.Join("testdata", "TestDo"))
|
||||
require.NoError(t, err)
|
||||
err = os.Remove(filepath.Join("testdata", "TestDo.golden"))
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
//
|
||||
// Test when Update is false
|
||||
//
|
||||
content := []byte("This is the golden file for TestDo")
|
||||
err := os.MkdirAll("testdata", 0o755)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(
|
||||
filepath.Join("testdata", "TestDo.golden"),
|
||||
content, 0o600,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
newContent := []byte("This should not be written")
|
||||
t.Setenv("GOLDEN_UPDATE", "false")
|
||||
got := Do(t, newContent)
|
||||
assert.Equal(t, content, got)
|
||||
|
||||
// Verify file wasn't changed
|
||||
fileContent, err := os.ReadFile(
|
||||
filepath.Join("testdata", "TestDo.golden"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, content, fileContent)
|
||||
|
||||
//
|
||||
// Test when Update is true
|
||||
//
|
||||
updatedContent := []byte("This is the updated content for TestDo")
|
||||
t.Setenv("GOLDEN_UPDATE", "true")
|
||||
got = Do(t, updatedContent)
|
||||
assert.Equal(t, updatedContent, got)
|
||||
|
||||
// Verify file was updated
|
||||
fileContent, err = os.ReadFile(
|
||||
filepath.Join("testdata", "TestDo.golden"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, updatedContent, fileContent)
|
||||
|
||||
//
|
||||
// Test with sub-tests
|
||||
//
|
||||
tests := []struct {
|
||||
name string
|
||||
content []byte
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
content: []byte("Simple content for sub-test"),
|
||||
},
|
||||
{
|
||||
name: "complex/path",
|
||||
content: []byte("Complex path content for sub-test"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Test with Update true
|
||||
t.Setenv("GOLDEN_UPDATE", "true")
|
||||
got := Do(t, tt.content)
|
||||
assert.Equal(t, tt.content, got)
|
||||
|
||||
// Verify file was written with correct content
|
||||
f := File(t)
|
||||
fileContent, err := os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.content, fileContent)
|
||||
|
||||
// Test with Update false
|
||||
t.Setenv("GOLDEN_UPDATE", "false")
|
||||
|
||||
newContent := []byte(
|
||||
"This should not be written in sub-test",
|
||||
)
|
||||
got = Do(t, newContent)
|
||||
assert.Equal(t, tt.content, got)
|
||||
|
||||
// Verify file wasn't changed
|
||||
f = File(t)
|
||||
fileContent, err = os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.content, fileContent)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFile(t *testing.T) {
|
||||
got := File(t)
|
||||
|
||||
@@ -58,8 +338,8 @@ func TestGet(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
content := []byte("foobar\nhello world :)")
|
||||
err = ioutil.WriteFile( //nolint:gosec
|
||||
filepath.Join("testdata", "TestGet.golden"), content, 0o644,
|
||||
err = os.WriteFile(
|
||||
filepath.Join("testdata", "TestGet.golden"), content, 0o600,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -109,7 +389,7 @@ func TestGet(t *testing.T) {
|
||||
err := os.MkdirAll(dir, 0o755)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
|
||||
err = os.WriteFile(f, tt.want, 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
got := Get(t)
|
||||
@@ -131,7 +411,7 @@ func TestSet(t *testing.T) {
|
||||
content := []byte("This is the default golden file for TestSet ^_^")
|
||||
Set(t, content)
|
||||
|
||||
b, err := ioutil.ReadFile(filepath.Join("testdata", "TestSet.golden"))
|
||||
b, err := os.ReadFile(filepath.Join("testdata", "TestSet.golden"))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, content, b)
|
||||
@@ -177,7 +457,7 @@ func TestSet(t *testing.T) {
|
||||
|
||||
Set(t, tt.content)
|
||||
|
||||
got, err := ioutil.ReadFile(f)
|
||||
got, err := os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tt.file, f)
|
||||
@@ -186,6 +466,97 @@ func TestSet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoP(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
err := os.RemoveAll(filepath.Join("testdata", "TestDoP"))
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
//
|
||||
// Test when Update is false
|
||||
//
|
||||
name := "test-format"
|
||||
content := []byte("This is the golden file for TestDoP")
|
||||
err := os.MkdirAll(filepath.Join("testdata", "TestDoP"), 0o755)
|
||||
require.NoError(t, err)
|
||||
|
||||
goldenFile := filepath.Join("testdata", "TestDoP", name+".golden")
|
||||
err = os.WriteFile(goldenFile, content, 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
newContent := []byte("This should not be written")
|
||||
t.Setenv("GOLDEN_UPDATE", "false")
|
||||
got := DoP(t, name, newContent)
|
||||
assert.Equal(t, content, got)
|
||||
|
||||
// Verify file wasn't changed
|
||||
fileContent, err := os.ReadFile(goldenFile)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, content, fileContent)
|
||||
|
||||
//
|
||||
// Test when Update is true
|
||||
//
|
||||
updatedContent := []byte("This is the updated content for TestDoP")
|
||||
t.Setenv("GOLDEN_UPDATE", "true")
|
||||
got = DoP(t, name, updatedContent)
|
||||
assert.Equal(t, updatedContent, got)
|
||||
|
||||
// Verify file was updated
|
||||
fileContent, err = os.ReadFile(goldenFile)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, updatedContent, fileContent)
|
||||
|
||||
//
|
||||
// Test with sub-tests
|
||||
//
|
||||
tests := []struct {
|
||||
testName string
|
||||
name string
|
||||
content []byte
|
||||
}{
|
||||
{
|
||||
testName: "json format",
|
||||
name: "json",
|
||||
content: []byte(`{"key": "value"}`),
|
||||
},
|
||||
{
|
||||
testName: "xml format",
|
||||
name: "xml",
|
||||
content: []byte(`<root><key>value</key></root>`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.testName, func(t *testing.T) {
|
||||
// Test with Update true
|
||||
t.Setenv("GOLDEN_UPDATE", "true")
|
||||
got := DoP(t, tt.name, tt.content)
|
||||
assert.Equal(t, tt.content, got)
|
||||
|
||||
// Verify file was written with correct content
|
||||
f := FileP(t, tt.name)
|
||||
fileContent, err := os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.content, fileContent)
|
||||
|
||||
// Test with Update false
|
||||
t.Setenv("GOLDEN_UPDATE", "false")
|
||||
newContent := []byte(
|
||||
"This should not be written in sub-test",
|
||||
)
|
||||
got = DoP(t, tt.name, newContent)
|
||||
assert.Equal(t, tt.content, got)
|
||||
|
||||
// Verify file wasn't changed
|
||||
f = FileP(t, tt.name)
|
||||
fileContent, err = os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.content, fileContent)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileP(t *testing.T) {
|
||||
got := FileP(t, "sub-name")
|
||||
assert.Equal(t,
|
||||
@@ -247,9 +618,9 @@ func TestGetP(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
content := []byte("this is the named golden file for TestGetP")
|
||||
err = ioutil.WriteFile( //nolint:gosec
|
||||
err = os.WriteFile(
|
||||
filepath.Join("testdata", "TestGetP", "sub-name.golden"),
|
||||
content, 0o644,
|
||||
content, 0o600,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -331,7 +702,7 @@ func TestGetP(t *testing.T) {
|
||||
err := os.MkdirAll(dir, 0o755)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
|
||||
err = os.WriteFile(f, tt.want, 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
got := GetP(t, tt.named)
|
||||
@@ -351,7 +722,7 @@ func TestSetP(t *testing.T) {
|
||||
content := []byte("This is the named golden file for TestSetP ^_^")
|
||||
SetP(t, "sub-name", content)
|
||||
|
||||
b, err := ioutil.ReadFile(
|
||||
b, err := os.ReadFile(
|
||||
filepath.Join("testdata", "TestSetP", "sub-name.golden"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
@@ -421,7 +792,7 @@ func TestSetP(t *testing.T) {
|
||||
|
||||
SetP(t, tt.named, tt.content)
|
||||
|
||||
got, err := ioutil.ReadFile(f)
|
||||
got, err := os.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tt.file, f)
|
||||
@@ -433,11 +804,13 @@ func TestSetP(t *testing.T) {
|
||||
func TestUpdate(t *testing.T) {
|
||||
for _, tt := range envUpdateFuncTestCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
envctl.WithClean(tt.env, func() {
|
||||
got := Update()
|
||||
for k, v := range tt.env {
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
got := Update()
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
43
options.go
Normal file
43
options.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package golden
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// Option is a function that modifies a Golden instance.
|
||||
type Option func(*Golden)
|
||||
|
||||
// WithDirMode sets the directory mode for a Golden instance.
|
||||
func WithDirMode(mode os.FileMode) Option {
|
||||
return func(g *Golden) {
|
||||
g.DirMode = mode
|
||||
}
|
||||
}
|
||||
|
||||
// WithFileMode sets the file mode for a Golden instance.
|
||||
func WithFileMode(mode os.FileMode) Option {
|
||||
return func(g *Golden) {
|
||||
g.FileMode = mode
|
||||
}
|
||||
}
|
||||
|
||||
// WithSuffix sets the file suffix for a Golden instance.
|
||||
func WithSuffix(suffix string) Option {
|
||||
return func(g *Golden) {
|
||||
g.Suffix = suffix
|
||||
}
|
||||
}
|
||||
|
||||
// WithDirname sets the directory name for a Golden instance.
|
||||
func WithDirname(dirname string) Option {
|
||||
return func(g *Golden) {
|
||||
g.Dirname = dirname
|
||||
}
|
||||
}
|
||||
|
||||
// WithUpdateFunc sets the update function for a Golden instance.
|
||||
func WithUpdateFunc(updateFunc UpdateFunc) Option {
|
||||
return func(g *Golden) {
|
||||
g.UpdateFunc = updateFunc
|
||||
}
|
||||
}
|
||||
58
options_test.go
Normal file
58
options_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package golden
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWithDirMode(t *testing.T) {
|
||||
customMode := os.FileMode(0o700)
|
||||
g := &Golden{}
|
||||
|
||||
opt := WithDirMode(customMode)
|
||||
opt(g)
|
||||
|
||||
assert.Equal(t, customMode, g.DirMode)
|
||||
}
|
||||
|
||||
func TestWithFileMode(t *testing.T) {
|
||||
customMode := os.FileMode(0o600)
|
||||
g := &Golden{}
|
||||
|
||||
opt := WithFileMode(customMode)
|
||||
opt(g)
|
||||
|
||||
assert.Equal(t, customMode, g.FileMode)
|
||||
}
|
||||
|
||||
func TestWithSuffix(t *testing.T) {
|
||||
customSuffix := ".custom"
|
||||
g := &Golden{}
|
||||
|
||||
opt := WithSuffix(customSuffix)
|
||||
opt(g)
|
||||
|
||||
assert.Equal(t, customSuffix, g.Suffix)
|
||||
}
|
||||
|
||||
func TestWithDirname(t *testing.T) {
|
||||
customDirname := "custom-testdata"
|
||||
g := &Golden{}
|
||||
|
||||
opt := WithDirname(customDirname)
|
||||
opt(g)
|
||||
|
||||
assert.Equal(t, customDirname, g.Dirname)
|
||||
}
|
||||
|
||||
func TestWithUpdateFunc(t *testing.T) {
|
||||
customUpdateFunc := func() bool { return true }
|
||||
g := &Golden{}
|
||||
|
||||
opt := WithUpdateFunc(customUpdateFunc)
|
||||
opt(g)
|
||||
|
||||
assertSameFunc(t, customUpdateFunc, g.UpdateFunc)
|
||||
}
|
||||
9
testing_t.go
Normal file
9
testing_t.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package golden
|
||||
|
||||
type TestingT interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Helper()
|
||||
Logf(format string, args ...interface{})
|
||||
Name() string
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package golden
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var truthyStrings = []string{"1", "y", "t", "yes", "on", "true"}
|
||||
|
||||
@@ -14,7 +17,7 @@ type UpdateFunc func() bool
|
||||
func EnvUpdateFunc() bool {
|
||||
env := os.Getenv("GOLDEN_UPDATE")
|
||||
for _, v := range truthyStrings {
|
||||
if env == v {
|
||||
if strings.EqualFold(env, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package golden
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jimeh/envctl"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -91,16 +90,44 @@ var envUpdateFuncTestCases = []struct {
|
||||
env: map[string]string{"GOLDEN_UPDATE": "foobarnopebbq"},
|
||||
want: false,
|
||||
},
|
||||
// Case-insensitive test cases
|
||||
{
|
||||
name: "GOLDEN_UPDATE set to Y (uppercase)",
|
||||
env: map[string]string{"GOLDEN_UPDATE": "Y"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "GOLDEN_UPDATE set to TRUE (uppercase)",
|
||||
env: map[string]string{"GOLDEN_UPDATE": "TRUE"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "GOLDEN_UPDATE set to Yes (mixed case)",
|
||||
env: map[string]string{"GOLDEN_UPDATE": "Yes"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "GOLDEN_UPDATE set to ON (uppercase)",
|
||||
env: map[string]string{"GOLDEN_UPDATE": "ON"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "GOLDEN_UPDATE set to TrUe (mixed case)",
|
||||
env: map[string]string{"GOLDEN_UPDATE": "TrUe"},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
func TestEnvUpdateFunc(t *testing.T) {
|
||||
for _, tt := range envUpdateFuncTestCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
envctl.WithClean(tt.env, func() {
|
||||
got := EnvUpdateFunc()
|
||||
for k, v := range tt.env {
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
got := EnvUpdateFunc()
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user