...

Source file src/github.com/magiconair/properties/decode_test.go

Documentation: github.com/magiconair/properties

     1  // Copyright 2013-2022 Frank Schroeder. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package properties
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestDecodeValues(t *testing.T) {
    14  	type S struct {
    15  		S   string
    16  		BT  bool
    17  		BF  bool
    18  		I   int
    19  		I8  int8
    20  		I16 int16
    21  		I32 int32
    22  		I64 int64
    23  		U   uint
    24  		U8  uint8
    25  		U16 uint16
    26  		U32 uint32
    27  		U64 uint64
    28  		F32 float32
    29  		F64 float64
    30  		D   time.Duration
    31  		TM  time.Time
    32  	}
    33  	in := `
    34  	S=abc
    35  	BT=true
    36  	BF=false
    37  	I=-1
    38  	I8=-8
    39  	I16=-16
    40  	I32=-32
    41  	I64=-64
    42  	U=1
    43  	U8=8
    44  	U16=16
    45  	U32=32
    46  	U64=64
    47  	F32=3.2
    48  	F64=6.4
    49  	D=5s
    50  	TM=2015-01-02T12:34:56Z
    51  	`
    52  	out := &S{
    53  		S:   "abc",
    54  		BT:  true,
    55  		BF:  false,
    56  		I:   -1,
    57  		I8:  -8,
    58  		I16: -16,
    59  		I32: -32,
    60  		I64: -64,
    61  		U:   1,
    62  		U8:  8,
    63  		U16: 16,
    64  		U32: 32,
    65  		U64: 64,
    66  		F32: 3.2,
    67  		F64: 6.4,
    68  		D:   5 * time.Second,
    69  		TM:  tm(t, time.RFC3339, "2015-01-02T12:34:56Z"),
    70  	}
    71  	testDecode(t, in, &S{}, out)
    72  }
    73  
    74  func TestDecodeValueDefaults(t *testing.T) {
    75  	type S struct {
    76  		S   string        `properties:",default=abc"`
    77  		BT  bool          `properties:",default=true"`
    78  		BF  bool          `properties:",default=false"`
    79  		I   int           `properties:",default=-1"`
    80  		I8  int8          `properties:",default=-8"`
    81  		I16 int16         `properties:",default=-16"`
    82  		I32 int32         `properties:",default=-32"`
    83  		I64 int64         `properties:",default=-64"`
    84  		U   uint          `properties:",default=1"`
    85  		U8  uint8         `properties:",default=8"`
    86  		U16 uint16        `properties:",default=16"`
    87  		U32 uint32        `properties:",default=32"`
    88  		U64 uint64        `properties:",default=64"`
    89  		F32 float32       `properties:",default=3.2"`
    90  		F64 float64       `properties:",default=6.4"`
    91  		D   time.Duration `properties:",default=5s"`
    92  		TM  time.Time     `properties:",default=2015-01-02T12:34:56Z"`
    93  	}
    94  	out := &S{
    95  		S:   "abc",
    96  		BT:  true,
    97  		BF:  false,
    98  		I:   -1,
    99  		I8:  -8,
   100  		I16: -16,
   101  		I32: -32,
   102  		I64: -64,
   103  		U:   1,
   104  		U8:  8,
   105  		U16: 16,
   106  		U32: 32,
   107  		U64: 64,
   108  		F32: 3.2,
   109  		F64: 6.4,
   110  		D:   5 * time.Second,
   111  		TM:  tm(t, time.RFC3339, "2015-01-02T12:34:56Z"),
   112  	}
   113  	testDecode(t, "", &S{}, out)
   114  }
   115  
   116  func TestDecodeArrays(t *testing.T) {
   117  	type S struct {
   118  		S   []string
   119  		B   []bool
   120  		I   []int
   121  		I8  []int8
   122  		I16 []int16
   123  		I32 []int32
   124  		I64 []int64
   125  		U   []uint
   126  		U8  []uint8
   127  		U16 []uint16
   128  		U32 []uint32
   129  		U64 []uint64
   130  		F32 []float32
   131  		F64 []float64
   132  		D   []time.Duration
   133  		TM  []time.Time
   134  	}
   135  	in := `
   136  	S=a;b
   137  	B=true;false
   138  	I=-1;-2
   139  	I8=-8;-9
   140  	I16=-16;-17
   141  	I32=-32;-33
   142  	I64=-64;-65
   143  	U=1;2
   144  	U8=8;9
   145  	U16=16;17
   146  	U32=32;33
   147  	U64=64;65
   148  	F32=3.2;3.3
   149  	F64=6.4;6.5
   150  	D=4s;5s
   151  	TM=2015-01-01T00:00:00Z;2016-01-01T00:00:00Z
   152  	`
   153  	out := &S{
   154  		S:   []string{"a", "b"},
   155  		B:   []bool{true, false},
   156  		I:   []int{-1, -2},
   157  		I8:  []int8{-8, -9},
   158  		I16: []int16{-16, -17},
   159  		I32: []int32{-32, -33},
   160  		I64: []int64{-64, -65},
   161  		U:   []uint{1, 2},
   162  		U8:  []uint8{8, 9},
   163  		U16: []uint16{16, 17},
   164  		U32: []uint32{32, 33},
   165  		U64: []uint64{64, 65},
   166  		F32: []float32{3.2, 3.3},
   167  		F64: []float64{6.4, 6.5},
   168  		D:   []time.Duration{4 * time.Second, 5 * time.Second},
   169  		TM:  []time.Time{tm(t, time.RFC3339, "2015-01-01T00:00:00Z"), tm(t, time.RFC3339, "2016-01-01T00:00:00Z")},
   170  	}
   171  	testDecode(t, in, &S{}, out)
   172  }
   173  
   174  func TestDecodeArrayDefaults(t *testing.T) {
   175  	type S struct {
   176  		S   []string        `properties:",default=a;b"`
   177  		B   []bool          `properties:",default=true;false"`
   178  		I   []int           `properties:",default=-1;-2"`
   179  		I8  []int8          `properties:",default=-8;-9"`
   180  		I16 []int16         `properties:",default=-16;-17"`
   181  		I32 []int32         `properties:",default=-32;-33"`
   182  		I64 []int64         `properties:",default=-64;-65"`
   183  		U   []uint          `properties:",default=1;2"`
   184  		U8  []uint8         `properties:",default=8;9"`
   185  		U16 []uint16        `properties:",default=16;17"`
   186  		U32 []uint32        `properties:",default=32;33"`
   187  		U64 []uint64        `properties:",default=64;65"`
   188  		F32 []float32       `properties:",default=3.2;3.3"`
   189  		F64 []float64       `properties:",default=6.4;6.5"`
   190  		D   []time.Duration `properties:",default=4s;5s"`
   191  		TM  []time.Time     `properties:",default=2015-01-01T00:00:00Z;2016-01-01T00:00:00Z"`
   192  	}
   193  	out := &S{
   194  		S:   []string{"a", "b"},
   195  		B:   []bool{true, false},
   196  		I:   []int{-1, -2},
   197  		I8:  []int8{-8, -9},
   198  		I16: []int16{-16, -17},
   199  		I32: []int32{-32, -33},
   200  		I64: []int64{-64, -65},
   201  		U:   []uint{1, 2},
   202  		U8:  []uint8{8, 9},
   203  		U16: []uint16{16, 17},
   204  		U32: []uint32{32, 33},
   205  		U64: []uint64{64, 65},
   206  		F32: []float32{3.2, 3.3},
   207  		F64: []float64{6.4, 6.5},
   208  		D:   []time.Duration{4 * time.Second, 5 * time.Second},
   209  		TM:  []time.Time{tm(t, time.RFC3339, "2015-01-01T00:00:00Z"), tm(t, time.RFC3339, "2016-01-01T00:00:00Z")},
   210  	}
   211  	testDecode(t, "", &S{}, out)
   212  }
   213  
   214  func TestDecodeSkipUndef(t *testing.T) {
   215  	type S struct {
   216  		X     string `properties:"-"`
   217  		Undef string `properties:",default=some value"`
   218  	}
   219  	in := `X=ignore`
   220  	out := &S{"", "some value"}
   221  	testDecode(t, in, &S{}, out)
   222  }
   223  
   224  func TestDecodeStruct(t *testing.T) {
   225  	type A struct {
   226  		S string
   227  		T string `properties:"t"`
   228  		U string `properties:"u,default=uuu"`
   229  	}
   230  	type S struct {
   231  		A A
   232  		B A `properties:"b"`
   233  	}
   234  	in := `
   235  	A.S=sss
   236  	A.t=ttt
   237  	b.S=SSS
   238  	b.t=TTT
   239  	`
   240  	out := &S{
   241  		A{S: "sss", T: "ttt", U: "uuu"},
   242  		A{S: "SSS", T: "TTT", U: "uuu"},
   243  	}
   244  	testDecode(t, in, &S{}, out)
   245  }
   246  
   247  func TestDecodeMap(t *testing.T) {
   248  	type S struct {
   249  		A string `properties:"a"`
   250  	}
   251  	type X struct {
   252  		A map[string]string
   253  		B map[string][]string
   254  		C map[string]map[string]string
   255  		D map[string]S
   256  		E map[string]int
   257  		F map[string]int `properties:"-"`
   258  	}
   259  	in := `
   260  	A.foo=bar
   261  	A.bar=bang
   262  	B.foo=a;b;c
   263  	B.bar=1;2;3
   264  	C.foo.one=1
   265  	C.foo.two=2
   266  	C.bar.three=3
   267  	C.bar.four=4
   268  	D.foo.a=bar
   269  	`
   270  	out := &X{
   271  		A: map[string]string{"foo": "bar", "bar": "bang"},
   272  		B: map[string][]string{"foo": {"a", "b", "c"}, "bar": {"1", "2", "3"}},
   273  		C: map[string]map[string]string{"foo": {"one": "1", "two": "2"}, "bar": {"three": "3", "four": "4"}},
   274  		D: map[string]S{"foo": {"bar"}},
   275  		E: map[string]int{},
   276  	}
   277  	testDecode(t, in, &X{}, out)
   278  }
   279  
   280  func testDecode(t *testing.T, in string, v, out interface{}) {
   281  	p, err := parse(in)
   282  	if err != nil {
   283  		t.Fatalf("got %v want nil", err)
   284  	}
   285  	if err := p.Decode(v); err != nil {
   286  		t.Fatalf("got %v want nil", err)
   287  	}
   288  	if got, want := v, out; !reflect.DeepEqual(got, want) {
   289  		t.Fatalf("\ngot  %+v\nwant %+v", got, want)
   290  	}
   291  }
   292  
   293  func tm(t *testing.T, layout, s string) time.Time {
   294  	tm, err := time.Parse(layout, s)
   295  	if err != nil {
   296  		t.Fatalf("got %v want nil", err)
   297  	}
   298  	return tm
   299  }
   300  

View as plain text