pax_global_header 0000666 0000000 0000000 00000000064 14143452617 0014521 g ustar 00root root 0000000 0000000 52 comment=28a118f1b860ab67c75c1afe0bab9b1cdb66a0ae
cupaloy-2.7.0/ 0000775 0000000 0000000 00000000000 14143452617 0013203 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/.github/ 0000775 0000000 0000000 00000000000 14143452617 0014543 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/.github/dependabot.yml 0000664 0000000 0000000 00000000177 14143452617 0017400 0 ustar 00root root 0000000 0000000 version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
cupaloy-2.7.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14143452617 0016600 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/.github/workflows/go.yml 0000664 0000000 0000000 00000002020 14143452617 0017722 0 ustar 00root root 0000000 0000000 name: Go
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
- name: Build
run: go build -v .
- name: Test
run: go test -v ./...
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.29
cupaloy-2.7.0/.gitignore 0000664 0000000 0000000 00000000434 14143452617 0015174 0 ustar 00root root 0000000 0000000 # Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
vendor/
cupaloy-2.7.0/.travis.yml 0000664 0000000 0000000 00000000541 14143452617 0015314 0 ustar 00root root 0000000 0000000 language: go
go:
- 1.x
- master
matrix:
allow_failures:
- go: master
install:
- make install
script:
- make test-ci
after_success:
- $GOPATH/bin/goveralls -service=travis-ci -coverprofile=coverage.out
notifications:
email:
on_success: never
on_failure: always
env:
global:
- MAKEFLAGS=" -j 2"
- GO111MODULE=on
cupaloy-2.7.0/LICENSE 0000664 0000000 0000000 00000002055 14143452617 0014212 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2017 bradleyjkemp
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
cupaloy-2.7.0/Makefile 0000664 0000000 0000000 00000001065 14143452617 0014645 0 ustar 00root root 0000000 0000000 .PHONY: install
install: get_dependencies install_linters
.PHONY: get_dependencies
get_dependencies:
go get github.com/mattn/goveralls
.PHONY: install_linters
install_linters:
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.12.5
.PHONY: lint
lint:
$(GOPATH)/bin/golangci-lint run
.PHONY: test
test: lint
go test ./...
.PHONY: test-ci
test-ci: coverage lint
.PHONY: coverage
coverage:
go test -v -coverpkg ./... -coverprofile coverage.out ./...
.PHONY: clean
clean:
rm -rf examples/ignored*
cupaloy-2.7.0/README.md 0000664 0000000 0000000 00000010576 14143452617 0014473 0 ustar 00root root 0000000 0000000
Incredibly simple Go snapshot testing: `cupaloy` takes a snapshot of your test output and compares it to a snapshot committed alongside your tests. If the values don't match then the test will be failed.
There's no need to manually manage snapshot files: just use the `cupaloy.SnapshotT(t, value)` function in your tests and `cupaloy` will automatically find the relevant snapshot file (based on the test name) and compare it with the given value.
## Usage
### Write a test
Firstly, write a test case generating some output and pass this output to `cupaloy.SnapshotT`:
```golang
func TestParsing(t *testing.T) {
ast := ParseFile("test_input")
// check that the result is the same as the last time the snapshot was updated
// if the result has changed (e.g. because the behaviour of the parser has changed)
// then the test will be failed with an error containing a diff of the changes
cupaloy.SnapshotT(t, ast)
}
```
The first time this test is run, a snapshot will be automatically created (using the [github.com/davecgh/go-spew](https://github.com/davecgh/go-spew) package).
### Update a snapshot
When the behaviour of your software changes causing the snapshot to change, this test will begin to fail with an error showing the difference between the old and new snapshots. Once you are happy that the new snapshot is correct (and hasn't just changed unexpectedly), you can save the new snapshot by setting the ```UPDATE_SNAPSHOTS``` environment and re-running your tests:
```bash
UPDATE_SNAPSHOTS=true go test ./...
```
This will fail all tests where the snapshot was updated (to stop you accidentally updating snapshots in CI) but your snapshot files will now have been updated to reflect the current output of your code.
### Supported formats
Snapshots of test output are generated using the [github.com/davecgh/go-spew](https://github.com/davecgh/go-spew) package which uses reflection to deep pretty-print your test result and so will support almost all the basic types (from simple strings, slices, and maps to deeply nested structs) without issue. The only types whose contents cannot be fully pretty-printed are functions and channels.
The most important property of your test output is that it is deterministic: if your output contains timestamps or other fields which will change on every run, then `cupaloy` will detect this as a change and so fail the test.
### Further Examples
#### Table driven tests
```golang
var testCases = map[string][]string{
"TestCaseOne": []string{......},
"AnotherTestCase": []string{......},
....
}
func TestCases(t *testing.T) {
for testName, args := range testCases {
t.Run(testName, func(t *testing.T) {
result := functionUnderTest(args...)
cupaloy.SnapshotT(t, result)
})
}
}
```
#### Changing output directory
```golang
func TestSubdirectory(t *testing.T) {
result := someFunction()
snapshotter := cupaloy.New(cupaloy.SnapshotSubdirectory("testdata"))
err := snapshotter.Snapshot(result)
if err != nil {
t.Fatalf("error: %s", err)
}
}
```
For further usage examples see basic_test.go and advanced_test.go in the examples/ directory which are both kept up to date and run on CI.
## Debugging
### Windows
It is important to note that git on Windows might be configured in a way that `\n` is replaced by `\r\n` during checkout (it is the case on GitHub actions). In such a case, the snapshot appears to be the same, but the test fails. Please ensure that git is configured correctly everywhere. There are multiple ways to do it, please check https://github.com/actions/checkout/issues/135 and https://github.com/bradleyjkemp/cupaloy/pull/73 for more details.
cupaloy-2.7.0/config.go 0000664 0000000 0000000 00000010555 14143452617 0015005 0 ustar 00root root 0000000 0000000 package cupaloy
// Configurator is a functional option that can be passed to cupaloy.New() to change snapshotting behaviour.
type Configurator func(*Config)
// EnvVariableName can be used to customize the environment variable that determines whether snapshots
// should be updated e.g.
// cupaloy.New(EnvVariableName("UPDATE"))
// Will create an instance where snapshots will be updated if the UPDATE environment variable is set.
// Default: UPDATE_SNAPSHOTS
func EnvVariableName(name string) Configurator {
return func(c *Config) {
c.shouldUpdate = func() bool {
return envVariableSet(name)
}
}
}
// ShouldUpdate can be used to provide custom logic to decide whether or not to update a snapshot
// e.g.
// var update = flag.Bool("update", false, "update snapshots")
// cupaloy.New(ShouldUpdate(func () bool { return *update })
// Will create an instance where snapshots are updated if the --update flag is passed to go test.
// Default: checks for the presence of the UPDATE_SNAPSHOTS environment variable
func ShouldUpdate(f func() bool) Configurator {
return func(c *Config) {
c.shouldUpdate = f
}
}
// SnapshotSubdirectory can be used to customize the location that snapshots are stored in.
// e.g.
// cupaloy.New(SnapshotSubdirectory("testdata"))
// Will create an instance where snapshots are stored in the "testdata" folder
// Default: .snapshots
func SnapshotSubdirectory(name string) Configurator {
return func(c *Config) {
c.subDirName = name
}
}
// FailOnUpdate controls whether tests should be failed when snapshots are updated.
// By default this is true to prevent snapshots being accidentally updated in CI.
// Default: true
func FailOnUpdate(failOnUpdate bool) Configurator {
return func(c *Config) {
c.failOnUpdate = failOnUpdate
}
}
// CreateNewAutomatically controls whether snapshots should be automatically created
// if no matching snapshot already exists.
// Default: true
func CreateNewAutomatically(createNewAutomatically bool) Configurator {
return func(c *Config) {
c.createNewAutomatically = createNewAutomatically
}
}
// FatalOnMismatch controls whether failed tests should fail using t.Fatal which should
// immediately stop any remaining tests. Will use t.Error on false.
// Default: false
func FatalOnMismatch(fatalOnMismatch bool) Configurator {
return func(c *Config) {
c.fatalOnMismatch = fatalOnMismatch
}
}
// SnapshotFileExtension allows you to change the extension of the snapshot files
// that are written. E.g. if you're snapshotting HTML then adding SnapshotFileExtension(".html")
// will allow for more easier viewing of snapshots.
// Default: "", no extension is added.
func SnapshotFileExtension(snapshotFileExtension string) Configurator {
return func(c *Config) {
c.snapshotFileExtension = snapshotFileExtension
}
}
// UseStringerMethods invoke String() or Error() methods when available rather than dumping the object.
// This should probably be disabled by default but is not for backwards compatibility reasons.
// Default: true
func UseStringerMethods(useStringerMethods bool) Configurator {
return func(c *Config) {
c.useStringerMethods = useStringerMethods
}
}
// Config provides the same snapshotting functions with additional configuration capabilities.
type Config struct {
shouldUpdate func() bool
subDirName string
failOnUpdate bool
createNewAutomatically bool
fatalOnMismatch bool
snapshotFileExtension string
useStringerMethods bool
}
// NewDefaultConfig returns a new Config instance initialised with the same options as
// the original Global instance (i.e. before any config changes were made to it)
func NewDefaultConfig() *Config {
return (&Config{}).WithOptions(
SnapshotSubdirectory(".snapshots"),
EnvVariableName("UPDATE_SNAPSHOTS"),
FailOnUpdate(true),
CreateNewAutomatically(true),
FatalOnMismatch(false),
SnapshotFileExtension(""),
UseStringerMethods(true),
)
}
// Global is the Config instance used by `cupaloy.SnapshotT` and other package-level functions.
var Global = NewDefaultConfig()
func (c *Config) clone() *Config {
return &Config{
shouldUpdate: c.shouldUpdate,
subDirName: c.subDirName,
failOnUpdate: c.failOnUpdate,
createNewAutomatically: c.createNewAutomatically,
fatalOnMismatch: c.fatalOnMismatch,
snapshotFileExtension: c.snapshotFileExtension,
useStringerMethods: c.useStringerMethods,
}
}
cupaloy-2.7.0/cupaloy.go 0000664 0000000 0000000 00000011454 14143452617 0015213 0 ustar 00root root 0000000 0000000 package cupaloy
import (
"fmt"
"os"
"strings"
"github.com/bradleyjkemp/cupaloy/v2/internal"
)
// New constructs a new, configured instance of cupaloy using the given
// Configurators applied to the default config.
func New(configurators ...Configurator) *Config {
return NewDefaultConfig().WithOptions(configurators...)
}
// Snapshot calls Snapshotter.Snapshot with the global config.
func Snapshot(i ...interface{}) error {
return Global.snapshot(getNameOfCaller(), i...)
}
// SnapshotMulti calls Snapshotter.SnapshotMulti with the global config.
func SnapshotMulti(snapshotID string, i ...interface{}) error {
snapshotName := fmt.Sprintf("%s-%s", getNameOfCaller(), snapshotID)
return Global.snapshot(snapshotName, i...)
}
// SnapshotT calls Snapshotter.SnapshotT with the global config.
func SnapshotT(t TestingT, i ...interface{}) {
t.Helper()
Global.SnapshotT(t, i...)
}
// SnapshotWithName calls Snapshotter.SnapshotWithName with the global config.
func SnapshotWithName(snapshotName string, i ...interface{}) error {
return Global.SnapshotWithName(snapshotName, i...)
}
// Snapshot compares the given variable to its previous value stored on the filesystem.
// An error containing a diff is returned if the snapshots do not match, or if a new
// snapshot was created.
//
// Snapshot determines the snapshot file automatically from the name of the calling function.
// As a result it can be called at most once per function. If you want to call Snapshot
// multiple times in a function, if possible, instead collect the values and call Snapshot
// with all values at once. Otherwise see SnapshotMulti.
//
// If using snapshots in tests, prefer the SnapshotT function which fails the test
// directly, rather than requiring your to remember to check the error.
func (c *Config) Snapshot(i ...interface{}) error {
return c.snapshot(getNameOfCaller(), i...)
}
// SnapshotMulti is similar to Snapshot but can be called multiple times from the
// same function. This is possible by providing a unique id for each snapshot which is
// appended to the function name to form the snapshot name.
func (c *Config) SnapshotMulti(snapshotID string, i ...interface{}) error {
snapshotName := fmt.Sprintf("%s-%s", getNameOfCaller(), snapshotID)
return c.snapshot(snapshotName, i...)
}
// SnapshotWithName is similar to SnapshotMulti without appending the function name.
// It is useful when you need full control of the snapshot filename.
func (c *Config) SnapshotWithName(snapshotName string, i ...interface{}) error {
return c.snapshot(snapshotName, i...)
}
// SnapshotT compares the given variable to the its previous value stored on the filesystem.
// The current test is failed (with error containing a diff) if the values do not match, or
// if a new snapshot was created.
//
// SnapshotT determines the snapshot file automatically from the name of the test (using
// the t.Name() function). As a result, SnapshotT can be called at most once per test.
// If you want to call SnapshotT multiple times in a test, if possible, instead collect the
// values and call SnapshotT with all values at once. Alternatively, use sub-tests and call
// SnapshotT once in each.
//
// If using snapshots in tests, SnapshotT is preferred over Snapshot and SnapshotMulti.
func (c *Config) SnapshotT(t TestingT, i ...interface{}) {
t.Helper()
if t.Failed() {
return
}
snapshotName := strings.Replace(t.Name(), "/", "-", -1)
err := c.snapshot(snapshotName, i...)
if err != nil {
if c.fatalOnMismatch {
t.Fatal(err)
return
}
t.Error(err)
}
}
// WithOptions returns a copy of an existing Config with additional Configurators applied.
// This can be used to apply a different option for a single call e.g.
// snapshotter.WithOptions(cupaloy.SnapshotSubdirectory("testdata")).SnapshotT(t, result)
// Or to modify the Global Config e.g.
// cupaloy.Global = cupaloy.Global.WithOptions(cupaloy.SnapshotSubdirectory("testdata"))
func (c *Config) WithOptions(configurators ...Configurator) *Config {
clonedConfig := c.clone()
for _, configurator := range configurators {
configurator(clonedConfig)
}
return clonedConfig
}
func (c *Config) snapshot(snapshotName string, i ...interface{}) error {
snapshot := c.takeSnapshot(i...)
prevSnapshot, err := c.readSnapshot(snapshotName)
if os.IsNotExist(err) {
if c.createNewAutomatically {
return c.updateSnapshot(snapshotName, prevSnapshot, snapshot)
}
return internal.ErrNoSnapshot{Name: snapshotName}
}
if err != nil {
return err
}
if snapshot == prevSnapshot || c.takeV1Snapshot(i...) == prevSnapshot {
// previous snapshot matches current value
return nil
}
if c.shouldUpdate() {
// updates snapshot to current value and upgrades snapshot format
return c.updateSnapshot(snapshotName, prevSnapshot, snapshot)
}
return internal.ErrSnapshotMismatch{
Diff: diffSnapshots(prevSnapshot, snapshot),
}
}
cupaloy-2.7.0/doc.go 0000664 0000000 0000000 00000002302 14143452617 0014274 0 ustar 00root root 0000000 0000000 // Package cupaloy provides a simple api for snapshot testing in golang: test that your changes don't unexpectedly alter the results of your code.
//
// cupaloy takes a snapshot of a given value and compares it to a snapshot committed alongside your tests. If the values don't match then you'll be forced to update the snapshot file before the test passes.
//
// Snapshot files are handled automagically: just use the cupaloy.Snapshot(value) function in your tests and cupaloy will automatically find the relevant snapshot file and compare it with the given value.
//
// Installation
// go get -u github.com/bradleyjkemp/cupaloy
//
// Usage
// func TestExample(t *testing.T) {
// result := someFunction()
//
// // check that the result is the same as the last time the snapshot was updated
// // if the result has changed then the test will be failed with an error containing
// // a diff of the changes
// cupaloy.SnapshotT(t, result)
// }
//
// To update the snapshots simply set the UPDATE_SNAPSHOTS environment variable and run your tests e.g.
// UPDATE_SNAPSHOTS=true go test ./...
// Your snapshot files will now have been updated to reflect the current output of your code.
package cupaloy
cupaloy-2.7.0/examples/ 0000775 0000000 0000000 00000000000 14143452617 0015021 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/examples/.gitignore 0000664 0000000 0000000 00000000011 14143452617 0017001 0 ustar 00root root 0000000 0000000 ignored*/ cupaloy-2.7.0/examples/.snapshots/ 0000775 0000000 0000000 00000000000 14143452617 0017121 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/examples/.snapshots/TestFailedSnapshotT 0000664 0000000 0000000 00000000021 14143452617 0022725 0 ustar 00root root 0000000 0000000 This should fail
cupaloy-2.7.0/examples/.snapshots/TestGlobalFailOnUpdate 0000664 0000000 0000000 00000000107 14143452617 0023336 0 ustar 00root root 0000000 0000000 This should fail because updating, but won't because of global setting
cupaloy-2.7.0/examples/.snapshots/TestGlobalFatalOnMismatch 0000664 0000000 0000000 00000000043 14143452617 0024034 0 ustar 00root root 0000000 0000000 This should fail due to a mismatch
cupaloy-2.7.0/examples/.snapshots/TestMultipleSnapshots-hello 0000664 0000000 0000000 00000000031 14143452617 0024475 0 ustar 00root root 0000000 0000000 (string) (len=5) "Hello"
cupaloy-2.7.0/examples/.snapshots/TestMultipleSnapshots-world 0000664 0000000 0000000 00000000031 14143452617 0024521 0 ustar 00root root 0000000 0000000 (string) (len=5) "World"
cupaloy-2.7.0/examples/.snapshots/TestSnapshotFileExtension.myextension 0000664 0000000 0000000 00000000071 14143452617 0026557 0 ustar 00root root 0000000 0000000 This should end up in a file with extension .myextension
cupaloy-2.7.0/examples/.snapshots/TestUseStringerMethods-disabled 0000664 0000000 0000000 00000000035 14143452617 0025245 0 ustar 00root root 0000000 0000000 (examples_test.stringer) {
}
cupaloy-2.7.0/examples/.snapshots/TestUseStringerMethods-enabled 0000664 0000000 0000000 00000000047 14143452617 0025073 0 ustar 00root root 0000000 0000000 (examples_test.stringer) with stringer
cupaloy-2.7.0/examples/.snapshots/chosen-by-user 0000664 0000000 0000000 00000000020 14143452617 0021677 0 ustar 00root root 0000000 0000000 Hello
Universe!
cupaloy-2.7.0/examples/.snapshots/examples-TestMap 0000664 0000000 0000000 00000000207 14143452617 0022234 0 ustar 00root root 0000000 0000000 (map[int]string) (len=3) {
(int) 1: (string) (len=5) "Hello",
(int) 2: (string) (len=5) "World",
(int) 3: (string) (len=1) "!"
}
cupaloy-2.7.0/examples/.snapshots/examples-TestMultipleSnapshots 0000664 0000000 0000000 00000000031 14143452617 0025210 0 ustar 00root root 0000000 0000000 (string) (len=5) "Hello"
cupaloy-2.7.0/examples/.snapshots/examples-TestMultipleSnapshots-result2 0000664 0000000 0000000 00000000031 14143452617 0026606 0 ustar 00root root 0000000 0000000 (string) (len=5) "World"
cupaloy-2.7.0/examples/.snapshots/examples-TestMultipleValues 0000664 0000000 0000000 00000000062 14143452617 0024471 0 ustar 00root root 0000000 0000000 (string) (len=5) "Hello"
(string) (len=5) "World"
cupaloy-2.7.0/examples/.snapshots/examples-TestSecondString 0000664 0000000 0000000 00000000044 14143452617 0024120 0 ustar 00root root 0000000 0000000 (string) (len=15) "Hello Universe!"
cupaloy-2.7.0/examples/.snapshots/examples-TestString 0000664 0000000 0000000 00000000040 14143452617 0022760 0 ustar 00root root 0000000 0000000 (string) (len=11) "Hello world"
cupaloy-2.7.0/examples/.snapshots/examples_test-TestConfig 0000664 0000000 0000000 00000000043 14143452617 0023761 0 ustar 00root root 0000000 0000000 (string) (len=14) "Hello Universe"
cupaloy-2.7.0/examples/.snapshots/examples_test-TestConfig-withExclamation 0000664 0000000 0000000 00000000066 14143452617 0027124 0 ustar 00root root 0000000 0000000 (string) (len=5) "Hello"
(string) (len=9) "Universe!"
cupaloy-2.7.0/examples/.snapshots/examples_test-TestFailOnUpdate 0000664 0000000 0000000 00000000014 14143452617 0025065 0 ustar 00root root 0000000 0000000 Hello world
cupaloy-2.7.0/examples/.snapshots/examples_test-TestRawBytes 0000664 0000000 0000000 00000000123 14143452617 0024313 0 ustar 00root root 0000000 0000000 Hello advanced world!
(*bytes.Buffer)(Hello advanced world!)
Hello advanced world!
cupaloy-2.7.0/examples/.snapshots/examples_test-TestShouldUpdate-func1 0000664 0000000 0000000 00000000031 14143452617 0026164 0 ustar 00root root 0000000 0000000 (string) (len=5) "Hello"
cupaloy-2.7.0/examples/.snapshots/examples_test-TestShouldUpdate-func2 0000664 0000000 0000000 00000000006 14143452617 0026167 0 ustar 00root root 0000000 0000000 Hello
cupaloy-2.7.0/examples/.snapshots/examples_test-TestString 0000664 0000000 0000000 00000000052 14143452617 0024022 0 ustar 00root root 0000000 0000000 (string) (len=21) "Hello advanced world!"
cupaloy-2.7.0/examples/.snapshots/examples_test-TestUpdate 0000664 0000000 0000000 00000000014 14143452617 0023774 0 ustar 00root root 0000000 0000000 Hello world
cupaloy-2.7.0/examples/TestingT_test.go 0000664 0000000 0000000 00000002164 14143452617 0020153 0 ustar 00root root 0000000 0000000 // Code generated by mockery v1.0.0
package examples_test
import mock "github.com/stretchr/testify/mock"
// TestingT is an autogenerated mock type for the TestingT type
type TestingT struct {
mock.Mock
}
// Error provides a mock function with given fields: args
func (_m *TestingT) Error(args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// Fatal provides a mock function with given fields: args
func (_m *TestingT) Fatal(args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// Failed provides a mock function with given fields:
func (_m *TestingT) Failed() bool {
ret := _m.Called()
var r0 bool
if rf, ok := ret.Get(0).(func() bool); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// Helper provides a mock function with given fields:
func (_m *TestingT) Helper() {
_m.Called()
}
// Name provides a mock function with given fields:
func (_m *TestingT) Name() string {
ret := _m.Called()
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
cupaloy-2.7.0/examples/advanced_test.go 0000664 0000000 0000000 00000016001 14143452617 0020152 0 ustar 00root root 0000000 0000000 package examples_test
import (
"bytes"
"io/ioutil"
"strings"
"testing"
"github.com/bradleyjkemp/cupaloy/v2/internal"
"github.com/bradleyjkemp/cupaloy/v2"
"github.com/stretchr/testify/mock"
)
// Snapshots are isolated by package so test functions with the same name are fine
func TestString(t *testing.T) {
result := "Hello advanced world!"
err := cupaloy.Snapshot(result)
if err != nil {
t.Fatal("Tests in different packages are independent of each other", err)
}
}
// New version of snapshot format should write out certain types directly
func TestRawBytes(t *testing.T) {
result := bytes.NewBufferString("Hello advanced world!")
err := cupaloy.Snapshot(result.Bytes(), result, result.String())
if err != nil {
t.Fatal("New version of snapshot format should write out certain types directly", err)
}
}
// A configured instance of cupaloy has the same interface as the static methods
func TestConfig(t *testing.T) {
snapshotter := cupaloy.New(cupaloy.EnvVariableName("UPDATE"))
err := snapshotter.Snapshot("Hello Universe")
if err != nil {
t.Fatalf("You can use a custom config struct to customise the behaviour of cupaloy %s", err)
}
err = snapshotter.SnapshotMulti("withExclamation", "Hello", "Universe!")
if err != nil {
t.Fatalf("The config struct has all the same methods as the default %s", err)
}
snapshotter.WithOptions(cupaloy.SnapshotSubdirectory("testdata")).SnapshotT(t, "Hello world!")
}
// SnapshotMulti allows a user to choose the full snapshot name
func TestSnapshotWithName(t *testing.T) {
err := cupaloy.SnapshotWithName("chosen-by-user", "Hello", "Universe!")
if err != nil {
t.Fatalf("The config struct has all the same methods as the default %s", err)
}
}
// If a snapshot is updated then this returns an error
// This is to prevent you accidentally updating your snapshots in CI
func TestUpdate(t *testing.T) {
snapshotter := cupaloy.New(cupaloy.EnvVariableName("HOME"))
defer snapshotter.Snapshot("Hello world") // reset snapshot to known state
err := snapshotter.Snapshot("Hello world")
if err != nil {
t.Fatalf("Updating a snapshot with the same value does not fail a test %s", err)
}
err = snapshotter.Snapshot("Hello new world")
if err == nil {
t.Fatalf("Updating a snapshot with a new value is always an error %s", err)
}
if _, ok := err.(internal.ErrSnapshotUpdated); !ok {
t.Fatalf("Error returned will be of type ErrSnapshotUpdated")
}
}
// If a snapshot doesn't exist then it is created and an error returned
func TestMissingSnapshot(t *testing.T) {
tempdir, err := ioutil.TempDir(".", "ignored")
if err != nil {
t.Fatal(err)
}
snapshotter := cupaloy.New(
cupaloy.EnvVariableName("ENOEXIST"),
cupaloy.SnapshotSubdirectory(tempdir))
err = snapshotter.Snapshot("Hello world")
if err == nil {
t.Fatalf("This will always return an error %s", err)
}
if _, ok := err.(internal.ErrSnapshotCreated); !ok {
t.Fatalf("Error returned will be of type ErrSnapshotCreated")
}
}
// Multiple snapshots can be taken in a single test
func TestMultipleSnapshots(t *testing.T) {
t.Run("hello", func(t *testing.T) {
result1 := "Hello"
cupaloy.SnapshotT(t, result1)
})
t.Run("world", func(t *testing.T) {
result2 := "World"
cupaloy.New().SnapshotT(t, result2)
})
}
// Test the ShouldUpdate configurator
func TestShouldUpdate(t *testing.T) {
t.Run("false", func(t *testing.T) {
result := "Hello!"
err := cupaloy.New(cupaloy.ShouldUpdate(func() bool { return false })).Snapshot(result)
if err == nil || !strings.Contains(err.Error(), "not equal") {
// not updating snapshot so error should contain a diff
t.Fatal(err)
}
})
t.Run("true", func(t *testing.T) {
result := "Hello!"
c := cupaloy.New(cupaloy.ShouldUpdate(func() bool { return true }))
err := c.Snapshot(result)
if err == nil || !strings.Contains(err.Error(), "updated") {
// snapshot should have been updated with error signalling this
t.Fatal(err)
}
// snapshot again with old value to revert the update
c.Snapshot("Hello")
})
}
func TestFailedSnapshotT(t *testing.T) {
mockT := &TestingT{}
mockT.On("Helper").Return()
mockT.On("Failed").Return(false)
mockT.On("Name").Return(t.Name())
mockT.On("Error", mock.Anything).Return()
cupaloy.SnapshotT(mockT, "This should fail due to a mismatch")
mockT.AssertCalled(t, "Error", mock.Anything)
}
func TestFailedTestNoop(t *testing.T) {
mockT := &TestingT{}
mockT.On("Helper").Return()
mockT.On("Failed").Return(true)
cupaloy.SnapshotT(mockT, "This should not create a snapshot")
mockT.AssertNotCalled(t, "Error")
}
func TestGlobalFailOnUpdate(t *testing.T) {
cupaloy.Global = cupaloy.Global.WithOptions(
cupaloy.FailOnUpdate(false),
cupaloy.ShouldUpdate(func() bool { return true }))
// reset global after test
defer func() { cupaloy.Global = cupaloy.NewDefaultConfig() }()
mockT := &TestingT{}
mockT.On("Helper").Return()
mockT.On("Failed").Return(false)
mockT.On("Name").Return(t.Name())
cupaloy.SnapshotT(mockT, "This should fail because updating, but won't because of global setting")
mockT.AssertNotCalled(t, "Error")
}
func TestGlobalCreateNewAutomatically(t *testing.T) {
cupaloy.Global = cupaloy.Global.WithOptions(cupaloy.CreateNewAutomatically(false))
// reset global after test
defer func() { cupaloy.Global = cupaloy.NewDefaultConfig() }()
mockT := &TestingT{}
mockT.On("Helper").Return()
mockT.On("Failed").Return(false)
mockT.On("Name").Return(t.Name())
mockT.On("Error", mock.Anything).Return()
cupaloy.SnapshotT(mockT, "This should fail because doesn't exist")
mockT.AssertCalled(t, "Error", mock.Anything)
}
func TestFailOnUpdate(t *testing.T) {
snapshotter := cupaloy.New(cupaloy.EnvVariableName("HOME"), cupaloy.FailOnUpdate(false))
err := snapshotter.Snapshot("Hello new world")
if err != nil {
t.Fatal("FailOnUpdate(false) should disable errors when updating snapshots")
}
snapshotter.Snapshot("Hello world") // reset snapshot to known state (ignoring return value)
}
func TestGlobalFatalOnMismatch(t *testing.T) {
cupaloy.Global = cupaloy.Global.WithOptions(cupaloy.FatalOnMismatch(true))
// reset global after test
defer func() { cupaloy.Global = cupaloy.NewDefaultConfig() }()
mockT := &TestingT{}
mockT.On("Helper").Return()
mockT.On("Failed").Return(false)
mockT.On("Name").Return(t.Name())
mockT.On("Error", mock.Anything).Return()
mockT.On("Fatal", mock.Anything).Return()
cupaloy.SnapshotT(mockT, "This should fatal due to a mismatch")
mockT.AssertNotCalled(t, "Error", mock.Anything)
mockT.AssertCalled(t, "Fatal", mock.Anything)
}
func TestSnapshotFileExtension(t *testing.T) {
snapshotter := cupaloy.New(cupaloy.SnapshotFileExtension(".myextension"))
snapshotter.SnapshotT(t, "This should end up in a file with extension .myextension")
}
type stringer struct {
}
func (s stringer) String() string {
return "with stringer"
}
func TestUseStringerMethods(t *testing.T) {
s := stringer{}
t.Run("enabled", func(t *testing.T) {
cupaloy.New(cupaloy.UseStringerMethods(true)).SnapshotT(t, s)
})
t.Run("disabled", func(t *testing.T) {
cupaloy.New(cupaloy.UseStringerMethods(false)).SnapshotT(t, s)
})
}
cupaloy-2.7.0/examples/basic_test.go 0000664 0000000 0000000 00000003143 14143452617 0017471 0 ustar 00root root 0000000 0000000 package examples
import (
"testing"
"github.com/bradleyjkemp/cupaloy/v2"
)
func TestString(t *testing.T) {
result := "Hello world"
err := cupaloy.Snapshot(result)
if err != nil {
t.Errorf("This will pass because \"Hello world\" is in the snapshot %s", err)
}
err = cupaloy.Snapshot("Hello world!")
if err == nil {
t.Errorf("Now it will fail because the snapshot doesn't have an exclamation mark %s", err)
}
}
// Tests are independent of each other
func TestSecondString(t *testing.T) {
result := "Hello Universe!"
err := cupaloy.Snapshot(result)
if err != nil {
t.Errorf("This will pass because Snapshots are per test function %s", err)
}
}
// Multiple snapshots can be taken in a single test
func TestMultipleSnapshots(t *testing.T) {
result1 := "Hello"
err := cupaloy.Snapshot(result1)
if err != nil {
t.Errorf("This will pass as normal %s", err)
}
result2 := "World"
err = cupaloy.SnapshotMulti("result2", result2)
if err != nil {
t.Errorf("This will pass also as we've specified a unique (to this function) id %s", err)
}
}
// Snapshot() takes an arbitrary number of values
func TestMultipleValues(t *testing.T) {
result1 := "Hello"
result2 := "World"
err := cupaloy.Snapshot(result1, result2)
if err != nil {
t.Errorf("You can snapshot multiple values in the same call to Snapshot %s", err)
}
}
// All types can be snapshotted. Maps are snapshotted in a deterministic way
func TestMap(t *testing.T) {
result := map[int]string{
1: "Hello",
3: "!",
2: "World",
}
err := cupaloy.Snapshot(result)
if err != nil {
t.Errorf("Snapshots can be taken of any type %s", err)
}
}
cupaloy-2.7.0/examples/doc.go 0000664 0000000 0000000 00000000021 14143452617 0016106 0 ustar 00root root 0000000 0000000 package examples
cupaloy-2.7.0/examples/testdata/ 0000775 0000000 0000000 00000000000 14143452617 0016632 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/examples/testdata/TestConfig 0000664 0000000 0000000 00000000015 14143452617 0020616 0 ustar 00root root 0000000 0000000 Hello world!
cupaloy-2.7.0/go.mod 0000664 0000000 0000000 00000000321 14143452617 0014305 0 ustar 00root root 0000000 0000000 module github.com/bradleyjkemp/cupaloy/v2
require (
github.com/davecgh/go-spew v1.1.1
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/objx v0.1.1 // indirect
github.com/stretchr/testify v1.6.1
)
cupaloy-2.7.0/go.sum 0000664 0000000 0000000 00000003214 14143452617 0014336 0 ustar 00root root 0000000 0000000 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=
cupaloy-2.7.0/internal/ 0000775 0000000 0000000 00000000000 14143452617 0015017 5 ustar 00root root 0000000 0000000 cupaloy-2.7.0/internal/errors.go 0000664 0000000 0000000 00000001312 14143452617 0016657 0 ustar 00root root 0000000 0000000 package internal
import "fmt"
type ErrSnapshotCreated struct {
Name string
Contents string
}
func (e ErrSnapshotCreated) Error() string {
return fmt.Sprintf("snapshot created for test %s, with contents:\n%s", e.Name, e.Contents)
}
type ErrSnapshotUpdated struct {
Name string
Diff string
}
func (e ErrSnapshotUpdated) Error() string {
return fmt.Sprintf("snapshot %s updated:\n%s", e.Name, e.Diff)
}
type ErrSnapshotMismatch struct {
Diff string
}
func (e ErrSnapshotMismatch) Error() string {
return fmt.Sprintf("snapshot not equal:\n%s", e.Diff)
}
type ErrNoSnapshot struct {
Name string
}
func (e ErrNoSnapshot) Error() string {
return fmt.Sprintf("snapshot %s does not exist", e.Name)
}
cupaloy-2.7.0/mascot.png 0000664 0000000 0000000 00001007117 14143452617 0015206 0 ustar 00root root 0000000 0000000 PNG
IHDR !C bKGD pHYs tIME!3䋶 IDATxyei]>眻/t \$$/&&.K~1BT'(EDDaa6f_z־ܺ98VwUU5sl p-9d=ϖD"5ƔDZS曊M2,kTU"RkVQժUD$]U6x\PS|J(Bxtuk9^p8p8 Hd||DQd86*Z)X[0cLVD2"rGȪjHW"VˊHYUCcȩՒH9<).2':4Fr" WJETnTAk QVU5!V50MUmu?uڰֶz15kQc}cRX ޣpbp8`ppy^.@5#@}`ɀTZJD--Da}9^$*DS6@k"XSݰV"1,l~'jlFAqWGIJp8.T)z?ATEJp(udO芈nWftXD\'?늵2XuZo=00nw0۞"p8'ñ`6u"^$cSIcIFq :.xqtskehjKUq(jkEp8p8sA?~ȧRO[IZ3f( ׄmUTY꼈̃.1@Z