4
4
"context"
5
5
"fmt"
6
6
"os"
7
+ "reflect"
7
8
"testing"
8
9
"time"
9
10
@@ -14,21 +15,48 @@ import (
14
15
)
15
16
16
17
var provider * unleashProvider.Provider
18
+ var ofClient * of.Client
17
19
18
20
func TestBooleanEvaluation (t * testing.T ) {
19
21
resolution := provider .BooleanEvaluation (context .Background (), "variant-flag" , false , nil )
20
22
enabled , _ := resolution .ProviderResolutionDetail .FlagMetadata .GetBool ("enabled" )
21
- if enabled == false {
23
+ if ! enabled {
24
+ t .Fatalf ("Expected feature to be enabled" )
25
+ }
26
+ if ! resolution .Value {
27
+ t .Fatalf ("Expected one of the variant payloads" )
28
+ }
29
+
30
+ t .Run ("evalCtx empty" , func (t * testing.T ) {
31
+ resolution := provider .BooleanEvaluation (context .Background (), "non-existing-flag" , false , nil )
32
+ require .Equal (t , false , resolution .Value )
33
+ })
34
+
35
+ t .Run ("evalCtx empty fallback to default" , func (t * testing.T ) {
36
+ resolution := provider .BooleanEvaluation (context .Background (), "non-existing-flag" , true , nil )
37
+ require .Equal (t , true , resolution .Value )
38
+ })
39
+ }
40
+
41
+ func TestIntEvaluation (t * testing.T ) {
42
+ resolution := provider .BooleanEvaluation (context .Background (), "int-flag" , false , nil )
43
+ enabled , _ := resolution .ProviderResolutionDetail .FlagMetadata .GetBool ("enabled" )
44
+ if ! enabled {
22
45
t .Fatalf ("Expected feature to be enabled" )
23
46
}
24
- if resolution .Value != true {
47
+ if ! resolution .Value {
25
48
t .Fatalf ("Expected one of the variant payloads" )
26
49
}
27
50
28
51
t .Run ("evalCtx empty" , func (t * testing.T ) {
29
52
resolution := provider .BooleanEvaluation (context .Background (), "non-existing-flag" , false , nil )
30
53
require .Equal (t , false , resolution .Value )
31
54
})
55
+
56
+ t .Run ("evalCtx empty fallback to default" , func (t * testing.T ) {
57
+ resolution := provider .BooleanEvaluation (context .Background (), "non-existing-flag" , true , nil )
58
+ require .Equal (t , true , resolution .Value )
59
+ })
32
60
}
33
61
34
62
func TestStringEvaluation (t * testing.T ) {
@@ -44,9 +72,6 @@ func TestStringEvaluation(t *testing.T) {
44
72
t .Fatalf ("Expected one of the variant payloads" )
45
73
}
46
74
47
- of .SetProvider (provider )
48
- ofClient := of .NewClient ("my-app" )
49
-
50
75
evalCtx := of .NewEvaluationContext (
51
76
"" ,
52
77
map [string ]interface {}{},
@@ -74,13 +99,15 @@ func TestBooleanEvaluationByUser(t *testing.T) {
74
99
t .Fatalf ("Expected feature to be disabled" )
75
100
}
76
101
77
- of .SetProvider (provider )
78
- ofClient := of .NewClient ("my-app" )
79
-
80
102
evalCtx := of .NewEvaluationContext (
81
103
"" ,
82
104
map [string ]interface {}{
83
- "UserId" : "111" ,
105
+ "UserId" : "111" ,
106
+ "AppName" : "test-app" ,
107
+ "CurrentTime" : "2006-01-02T15:04:05Z" ,
108
+ "Environment" : "test-env" ,
109
+ "RemoteAddress" : "1.2.3.4" ,
110
+ "SessionId" : "test-session" ,
84
111
},
85
112
)
86
113
enabled , _ = ofClient .BooleanValue (context .Background (), "users-flag" , false , evalCtx )
@@ -89,6 +116,97 @@ func TestBooleanEvaluationByUser(t *testing.T) {
89
116
}
90
117
}
91
118
119
+ func TestStringEvaluationByCurrentTime (t * testing.T ) {
120
+ resolution := provider .StringEvaluation (context .Background (), "variant-flag-by-date" , "fallback" , map [string ]interface {}{
121
+ "UserId" : "2" ,
122
+ "CurrentTime" : "2025-01-02T15:04:05Z" ,
123
+ })
124
+ enabled , _ := resolution .ProviderResolutionDetail .FlagMetadata .GetBool ("enabled" )
125
+ if enabled == false {
126
+ t .Fatalf ("Expected feature to be enabled" )
127
+ }
128
+
129
+ if resolution .ProviderResolutionDetail .Variant != "var1" {
130
+ t .Fatalf ("Expected variant name" )
131
+ }
132
+ if resolution .Value != "v1" {
133
+ t .Fatalf ("Expected one of the variant payloads" )
134
+ }
135
+
136
+ resolution = provider .StringEvaluation (context .Background (), "variant-flag-by-date" , "fallback" , map [string ]interface {}{
137
+ "UserId" : "2" ,
138
+ "CurrentTime" : "2023-01-02T15:04:05Z" ,
139
+ })
140
+ if resolution .Value != "fallback" {
141
+ t .Fatalf ("Expected fallback value" )
142
+ }
143
+ }
144
+
145
+ func TestInvalidContextEvaluation (t * testing.T ) {
146
+ evalCtx := make (of.FlattenedContext )
147
+ defaultValue := true
148
+ evalCtx ["Invalid-key" ] = make (chan int )
149
+ resolution := provider .BooleanEvaluation (context .Background (), "non-existing-flag" , defaultValue , evalCtx )
150
+ if resolution .Value != defaultValue {
151
+ t .Errorf ("Expected value to be %v when evaluation context is invalid, got %v" , defaultValue , resolution .Value )
152
+ }
153
+ if resolution .Reason != of .ErrorReason {
154
+ t .Errorf ("Expected reason to be %s, got %s" , of .ErrorReason , resolution .Reason )
155
+ }
156
+ }
157
+
158
+ func TestEvaluationMethods (t * testing.T ) {
159
+
160
+ tests := []struct {
161
+ flag string
162
+ defaultValue interface {}
163
+ evalCtx of.FlattenedContext
164
+ expected interface {}
165
+ expectedError string
166
+ }{
167
+ {flag : "DateExample" , defaultValue : false , evalCtx : of.FlattenedContext {}, expected : true , expectedError : "" },
168
+ {flag : "variant-flag" , defaultValue : false , evalCtx : of.FlattenedContext {}, expected : true , expectedError : "" },
169
+ {flag : "double-flag" , defaultValue : 9.9 , evalCtx : of.FlattenedContext {}, expected : 1.23 , expectedError : "" },
170
+ {flag : "variant-flag" , defaultValue : "fallback" , evalCtx : of.FlattenedContext {}, expected : "v1" , expectedError : "" },
171
+ {flag : "json-flag" , defaultValue : "fallback" , evalCtx : of.FlattenedContext {}, expected : "{\n \" k1\" : \" v1\" \n }" , expectedError : "" },
172
+ {flag : "csv-flag" , defaultValue : "fallback" , evalCtx : of.FlattenedContext {}, expected : "a,b,c" , expectedError : "" },
173
+
174
+ {flag : "csv-invalid_flag" , defaultValue : false , evalCtx : of.FlattenedContext {}, expected : false , expectedError : "" },
175
+ {flag : "csv-invalid_flag" , defaultValue : true , evalCtx : of.FlattenedContext {}, expected : true , expectedError : "" },
176
+
177
+ {"float" , 1.23 , of.FlattenedContext {"UserID" : "123" }, 1.23 , "flag not found" },
178
+ {"number" , int64 (43 ), of.FlattenedContext {"UserID" : "123" }, int64 (43 ), "flag not found" },
179
+ {"object" , map [string ]interface {}{"key1" : "other-value" }, of.FlattenedContext {"UserID" : "123" }, map [string ]interface {}{"key1" : "other-value" }, "flag not found" },
180
+ {"string" , "value2" , of.FlattenedContext {"UserID" : "123" }, "value2" , "flag not found" },
181
+
182
+ {"invalid_user_context" , false , of.FlattenedContext {"UserID" : "123" , "invalid" : "value" }, false , "" },
183
+ {"enriched_user_context" , false , of.FlattenedContext {"UserID" : "123" , "Email" : "v" , "IpAddress" : "v" , "UserAgent" : "v" , "Country" : "v" , "Locale" : "v" }, false , "" },
184
+ {"missing_feature_config" , int64 (43 ), of.FlattenedContext {"UserID" : "123" }, int64 (43 ), "" },
185
+ {"empty_context" , int64 (43 ), of.FlattenedContext {}, int64 (43 ), "" },
186
+ }
187
+
188
+ for _ , test := range tests {
189
+ rt := reflect .TypeOf (test .expected )
190
+ switch rt .Kind () {
191
+ case reflect .Bool :
192
+ res := provider .BooleanEvaluation (context .Background (), test .flag , test .defaultValue .(bool ), test .evalCtx )
193
+ require .Equal (t , test .expected , res .Value , fmt .Errorf ("failed for test flag `%s`" , test .flag ))
194
+ case reflect .Int , reflect .Int8 , reflect .Int32 , reflect .Int64 :
195
+ res := provider .IntEvaluation (context .Background (), test .flag , test .defaultValue .(int64 ), test .evalCtx )
196
+ require .Equal (t , test .expected , res .Value , fmt .Errorf ("failed for test flag `%s`" , test .flag ))
197
+ case reflect .Float32 , reflect .Float64 :
198
+ res := provider .FloatEvaluation (context .Background (), test .flag , test .defaultValue .(float64 ), test .evalCtx )
199
+ require .Equal (t , test .expected , res .Value , fmt .Errorf ("failed for test flag `%s`" , test .flag ))
200
+ case reflect .String :
201
+ res := provider .StringEvaluation (context .Background (), test .flag , test .defaultValue .(string ), test .evalCtx )
202
+ require .Equal (t , test .expected , res .Value , fmt .Errorf ("failed for test flag `%s`" , test .flag ))
203
+ default :
204
+ res := provider .ObjectEvaluation (context .Background (), test .flag , test .defaultValue , test .evalCtx )
205
+ require .Equal (t , test .expected , res .Value , fmt .Errorf ("failed for test flag `%s`" , test .flag ))
206
+ }
207
+ }
208
+ }
209
+
92
210
// global cleanup
93
211
func cleanup () {
94
212
provider .Shutdown ()
@@ -100,7 +218,9 @@ func TestMain(m *testing.M) {
100
218
demoReader , err := os .Open ("demo_app_toggles.json" )
101
219
if err != nil {
102
220
fmt .Printf ("Error during features file open: %v\n " , err )
221
+ os .Exit (1 )
103
222
}
223
+ defer demoReader .Close ()
104
224
105
225
providerOptions := unleashProvider.ProviderConfig {
106
226
Options : []unleash.ConfigOption {
@@ -118,10 +238,12 @@ func TestMain(m *testing.M) {
118
238
if err != nil {
119
239
fmt .Printf ("Error during provider open: %v\n " , err )
120
240
}
121
- err = provider . Init ( of.EvaluationContext {} )
241
+ err = of .SetProviderAndWait ( provider )
122
242
if err != nil {
123
- fmt .Printf ("Error during provider init: %v\n " , err )
243
+ fmt .Printf ("Error during SetProviderAndWait: %v\n " , err )
244
+ os .Exit (1 )
124
245
}
246
+ ofClient = of .NewClient ("my-app" )
125
247
126
248
fmt .Printf ("provider: %v\n " , provider )
127
249
0 commit comments