mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
opentracing -> opencensus (#802)
* update vendor directory, add go.opencensus.io * update imports * oops * s/opentracing/opencensus/ & remove prometheus / zipkin stuff & remove old stats * the dep train rides again * fix gin build * deps from last guy * start in on the agent metrics * she builds * remove tags for now, cardinality error is fussing. subscribe instead of register * update to patched version of opencensus to proceed for now TODO switch to a release * meh fix imports * println debug the bad boys * lace it with the tags * update deps again * fix all inconsistent cardinality errors * add our own logger * fix init * fix oom measure * remove bugged removal code * fix s3 measures * fix prom handler nil
This commit is contained in:
2
vendor/github.com/mitchellh/mapstructure/README.md
generated
vendored
2
vendor/github.com/mitchellh/mapstructure/README.md
generated
vendored
@@ -1,4 +1,4 @@
|
||||
# mapstructure [](https://godoc.org/github.com/mitchell/mapstructure)
|
||||
# mapstructure [](https://godoc.org/github.com/mitchellh/mapstructure)
|
||||
|
||||
mapstructure is a Go library for decoding generic map values to structures
|
||||
and vice versa, while providing helpful error handling.
|
||||
|
||||
19
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
19
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
@@ -115,6 +115,25 @@ func StringToTimeDurationHookFunc() DecodeHookFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// StringToTimeHookFunc returns a DecodeHookFunc that converts
|
||||
// strings to time.Time.
|
||||
func StringToTimeHookFunc(layout string) DecodeHookFunc {
|
||||
return func(
|
||||
f reflect.Type,
|
||||
t reflect.Type,
|
||||
data interface{}) (interface{}, error) {
|
||||
if f.Kind() != reflect.String {
|
||||
return data, nil
|
||||
}
|
||||
if t != reflect.TypeOf(time.Time{}) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Convert it by parsing
|
||||
return time.Parse(layout, data.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
|
||||
// the decoder.
|
||||
//
|
||||
|
||||
30
vendor/github.com/mitchellh/mapstructure/decode_hooks_test.go
generated
vendored
30
vendor/github.com/mitchellh/mapstructure/decode_hooks_test.go
generated
vendored
@@ -153,6 +153,36 @@ func TestStringToTimeDurationHookFunc(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringToTimeHookFunc(t *testing.T) {
|
||||
strType := reflect.TypeOf("")
|
||||
timeType := reflect.TypeOf(time.Time{})
|
||||
cases := []struct {
|
||||
f, t reflect.Type
|
||||
layout string
|
||||
data interface{}
|
||||
result interface{}
|
||||
err bool
|
||||
}{
|
||||
{strType, timeType, time.RFC3339, "2006-01-02T15:04:05Z",
|
||||
time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC), false},
|
||||
{strType, timeType, time.RFC3339, "5", time.Time{}, true},
|
||||
{strType, strType, time.RFC3339, "5", "5", false},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
f := StringToTimeHookFunc(tc.layout)
|
||||
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||||
if tc.err != (err != nil) {
|
||||
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.result) {
|
||||
t.Fatalf(
|
||||
"case %d: expected %#v, got %#v",
|
||||
i, tc.result, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeaklyTypedHook(t *testing.T) {
|
||||
var f DecodeHookFunc = WeaklyTypedHook
|
||||
|
||||
|
||||
260
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
260
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
@@ -114,12 +114,12 @@ type Metadata struct {
|
||||
Unused []string
|
||||
}
|
||||
|
||||
// Decode takes a map and uses reflection to convert it into the
|
||||
// given Go native structure. val must be a pointer to a struct.
|
||||
func Decode(m interface{}, rawVal interface{}) error {
|
||||
// Decode takes an input structure and uses reflection to translate it to
|
||||
// the output structure. output must be a pointer to a map or struct.
|
||||
func Decode(input interface{}, output interface{}) error {
|
||||
config := &DecoderConfig{
|
||||
Metadata: nil,
|
||||
Result: rawVal,
|
||||
Result: output,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
@@ -127,7 +127,7 @@ func Decode(m interface{}, rawVal interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return decoder.Decode(m)
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
// WeakDecode is the same as Decode but is shorthand to enable
|
||||
@@ -147,6 +147,40 @@ func WeakDecode(input, output interface{}) error {
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
// DecodeMetadata is the same as Decode, but is shorthand to
|
||||
// enable metadata collection. See DecoderConfig for more info.
|
||||
func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
|
||||
config := &DecoderConfig{
|
||||
Metadata: metadata,
|
||||
Result: output,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
// WeakDecodeMetadata is the same as Decode, but is shorthand to
|
||||
// enable both WeaklyTypedInput and metadata collection. See
|
||||
// DecoderConfig for more info.
|
||||
func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
|
||||
config := &DecoderConfig{
|
||||
Metadata: metadata,
|
||||
Result: output,
|
||||
WeaklyTypedInput: true,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder for the given configuration. Once
|
||||
// a decoder has been returned, the same configuration must not be used
|
||||
// again.
|
||||
@@ -184,70 +218,81 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
|
||||
|
||||
// Decode decodes the given raw interface to the target pointer specified
|
||||
// by the configuration.
|
||||
func (d *Decoder) Decode(raw interface{}) error {
|
||||
return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem())
|
||||
func (d *Decoder) Decode(input interface{}) error {
|
||||
return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
|
||||
}
|
||||
|
||||
// Decodes an unknown data type into a specific reflection value.
|
||||
func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
|
||||
if data == nil {
|
||||
// If the data is nil, then we don't set anything.
|
||||
func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
|
||||
if input == nil {
|
||||
// If the data is nil, then we don't set anything, unless ZeroFields is set
|
||||
// to true.
|
||||
if d.config.ZeroFields {
|
||||
outVal.Set(reflect.Zero(outVal.Type()))
|
||||
|
||||
if d.config.Metadata != nil && name != "" {
|
||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
dataVal := reflect.ValueOf(data)
|
||||
if !dataVal.IsValid() {
|
||||
// If the data value is invalid, then we just set the value
|
||||
inputVal := reflect.ValueOf(input)
|
||||
if !inputVal.IsValid() {
|
||||
// If the input value is invalid, then we just set the value
|
||||
// to be the zero value.
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
outVal.Set(reflect.Zero(outVal.Type()))
|
||||
if d.config.Metadata != nil && name != "" {
|
||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if d.config.DecodeHook != nil {
|
||||
// We have a DecodeHook, so let's pre-process the data.
|
||||
// We have a DecodeHook, so let's pre-process the input.
|
||||
var err error
|
||||
data, err = DecodeHookExec(
|
||||
input, err = DecodeHookExec(
|
||||
d.config.DecodeHook,
|
||||
dataVal.Type(), val.Type(), data)
|
||||
inputVal.Type(), outVal.Type(), input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error decoding '%s': %s", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
dataKind := getKind(val)
|
||||
switch dataKind {
|
||||
inputKind := getKind(outVal)
|
||||
switch inputKind {
|
||||
case reflect.Bool:
|
||||
err = d.decodeBool(name, data, val)
|
||||
err = d.decodeBool(name, input, outVal)
|
||||
case reflect.Interface:
|
||||
err = d.decodeBasic(name, data, val)
|
||||
err = d.decodeBasic(name, input, outVal)
|
||||
case reflect.String:
|
||||
err = d.decodeString(name, data, val)
|
||||
err = d.decodeString(name, input, outVal)
|
||||
case reflect.Int:
|
||||
err = d.decodeInt(name, data, val)
|
||||
err = d.decodeInt(name, input, outVal)
|
||||
case reflect.Uint:
|
||||
err = d.decodeUint(name, data, val)
|
||||
err = d.decodeUint(name, input, outVal)
|
||||
case reflect.Float32:
|
||||
err = d.decodeFloat(name, data, val)
|
||||
err = d.decodeFloat(name, input, outVal)
|
||||
case reflect.Struct:
|
||||
err = d.decodeStruct(name, data, val)
|
||||
err = d.decodeStruct(name, input, outVal)
|
||||
case reflect.Map:
|
||||
err = d.decodeMap(name, data, val)
|
||||
err = d.decodeMap(name, input, outVal)
|
||||
case reflect.Ptr:
|
||||
err = d.decodePtr(name, data, val)
|
||||
err = d.decodePtr(name, input, outVal)
|
||||
case reflect.Slice:
|
||||
err = d.decodeSlice(name, data, val)
|
||||
err = d.decodeSlice(name, input, outVal)
|
||||
case reflect.Array:
|
||||
err = d.decodeArray(name, data, val)
|
||||
err = d.decodeArray(name, input, outVal)
|
||||
case reflect.Func:
|
||||
err = d.decodeFunc(name, data, val)
|
||||
err = d.decodeFunc(name, input, outVal)
|
||||
default:
|
||||
// If we reached this point then we weren't able to decode it
|
||||
return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
|
||||
return fmt.Errorf("%s: unsupported type: %s", name, inputKind)
|
||||
}
|
||||
|
||||
// If we reached here, then we successfully decoded SOMETHING, so
|
||||
// mark the key as used if we're tracking metadata.
|
||||
// mark the key as used if we're tracking metainput.
|
||||
if d.config.Metadata != nil && name != "" {
|
||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||
}
|
||||
@@ -258,6 +303,9 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
|
||||
// This decodes a basic type (bool, int, string, etc.) and sets the
|
||||
// value to "data" of that type.
|
||||
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
||||
if val.IsValid() && val.Elem().IsValid() {
|
||||
return d.decode(name, data, val.Elem())
|
||||
}
|
||||
dataVal := reflect.ValueOf(data)
|
||||
if !dataVal.IsValid() {
|
||||
dataVal = reflect.Zero(val.Type())
|
||||
@@ -499,34 +547,50 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er
|
||||
valMap = reflect.MakeMap(mapType)
|
||||
}
|
||||
|
||||
// Check input type
|
||||
// Check input type and based on the input type jump to the proper func
|
||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||
if dataVal.Kind() != reflect.Map {
|
||||
// In weak mode, we accept a slice of maps as an input...
|
||||
switch dataVal.Kind() {
|
||||
case reflect.Map:
|
||||
return d.decodeMapFromMap(name, dataVal, val, valMap)
|
||||
|
||||
case reflect.Struct:
|
||||
return d.decodeMapFromStruct(name, dataVal, val, valMap)
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
if d.config.WeaklyTypedInput {
|
||||
switch dataVal.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
// Special case for BC reasons (covered by tests)
|
||||
if dataVal.Len() == 0 {
|
||||
val.Set(valMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < dataVal.Len(); i++ {
|
||||
err := d.decode(
|
||||
fmt.Sprintf("%s[%d]", name, i),
|
||||
dataVal.Index(i).Interface(), val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
return d.decodeMapFromSlice(name, dataVal, val, valMap)
|
||||
}
|
||||
|
||||
fallthrough
|
||||
|
||||
default:
|
||||
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
|
||||
// Special case for BC reasons (covered by tests)
|
||||
if dataVal.Len() == 0 {
|
||||
val.Set(valMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < dataVal.Len(); i++ {
|
||||
err := d.decode(
|
||||
fmt.Sprintf("%s[%d]", name, i),
|
||||
dataVal.Index(i).Interface(), val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
|
||||
valType := val.Type()
|
||||
valKeyType := valType.Key()
|
||||
valElemType := valType.Elem()
|
||||
|
||||
// Accumulate errors
|
||||
errors := make([]string, 0)
|
||||
@@ -563,22 +627,88 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
|
||||
typ := dataVal.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
// Get the StructField first since this is a cheap operation. If the
|
||||
// field is unexported, then ignore it.
|
||||
f := typ.Field(i)
|
||||
if f.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Next get the actual value of this field and verify it is assignable
|
||||
// to the map value.
|
||||
v := dataVal.Field(i)
|
||||
if !v.Type().AssignableTo(valMap.Type().Elem()) {
|
||||
return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
|
||||
}
|
||||
|
||||
// Determine the name of the key in the map
|
||||
keyName := f.Name
|
||||
tagValue := f.Tag.Get(d.config.TagName)
|
||||
tagValue = strings.SplitN(tagValue, ",", 2)[0]
|
||||
if tagValue != "" {
|
||||
if tagValue == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
keyName = tagValue
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
// this is an embedded struct, so handle it differently
|
||||
case reflect.Struct:
|
||||
x := reflect.New(v.Type())
|
||||
x.Elem().Set(v)
|
||||
|
||||
vType := valMap.Type()
|
||||
vKeyType := vType.Key()
|
||||
vElemType := vType.Elem()
|
||||
mType := reflect.MapOf(vKeyType, vElemType)
|
||||
vMap := reflect.MakeMap(mType)
|
||||
|
||||
err := d.decode(keyName, x.Interface(), vMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
|
||||
|
||||
default:
|
||||
valMap.SetMapIndex(reflect.ValueOf(keyName), v)
|
||||
}
|
||||
}
|
||||
|
||||
if val.CanAddr() {
|
||||
val.Set(valMap)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
|
||||
// Create an element of the concrete (non pointer) type and decode
|
||||
// into that. Then set the value of the pointer to this type.
|
||||
valType := val.Type()
|
||||
valElemType := valType.Elem()
|
||||
|
||||
realVal := val
|
||||
if realVal.IsNil() || d.config.ZeroFields {
|
||||
realVal = reflect.New(valElemType)
|
||||
}
|
||||
if val.CanSet() {
|
||||
realVal := val
|
||||
if realVal.IsNil() || d.config.ZeroFields {
|
||||
realVal = reflect.New(valElemType)
|
||||
}
|
||||
|
||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(realVal)
|
||||
val.Set(realVal)
|
||||
} else {
|
||||
if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -614,7 +744,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||
val.Set(reflect.MakeSlice(sliceType, 0, 0))
|
||||
return nil
|
||||
}
|
||||
|
||||
case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
|
||||
return d.decodeSlice(name, []byte(dataVal.String()), val)
|
||||
// All other types we try to convert to the slice type
|
||||
// and "lift" it into it. i.e. a string becomes a string slice.
|
||||
default:
|
||||
@@ -622,7 +753,6 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||
return d.decodeSlice(name, []interface{}{data}, val)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
||||
|
||||
|
||||
162
vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
generated
vendored
162
vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
generated
vendored
@@ -1,48 +1,142 @@
|
||||
package mapstructure
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// GH-1
|
||||
// GH-1, GH-10, GH-96
|
||||
func TestDecode_NilValue(t *testing.T) {
|
||||
input := map[string]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in interface{}
|
||||
target interface{}
|
||||
out interface{}
|
||||
metaKeys []string
|
||||
metaUnused []string
|
||||
}{
|
||||
{
|
||||
"all nil",
|
||||
&map[string]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"partial nil",
|
||||
&map[string]interface{}{
|
||||
"vfoo": "baz",
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "baz", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"partial decode",
|
||||
&map[string]interface{}{
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "foo", Vother: nil},
|
||||
[]string{"Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"unused values",
|
||||
&map[string]interface{}{
|
||||
"vbar": "bar",
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{"vbar"},
|
||||
},
|
||||
{
|
||||
"map interface all nil",
|
||||
&map[interface{}]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"map interface partial nil",
|
||||
&map[interface{}]interface{}{
|
||||
"vfoo": "baz",
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "baz", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"map interface partial decode",
|
||||
&map[interface{}]interface{}{
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "foo", Vother: nil},
|
||||
[]string{"Vother"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"map interface unused values",
|
||||
&map[interface{}]interface{}{
|
||||
"vbar": "bar",
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
},
|
||||
&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
|
||||
&Map{Vfoo: "", Vother: nil},
|
||||
[]string{"Vfoo", "Vother"},
|
||||
[]string{"vbar"},
|
||||
},
|
||||
}
|
||||
|
||||
var result Map
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config := &DecoderConfig{
|
||||
Metadata: new(Metadata),
|
||||
Result: tc.target,
|
||||
ZeroFields: true,
|
||||
}
|
||||
|
||||
if result.Vfoo != "" {
|
||||
t.Fatalf("value should be default: %s", result.Vfoo)
|
||||
}
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vother != nil {
|
||||
t.Fatalf("Vother should be nil: %s", result.Vother)
|
||||
}
|
||||
}
|
||||
err = decoder.Decode(tc.in)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
|
||||
// GH-10
|
||||
func TestDecode_mapInterfaceInterface(t *testing.T) {
|
||||
input := map[interface{}]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
}
|
||||
if !reflect.DeepEqual(tc.out, tc.target) {
|
||||
t.Fatalf("%q: TestDecode_NilValue() expected: %#v, got: %#v", tc.name, tc.out, tc.target)
|
||||
}
|
||||
|
||||
var result Map
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(tc.metaKeys, config.Metadata.Keys) {
|
||||
t.Fatalf("%q: Metadata.Keys mismatch expected: %#v, got: %#v", tc.name, tc.metaKeys, config.Metadata.Keys)
|
||||
}
|
||||
|
||||
if result.Vfoo != "" {
|
||||
t.Fatalf("value should be default: %s", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vother != nil {
|
||||
t.Fatalf("Vother should be nil: %s", result.Vother)
|
||||
if !reflect.DeepEqual(tc.metaUnused, config.Metadata.Unused) {
|
||||
t.Fatalf("%q: Metadata.Unused mismatch expected: %#v, got: %#v", tc.name, tc.metaUnused, config.Metadata.Unused)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
340
vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
generated
vendored
340
vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
generated
vendored
@@ -128,6 +128,7 @@ type TypeConversionResult struct {
|
||||
FloatToBool bool
|
||||
FloatToString string
|
||||
SliceUint8ToString string
|
||||
StringToSliceUint8 []byte
|
||||
ArrayUint8ToString string
|
||||
StringToInt int
|
||||
StringToUint uint
|
||||
@@ -248,6 +249,32 @@ func TestBasic_Merge(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test for issue #46.
|
||||
func TestBasic_Struct(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vdata": map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
},
|
||||
}
|
||||
|
||||
var result, inner Basic
|
||||
result.Vdata = &inner
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
expected := Basic{
|
||||
Vdata: &Basic{
|
||||
Vstring: "foo",
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_BasicSquash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -626,6 +653,7 @@ func TestDecode_TypeConversion(t *testing.T) {
|
||||
"FloatToBool": 42.42,
|
||||
"FloatToString": 42.42,
|
||||
"SliceUint8ToString": []uint8("foo"),
|
||||
"StringToSliceUint8": "foo",
|
||||
"ArrayUint8ToString": [3]uint8{'f', 'o', 'o'},
|
||||
"StringToInt": "42",
|
||||
"StringToUint": "42",
|
||||
@@ -671,6 +699,7 @@ func TestDecode_TypeConversion(t *testing.T) {
|
||||
FloatToBool: true,
|
||||
FloatToString: "42.42",
|
||||
SliceUint8ToString: "foo",
|
||||
StringToSliceUint8: []byte("foo"),
|
||||
ArrayUint8ToString: "foo",
|
||||
StringToInt: 42,
|
||||
StringToUint: 42,
|
||||
@@ -926,6 +955,56 @@ func TestNestedTypePointer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test for issue #46.
|
||||
func TestNestedTypeInterface(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": &map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vint": 42,
|
||||
"vbool": true,
|
||||
|
||||
"vdata": map[string]interface{}{
|
||||
"vstring": "bar",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var result NestedPointer
|
||||
result.Vbar = new(Basic)
|
||||
result.Vbar.Vdata = new(Basic)
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vfoo != "foo" {
|
||||
t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vbar.Vstring != "foo" {
|
||||
t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring)
|
||||
}
|
||||
|
||||
if result.Vbar.Vint != 42 {
|
||||
t.Errorf("vint value should be 42: %#v", result.Vbar.Vint)
|
||||
}
|
||||
|
||||
if result.Vbar.Vbool != true {
|
||||
t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool)
|
||||
}
|
||||
|
||||
if result.Vbar.Vextra != "" {
|
||||
t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra)
|
||||
}
|
||||
|
||||
if result.Vbar.Vdata.(*Basic).Vstring != "bar" {
|
||||
t.Errorf("vstring value should be 'bar': %#v", result.Vbar.Vdata.(*Basic).Vstring)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1112,6 +1191,197 @@ func TestArrayToMap(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapOutputForStructuredInputs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in interface{}
|
||||
target interface{}
|
||||
out interface{}
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"basic struct input",
|
||||
&Basic{
|
||||
Vstring: "vstring",
|
||||
Vint: 2,
|
||||
Vuint: 3,
|
||||
Vbool: true,
|
||||
Vfloat: 4.56,
|
||||
Vextra: "vextra",
|
||||
vsilent: true,
|
||||
Vdata: []byte("data"),
|
||||
},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{
|
||||
"Vstring": "vstring",
|
||||
"Vint": 2,
|
||||
"Vuint": uint(3),
|
||||
"Vbool": true,
|
||||
"Vfloat": 4.56,
|
||||
"Vextra": "vextra",
|
||||
"Vdata": []byte("data"),
|
||||
"VjsonInt": 0,
|
||||
"VjsonFloat": 0.0,
|
||||
"VjsonNumber": json.Number(""),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"embedded struct input",
|
||||
&Embedded{
|
||||
Vunique: "vunique",
|
||||
Basic: Basic{
|
||||
Vstring: "vstring",
|
||||
Vint: 2,
|
||||
Vuint: 3,
|
||||
Vbool: true,
|
||||
Vfloat: 4.56,
|
||||
Vextra: "vextra",
|
||||
vsilent: true,
|
||||
Vdata: []byte("data"),
|
||||
},
|
||||
},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{
|
||||
"Vunique": "vunique",
|
||||
"Basic": map[string]interface{}{
|
||||
"Vstring": "vstring",
|
||||
"Vint": 2,
|
||||
"Vuint": uint(3),
|
||||
"Vbool": true,
|
||||
"Vfloat": 4.56,
|
||||
"Vextra": "vextra",
|
||||
"Vdata": []byte("data"),
|
||||
"VjsonInt": 0,
|
||||
"VjsonFloat": 0.0,
|
||||
"VjsonNumber": json.Number(""),
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"slice input - should error",
|
||||
[]string{"foo", "bar"},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"struct with slice property",
|
||||
&Slice{
|
||||
Vfoo: "vfoo",
|
||||
Vbar: []string{"foo", "bar"},
|
||||
},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{
|
||||
"Vfoo": "vfoo",
|
||||
"Vbar": []string{"foo", "bar"},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"struct with slice of struct property",
|
||||
&SliceOfStruct{
|
||||
Value: []Basic{
|
||||
Basic{
|
||||
Vstring: "vstring",
|
||||
Vint: 2,
|
||||
Vuint: 3,
|
||||
Vbool: true,
|
||||
Vfloat: 4.56,
|
||||
Vextra: "vextra",
|
||||
vsilent: true,
|
||||
Vdata: []byte("data"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{
|
||||
"Value": []Basic{
|
||||
Basic{
|
||||
Vstring: "vstring",
|
||||
Vint: 2,
|
||||
Vuint: 3,
|
||||
Vbool: true,
|
||||
Vfloat: 4.56,
|
||||
Vextra: "vextra",
|
||||
vsilent: true,
|
||||
Vdata: []byte("data"),
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"struct with map property",
|
||||
&Map{
|
||||
Vfoo: "vfoo",
|
||||
Vother: map[string]string{"vother": "vother"},
|
||||
},
|
||||
&map[string]interface{}{},
|
||||
&map[string]interface{}{
|
||||
"Vfoo": "vfoo",
|
||||
"Vother": map[string]string{
|
||||
"vother": "vother",
|
||||
}},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"tagged struct",
|
||||
&Tagged{
|
||||
Extra: "extra",
|
||||
Value: "value",
|
||||
},
|
||||
&map[string]string{},
|
||||
&map[string]string{
|
||||
"bar": "extra",
|
||||
"foo": "value",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"omit tag struct",
|
||||
&struct {
|
||||
Value string `mapstructure:"value"`
|
||||
Omit string `mapstructure:"-"`
|
||||
}{
|
||||
Value: "value",
|
||||
Omit: "omit",
|
||||
},
|
||||
&map[string]string{},
|
||||
&map[string]string{
|
||||
"value": "value",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"decode to wrong map type",
|
||||
&struct {
|
||||
Value string
|
||||
}{
|
||||
Value: "string",
|
||||
},
|
||||
&map[string]int{},
|
||||
&map[string]int{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := Decode(tt.in, tt.target); (err != nil) != tt.wantErr {
|
||||
t.Fatalf("%q: TestMapOutputForStructuredInputs() unexpected error: %s", tt.name, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tt.out, tt.target) {
|
||||
t.Fatalf("%q: TestMapOutputForStructuredInputs() expected: %#v, got: %#v", tt.name, tt.out, tt.target)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1171,6 +1441,39 @@ func TestInvalidType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"Vuint": 42,
|
||||
"foo": "bar",
|
||||
},
|
||||
"bar": "nil",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result Nested
|
||||
|
||||
err := DecodeMetadata(input, &result, &md)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err.Error())
|
||||
}
|
||||
|
||||
expectedKeys := []string{"Vbar", "Vbar.Vstring", "Vbar.Vuint", "Vfoo"}
|
||||
sort.Strings(md.Keys)
|
||||
if !reflect.DeepEqual(md.Keys, expectedKeys) {
|
||||
t.Fatalf("bad keys: %#v", md.Keys)
|
||||
}
|
||||
|
||||
expectedUnused := []string{"Vbar.foo", "bar"}
|
||||
if !reflect.DeepEqual(md.Unused, expectedUnused) {
|
||||
t.Fatalf("bad unused: %#v", md.Unused)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1311,6 +1614,43 @@ func TestWeakDecode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeakDecodeMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"foo": "4",
|
||||
"bar": "value",
|
||||
"unused": "value",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result struct {
|
||||
Foo int
|
||||
Bar string
|
||||
}
|
||||
|
||||
if err := WeakDecodeMetadata(input, &result, &md); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if result.Foo != 4 {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
if result.Bar != "value" {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
|
||||
expectedKeys := []string{"Bar", "Foo"}
|
||||
sort.Strings(md.Keys)
|
||||
if !reflect.DeepEqual(md.Keys, expectedKeys) {
|
||||
t.Fatalf("bad keys: %#v", md.Keys)
|
||||
}
|
||||
|
||||
expectedUnused := []string{"unused"}
|
||||
if !reflect.DeepEqual(md.Unused, expectedUnused) {
|
||||
t.Fatalf("bad unused: %#v", md.Unused)
|
||||
}
|
||||
}
|
||||
|
||||
func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) {
|
||||
var result Slice
|
||||
err := Decode(input, &result)
|
||||
|
||||
Reference in New Issue
Block a user