Implements tests/_plans and previously deferred packages; updates plan README with new coverage numbers.
217 lines
5.6 KiB
Go
217 lines
5.6 KiB
Go
package template
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
type accessItem struct {
|
|
Name string
|
|
ID int
|
|
}
|
|
|
|
func TestGetAndGetOr(t *testing.T) {
|
|
m := map[string]interface{}{"a": 1, "nilv": nil}
|
|
if got := Get(m, "a"); got != 1 {
|
|
t.Errorf("Get: %v", got)
|
|
}
|
|
if got := Get(m, "missing"); got != nil {
|
|
t.Errorf("Get missing: %v", got)
|
|
}
|
|
if got := Get(nil, "a"); got != nil {
|
|
t.Errorf("Get nil map: %v", got)
|
|
}
|
|
if got := GetOr(m, "missing", "def"); got != "def" {
|
|
t.Errorf("GetOr missing: %v", got)
|
|
}
|
|
if got := GetOr(m, "nilv", "def"); got != "def" {
|
|
t.Errorf("GetOr nil value: %v", got)
|
|
}
|
|
if got := GetOr(m, "a", "def"); got != 1 {
|
|
t.Errorf("GetOr present: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestGetPath(t *testing.T) {
|
|
cfg := map[string]interface{}{
|
|
"db": map[string]interface{}{"conn": map[string]interface{}{"host": "h"}},
|
|
}
|
|
if got := GetPath(cfg, "db.conn.host"); got != "h" {
|
|
t.Errorf("GetPath: %v", got)
|
|
}
|
|
if got := GetPath(cfg, "db.nope.host"); got != nil {
|
|
t.Errorf("GetPath missing: %v", got)
|
|
}
|
|
if got := GetPathOr(cfg, "db.nope", "dflt"); got != "dflt" {
|
|
t.Errorf("GetPathOr: %v", got)
|
|
}
|
|
if got := GetPathOr(cfg, "db.conn.host", "dflt"); got != "h" {
|
|
t.Errorf("GetPathOr present: %v", got)
|
|
}
|
|
if !HasPath(cfg, "db.conn") || HasPath(cfg, "db.x") || HasPath(nil, "a") {
|
|
t.Errorf("HasPath mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSafeIndex(t *testing.T) {
|
|
s := []string{"a", "b"}
|
|
if got := SafeIndex(s, 1); got != "b" {
|
|
t.Errorf("SafeIndex: %v", got)
|
|
}
|
|
for _, i := range []int{-1, 2, 99} {
|
|
if got := SafeIndex(s, i); got != nil {
|
|
t.Errorf("SafeIndex(%d) must be nil, got %v", i, got)
|
|
}
|
|
}
|
|
if got := SafeIndex("notslice", 0); got != nil {
|
|
t.Errorf("non-slice: %v", got)
|
|
}
|
|
if got := SafeIndexOr(s, 5, "d"); got != "d" {
|
|
t.Errorf("SafeIndexOr: %v", got)
|
|
}
|
|
if got := SafeIndexOr(s, 0, "d"); got != "a" {
|
|
t.Errorf("SafeIndexOr present: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestHas(t *testing.T) {
|
|
m := map[string]int{"a": 1}
|
|
var nilPtr *map[string]int
|
|
tests := []struct {
|
|
name string
|
|
m interface{}
|
|
key interface{}
|
|
want bool
|
|
}{
|
|
{"present", m, "a", true},
|
|
{"missing", m, "b", false},
|
|
{"pointer to map", &m, "a", true},
|
|
{"nil pointer", nilPtr, "a", false},
|
|
{"non-map", []int{1}, 0, false},
|
|
{"nil", nil, "a", false},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := Has(tt.m, tt.key); got != tt.want {
|
|
t.Errorf("got %v", got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestKeysValues(t *testing.T) {
|
|
m := map[string]int{"a": 1, "b": 2}
|
|
if got := Keys(m); len(got) != 2 {
|
|
t.Errorf("Keys: %v", got)
|
|
}
|
|
if got := Values(m); len(got) != 2 {
|
|
t.Errorf("Values: %v", got)
|
|
}
|
|
if got := Keys(nil); len(got) != 0 {
|
|
t.Errorf("Keys nil: %v", got)
|
|
}
|
|
if got := Values(5); len(got) != 0 {
|
|
t.Errorf("Values non-map: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestMerge(t *testing.T) {
|
|
m1 := map[string]int{"a": 1, "b": 2}
|
|
m2 := map[string]int{"b": 3, "c": 4}
|
|
var nilPtr *map[string]int
|
|
got := Merge(m1, &m2, nilPtr, nil, 5)
|
|
want := map[interface{}]interface{}{"a": 1, "b": 3, "c": 4}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("got %v", got)
|
|
}
|
|
if got := Merge(); len(got) != 0 {
|
|
t.Errorf("empty merge: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestPickOmit(t *testing.T) {
|
|
m := map[string]int{"a": 1, "b": 2, "c": 3}
|
|
var nilPtr *map[string]int
|
|
|
|
if got := Pick(m, "a", "z"); !reflect.DeepEqual(got, map[interface{}]interface{}{"a": 1}) {
|
|
t.Errorf("Pick: %v", got)
|
|
}
|
|
if got := Pick(&m, "b"); len(got) != 1 {
|
|
t.Errorf("Pick ptr: %v", got)
|
|
}
|
|
if got := Pick(nilPtr, "a"); len(got) != 0 {
|
|
t.Errorf("Pick nil ptr: %v", got)
|
|
}
|
|
if got := Pick(5, "a"); len(got) != 0 {
|
|
t.Errorf("Pick non-map: %v", got)
|
|
}
|
|
|
|
if got := Omit(m, "a", "z"); !reflect.DeepEqual(got, map[interface{}]interface{}{"b": 2, "c": 3}) {
|
|
t.Errorf("Omit: %v", got)
|
|
}
|
|
if got := Omit(&m); len(got) != 3 {
|
|
t.Errorf("Omit ptr: %v", got)
|
|
}
|
|
if got := Omit(nilPtr, "a"); len(got) != 0 {
|
|
t.Errorf("Omit nil ptr: %v", got)
|
|
}
|
|
if got := Omit("x", "a"); len(got) != 0 {
|
|
t.Errorf("Omit non-map: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestSliceContainsIndexOf(t *testing.T) {
|
|
s := []string{"a", "b", "c"}
|
|
sp := &s
|
|
var nilPtr *[]string
|
|
if !SliceContains(s, "b") || SliceContains(s, "z") {
|
|
t.Errorf("SliceContains")
|
|
}
|
|
if !SliceContains(sp, "c") || !SliceContains([2]int{1, 2}, 2) {
|
|
t.Errorf("SliceContains ptr/array")
|
|
}
|
|
if SliceContains(nilPtr, "a") || SliceContains("str", "s") || SliceContains(nil, 1) {
|
|
t.Errorf("SliceContains invalid input")
|
|
}
|
|
if got := IndexOf(s, "c"); got != 2 {
|
|
t.Errorf("IndexOf: %d", got)
|
|
}
|
|
if got := IndexOf(sp, "a"); got != 0 {
|
|
t.Errorf("IndexOf ptr: %d", got)
|
|
}
|
|
for _, in := range []interface{}{s, nilPtr, "str", nil} {
|
|
if got := IndexOf(in, "zzz"); got != -1 {
|
|
t.Errorf("IndexOf miss %v: %d", in, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPluck(t *testing.T) {
|
|
items := []*accessItem{{"a", 1}, nil, {"c", 3}}
|
|
got := Pluck(items, "Name")
|
|
if !reflect.DeepEqual(got, []interface{}{"a", nil, "c"}) {
|
|
t.Errorf("struct ptrs: %v", got)
|
|
}
|
|
if got := Pluck([]accessItem{{"a", 1}}, "Missing"); !reflect.DeepEqual(got, []interface{}{nil}) {
|
|
t.Errorf("missing field: %v", got)
|
|
}
|
|
maps := []map[string]int{{"k": 1}, {"x": 2}}
|
|
if got := Pluck(maps, "k"); !reflect.DeepEqual(got, []interface{}{1, nil}) {
|
|
t.Errorf("maps: %v", got)
|
|
}
|
|
if got := Pluck([]int{1, 2}, "k"); !reflect.DeepEqual(got, []interface{}{nil, nil}) {
|
|
t.Errorf("scalars: %v", got)
|
|
}
|
|
var nilPtr *[]accessItem
|
|
if got := Pluck(nilPtr, "Name"); len(got) != 0 {
|
|
t.Errorf("nil ptr: %v", got)
|
|
}
|
|
if got := Pluck("str", "Name"); len(got) != 0 {
|
|
t.Errorf("non-slice: %v", got)
|
|
}
|
|
s := []accessItem{{"z", 9}}
|
|
if got := Pluck(&s, "ID"); !reflect.DeepEqual(got, []interface{}{9}) {
|
|
t.Errorf("ptr to slice: %v", got)
|
|
}
|
|
}
|