-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathusage_test.go
More file actions
144 lines (118 loc) · 4.8 KB
/
Copy pathusage_test.go
File metadata and controls
144 lines (118 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package uconfig_test
import (
"bytes"
"encoding/json"
"os"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/omeid/uconfig"
"github.com/omeid/uconfig/flat"
"github.com/omeid/uconfig/internal/f"
"github.com/omeid/uconfig/paths"
"github.com/omeid/uconfig/plugins"
"github.com/omeid/uconfig/plugins/file"
"github.com/omeid/uconfig/plugins/fileset"
"github.com/omeid/uconfig/plugins/secret"
)
const expectedUsageMessage = `Usage:
uconfig.test [flags] [command]
FIELDS FLAG ENV DEFAULT GOODPLUGIN SECRET USAGE
------ ----- ----- ------- ---------- ------ -----
Version -version VERSION Version
GoHard -gohard GOHARD GoHard
Redis.Address -redis-address REDIS_ADDRESS Redis.Address
Redis.Port -redis-port REDIS_PORT Redis.Port
Rethink.Host.Address -rethink-host-address RETHINK_HOST_ADDRESS Rethink.Host.Address
Rethink.Host.Port -rethink-host-port RETHINK_HOST_PORT Rethink.Host.Port
Rethink.Db -rethink-db RETHINK_DB primary Rethink.Db main database used by our application
Rethink.Password -rethink-password RETHINK_PASSWORD Rethink.Password RETHINK_PASSWORD
Apps -apps APPS Apps
Command [command] COMMAND run Command
Files:
absolute: /etc/app/config.yaml
relative: config.json
FOLDED TYPE USAGE
------ ---- -----
Webhooks []f.Webhook
.URL string destination url
.Events []string list of events to subscribe to
`
type UselessPluginVisitor struct {
plugins.Plugin
}
func (*UselessPluginVisitor) Parse() error { return nil }
func (*UselessPluginVisitor) Visit(fields flat.Fields) error {
for _, f := range fields {
name, _ := f.Name("goodplugin")
f.Meta()["goodplugin"] = name
}
return nil
}
var files = uconfig.Files{
{Path: file.Absolute("/etc/app/config.yaml"), Unmarshal: json.Unmarshal, Optional: true},
{Path: file.Relative("config.json"), Unmarshal: json.Unmarshal, Optional: true}, // just for testing of file listing.
}
func TestUsage(t *testing.T) {
// Isolate from go test flags
oldArgs := os.Args
os.Args = []string{"uconfig.test"}
defer func() { os.Args = oldArgs }()
var stdout bytes.Buffer
uconfig.UsageOutput = &stdout
defer func() {
if r := recover(); r != nil {
t.Errorf("Usage should not panic, but did: %v", r)
}
}()
// good plugin is used just so that we have more than
// one tag/field that isn't pre-weighted in "usage".
noopPlugin := &UselessPluginVisitor{}
secretProvider := func(name string) (string, error) { return "top secret token", nil }
// the test creates an ad-hoc implementation of paths.Set:
fsPluginAbs := fileset.New("apps", mockSet{
name: "testdata/etc/app/*.yaml",
kind: paths.Absolute,
resolve: func() ([]string, error) {
return []string{"testdata/etc/app/match1.yml", "testdata/etc/app/match2.yml"}, nil
},
}, json.Unmarshal)
fsPluginRel := fileset.New("apps", mockSet{
name: "testdata/apps.d/*.json",
kind: paths.Relative,
resolve: func() ([]string, error) {
return []string{"testdata/apps.d/a.json", "testdata/apps.d/b.json"}, nil
},
}, json.Unmarshal)
type UsageConfig struct {
f.Config
Apps []string `fileset:"apps"`
}
conf := uconfig.Classic[UsageConfig](files, secret.New(secretProvider), noopPlugin, fsPluginAbs, fsPluginRel)
_, err := conf.Parse()
if err != nil {
t.Fatal(err)
}
if size := stdout.Len(); size != 0 {
t.Fatalf(
"Expected nothing in UsageOutput before usage, got len: %v\n%s",
size,
stdout.String(),
)
}
conf.Usage()
output := stdout.String()
if diff := cmp.Diff(expectedUsageMessage, output); diff != "" {
t.Fatalf(
"Expected Usage Output to be same as expectedUsageMessage:\n%s",
diff,
)
}
}
type mockSet struct {
name string
kind paths.Kind
resolve func() ([]string, error)
}
func (m mockSet) Name() string { return m.name }
func (m mockSet) Kind() paths.Kind { return m.kind }
func (m mockSet) Resolve() ([]string, error) { return m.resolve() }