You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
5.9 KiB
319 lines
5.9 KiB
package config |
|
|
|
import ( |
|
"fmt" |
|
"reflect" |
|
"testing" |
|
|
|
"github.com/go-kratos/kratos/v2/encoding" |
|
) |
|
|
|
func TestReader_Merge(t *testing.T) { |
|
var ( |
|
err error |
|
ok bool |
|
) |
|
opts := options{ |
|
decoder: func(kv *KeyValue, v map[string]interface{}) error { |
|
if codec := encoding.GetCodec(kv.Format); codec != nil { |
|
return codec.Unmarshal(kv.Value, &v) |
|
} |
|
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format) |
|
}, |
|
resolver: defaultResolver, |
|
} |
|
r := newReader(opts) |
|
err = r.Merge(&KeyValue{ |
|
Key: "a", |
|
Value: []byte("bad"), |
|
Format: "json", |
|
}) |
|
if err == nil { |
|
t.Fatal(`err is nil`) |
|
} |
|
|
|
err = r.Merge(&KeyValue{ |
|
Key: "b", |
|
Value: []byte(`{"nice": "boat", "x": 1}`), |
|
Format: "json", |
|
}) |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
vv, ok := r.Value("nice") |
|
if !ok { |
|
t.Fatal(`ok is false`) |
|
} |
|
vvv, err := vv.String() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if vvv != "boat" { |
|
t.Fatal(`vvv is not equal to "boat"`) |
|
} |
|
|
|
err = r.Merge(&KeyValue{ |
|
Key: "b", |
|
Value: []byte(`{"x": 2}`), |
|
Format: "json", |
|
}) |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
vv, ok = r.Value("x") |
|
if !ok { |
|
t.Fatal(`ok is false`) |
|
} |
|
vvx, err := vv.Int() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if int64(2) != vvx { |
|
t.Fatal(`vvx is not equal to 2`) |
|
} |
|
} |
|
|
|
func TestReader_Value(t *testing.T) { |
|
opts := options{ |
|
decoder: func(kv *KeyValue, v map[string]interface{}) error { |
|
if codec := encoding.GetCodec(kv.Format); codec != nil { |
|
return codec.Unmarshal(kv.Value, &v) |
|
} |
|
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format) |
|
}, |
|
resolver: defaultResolver, |
|
} |
|
|
|
ymlval := ` |
|
a: |
|
b: |
|
X: 1 |
|
Y: "lol" |
|
z: true |
|
` |
|
tests := []struct { |
|
name string |
|
kv KeyValue |
|
}{ |
|
{ |
|
name: "json value", |
|
kv: KeyValue{ |
|
Key: "config", |
|
Value: []byte(`{"a": {"b": {"X": 1, "Y": "lol", "z": true}}}`), |
|
Format: "json", |
|
}, |
|
}, |
|
{ |
|
name: "yaml value", |
|
kv: KeyValue{ |
|
Key: "config", |
|
Value: []byte(ymlval), |
|
Format: "yaml", |
|
}, |
|
}, |
|
} |
|
|
|
for _, test := range tests { |
|
t.Run(test.name, func(t *testing.T) { |
|
r := newReader(opts) |
|
err := r.Merge(&test.kv) |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
vv, ok := r.Value("a.b.X") |
|
if !ok { |
|
t.Fatal(`ok is false`) |
|
} |
|
vvv, err := vv.Int() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if int64(1) != vvv { |
|
t.Fatal(`vvv is not equal to 1`) |
|
} |
|
|
|
vv, ok = r.Value("a.b.Y") |
|
if !ok { |
|
t.Fatal(`ok is false`) |
|
} |
|
vvy, err := vv.String() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if vvy != "lol" { |
|
t.Fatal(`vvy is not equal to "lol"`) |
|
} |
|
|
|
vv, ok = r.Value("a.b.z") |
|
if !ok { |
|
t.Fatal(`ok is false`) |
|
} |
|
vvz, err := vv.Bool() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if !vvz { |
|
t.Fatal(`vvz is not equal to true`) |
|
} |
|
|
|
_, ok = r.Value("aasasdg=234l.asdfk,") |
|
if ok { |
|
t.Fatal(`ok is true`) |
|
} |
|
|
|
_, ok = r.Value("aas......asdg=234l.asdfk,") |
|
if ok { |
|
t.Fatal(`ok is true`) |
|
} |
|
|
|
_, ok = r.Value("a.b.Y.") |
|
if ok { |
|
t.Fatal(`ok is true`) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func TestReader_Source(t *testing.T) { |
|
var err error |
|
opts := options{ |
|
decoder: func(kv *KeyValue, v map[string]interface{}) error { |
|
if codec := encoding.GetCodec(kv.Format); codec != nil { |
|
return codec.Unmarshal(kv.Value, &v) |
|
} |
|
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format) |
|
}, |
|
resolver: defaultResolver, |
|
} |
|
r := newReader(opts) |
|
err = r.Merge(&KeyValue{ |
|
Key: "b", |
|
Value: []byte(`{"a": {"b": {"X": 1}}}`), |
|
Format: "json", |
|
}) |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
b, err := r.Source() |
|
if err != nil { |
|
t.Fatal(`err is not nil`) |
|
} |
|
if !reflect.DeepEqual([]byte(`{"a":{"b":{"X":1}}}`), b) { |
|
t.Fatal("[]byte(`{\"a\":{\"b\":{\"X\":1}}}`) is not equal to b") |
|
} |
|
} |
|
|
|
func TestCloneMap(t *testing.T) { |
|
tests := []struct { |
|
input map[string]interface{} |
|
want map[string]interface{} |
|
}{ |
|
{ |
|
input: map[string]interface{}{ |
|
"a": 1, |
|
"b": "2", |
|
"c": true, |
|
}, |
|
want: map[string]interface{}{ |
|
"a": 1, |
|
"b": "2", |
|
"c": true, |
|
}, |
|
}, |
|
{ |
|
input: map[string]interface{}{}, |
|
want: map[string]interface{}{}, |
|
}, |
|
{ |
|
input: nil, |
|
want: map[string]interface{}{}, |
|
}, |
|
} |
|
for _, tt := range tests { |
|
if got, err := cloneMap(tt.input); err != nil { |
|
t.Errorf("expect no err, got %v", err) |
|
} else if !reflect.DeepEqual(got, tt.want) { |
|
t.Errorf("cloneMap(%v) = %v, want %v", tt.input, got, tt.want) |
|
} |
|
} |
|
} |
|
|
|
func TestConvertMap(t *testing.T) { |
|
tests := []struct { |
|
input interface{} |
|
want interface{} |
|
}{ |
|
{ |
|
input: map[string]interface{}{ |
|
"a": 1, |
|
"b": "2", |
|
"c": true, |
|
"d": []byte{65, 66, 67}, |
|
}, |
|
want: map[string]interface{}{ |
|
"a": 1, |
|
"b": "2", |
|
"c": true, |
|
"d": "ABC", |
|
}, |
|
}, |
|
{ |
|
input: []interface{}{1, 2.0, "3", true, nil, []interface{}{1, 2.0, "3", true, nil}}, |
|
want: []interface{}{1, 2.0, "3", true, nil, []interface{}{1, 2.0, "3", true, nil}}, |
|
}, |
|
{ |
|
input: []byte{65, 66, 67}, |
|
want: "ABC", |
|
}, |
|
} |
|
for _, tt := range tests { |
|
if got := convertMap(tt.input); !reflect.DeepEqual(got, tt.want) { |
|
t.Errorf("convertMap(%v) = %v, want %v", tt.input, got, tt.want) |
|
} |
|
} |
|
} |
|
|
|
func TestReadValue(t *testing.T) { |
|
m := map[string]interface{}{ |
|
"a": 1, |
|
"b": map[string]interface{}{ |
|
"c": "3", |
|
"d": map[string]interface{}{ |
|
"e": true, |
|
}, |
|
}, |
|
} |
|
va := atomicValue{} |
|
va.Store(1) |
|
|
|
vbc := atomicValue{} |
|
vbc.Store("3") |
|
|
|
vbde := atomicValue{} |
|
vbde.Store(true) |
|
|
|
tests := []struct { |
|
path string |
|
want atomicValue |
|
}{ |
|
{ |
|
path: "a", |
|
want: va, |
|
}, |
|
{ |
|
path: "b.c", |
|
want: vbc, |
|
}, |
|
{ |
|
path: "b.d.e", |
|
want: vbde, |
|
}, |
|
} |
|
for _, tt := range tests { |
|
if got, found := readValue(m, tt.path); !found { |
|
t.Errorf("expect found %v in %v, but not.", tt.path, m) |
|
} else if got.Load() != tt.want.Load() { |
|
t.Errorf("readValue(%v, %v) = %v, want %v", m, tt.path, got, tt.want) |
|
} |
|
} |
|
}
|
|
|