mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 10:57:50 +08:00
198 lines
4.6 KiB
Go
198 lines
4.6 KiB
Go
package vals
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// Tester is a helper for testing properties of a value.
|
|
type Tester struct {
|
|
t *testing.T
|
|
v any
|
|
}
|
|
|
|
// TestValue returns a ValueTester.
|
|
func TestValue(t *testing.T, v any) Tester {
|
|
// Hack to get test coverage on the marker method IsStructMap, which is
|
|
// never invoked.
|
|
if m, ok := v.(StructMap); ok {
|
|
m.IsStructMap()
|
|
}
|
|
return Tester{t, v}
|
|
}
|
|
|
|
// Kind tests the Kind of the value.
|
|
func (vt Tester) Kind(wantKind string) Tester {
|
|
vt.t.Helper()
|
|
kind := Kind(vt.v)
|
|
if kind != wantKind {
|
|
vt.t.Errorf("Kind(v) = %s, want %s", kind, wantKind)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Bool tests the Boool of the value.
|
|
func (vt Tester) Bool(wantBool bool) Tester {
|
|
vt.t.Helper()
|
|
b := Bool(vt.v)
|
|
if b != wantBool {
|
|
vt.t.Errorf("Bool(v) = %v, want %v", b, wantBool)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Hash tests the Hash of the value.
|
|
func (vt Tester) Hash(wantHash uint32) Tester {
|
|
vt.t.Helper()
|
|
hash := Hash(vt.v)
|
|
if hash != wantHash {
|
|
vt.t.Errorf("Hash(v) = %v, want %v", hash, wantHash)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Len tests the Len of the value.
|
|
func (vt Tester) Len(wantLen int) Tester {
|
|
vt.t.Helper()
|
|
kind := Len(vt.v)
|
|
if kind != wantLen {
|
|
vt.t.Errorf("Len(v) = %v, want %v", kind, wantLen)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Repr tests the Repr of the value.
|
|
func (vt Tester) Repr(wantRepr string) Tester {
|
|
vt.t.Helper()
|
|
kind := ReprPlain(vt.v)
|
|
if kind != wantRepr {
|
|
vt.t.Errorf("Repr(v) = %s, want %s", kind, wantRepr)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Equal tests that the value is Equal to every of the given values.
|
|
func (vt Tester) Equal(others ...any) Tester {
|
|
vt.t.Helper()
|
|
for _, other := range others {
|
|
eq := Equal(vt.v, other)
|
|
if !eq {
|
|
vt.t.Errorf("Equal(v, %v) = false, want true", other)
|
|
}
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// NotEqual tests that the value is not Equal to any of the given values.
|
|
func (vt Tester) NotEqual(others ...any) Tester {
|
|
vt.t.Helper()
|
|
for _, other := range others {
|
|
eq := Equal(vt.v, other)
|
|
if eq {
|
|
vt.t.Errorf("Equal(v, %v) = true, want false", other)
|
|
}
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// HasKey tests that the value has each of the given keys.
|
|
func (vt Tester) HasKey(keys ...any) Tester {
|
|
vt.t.Helper()
|
|
for _, key := range keys {
|
|
has := HasKey(vt.v, key)
|
|
if !has {
|
|
vt.t.Errorf("HasKey(v, %v) = false, want true", key)
|
|
}
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// HasNoKey tests that the value does not have any of the given keys.
|
|
func (vt Tester) HasNoKey(keys ...any) Tester {
|
|
vt.t.Helper()
|
|
for _, key := range keys {
|
|
has := HasKey(vt.v, key)
|
|
if has {
|
|
vt.t.Errorf("HasKey(v, %v) = true, want false", key)
|
|
}
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// AllKeys tests that the given keys match what the result of IterateKeys on the
|
|
// value.
|
|
//
|
|
// NOTE: This now checks equality using reflect.DeepEqual, since all the builtin
|
|
// types have string keys. This can be changed in future to use Equal is the
|
|
// need arises.
|
|
func (vt Tester) AllKeys(wantKeys ...any) Tester {
|
|
vt.t.Helper()
|
|
keys, err := collectKeys(vt.v)
|
|
if err != nil {
|
|
vt.t.Errorf("IterateKeys(v, f) -> err %v, want nil", err)
|
|
}
|
|
if !reflect.DeepEqual(keys, wantKeys) {
|
|
vt.t.Errorf("IterateKeys(v, f) calls f with %v, want %v", keys, wantKeys)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
func collectKeys(v any) ([]any, error) {
|
|
var keys []any
|
|
err := IterateKeys(v, func(k any) bool {
|
|
keys = append(keys, k)
|
|
return true
|
|
})
|
|
return keys, err
|
|
}
|
|
|
|
// Index tests that Index'ing the value with the given key returns the wanted value
|
|
// and no error.
|
|
func (vt Tester) Index(key, wantVal any) Tester {
|
|
vt.t.Helper()
|
|
got, err := Index(vt.v, key)
|
|
if err != nil {
|
|
vt.t.Errorf("Index(v, %v) -> err %v, want nil", key, err)
|
|
}
|
|
if !Equal(got, wantVal) {
|
|
vt.t.Errorf("Index(v, %v) -> %v, want %v", key, got, wantVal)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// IndexError tests that Index'ing the value with the given key returns the given
|
|
// error.
|
|
func (vt Tester) IndexError(key any, wantErr error) Tester {
|
|
vt.t.Helper()
|
|
_, err := Index(vt.v, key)
|
|
if !reflect.DeepEqual(err, wantErr) {
|
|
vt.t.Errorf("Index(v, %v) -> err %v, want %v", key, err, wantErr)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// Assoc tests that Assoc'ing the value with the given key-value pair returns
|
|
// the wanted new value and no error.
|
|
func (vt Tester) Assoc(key, val, wantNew any) Tester {
|
|
vt.t.Helper()
|
|
got, err := Assoc(vt.v, key, val)
|
|
if err != nil {
|
|
vt.t.Errorf("Assoc(v, %v) -> err %v, want nil", key, err)
|
|
}
|
|
if !Equal(got, wantNew) {
|
|
vt.t.Errorf("Assoc(v, %v) -> %v, want %v", key, got, wantNew)
|
|
}
|
|
return vt
|
|
}
|
|
|
|
// AssocError tests that Assoc'ing the value with the given key-value pair
|
|
// returns the given error.
|
|
func (vt Tester) AssocError(key, val any, wantErr error) Tester {
|
|
vt.t.Helper()
|
|
_, err := Assoc(vt.v, key, val)
|
|
if !reflect.DeepEqual(err, wantErr) {
|
|
vt.t.Errorf("Assoc(v, %v) -> err %v, want %v", key, err, wantErr)
|
|
}
|
|
return vt
|
|
}
|