diff --git a/vendor/gotest.tools/assert/assert.go b/vendor/gotest.tools/assert/assert.go
new file mode 100644
index 0000000..05d6635
--- /dev/null
+++ b/vendor/gotest.tools/assert/assert.go
@@ -0,0 +1,311 @@
+/*Package assert provides assertions for comparing expected values to actual
+values. When an assertion fails a helpful error message is printed.
+
+Assert and Check
+
+Assert() and Check() both accept a Comparison, and fail the test when the
+comparison fails. The one difference is that Assert() will end the test execution
+immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()),
+return the value of the comparison, then proceed with the rest of the test case.
+
+Example usage
+
+The example below shows assert used with some common types.
+
+
+	import (
+	    "testing"
+
+	    "gotest.tools/assert"
+	    is "gotest.tools/assert/cmp"
+	)
+
+	func TestEverything(t *testing.T) {
+	    // booleans
+	    assert.Assert(t, ok)
+	    assert.Assert(t, !missing)
+
+	    // primitives
+	    assert.Equal(t, count, 1)
+	    assert.Equal(t, msg, "the message")
+	    assert.Assert(t, total != 10) // NotEqual
+
+	    // errors
+	    assert.NilError(t, closer.Close())
+	    assert.Error(t, err, "the exact error message")
+	    assert.ErrorContains(t, err, "includes this")
+	    assert.ErrorType(t, err, os.IsNotExist)
+
+	    // complex types
+	    assert.DeepEqual(t, result, myStruct{Name: "title"})
+	    assert.Assert(t, is.Len(items, 3))
+	    assert.Assert(t, len(sequence) != 0) // NotEmpty
+	    assert.Assert(t, is.Contains(mapping, "key"))
+
+	    // pointers and interface
+	    assert.Assert(t, is.Nil(ref))
+	    assert.Assert(t, ref != nil) // NotNil
+	}
+
+Comparisons
+
+Package https://godoc.org/gotest.tools/assert/cmp provides
+many common comparisons. Additional comparisons can be written to compare
+values in other ways. See the example Assert (CustomComparison).
+
+Automated migration from testify
+
+gty-migrate-from-testify is a binary which can update source code which uses
+testify assertions to use the assertions provided by this package.
+
+See http://bit.do/cmd-gty-migrate-from-testify.
+
+
+*/
+package assert // import "gotest.tools/assert"
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	gocmp "github.com/google/go-cmp/cmp"
+	"gotest.tools/assert/cmp"
+	"gotest.tools/internal/format"
+	"gotest.tools/internal/source"
+)
+
+// BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage.
+type BoolOrComparison interface{}
+
+// TestingT is the subset of testing.T used by the assert package.
+type TestingT interface {
+	FailNow()
+	Fail()
+	Log(args ...interface{})
+}
+
+type helperT interface {
+	Helper()
+}
+
+const failureMessage = "assertion failed: "
+
+// nolint: gocyclo
+func assert(
+	t TestingT,
+	failer func(),
+	argSelector argSelector,
+	comparison BoolOrComparison,
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	var success bool
+	switch check := comparison.(type) {
+	case bool:
+		if check {
+			return true
+		}
+		logFailureFromBool(t, msgAndArgs...)
+
+	// Undocumented legacy comparison without Result type
+	case func() (success bool, message string):
+		success = runCompareFunc(t, check, msgAndArgs...)
+
+	case nil:
+		return true
+
+	case error:
+		msg := "error is not nil: "
+		t.Log(format.WithCustomMessage(failureMessage+msg+check.Error(), msgAndArgs...))
+
+	case cmp.Comparison:
+		success = runComparison(t, argSelector, check, msgAndArgs...)
+
+	case func() cmp.Result:
+		success = runComparison(t, argSelector, check, msgAndArgs...)
+
+	default:
+		t.Log(fmt.Sprintf("invalid Comparison: %v (%T)", check, check))
+	}
+
+	if success {
+		return true
+	}
+	failer()
+	return false
+}
+
+func runCompareFunc(
+	t TestingT,
+	f func() (success bool, message string),
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	if success, message := f(); !success {
+		t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...))
+		return false
+	}
+	return true
+}
+
+func logFailureFromBool(t TestingT, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	const stackIndex = 3 // Assert()/Check(), assert(), formatFailureFromBool()
+	const comparisonArgPos = 1
+	args, err := source.CallExprArgs(stackIndex)
+	if err != nil {
+		t.Log(err.Error())
+		return
+	}
+
+	msg, err := boolFailureMessage(args[comparisonArgPos])
+	if err != nil {
+		t.Log(err.Error())
+		msg = "expression is false"
+	}
+
+	t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...))
+}
+
+func boolFailureMessage(expr ast.Expr) (string, error) {
+	if binaryExpr, ok := expr.(*ast.BinaryExpr); ok && binaryExpr.Op == token.NEQ {
+		x, err := source.FormatNode(binaryExpr.X)
+		if err != nil {
+			return "", err
+		}
+		y, err := source.FormatNode(binaryExpr.Y)
+		if err != nil {
+			return "", err
+		}
+		return x + " is " + y, nil
+	}
+
+	if unaryExpr, ok := expr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.NOT {
+		x, err := source.FormatNode(unaryExpr.X)
+		if err != nil {
+			return "", err
+		}
+		return x + " is true", nil
+	}
+
+	formatted, err := source.FormatNode(expr)
+	if err != nil {
+		return "", err
+	}
+	return "expression is false: " + formatted, nil
+}
+
+// Assert performs a comparison. If the comparison fails the test is marked as
+// failed, a failure message is logged, and execution is stopped immediately.
+//
+// The comparison argument may be one of three types: bool, cmp.Comparison or
+// error.
+// When called with a bool the failure message will contain the literal source
+// code of the expression.
+// When called with a cmp.Comparison the comparison is responsible for producing
+// a helpful failure message.
+// When called with an error a nil value is considered success. A non-nil error
+// is a failure, and Error() is used as the failure message.
+func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsFromComparisonCall, comparison, msgAndArgs...)
+}
+
+// Check performs a comparison. If the comparison fails the test is marked as
+// failed, a failure message is logged, and Check returns false. Otherwise returns
+// true.
+//
+// See Assert for details about the comparison arg and failure messages.
+func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	return assert(t, t.Fail, argsFromComparisonCall, comparison, msgAndArgs...)
+}
+
+// NilError fails the test immediately if err is not nil.
+// This is equivalent to Assert(t, err)
+func NilError(t TestingT, err error, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, err, msgAndArgs...)
+}
+
+// Equal uses the == operator to assert two values are equal and fails the test
+// if they are not equal.
+//
+// If the comparison fails Equal will use the variable names for x and y as part
+// of the failure message to identify the actual and expected values.
+//
+// If either x or y are a multi-line string the failure message will include a
+// unified diff of the two values. If the values only differ by whitespace
+// the unified diff will be augmented by replacing whitespace characters with
+// visible characters to identify the whitespace difference.
+//
+// This is equivalent to Assert(t, cmp.Equal(x, y)).
+func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.Equal(x, y), msgAndArgs...)
+}
+
+// DeepEqual uses google/go-cmp (http://bit.do/go-cmp) to assert two values are
+// equal and fails the test if they are not equal.
+//
+// Package https://godoc.org/gotest.tools/assert/opt provides some additional
+// commonly used Options.
+//
+// This is equivalent to Assert(t, cmp.DeepEqual(x, y)).
+func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.DeepEqual(x, y, opts...))
+}
+
+// Error fails the test if err is nil, or the error message is not the expected
+// message.
+// Equivalent to Assert(t, cmp.Error(err, message)).
+func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.Error(err, message), msgAndArgs...)
+}
+
+// ErrorContains fails the test if err is nil, or the error message does not
+// contain the expected substring.
+// Equivalent to Assert(t, cmp.ErrorContains(err, substring)).
+func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...)
+}
+
+// ErrorType fails the test if err is nil, or err is not the expected type.
+//
+// Expected can be one of:
+// a func(error) bool which returns true if the error is the expected type,
+// an instance of (or a pointer to) a struct of the expected type,
+// a pointer to an interface the error is expected to implement,
+// a reflect.Type of the expected struct or interface.
+//
+// Equivalent to Assert(t, cmp.ErrorType(err, expected)).
+func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.ErrorType(err, expected), msgAndArgs...)
+}
diff --git a/vendor/gotest.tools/assert/cmp/compare.go b/vendor/gotest.tools/assert/cmp/compare.go
new file mode 100644
index 0000000..cf48d88
--- /dev/null
+++ b/vendor/gotest.tools/assert/cmp/compare.go
@@ -0,0 +1,356 @@
+/*Package cmp provides Comparisons for Assert and Check*/
+package cmp // import "gotest.tools/assert/cmp"
+
+import (
+	"fmt"
+	"reflect"
+	"regexp"
+	"strings"
+
+	"github.com/google/go-cmp/cmp"
+	"gotest.tools/internal/format"
+)
+
+// Comparison is a function which compares values and returns ResultSuccess if
+// the actual value matches the expected value. If the values do not match the
+// Result will contain a message about why it failed.
+type Comparison func() Result
+
+// DeepEqual compares two values using google/go-cmp (http://bit.do/go-cmp)
+// and succeeds if the values are equal.
+//
+// The comparison can be customized using comparison Options.
+// Package https://godoc.org/gotest.tools/assert/opt provides some additional
+// commonly used Options.
+func DeepEqual(x, y interface{}, opts ...cmp.Option) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if panicmsg, handled := handleCmpPanic(recover()); handled {
+				result = ResultFailure(panicmsg)
+			}
+		}()
+		diff := cmp.Diff(x, y, opts...)
+		if diff == "" {
+			return ResultSuccess
+		}
+		return multiLineDiffResult(diff)
+	}
+}
+
+func handleCmpPanic(r interface{}) (string, bool) {
+	if r == nil {
+		return "", false
+	}
+	panicmsg, ok := r.(string)
+	if !ok {
+		panic(r)
+	}
+	switch {
+	case strings.HasPrefix(panicmsg, "cannot handle unexported field"):
+		return panicmsg, true
+	}
+	panic(r)
+}
+
+func toResult(success bool, msg string) Result {
+	if success {
+		return ResultSuccess
+	}
+	return ResultFailure(msg)
+}
+
+// RegexOrPattern may be either a *regexp.Regexp or a string that is a valid
+// regexp pattern.
+type RegexOrPattern interface{}
+
+// Regexp succeeds if value v matches regular expression re.
+//
+// Example:
+//   assert.Assert(t, cmp.Regexp("^[0-9a-f]{32}$", str))
+//   r := regexp.MustCompile("^[0-9a-f]{32}$")
+//   assert.Assert(t, cmp.Regexp(r, str))
+func Regexp(re RegexOrPattern, v string) Comparison {
+	match := func(re *regexp.Regexp) Result {
+		return toResult(
+			re.MatchString(v),
+			fmt.Sprintf("value %q does not match regexp %q", v, re.String()))
+	}
+
+	return func() Result {
+		switch regex := re.(type) {
+		case *regexp.Regexp:
+			return match(regex)
+		case string:
+			re, err := regexp.Compile(regex)
+			if err != nil {
+				return ResultFailure(err.Error())
+			}
+			return match(re)
+		default:
+			return ResultFailure(fmt.Sprintf("invalid type %T for regex pattern", regex))
+		}
+	}
+}
+
+// Equal succeeds if x == y. See assert.Equal for full documentation.
+func Equal(x, y interface{}) Comparison {
+	return func() Result {
+		switch {
+		case x == y:
+			return ResultSuccess
+		case isMultiLineStringCompare(x, y):
+			diff := format.UnifiedDiff(format.DiffConfig{A: x.(string), B: y.(string)})
+			return multiLineDiffResult(diff)
+		}
+		return ResultFailureTemplate(`
+			{{- .Data.x}} (
+				{{- with callArg 0 }}{{ formatNode . }} {{end -}}
+				{{- printf "%T" .Data.x -}}
+			) != {{ .Data.y}} (
+				{{- with callArg 1 }}{{ formatNode . }} {{end -}}
+				{{- printf "%T" .Data.y -}}
+			)`,
+			map[string]interface{}{"x": x, "y": y})
+	}
+}
+
+func isMultiLineStringCompare(x, y interface{}) bool {
+	strX, ok := x.(string)
+	if !ok {
+		return false
+	}
+	strY, ok := y.(string)
+	if !ok {
+		return false
+	}
+	return strings.Contains(strX, "\n") || strings.Contains(strY, "\n")
+}
+
+func multiLineDiffResult(diff string) Result {
+	return ResultFailureTemplate(`
+--- {{ with callArg 0 }}{{ formatNode . }}{{else}}←{{end}}
++++ {{ with callArg 1 }}{{ formatNode . }}{{else}}→{{end}}
+{{ .Data.diff }}`,
+		map[string]interface{}{"diff": diff})
+}
+
+// Len succeeds if the sequence has the expected length.
+func Len(seq interface{}, expected int) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if e := recover(); e != nil {
+				result = ResultFailure(fmt.Sprintf("type %T does not have a length", seq))
+			}
+		}()
+		value := reflect.ValueOf(seq)
+		length := value.Len()
+		if length == expected {
+			return ResultSuccess
+		}
+		msg := fmt.Sprintf("expected %s (length %d) to have length %d", seq, length, expected)
+		return ResultFailure(msg)
+	}
+}
+
+// Contains succeeds if item is in collection. Collection may be a string, map,
+// slice, or array.
+//
+// If collection is a string, item must also be a string, and is compared using
+// strings.Contains().
+// If collection is a Map, contains will succeed if item is a key in the map.
+// If collection is a slice or array, item is compared to each item in the
+// sequence using reflect.DeepEqual().
+func Contains(collection interface{}, item interface{}) Comparison {
+	return func() Result {
+		colValue := reflect.ValueOf(collection)
+		if !colValue.IsValid() {
+			return ResultFailure(fmt.Sprintf("nil does not contain items"))
+		}
+		msg := fmt.Sprintf("%v does not contain %v", collection, item)
+
+		itemValue := reflect.ValueOf(item)
+		switch colValue.Type().Kind() {
+		case reflect.String:
+			if itemValue.Type().Kind() != reflect.String {
+				return ResultFailure("string may only contain strings")
+			}
+			return toResult(
+				strings.Contains(colValue.String(), itemValue.String()),
+				fmt.Sprintf("string %q does not contain %q", collection, item))
+
+		case reflect.Map:
+			if itemValue.Type() != colValue.Type().Key() {
+				return ResultFailure(fmt.Sprintf(
+					"%v can not contain a %v key", colValue.Type(), itemValue.Type()))
+			}
+			return toResult(colValue.MapIndex(itemValue).IsValid(), msg)
+
+		case reflect.Slice, reflect.Array:
+			for i := 0; i < colValue.Len(); i++ {
+				if reflect.DeepEqual(colValue.Index(i).Interface(), item) {
+					return ResultSuccess
+				}
+			}
+			return ResultFailure(msg)
+		default:
+			return ResultFailure(fmt.Sprintf("type %T does not contain items", collection))
+		}
+	}
+}
+
+// Panics succeeds if f() panics.
+func Panics(f func()) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if err := recover(); err != nil {
+				result = ResultSuccess
+			}
+		}()
+		f()
+		return ResultFailure("did not panic")
+	}
+}
+
+// Error succeeds if err is a non-nil error, and the error message equals the
+// expected message.
+func Error(err error, message string) Comparison {
+	return func() Result {
+		switch {
+		case err == nil:
+			return ResultFailure("expected an error, got nil")
+		case err.Error() != message:
+			return ResultFailure(fmt.Sprintf(
+				"expected error %q, got %s", message, formatErrorMessage(err)))
+		}
+		return ResultSuccess
+	}
+}
+
+// ErrorContains succeeds if err is a non-nil error, and the error message contains
+// the expected substring.
+func ErrorContains(err error, substring string) Comparison {
+	return func() Result {
+		switch {
+		case err == nil:
+			return ResultFailure("expected an error, got nil")
+		case !strings.Contains(err.Error(), substring):
+			return ResultFailure(fmt.Sprintf(
+				"expected error to contain %q, got %s", substring, formatErrorMessage(err)))
+		}
+		return ResultSuccess
+	}
+}
+
+func formatErrorMessage(err error) string {
+	if _, ok := err.(interface {
+		Cause() error
+	}); ok {
+		return fmt.Sprintf("%q\n%+v", err, err)
+	}
+	// This error was not wrapped with github.com/pkg/errors
+	return fmt.Sprintf("%q", err)
+}
+
+// Nil succeeds if obj is a nil interface, pointer, or function.
+//
+// Use NilError() for comparing errors. Use Len(obj, 0) for comparing slices,
+// maps, and channels.
+func Nil(obj interface{}) Comparison {
+	msgFunc := func(value reflect.Value) string {
+		return fmt.Sprintf("%v (type %s) is not nil", reflect.Indirect(value), value.Type())
+	}
+	return isNil(obj, msgFunc)
+}
+
+func isNil(obj interface{}, msgFunc func(reflect.Value) string) Comparison {
+	return func() Result {
+		if obj == nil {
+			return ResultSuccess
+		}
+		value := reflect.ValueOf(obj)
+		kind := value.Type().Kind()
+		if kind >= reflect.Chan && kind <= reflect.Slice {
+			if value.IsNil() {
+				return ResultSuccess
+			}
+			return ResultFailure(msgFunc(value))
+		}
+
+		return ResultFailure(fmt.Sprintf("%v (type %s) can not be nil", value, value.Type()))
+	}
+}
+
+// ErrorType succeeds if err is not nil and is of the expected type.
+//
+// Expected can be one of:
+// a func(error) bool which returns true if the error is the expected type,
+// an instance of (or a pointer to) a struct of the expected type,
+// a pointer to an interface the error is expected to implement,
+// a reflect.Type of the expected struct or interface.
+func ErrorType(err error, expected interface{}) Comparison {
+	return func() Result {
+		switch expectedType := expected.(type) {
+		case func(error) bool:
+			return cmpErrorTypeFunc(err, expectedType)
+		case reflect.Type:
+			if expectedType.Kind() == reflect.Interface {
+				return cmpErrorTypeImplementsType(err, expectedType)
+			}
+			return cmpErrorTypeEqualType(err, expectedType)
+		case nil:
+			return ResultFailure(fmt.Sprintf("invalid type for expected: nil"))
+		}
+
+		expectedType := reflect.TypeOf(expected)
+		switch {
+		case expectedType.Kind() == reflect.Struct, isPtrToStruct(expectedType):
+			return cmpErrorTypeEqualType(err, expectedType)
+		case isPtrToInterface(expectedType):
+			return cmpErrorTypeImplementsType(err, expectedType.Elem())
+		}
+		return ResultFailure(fmt.Sprintf("invalid type for expected: %T", expected))
+	}
+}
+
+func cmpErrorTypeFunc(err error, f func(error) bool) Result {
+	if f(err) {
+		return ResultSuccess
+	}
+	actual := "nil"
+	if err != nil {
+		actual = fmt.Sprintf("%s (%T)", err, err)
+	}
+	return ResultFailureTemplate(`error is {{ .Data.actual }}
+		{{- with callArg 1 }}, not {{ formatNode . }}{{end -}}`,
+		map[string]interface{}{"actual": actual})
+}
+
+func cmpErrorTypeEqualType(err error, expectedType reflect.Type) Result {
+	if err == nil {
+		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType))
+	}
+	errValue := reflect.ValueOf(err)
+	if errValue.Type() == expectedType {
+		return ResultSuccess
+	}
+	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType))
+}
+
+func cmpErrorTypeImplementsType(err error, expectedType reflect.Type) Result {
+	if err == nil {
+		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType))
+	}
+	errValue := reflect.ValueOf(err)
+	if errValue.Type().Implements(expectedType) {
+		return ResultSuccess
+	}
+	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType))
+}
+
+func isPtrToInterface(typ reflect.Type) bool {
+	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Interface
+}
+
+func isPtrToStruct(typ reflect.Type) bool {
+	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct
+}
diff --git a/vendor/gotest.tools/assert/cmp/result.go b/vendor/gotest.tools/assert/cmp/result.go
new file mode 100644
index 0000000..7c3c37d
--- /dev/null
+++ b/vendor/gotest.tools/assert/cmp/result.go
@@ -0,0 +1,94 @@
+package cmp
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"text/template"
+
+	"gotest.tools/internal/source"
+)
+
+// Result of a Comparison.
+type Result interface {
+	Success() bool
+}
+
+type result struct {
+	success bool
+	message string
+}
+
+func (r result) Success() bool {
+	return r.success
+}
+
+func (r result) FailureMessage() string {
+	return r.message
+}
+
+// ResultSuccess is a constant which is returned by a ComparisonWithResult to
+// indicate success.
+var ResultSuccess = result{success: true}
+
+// ResultFailure returns a failed Result with a failure message.
+func ResultFailure(message string) Result {
+	return result{message: message}
+}
+
+// ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure
+// is returned with the error message as the failure message.
+func ResultFromError(err error) Result {
+	if err == nil {
+		return ResultSuccess
+	}
+	return ResultFailure(err.Error())
+}
+
+type templatedResult struct {
+	success  bool
+	template string
+	data     map[string]interface{}
+}
+
+func (r templatedResult) Success() bool {
+	return r.success
+}
+
+func (r templatedResult) FailureMessage(args []ast.Expr) string {
+	msg, err := renderMessage(r, args)
+	if err != nil {
+		return fmt.Sprintf("failed to render failure message: %s", err)
+	}
+	return msg
+}
+
+// ResultFailureTemplate returns a Result with a template string and data which
+// can be used to format a failure message. The template may access data from .Data,
+// the comparison args with the callArg function, and the formatNode function may
+// be used to format the call args.
+func ResultFailureTemplate(template string, data map[string]interface{}) Result {
+	return templatedResult{template: template, data: data}
+}
+
+func renderMessage(result templatedResult, args []ast.Expr) (string, error) {
+	tmpl := template.New("failure").Funcs(template.FuncMap{
+		"formatNode": source.FormatNode,
+		"callArg": func(index int) ast.Expr {
+			if index >= len(args) {
+				return nil
+			}
+			return args[index]
+		},
+	})
+	var err error
+	tmpl, err = tmpl.Parse(result.template)
+	if err != nil {
+		return "", err
+	}
+	buf := new(bytes.Buffer)
+	err = tmpl.Execute(buf, map[string]interface{}{
+		"Data": result.data,
+	})
+	return buf.String(), err
+}
diff --git a/vendor/gotest.tools/assert/result.go b/vendor/gotest.tools/assert/result.go
new file mode 100644
index 0000000..949d939
--- /dev/null
+++ b/vendor/gotest.tools/assert/result.go
@@ -0,0 +1,106 @@
+package assert
+
+import (
+	"fmt"
+	"go/ast"
+
+	"gotest.tools/assert/cmp"
+	"gotest.tools/internal/format"
+	"gotest.tools/internal/source"
+)
+
+func runComparison(
+	t TestingT,
+	argSelector argSelector,
+	f cmp.Comparison,
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	result := f()
+	if result.Success() {
+		return true
+	}
+
+	var message string
+	switch typed := result.(type) {
+	case resultWithComparisonArgs:
+		const stackIndex = 3 // Assert/Check, assert, runComparison
+		args, err := source.CallExprArgs(stackIndex)
+		if err != nil {
+			t.Log(err.Error())
+		}
+		message = typed.FailureMessage(filterPrintableExpr(argSelector(args)))
+	case resultBasic:
+		message = typed.FailureMessage()
+	default:
+		message = fmt.Sprintf("comparison returned invalid Result type: %T", result)
+	}
+
+	t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...))
+	return false
+}
+
+type resultWithComparisonArgs interface {
+	FailureMessage(args []ast.Expr) string
+}
+
+type resultBasic interface {
+	FailureMessage() string
+}
+
+// filterPrintableExpr filters the ast.Expr slice to only include Expr that are
+// easy to read when printed and contain relevant information to an assertion.
+//
+// Ident and SelectorExpr are included because they print nicely and the variable
+// names may provide additional context to their values.
+// BasicLit and CompositeLit are excluded because their source is equivalent to
+// their value, which is already available.
+// Other types are ignored for now, but could be added if they are relevant.
+func filterPrintableExpr(args []ast.Expr) []ast.Expr {
+	result := make([]ast.Expr, len(args))
+	for i, arg := range args {
+		if isShortPrintableExpr(arg) {
+			result[i] = arg
+			continue
+		}
+
+		if starExpr, ok := arg.(*ast.StarExpr); ok {
+			result[i] = starExpr.X
+			continue
+		}
+	}
+	return result
+}
+
+func isShortPrintableExpr(expr ast.Expr) bool {
+	switch expr.(type) {
+	case *ast.Ident, *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr:
+		return true
+	case *ast.BinaryExpr, *ast.UnaryExpr:
+		return true
+	default:
+		// CallExpr, ParenExpr, TypeAssertExpr, KeyValueExpr, StarExpr
+		return false
+	}
+}
+
+type argSelector func([]ast.Expr) []ast.Expr
+
+func argsAfterT(args []ast.Expr) []ast.Expr {
+	if len(args) < 1 {
+		return nil
+	}
+	return args[1:]
+}
+
+func argsFromComparisonCall(args []ast.Expr) []ast.Expr {
+	if len(args) < 1 {
+		return nil
+	}
+	if callExpr, ok := args[1].(*ast.CallExpr); ok {
+		return callExpr.Args
+	}
+	return nil
+}
