-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinding_normalization_test.go
More file actions
170 lines (147 loc) · 4.25 KB
/
binding_normalization_test.go
File metadata and controls
170 lines (147 loc) · 4.25 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package rigging
import (
"reflect"
"testing"
)
// TestBindStruct_FieldNameNormalization tests that multi-word field names
// are properly normalized to match lowercase configuration keys.
func TestBindStruct_FieldNameNormalization(t *testing.T) {
tests := []struct {
name string
fieldName string
configKey string
value string
}{
{
name: "APIKey matches api_key",
fieldName: "APIKey",
configKey: "api_key",
value: "secret123",
},
{
name: "MaxConnections matches max_connections",
fieldName: "MaxConnections",
configKey: "max_connections",
value: "100",
},
{
name: "RetryTimeout matches retry_timeout",
fieldName: "RetryTimeout",
configKey: "retry_timeout",
value: "30s",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create a struct type dynamically for each test case
// For simplicity, we'll test with predefined struct types
})
}
}
// TestBindStruct_MultiWordFields tests binding with actual multi-word field names.
func TestBindStruct_MultiWordFields(t *testing.T) {
type Config struct {
APIKey string
MaxConnections int
RetryTimeout string
}
data := map[string]mergedEntry{
"api_key": {value: "secret123", sourceName: "env"},
"max_connections": {value: "100", sourceName: "file"},
"retry_timeout": {value: "30s", sourceName: "default"},
}
var cfg Config
var provFields []FieldProvenance
errors := bindStruct(reflect.ValueOf(&cfg), data, &provFields, "", "")
if len(errors) > 0 {
t.Fatalf("unexpected errors: %v", errors)
}
if cfg.APIKey != "secret123" {
t.Errorf("APIKey = %q, want %q", cfg.APIKey, "secret123")
}
if cfg.MaxConnections != 100 {
t.Errorf("MaxConnections = %d, want %d", cfg.MaxConnections, 100)
}
if cfg.RetryTimeout != "30s" {
t.Errorf("RetryTimeout = %q, want %q", cfg.RetryTimeout, "30s")
}
// Verify provenance
if len(provFields) != 3 {
t.Fatalf("provenance fields = %d, want 3", len(provFields))
}
}
// TestBindStruct_PrefixNormalization tests that prefix tags are normalized.
func TestBindStruct_PrefixNormalization(t *testing.T) {
type DatabaseConfig struct {
Host string
Port int
}
type Config struct {
Database DatabaseConfig `conf:"prefix:DATABASE"` // Uppercase prefix
}
data := map[string]mergedEntry{
"database.host": {value: "localhost", sourceName: "file"},
"database.port": {value: "5432", sourceName: "file"},
}
var cfg Config
var provFields []FieldProvenance
errors := bindStruct(reflect.ValueOf(&cfg), data, &provFields, "", "")
if len(errors) > 0 {
t.Fatalf("unexpected errors: %v", errors)
}
if cfg.Database.Host != "localhost" {
t.Errorf("Database.Host = %q, want %q", cfg.Database.Host, "localhost")
}
if cfg.Database.Port != 5432 {
t.Errorf("Database.Port = %d, want %d", cfg.Database.Port, 5432)
}
}
// TestBindStruct_CustomNameNormalization tests that name tags are normalized.
func TestBindStruct_CustomNameNormalization(t *testing.T) {
type Config struct {
APIKey string `conf:"name:API.KEY"` // Uppercase in tag
}
data := map[string]mergedEntry{
"api.key": {value: "secret123", sourceName: "env"},
}
var cfg Config
var provFields []FieldProvenance
errors := bindStruct(reflect.ValueOf(&cfg), data, &provFields, "", "")
if len(errors) > 0 {
t.Fatalf("unexpected errors: %v", errors)
}
if cfg.APIKey != "secret123" {
t.Errorf("APIKey = %q, want %q", cfg.APIKey, "secret123")
}
// Verify provenance uses normalized key
if len(provFields) != 1 {
t.Fatalf("provenance fields = %d, want 1", len(provFields))
}
if provFields[0].KeyPath != "api.key" {
t.Errorf("KeyPath = %q, want %q", provFields[0].KeyPath, "api.key")
}
}
// TestDeriveFieldKey tests the field key derivation function.
func TestDeriveFieldKey(t *testing.T) {
tests := []struct {
fieldName string
want string
}{
{"Host", "host"},
{"Port", "port"},
{"APIKey", "api_key"},
{"MaxConnections", "max_connections"},
{"RetryTimeout", "retry_timeout"},
{"HTTPServer", "http_server"},
{"URLPath", "url_path"},
{"", ""},
}
for _, tt := range tests {
t.Run(tt.fieldName, func(t *testing.T) {
got := deriveFieldKey(tt.fieldName)
if got != tt.want {
t.Errorf("deriveFieldKey(%q) = %q, want %q", tt.fieldName, got, tt.want)
}
})
}
}