diff --git a/go.mod b/go.mod
index d488823..0a0da72 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
module github.com/mediocregopher/mediocre-go-lib/v2
-go 1.15
+go 1.20
diff --git a/internal/massert/massert.go b/internal/massert/massert.go
new file mode 100644
index 0000000..84bdaa8
--- /dev/null
+++ b/internal/massert/massert.go
@@ -0,0 +1,26 @@
+// massert helper assertion methods for tests.
+package massert
+
+import (
+ "reflect"
+ "testing"
+)
+
+// Equal fatals if reflect.DeepEqual fails.
+func Equal[T any](t testing.TB, want, got T) {
+ t.Helper()
+ if !reflect.DeepEqual(want, got) {
+ t.Fatalf("%#v != %#v", want, got)
+ }
+}
+
+// Equalf is like Equal but extra formatting is appended.
+func Equalf[T any](
+ t testing.TB, want, got T, fmtStr string, fmtArgs ...any,
+) {
+ t.Helper()
+ if !reflect.DeepEqual(want, got) {
+ fmtArgs = append([]any{want, got}, fmtArgs...)
+ t.Fatalf("%#v != %#v "+fmtStr, fmtArgs...)
+ }
+}
diff --git a/mctx/annotate_test.go b/mctx/annotate_test.go
index 053c841..83dafb0 100644
--- a/mctx/annotate_test.go
+++ b/mctx/annotate_test.go
@@ -2,9 +2,8 @@ package mctx
import (
"context"
+ "reflect"
. "testing"
-
- "github.com/mediocregopher/mediocre-go-lib/v2/mtest/massert"
)
type testAnnotator [2]string
@@ -22,32 +21,36 @@ func TestAnnotate(t *T) {
aa := Annotations{}
EvaluateAnnotations(ctx, aa)
- massert.Require(t,
- massert.Equal(Annotations{
- "a": "foo",
- "b": "BAR",
- }, aa),
- )
+ wantAA := Annotations{
+ "a": "foo",
+ "b": "BAR",
+ }
+
+ if !reflect.DeepEqual(wantAA, aa) {
+ t.Fatalf("%#v != %#v", wantAA, aa)
+ }
}
func TestAnnotationsStringMap(t *T) {
type A int
type B int
- aa := Annotations{
+ got := Annotations{
0: "zero",
1: "one",
A(2): "two",
B(2): "TWO",
+ }.StringMap()
+
+ want := map[string]string{
+ "0": "zero",
+ "1": "one",
+ "mctx.A(2)": "two",
+ "mctx.B(2)": "TWO",
}
- massert.Require(t,
- massert.Equal(map[string]string{
- "0": "zero",
- "1": "one",
- "mctx.A(2)": "two",
- "mctx.B(2)": "TWO",
- }, aa.StringMap()),
- )
+ if !reflect.DeepEqual(want, got) {
+ t.Fatalf("%#v != %#v", want, got)
+ }
}
func TestMergeAnnotations(t *T) {
@@ -60,12 +63,14 @@ func TestMergeAnnotations(t *T) {
aa := Annotations{}
EvaluateAnnotations(ctx, aa)
- err := massert.Equal(map[string]string{
+ got := aa.StringMap()
+ want := map[string]string{
"0": "ZERO",
"1": "ONE",
"2": "TWO",
- }, aa.StringMap()).Assert()
- if err != nil {
- t.Fatal(err)
+ }
+
+ if !reflect.DeepEqual(want, got) {
+ t.Fatalf("%#v != %#v", want, got)
}
}
diff --git a/merr/merr_test.go b/merr/merr_test.go
index 942b06b..1b1234a 100644
--- a/merr/merr_test.go
+++ b/merr/merr_test.go
@@ -6,12 +6,12 @@ import (
"fmt"
"testing"
+ "github.com/mediocregopher/mediocre-go-lib/v2/internal/massert"
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
- "github.com/mediocregopher/mediocre-go-lib/v2/mtest/massert"
)
func TestFullError(t *testing.T) {
- massert.Require(t, massert.Nil(Wrap(context.Background(), nil)))
+ massert.Equal(t, nil, Wrap(context.Background(), nil))
ctx := mctx.Annotate(context.Background(),
"a", "aaa aaa\n",
@@ -27,7 +27,7 @@ func TestFullError(t *testing.T) {
ccc
* d: weird key but ok
* line: merr/merr_test.go:22`
- massert.Require(t, massert.Equal(exp, e.(Error).FullError()))
+ massert.Equal(t, exp, e.(Error).FullError())
}
{
@@ -39,7 +39,7 @@ func TestFullError(t *testing.T) {
ccc
* d: weird key but ok
* line: merr/merr_test.go:34`
- massert.Require(t, massert.Equal(exp, e.(Error).FullError()))
+ massert.Equal(t, exp, e.(Error).FullError())
}
}
@@ -136,10 +136,9 @@ func TestAsIsError(t *testing.T) {
var in Error
ok := errors.As(test.in, &in)
- massert.Require(t, massert.Comment(
- massert.Equal(test.expAs != nil, ok),
- "test.in:%#v ok:%v", test.in, ok,
- ))
+ massert.Equalf(
+ t, ok, test.expAs != nil, "test.in:%#v ok:%v", test.in, ok,
+ )
if test.expAs == nil {
return
@@ -152,15 +151,13 @@ func TestAsIsError(t *testing.T) {
in.Ctx = nil
expAs.Ctx = nil
- massert.Require(t,
- massert.Equal(expAsAA, inAA),
- massert.Equal(expAs, in),
- massert.Comment(
- massert.Equal(true, errors.Is(test.in, test.expIs)),
- "errors.Is(\ntest.in:%#v,\ntest.expIs:%#v,\n)", test.in, test.expIs,
- ),
- massert.Equal(test.expStr, test.in.Error()),
+ massert.Equal(t, expAsAA, inAA)
+ massert.Equal(t, expAs, in)
+ massert.Equalf(
+ t, true, errors.Is(test.in, test.expIs),
+ "errors.Is(\ntest.in:%#v,\ntest.expIs:%#v,\n)", test.in, test.expIs,
)
+ massert.Equal(t, test.expStr, test.in.Error())
})
}
}
diff --git a/mlog/mlog_test.go b/mlog/mlog_test.go
index a9dfbaf..d7c1cf8 100644
--- a/mlog/mlog_test.go
+++ b/mlog/mlog_test.go
@@ -6,39 +6,36 @@ import (
"errors"
"fmt"
"strings"
+ "testing"
. "testing"
"time"
+ "github.com/mediocregopher/mediocre-go-lib/v2/internal/massert"
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
- "github.com/mediocregopher/mediocre-go-lib/v2/mtest/massert"
)
func TestTruncate(t *T) {
- massert.Require(t,
- massert.Equal("abc", Truncate("abc", 4)),
- massert.Equal("abc", Truncate("abc", 3)),
- massert.Equal("ab...", Truncate("abc", 2)),
- )
+ massert.Equal(t, "abc", Truncate("abc", 4))
+ massert.Equal(t, "abc", Truncate("abc", 3))
+ massert.Equal(t, "ab...", Truncate("abc", 2))
}
-func TestLogger(t *T) {
+func TestJSONLogger(t *T) {
buf := new(bytes.Buffer)
now := time.Now().UTC()
td, ts := now.Format(msgTimeFormat), fmt.Sprint(now.UnixNano())
l := NewLogger(&LoggerOpts{
- MessageHandler: NewMessageHandler(buf),
+ MessageHandler: NewJSONMessageHandler(buf),
Now: func() time.Time { return now },
})
- assertOut := func(expected string) massert.Assertion {
+ assertOut := func(t *testing.T, expected string) {
expected = strings.ReplaceAll(expected, "
", td)
expected = strings.ReplaceAll(expected, "", ts)
out, err := buf.ReadString('\n')
- return massert.All(
- massert.Nil(err),
- massert.Equal(expected, strings.TrimSpace(out)),
- )
+ massert.Equal(t, nil, err)
+ massert.Equal(t, expected, strings.TrimSpace(out))
}
ctx := context.Background()
@@ -48,23 +45,17 @@ func TestLogger(t *T) {
l.Info(ctx, "bar")
l.Warn(ctx, "baz", errors.New("ERR"))
l.Error(ctx, "buz", errors.New("ERR"))
- massert.Require(t,
- assertOut(`{"td":"","ts":,"level":"INFO","descr":"bar","level_int":30}`),
- assertOut(`{"td":"","ts":,"level":"WARN","descr":"baz","level_int":20,"annotations":{"errMsg":"ERR"}}`),
- assertOut(`{"td":"","ts":,"level":"ERROR","descr":"buz","level_int":10,"annotations":{"errMsg":"ERR"}}`),
- )
+ assertOut(t, `{"td":"","ts":,"level":"INFO","descr":"bar","level_int":30}`)
+ assertOut(t, `{"td":"","ts":,"level":"WARN","descr":"baz","level_int":20,"annotations":{"errMsg":"ERR"}}`)
+ assertOut(t, `{"td":"","ts":,"level":"ERROR","descr":"buz","level_int":10,"annotations":{"errMsg":"ERR"}}`)
// annotate context
ctx = mctx.Annotate(ctx, "foo", "bar")
l.Info(ctx, "bar")
- massert.Require(t,
- assertOut(`{"td":"","ts":,"level":"INFO","descr":"bar","level_int":30,"annotations":{"foo":"bar"}}`),
- )
+ assertOut(t, `{"td":"","ts":,"level":"INFO","descr":"bar","level_int":30,"annotations":{"foo":"bar"}}`)
// add namespace
l = l.WithNamespace("ns")
l.Info(ctx, "bar")
- massert.Require(t,
- assertOut(`{"td":"","ts":,"level":"INFO","ns":["ns"],"descr":"bar","level_int":30,"annotations":{"foo":"bar"}}`),
- )
+ assertOut(t, `{"td":"","ts":,"level":"INFO","ns":["ns"],"descr":"bar","level_int":30,"annotations":{"foo":"bar"}}`)
}
diff --git a/mtest/massert/massert.go b/mtest/massert/massert.go
deleted file mode 100644
index 9d4ee74..0000000
--- a/mtest/massert/massert.go
+++ /dev/null
@@ -1,462 +0,0 @@
-// Package massert implements an assertion framework which is useful in tests.
-package massert
-
-import (
- "bytes"
- "errors"
- "fmt"
- "path/filepath"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "testing"
- "text/tabwriter"
-)
-
-// AssertErr is an error returned by Assertions which have failed, containing
-// information about both the reason for failure and the Assertion itself.
-type AssertErr struct {
- Err error // The error which occurred
- Assertion Assertion // The Assertion which failed
-}
-
-func fmtBlock(str string) string {
- if strings.Index(str, "\n") == -1 {
- return str
- }
- return "\n\t" + strings.Replace(str, "\n", "\n\t", -1) + "\n"
-}
-
-func fmtMultiBlock(prefix string, elems ...string) string {
- if len(elems) == 0 {
- return prefix + "()"
- } else if len(elems) == 1 {
- return prefix + "(" + fmtBlock(elems[0]) + ")"
- }
-
- buf := new(bytes.Buffer)
- fmt.Fprintf(buf, "%s(\n", prefix)
- for _, el := range elems {
- elStr := "\t" + strings.Replace(el, "\n", "\n\t", -1)
- fmt.Fprintf(buf, "%s,\n", elStr)
- }
- fmt.Fprintf(buf, ")")
- return buf.String()
-}
-
-func fmtMultiDescr(prefix string, aa ...Assertion) string {
- descrs := make([]string, len(aa))
- for i := range aa {
- descrs[i] = aa[i].Description()
- }
- return fmtMultiBlock(prefix, descrs...)
-}
-
-func fmtStack(frames []runtime.Frame) string {
- buf := new(bytes.Buffer)
- tw := tabwriter.NewWriter(buf, 0, 4, 2, ' ', 0)
- for _, frame := range frames {
- file := filepath.Base(frame.File)
- fmt.Fprintf(tw, "%s:%d\t%s\n", file, frame.Line, frame.Function)
- }
- if err := tw.Flush(); err != nil {
- panic(err) // fuck it
- }
- return buf.String()
-}
-
-func (ae AssertErr) Error() string {
- buf := new(bytes.Buffer)
- fmt.Fprintf(buf, "\n")
- fmt.Fprintf(buf, "Assertion: %s\n", fmtBlock(ae.Assertion.Description()))
- fmt.Fprintf(buf, "Error: %s\n", fmtBlock(ae.Err.Error()))
- fmt.Fprintf(buf, "Stack: %s\n", fmtBlock(fmtStack(ae.Assertion.Stack())))
- return buf.String()
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Assertion is an entity which will make some kind of assertion and produce an
-// error if that assertion does not hold true. The error returned will generally
-// be of type AssertErr.
-type Assertion interface {
- Assert() error
- Description() string // A description of the Assertion
-
- // Returns the callstack of where the Assertion was created, ordered from
- // closest to farthest. This may not necessarily contain the entire
- // callstack if that would be inconveniently cumbersome.
- Stack() []runtime.Frame
-}
-
-const maxStackLen = 8
-
-type assertion struct {
- fn func() error
- descr string
- stack []runtime.Frame
-}
-
-func newFutureAssertion(assertFn func() error, descr string, skip int) Assertion {
- pcs := make([]uintptr, maxStackLen)
- // first skip is for runtime.Callers, second is for newAssertion, third is
- // for whatever is calling newAssertion
- numPCs := runtime.Callers(skip+3, pcs)
- stack := make([]runtime.Frame, 0, maxStackLen)
- frames := runtime.CallersFrames(pcs[:numPCs])
- for {
- frame, more := frames.Next()
- stack = append(stack, frame)
- if !more || len(stack) == maxStackLen {
- break
- }
- }
-
- a := &assertion{
- descr: descr,
- stack: stack,
- }
- a.fn = func() error {
- err := assertFn()
- if err == nil {
- return nil
- } else if ae, ok := err.(AssertErr); ok {
- return ae
- }
- return AssertErr{
- Err: err,
- Assertion: a,
- }
- }
- return a
-}
-
-func newAssertion(assertFn func() error, descr string, skip int) Assertion {
- err := assertFn()
- return newFutureAssertion(func() error { return err }, descr, skip+1)
-}
-
-func (a *assertion) Assert() error {
- return a.fn()
-}
-
-func (a *assertion) Description() string {
- return a.descr
-}
-
-func (a *assertion) Stack() []runtime.Frame {
- return a.stack
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Require is a convenience function which performs the Assertions and calls
-// Fatal on the testing.T instance for the first Assertion which fails.
-func Require(t *testing.T, aa ...Assertion) {
- for _, a := range aa {
- if err := a.Assert(); err != nil {
- t.Fatal(err)
- }
- }
-}
-
-// Assert is a convenience function which performs the Assertion and calls Error
-// on the testing.T instance for the first Assertion which fails.
-func Assert(t *testing.T, aa ...Assertion) {
- for _, a := range aa {
- if err := a.Assert(); err != nil {
- t.Error(err)
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Assertion wrappers
-
-// if the Assertion is a wrapper for another, this makes sure that if the
-// underlying one returns an AssertErr that this Assertion is what ends up in
-// that AssertErr
-type wrap struct {
- Assertion
-}
-
-func (wa wrap) Assert() error {
- err := wa.Assertion.Assert()
- if err == nil {
- return nil
- }
- ae := err.(AssertErr)
- ae.Assertion = wa.Assertion
- return ae
-}
-
-type descrWrap struct {
- Assertion
- descr string
-}
-
-func (dw descrWrap) Description() string {
- return dw.descr
-}
-
-// Comment prepends a formatted string to the given Assertion's string
-// description.
-func Comment(a Assertion, msg string, args ...interface{}) Assertion {
- msg = strings.TrimSpace(msg)
- descr := fmt.Sprintf("/* "+msg+" */\n", args...)
- descr += a.Description()
- return wrap{descrWrap{Assertion: a, descr: descr}}
-}
-
-// Not negates an Assertion, so that it fails if the given Assertion does not,
-// and vice-versa.
-func Not(a Assertion) Assertion {
- fn := func() error {
- if err := a.Assert(); err == nil {
- return errors.New("assertion should have failed")
- }
- return nil
- }
- return newAssertion(fn, fmtMultiDescr("Not", a), 0)
-}
-
-// Any asserts that at least one of the given Assertions succeeds.
-func Any(aa ...Assertion) Assertion {
- fn := func() error {
- for _, a := range aa {
- if err := a.Assert(); err == nil {
- return nil
- }
- }
- return errors.New("no assertions succeeded")
- }
- return newAssertion(fn, fmtMultiDescr("Any", aa...), 0)
-}
-
-// AnyOne asserts that exactly one of the given Assertions succeeds.
-func AnyOne(aa ...Assertion) Assertion {
- fn := func() error {
- any := -1
- for i, a := range aa {
- if err := a.Assert(); err == nil {
- if any >= 0 {
- return fmt.Errorf("assertions indices %d and %d both succeeded", any, i)
- }
- any = i
- }
- }
- if any == -1 {
- return errors.New("no assertions succeeded")
- }
- return nil
- }
- return newAssertion(fn, fmtMultiDescr("AnyOne", aa...), 0)
-}
-
-// All asserts that at all of the given Assertions succeed. Its Assert method
-// will return the error of whichever Assertion failed.
-func All(aa ...Assertion) Assertion {
- fn := func() error {
- for _, a := range aa {
- if err := a.Assert(); err != nil {
- // newAssertion will pass this error through, so that its
- // description and callstack is what gets displayed as the
- // error. This isn't totally consistent with Any's behavior, but
- // it's fine.
- return err
- }
- }
- return nil
- }
- return newAssertion(fn, fmtMultiDescr("All", aa...), 0)
-}
-
-// None asserts that all of the given Assertions fail.
-//
-// NOTE this is functionally equivalent to doing `Not(Any(aa...))`, but the
-// error returned is more helpful.
-func None(aa ...Assertion) Assertion {
- fn := func() error {
- for _, a := range aa {
- if err := a.Assert(); err == nil {
- return AssertErr{
- Err: errors.New("assertion should not have succeeded"),
- Assertion: a,
- }
- }
- }
- return nil
- }
- return newAssertion(fn, fmtMultiDescr("None", aa...), 0)
-}
-
-// Error returns an Assertion which always fails with the given error.
-func Error(err error) Assertion {
- return newAssertion(func() error { return err }, "", 0)
-}
-
-// Errorf is like Err but allows for a formatted string.
-func Errorf(str string, args ...interface{}) Assertion {
- return Error(fmt.Errorf(str, args...))
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-func toStr(i interface{}) string {
- return fmt.Sprintf("%T(%#v)", i, i)
-}
-
-// Equal asserts that the two values are exactly equal, and uses the
-// reflect.DeepEqual function to determine if they are.
-func Equal(a, b interface{}) Assertion {
- return newAssertion(func() error {
- if !reflect.DeepEqual(a, b) {
- return errors.New("not exactly equal")
- }
- return nil
- }, toStr(a)+" == "+toStr(b), 0)
-}
-
-// Nil asserts that the value is nil. This assertion works both if the value is
-// the untyped nil value (e.g. `Nil(nil)`) or if it's a typed nil value (e.g.
-// `Nil([]byte(nil))`).
-func Nil(i interface{}) Assertion {
- return newAssertion(func() error {
- if i == nil {
- return nil
- }
- v := reflect.ValueOf(i)
- switch v.Kind() {
- case reflect.Chan, reflect.Func, reflect.Interface,
- reflect.Map, reflect.Ptr, reflect.Slice:
- if v.IsNil() {
- return nil
- }
- default:
- }
- return errors.New("not nil")
- }, toStr(i)+" is nil", 0)
-}
-
-type setKV struct {
- k, v interface{}
-}
-
-func toSet(i interface{}, keyedMap bool) ([]interface{}, error) {
- v := reflect.ValueOf(i)
- switch v.Kind() {
- case reflect.Array, reflect.Slice:
- vv := make([]interface{}, v.Len())
- for i := range vv {
- vv[i] = v.Index(i).Interface()
- }
- return vv, nil
- case reflect.Map:
- keys := v.MapKeys()
- vv := make([]interface{}, len(keys))
- for i := range keys {
- if keyedMap {
- vv[i] = setKV{
- k: keys[i].Interface(),
- v: v.MapIndex(keys[i]).Interface(),
- }
- } else {
- vv[i] = v.MapIndex(keys[i]).Interface()
- }
- }
- return vv, nil
- default:
- return nil, fmt.Errorf("cannot turn value of type %s into a set", v.Type())
- }
-}
-
-// Subset asserts that the given subset is a subset of the given set. Both must
-// be of the same type and may be arrays, slices, or maps.
-func Subset(set, subset interface{}) Assertion {
- if reflect.TypeOf(set) != reflect.TypeOf(subset) {
- panic(errors.New("set and subset aren't of same type"))
- }
-
- setVV, err := toSet(set, true)
- if err != nil {
- panic(err)
- }
- subsetVV, err := toSet(subset, true)
- if err != nil {
- panic(err)
- }
- return newAssertion(func() error {
- // this is obviously not the most efficient way to do this
- outer:
- for i := range subsetVV {
- for j := range setVV {
- if reflect.DeepEqual(setVV[j], subsetVV[i]) {
- continue outer
- }
- }
- return fmt.Errorf("missing element %s", toStr(subsetVV[i]))
- }
- return nil
- }, toStr(set)+" has subset "+toStr(subset), 0)
-}
-
-// HasValue asserts that the given set has the given element as a value in it.
-// The set may be an array, a slice, or a map, and if it's a map then the elem
-// will need to be a value in it.
-func HasValue(set, elem interface{}) Assertion {
- setVV, err := toSet(set, false)
- if err != nil {
- panic(err)
- }
-
- return newAssertion(func() error {
- for i := range setVV {
- if reflect.DeepEqual(setVV[i], elem) {
- return nil
- }
- }
- return errors.New("value not in set")
- }, toStr(set)+" has value "+toStr(elem), 0)
-}
-
-// HasKey asserts that the given set (which must be a map type) has the given
-// element as a key in it.
-func HasKey(set, elem interface{}) Assertion {
- if v := reflect.ValueOf(set); v.Kind() != reflect.Map {
- panic(fmt.Errorf("type %s is not a map", v.Type()))
- }
- setVV, err := toSet(set, true)
- if err != nil {
- panic(err)
- }
- return newAssertion(func() error {
- for _, kv := range setVV {
- if reflect.DeepEqual(kv.(setKV).k, elem) {
- return nil
- }
- }
- return errors.New("value not a key in the map")
- }, toStr(set)+" has key "+toStr(elem), 0)
-}
-
-// Length asserts that the given set has the given number of elements in it. The
-// set may be an array, a slice, or a map. A nil value'd set is considered to be
-// a length of zero.
-func Length(set interface{}, length int) Assertion {
- setVV, err := toSet(set, false)
- if err != nil {
- panic(err)
- }
-
- return newAssertion(func() error {
- if len(setVV) != length {
- return fmt.Errorf("set not correct length, is %d", len(setVV))
- }
- return nil
- }, toStr(set)+" has length "+strconv.Itoa(length), 0)
-}
-
-// TODO ChanRead(ch interface{}, within time.Duration, callback func(interface{}) error)
-// TODO ChanBlock(ch interface{}, for time.Duration)
-// TODO ChanClosed(ch interface{})
diff --git a/mtest/massert/massert_test.go b/mtest/massert/massert_test.go
deleted file mode 100644
index 125417b..0000000
--- a/mtest/massert/massert_test.go
+++ /dev/null
@@ -1,249 +0,0 @@
-package massert
-
-import (
- "errors"
- . "testing"
-)
-
-func succeed() Assertion {
- return newAssertion(func() error { return nil }, "Succeed", 0)
-}
-
-func fail() Assertion {
- return newAssertion(func() error { return errors.New("failure") }, "Fail", 0)
-}
-
-func TestNot(t *T) {
- if err := Not(succeed()).Assert(); err == nil {
- t.Fatal("Not(succeed()) should have failed")
- }
-
- if err := Not(fail()).Assert(); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestAny(t *T) {
- if err := Any().Assert(); err == nil {
- t.Fatal("empty Any should fail")
- }
-
- if err := Any(succeed(), succeed()).Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := Any(succeed(), fail()).Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := Any(fail(), fail()).Assert(); err == nil {
- t.Fatal("Any should have failed with all inner fail Assertions")
- }
-}
-
-func TestAnyOne(t *T) {
- if err := AnyOne().Assert(); err == nil {
- t.Fatal("empty AnyOne should fail")
- }
-
- if err := AnyOne(succeed(), succeed()).Assert(); err == nil {
- t.Fatal("AnyOne with two succeeds should fail")
- }
-
- if err := AnyOne(succeed(), fail()).Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := AnyOne(fail(), fail()).Assert(); err == nil {
- t.Fatal("AnyOne should have failed with all inner fail Assertions")
- }
-}
-
-func TestAll(t *T) {
- if err := All().Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := All(succeed(), succeed()).Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := All(succeed(), fail()).Assert(); err == nil {
- t.Fatal("All should have failed with one inner fail Assertion")
- }
-
- if err := All(fail(), fail()).Assert(); err == nil {
- t.Fatal("All should have failed with all inner fail Assertions")
- }
-}
-
-func TestNone(t *T) {
- if err := None().Assert(); err != nil {
- t.Fatal(err)
- }
-
- if err := None(succeed(), succeed()).Assert(); err == nil {
- t.Fatal("None should have failed with all inner succeed Assertions")
- }
-
- if err := None(succeed(), fail()).Assert(); err == nil {
- t.Fatal("None should have failed with one inner succeed Assertion")
- }
-
- if err := None(fail(), fail()).Assert(); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestEqual(t *T) {
- Require(t,
- Equal(1, 1),
- Equal("foo", "foo"),
- )
-
- Require(t, None(
- Equal(1, 2),
- Equal(1, int64(1)),
- Equal(1, uint64(1)),
- Equal("foo", "bar"),
- ))
-
- // test that assertions take in the value at the moment the assertion is
- // made
- var aa []Assertion
- m := map[string]int{}
- m["foo"] = 1
- aa = append(aa, Equal(1, m["foo"]))
- m["foo"] = 2
- aa = append(aa, Equal(2, m["foo"]))
- Require(t, aa...)
-}
-
-func TestNil(t *T) {
- Require(t,
- Nil(nil),
- Nil([]byte(nil)),
- Nil(map[int]int(nil)),
- Nil((*struct{})(nil)),
- Nil(interface{}(nil)),
- Nil(error(nil)),
- )
-
- Require(t, None(
- Nil(1),
- Nil([]byte("foo")),
- Nil(map[int]int{1: 1}),
- Nil(&struct{}{}),
- Nil(interface{}("hi")),
- Nil(errors.New("some error")),
- ))
-}
-
-func TestSubset(t *T) {
- Require(t,
- Subset([]int{1, 2, 3}, []int{}),
- Subset([]int{1, 2, 3}, []int{1}),
- Subset([]int{1, 2, 3}, []int{2}),
- Subset([]int{1, 2, 3}, []int{1, 2}),
- Subset([]int{1, 2, 3}, []int{2, 1}),
- Subset([]int{1, 2, 3}, []int{1, 2, 3}),
- Subset([]int{1, 2, 3}, []int{1, 3, 2}),
-
- Subset(map[int]int{1: 1, 2: 2}, map[int]int{}),
- Subset(map[int]int{1: 1, 2: 2}, map[int]int{1: 1}),
- Subset(map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}),
- )
-
- Require(t, None(
- Subset([]int{}, []int{1, 2, 3}),
- Subset([]int{1, 2, 3}, []int{4}),
- Subset([]int{1, 2, 3}, []int{1, 3, 2, 4}),
-
- Subset(map[int]int{1: 1, 2: 2}, map[int]int{1: 2}),
- Subset(map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 3: 3}),
- ))
-
- // make sure changes don't retroactively fail the assertion
- m := map[int]int{1: 1, 2: 2}
- a := Subset(m, map[int]int{1: 1})
- m[1] = 2
- Require(t, a)
-}
-
-func TestHasValue(t *T) {
- Require(t,
- HasValue([]int{1}, 1),
- HasValue([]int{1, 2}, 1),
- HasValue([]int{2, 1}, 1),
- HasValue(map[int]int{1: 1}, 1),
- HasValue(map[int]int{1: 2}, 2),
- HasValue(map[int]int{1: 2, 2: 1}, 1),
- HasValue(map[int]int{1: 2, 2: 2}, 2),
- )
-
- Require(t, None(
- HasValue([]int{}, 1),
- HasValue([]int{1}, 2),
- HasValue([]int{2, 1}, 3),
- HasValue(map[int]int{}, 1),
- HasValue(map[int]int{1: 1}, 2),
- HasValue(map[int]int{1: 2}, 1),
- HasValue(map[int]int{1: 2, 2: 1}, 3),
- ))
-
- // make sure changes don't retroactively fail the assertion
- m := map[int]int{1: 1}
- a := HasValue(m, 1)
- m[1] = 2
- Require(t, a)
-}
-
-func TestHasKey(t *T) {
- Require(t,
- HasKey(map[int]int{1: 1}, 1),
- HasKey(map[int]int{1: 1, 2: 2}, 1),
- HasKey(map[int]int{1: 1, 2: 2}, 2),
- )
-
- Require(t, None(
- HasKey(map[int]int{}, 1),
- HasKey(map[int]int{2: 2}, 1),
- ))
-
- // make sure changes don't retroactively fail the assertion
- m := map[int]int{1: 1}
- a := HasKey(m, 1)
- delete(m, 1)
- Require(t, a)
-
-}
-
-func TestLength(t *T) {
- Require(t,
- Length([]int(nil), 0),
- Length([]int{}, 0),
- Length([]int{1}, 1),
- Length([]int{1, 2}, 2),
- Length(map[int]int(nil), 0),
- Length(map[int]int{}, 0),
- Length(map[int]int{1: 1}, 1),
- Length(map[int]int{1: 1, 2: 2}, 2),
- )
-
- Require(t, None(
- Length([]int(nil), 1),
- Length([]int{}, 1),
- Length([]int{1}, 0),
- Length([]int{1}, 2),
- Length([]int{1, 2}, 1),
- Length([]int{1, 2}, 3),
- Length(map[int]int(nil), 1),
- Length(map[int]int{}, 1),
- ))
-
- // make sure changes don't retroactively fail the assertion
- m := map[int]int{1: 1}
- a := Length(m, 1)
- m[2] = 2
- Require(t, a)
-}
| | | | | | | | | | |