Files
go-golden/asserter.go
Jim Myhrberg 4e07a1a657 wip(assertion): incomplete refactor of tests and assertion helpers
Tests have started using github.com/jimeh/go-mocktesting which allows
testing unhappy paths where t.Fatal() and related functions are called.
2021-12-28 02:24:00 +00:00

179 lines
4.9 KiB
Go

package golden
import (
"github.com/jimeh/go-golden/marshal"
"github.com/jimeh/go-golden/unmarshal"
)
// Asserter exposes a series of JSON, YAML, and XML marshaling assertion
// helpers.
type Asserter interface {
// JSONMarshaling asserts that the given "v" value JSON marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "v" when
// unmarshaled.
//
// Used for objects that do NOT change when they are marshaled and
// unmarshaled.
JSONMarshaling(t TestingT, v interface{})
// JSONMarshalingP asserts that the given "v" value JSON marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "want" when
// unmarshaled.
//
// Used for objects that change when they are marshaled and unmarshaled.
JSONMarshalingP(t TestingT, v interface{}, want interface{})
// XMLMarshaling asserts that the given "v" value XML marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "v" when
// unmarshaled.
//
// Used for objects that do NOT change when they are marshaled and
// unmarshaled.
XMLMarshaling(t TestingT, v interface{})
// XMLMarshalingP asserts that the given "v" value XML marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "want" when
// unmarshaled.
//
// Used for objects that change when they are marshaled and unmarshaled.
XMLMarshalingP(t TestingT, v interface{}, want interface{})
// YAMLMarshaling asserts that the given "v" value YAML marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "v" when
// unmarshaled.
//
// Used for objects that do NOT change when they are marshaled and
// unmarshaled.
YAMLMarshaling(t TestingT, v interface{})
// YAMLMarshalingP asserts that the given "v" value YAML marshals to an
// expected value fetched from a golden file on disk, and then verifies that
// the marshaled result produces a value that is equal to "want" when
// unmarshaled.
//
// Used for objects that change when they are marshaled and unmarshaled.
YAMLMarshalingP(t TestingT, v interface{}, want interface{})
}
// NewAsserter returns a new Asserter which exposes a number of marshaling
// assertion helpers for JSON, YAML and XML.
//
// The default encoders all specify indentation of two spaces, essentially
// enforcing pretty formatting for JSON and XML.
//
// The default decoders for JSON and YAML prohibit unknown fields which are not
// present on the provided struct.
func NewAsserter(options ...AsserterOption) Asserter {
o := &asserterOptions{
golden: defaultGolden,
normalizeLineBreaks: true,
}
for _, opt := range options {
opt.apply(o)
}
return &asserter{
json: NewMarshalingAsserter(
o.golden, "JSON",
marshal.JSON, unmarshal.JSON,
o.normalizeLineBreaks,
),
xml: NewMarshalingAsserter(
o.golden, "XML",
marshal.XML, unmarshal.XML,
o.normalizeLineBreaks,
),
yaml: NewMarshalingAsserter(
o.golden, "YAML",
marshal.YAML, unmarshal.YAML,
o.normalizeLineBreaks,
),
}
}
type asserterOptions struct {
golden Golden
normalizeLineBreaks bool
}
type AsserterOption interface {
apply(*asserterOptions)
}
type asserterOptionFunc func(*asserterOptions)
func (fn asserterOptionFunc) apply(c *asserterOptions) {
fn(c)
}
// WithGolden allows setting a custom *Golden instance when calling NewAssert().
func WithGolden(golden Golden) AsserterOption {
return asserterOptionFunc(func(a *asserterOptions) {
if golden != nil {
a.golden = golden
}
})
}
// WithNormalizedLineBreaks allows turning off line-break normalization which
// replaces Windows' CRLF (\r\n) and Mac Classic CR (\r) line breaks with Unix's
// LF (\n) line breaks.
func WithNormalizedLineBreaks(value bool) AsserterOption {
return asserterOptionFunc(func(a *asserterOptions) {
a.normalizeLineBreaks = value
})
}
// asserter implements the Assert interface.
type asserter struct {
json *MarshalingAsserter
xml *MarshalingAsserter
yaml *MarshalingAsserter
}
func (s *asserter) JSONMarshaling(t TestingT, v interface{}) {
t.Helper()
s.json.Marshaling(t, v)
}
func (s *asserter) JSONMarshalingP(
t TestingT,
v interface{},
want interface{},
) {
t.Helper()
s.json.MarshalingP(t, v, want)
}
func (s *asserter) XMLMarshaling(t TestingT, v interface{}) {
t.Helper()
s.xml.Marshaling(t, v)
}
func (s *asserter) XMLMarshalingP(t TestingT, v, want interface{}) {
t.Helper()
s.xml.MarshalingP(t, v, want)
}
func (s *asserter) YAMLMarshaling(t TestingT, v interface{}) {
t.Helper()
s.yaml.Marshaling(t, v)
}
func (s *asserter) YAMLMarshalingP(t TestingT, v, want interface{}) {
t.Helper()
s.yaml.MarshalingP(t, v, want)
}