1package flags
2
3import (
4	"bytes"
5	"encoding/json"
6	"fmt"
7	"path"
8	"reflect"
9	"strings"
10	"testing"
11
12	"github.com/mitchellh/mapstructure"
13)
14
15func TestConfigUtil_Values(t *testing.T) {
16	t.Parallel()
17	type config struct {
18		B BoolValue     `mapstructure:"bool"`
19		D DurationValue `mapstructure:"duration"`
20		S StringValue   `mapstructure:"string"`
21		U UintValue     `mapstructure:"uint"`
22	}
23
24	cases := []struct {
25		in      string
26		success string
27		failure string
28	}{
29		{
30			`{ }`,
31			`"false" "0s" "" "0"`,
32			"",
33		},
34		{
35			`{ "bool": true, "duration": "2h", "string": "hello", "uint": 23 }`,
36			`"true" "2h0m0s" "hello" "23"`,
37			"",
38		},
39		{
40			`{ "bool": "nope" }`,
41			"",
42			"got 'string'",
43		},
44		{
45			`{ "duration": "nope" }`,
46			"",
47			`invalid duration "nope"`,
48		},
49		{
50			`{ "string": 123 }`,
51			"",
52			"got 'float64'",
53		},
54		{
55			`{ "uint": -1 }`,
56			"",
57			"value cannot be negative",
58		},
59		{
60			`{ "uint": 4294967296 }`,
61			"",
62			"value is too large",
63		},
64	}
65	for i, c := range cases {
66		var raw interface{}
67		dec := json.NewDecoder(bytes.NewBufferString(c.in))
68		if err := dec.Decode(&raw); err != nil {
69			t.Fatalf("(case %d) err: %v", i, err)
70		}
71
72		var r config
73		msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
74			DecodeHook:  ConfigDecodeHook,
75			Result:      &r,
76			ErrorUnused: true,
77		})
78		if err != nil {
79			t.Fatalf("(case %d) err: %v", i, err)
80		}
81
82		err = msdec.Decode(raw)
83		if c.failure != "" {
84			if err == nil || !strings.Contains(err.Error(), c.failure) {
85				t.Fatalf("(case %d) err: %v", i, err)
86			}
87			continue
88		}
89		if err != nil {
90			t.Fatalf("(case %d) err: %v", i, err)
91		}
92
93		actual := fmt.Sprintf("%q %q %q %q",
94			r.B.String(),
95			r.D.String(),
96			r.S.String(),
97			r.U.String())
98		if actual != c.success {
99			t.Fatalf("(case %d) bad: %s", i, actual)
100		}
101	}
102}
103
104func TestConfigUtil_Visit(t *testing.T) {
105	t.Parallel()
106	var trail []string
107	visitor := func(path string) error {
108		trail = append(trail, path)
109		return nil
110	}
111
112	basePath := "../../test/command/merge"
113	if err := Visit(basePath, visitor); err != nil {
114		t.Fatalf("err: %v", err)
115	}
116	if err := Visit(path.Join(basePath, "subdir", "c.json"), visitor); err != nil {
117		t.Fatalf("err: %v", err)
118	}
119
120	expected := []string{
121		path.Join(basePath, "a.json"),
122		path.Join(basePath, "b.json"),
123		path.Join(basePath, "nope"),
124		path.Join(basePath, "zero.json"),
125		path.Join(basePath, "subdir", "c.json"),
126	}
127	if !reflect.DeepEqual(trail, expected) {
128		t.Fatalf("bad: %#v", trail)
129	}
130}
131