Skip to content

Commit

Permalink
assert: make YAML dependency pluggable via build tags
Browse files Browse the repository at this point in the history
Make the YAML dependency required for {assert,require}.YAMLEq{,f} pluggable.

The implementation can be selected using build tags:
- testify_yaml_default (default): gopkg.in/yaml.v3 is used, like before
- testify_yaml_fail: YAML deserialization is not implemented and always
  fails. So assert.YAMLEq always fails. This is useful if the test suite
  package doesn't use assert.YAMLEq (very common case).
- testify_yaml_custom: the github.com/stretchr/testify/assert/yaml
  package exposes an Unmarshal variable of type func([]byte, any) error
  (same as gopkg.in/yaml.v3) that allows to plug any alternate
  implementation. For example github.com/goccy/go-yaml.Unmarshal.
  This allows to avoid the link constraints of the license of
  gopkg.in/yaml.v3 (see PR #1120).

Usage: go test -tags testify_yaml_fail

To install the alternate implementation with testify_yaml_custom:

	//go:build testify_yaml_custom

	package my_pkg_test

	import (
		goyaml "github.com/goccy/go-yaml"
		"github.com/stretchr/testify/assert/yaml"
	)

	func init() {
		yaml.Unmarshal = goyaml.Unmarshal
	}
  • Loading branch information
dolmen committed Mar 31, 2024
1 parent be3fbeb commit d3dbb19
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
4 changes: 3 additions & 1 deletion assert/assertions.go
Expand Up @@ -19,7 +19,9 @@ import (

"github.com/davecgh/go-spew/spew"
"github.com/pmezard/go-difflib/difflib"
"gopkg.in/yaml.v3"

// Wrapper around gopkg.in/yaml.v3
"github.com/stretchr/testify/assert/yaml"
)

//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl"
Expand Down
25 changes: 25 additions & 0 deletions assert/yaml/yaml_custom.go
@@ -0,0 +1,25 @@
//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default
// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default

// Package yaml is an implementation of YAML functions that calls a pluggable implementation.
//
// This implementation is selected with the testify_yaml_custom build tag.
//
// go test -tags testify_yaml_custom
//
// This implementation can be used at build time to replace the default implementation
// to avoid linking with [gopkg.in/yaml.v3].
//
// In your test package:
//
// import assertYaml "github.com/stretchr/testify/assert/yaml"
//
// func init() {
// assertYaml.Unmarshall = func (in []byte, out interface{}) error {
// // ...
// return nil
// }
// }
package yaml

var Unmarshal func(in []byte, out interface{}) error
37 changes: 37 additions & 0 deletions assert/yaml/yaml_default.go
@@ -0,0 +1,37 @@
//go:build !testify_yaml_fail && !testify_yaml_custom
// +build !testify_yaml_fail,!testify_yaml_custom

// Package yaml is just an indirection to handle YAML deserialization.
//
// This package is just an indirection that allows the builder to override the
// indirection with an alternative implementation of this package that uses
// another implemantation of YAML deserialization. This allows to not either not
// use YAML deserialization at all, or to use another implementation than
// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).
//
// Alternative implementations are selected using build tags:
//
// - testify_yaml_fail: [Unmarshal] always fails with an error
// - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it
// before calling any of [github.com/stretchr/testify/assert.YAMLEq] or
// [github.com/stretchr/testify/assert.YAMLEqf].
//
// Usage:
//
// go test -tags testify_yaml_fail
//
// You can check with "go list" which implementation is linked:
//
// go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
// go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
// go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
//
// [PR #1120]: https://github.com/stretchr/testify/pull/1120
package yaml

import goyaml "gopkg.in/yaml.v3"

// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal].
func Unmarshal(in []byte, out interface{}) error {
return goyaml.Unmarshal(in, out)
}
18 changes: 18 additions & 0 deletions assert/yaml/yaml_fail.go
@@ -0,0 +1,18 @@
//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default
// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default

// Package yaml is an implementation of YAML functions that always fail.
//
// This implementation can be used at build time to replace the default implementation
// to avoid linking with [gopkg.in/yaml.v3]:
//
// go test -tags testify_yaml_fail
package yaml

import "errors"

var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)")

func Unmarshal([]byte, interface{}) error {
return errNotImplemented
}

0 comments on commit d3dbb19

Please sign in to comment.