diff options
Diffstat (limited to 'scfg/unmarshal_test.go')
-rw-r--r-- | scfg/unmarshal_test.go | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/scfg/unmarshal_test.go b/scfg/unmarshal_test.go new file mode 100644 index 0000000..5b8df32 --- /dev/null +++ b/scfg/unmarshal_test.go @@ -0,0 +1,251 @@ +package scfg_test + +import ( + "fmt" + "log" + "reflect" + "strings" + "testing" + + "go.lindenii.runxiyu.org/lindenii-common/scfg" +) + +func ExampleDecoder() { + var data struct { + Foo int `scfg:"foo"` + Bar struct { + Param string `scfg:",param"` + Baz string `scfg:"baz"` + } `scfg:"bar"` + } + + raw := `foo 42 +bar asdf { + baz hello +} +` + + r := strings.NewReader(raw) + if err := scfg.NewDecoder(r).Decode(&data); err != nil { + log.Fatal(err) + } + + fmt.Printf("Foo = %v\n", data.Foo) + fmt.Printf("Bar.Param = %v\n", data.Bar.Param) + fmt.Printf("Bar.Baz = %v\n", data.Bar.Baz) + + // Output: + // Foo = 42 + // Bar.Param = asdf + // Bar.Baz = hello +} + +type nestedStructInner struct { + Bar string `scfg:"bar"` +} + +type structParams struct { + Params []string `scfg:",param"` + Bar string +} + +type textUnmarshaler struct { + text string +} + +func (tu *textUnmarshaler) UnmarshalText(text []byte) error { + tu.text = string(text) + return nil +} + +type textUnmarshalerParams struct { + Params []textUnmarshaler `scfg:",param"` +} + +var barStr = "bar" + +var unmarshalTests = []struct { + name string + raw string + want interface{} +}{ + { + name: "stringMap", + raw: `hello world +foo bar`, + want: map[string]string{ + "hello": "world", + "foo": "bar", + }, + }, + { + name: "simpleStruct", + raw: `MyString asdf +MyBool true +MyInt -42 +MyUint 42 +MyFloat 3.14`, + want: struct { + MyString string + MyBool bool + MyInt int + MyUint uint + MyFloat float32 + }{ + MyString: "asdf", + MyBool: true, + MyInt: -42, + MyUint: 42, + MyFloat: 3.14, + }, + }, + { + name: "simpleStructTag", + raw: `foo bar`, + want: struct { + Foo string `scfg:"foo"` + }{ + Foo: "bar", + }, + }, + { + name: "sliceParams", + raw: `Foo a s d f`, + want: struct { + Foo []string + }{ + Foo: []string{"a", "s", "d", "f"}, + }, + }, + { + name: "arrayParams", + raw: `Foo a s d f`, + want: struct { + Foo [4]string + }{ + Foo: [4]string{"a", "s", "d", "f"}, + }, + }, + { + name: "pointers", + raw: `Foo bar`, + want: struct { + Foo *string + }{ + Foo: &barStr, + }, + }, + { + name: "nestedMap", + raw: `foo { + bar baz +}`, + want: struct { + Foo map[string]string `scfg:"foo"` + }{ + Foo: map[string]string{"bar": "baz"}, + }, + }, + { + name: "nestedStruct", + raw: `foo { + bar baz +}`, + want: struct { + Foo nestedStructInner `scfg:"foo"` + }{ + Foo: nestedStructInner{ + Bar: "baz", + }, + }, + }, + { + name: "structParams", + raw: `Foo param1 param2 { + Bar baz +}`, + want: struct { + Foo structParams + }{ + Foo: structParams{ + Params: []string{"param1", "param2"}, + Bar: "baz", + }, + }, + }, + { + name: "textUnmarshaler", + raw: `Foo param1 +Bar param2 +Baz param3`, + want: struct { + Foo []textUnmarshaler + Bar *textUnmarshaler + Baz textUnmarshalerParams + }{ + Foo: []textUnmarshaler{{"param1"}}, + Bar: &textUnmarshaler{"param2"}, + Baz: textUnmarshalerParams{ + Params: []textUnmarshaler{{"param3"}}, + }, + }, + }, + { + name: "directiveStructSlice", + raw: `Foo param1 param2 { + Bar baz +} +Foo param3 param4`, + want: struct { + Foo []structParams + }{ + Foo: []structParams{ + { + Params: []string{"param1", "param2"}, + Bar: "baz", + }, + { + Params: []string{"param3", "param4"}, + }, + }, + }, + }, + { + name: "directiveMapSlice", + raw: `Foo { + key1 param1 +} +Foo { + key2 param2 +}`, + want: struct { + Foo []map[string]string + }{ + Foo: []map[string]string{ + {"key1": "param1"}, + {"key2": "param2"}, + }, + }, + }, +} + +func TestUnmarshal(t *testing.T) { + for _, tc := range unmarshalTests { + tc := tc // capture variable + t.Run(tc.name, func(t *testing.T) { + testUnmarshal(t, tc.raw, tc.want) + }) + } +} + +func testUnmarshal(t *testing.T, raw string, want interface{}) { + out := reflect.New(reflect.TypeOf(want)) + r := strings.NewReader(raw) + if err := scfg.NewDecoder(r).Decode(out.Interface()); err != nil { + t.Fatalf("Decode() = %v", err) + } + got := out.Elem().Interface() + if !reflect.DeepEqual(got, want) { + t.Errorf("Decode() = \n%#v\n but want \n%#v", got, want) + } +} |