1 package ldmodel
2
3 import (
4 "fmt"
5 "testing"
6
7 "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
8
9 "github.com/stretchr/testify/assert"
10 )
11
12 func TestClauseFindValue(t *testing.T) {
13 foundValues := []ldvalue.Value{ldvalue.Bool(true), ldvalue.Int(2), ldvalue.String("x")}
14 notFoundValues := []ldvalue.Value{ldvalue.Bool(false), ldvalue.Int(3), ldvalue.String("y")}
15
16 for _, withPreprocessing := range []bool{false, true} {
17 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
18 clause := Clause{Op: OperatorIn, Values: foundValues}
19 if withPreprocessing {
20 clause.preprocessed = preprocessClause(clause)
21 }
22 for _, value := range foundValues {
23 assert.True(t, EvaluatorAccessors.ClauseFindValue(&clause, value), "value: %s", value)
24 }
25 for _, value := range notFoundValues {
26 assert.False(t, EvaluatorAccessors.ClauseFindValue(&clause, value), "value: %s", value)
27 }
28 })
29 }
30
31 t.Run("unsupported value types return false", func(t *testing.T) {
32 badValues := []ldvalue.Value{ldvalue.Null(), ldvalue.ArrayOf(), ldvalue.ObjectBuild().Build()}
33 for _, withPreprocessing := range []bool{false, true} {
34 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
35 clause := Clause{Op: OperatorIn, Values: badValues}
36 if withPreprocessing {
37 clause.preprocessed = preprocessClause(clause)
38 }
39 for _, value := range badValues {
40 assert.False(t, EvaluatorAccessors.ClauseFindValue(&clause, value), "value: %s", value)
41 }
42 })
43 }
44 })
45
46 t.Run("nil pointer", func(t *testing.T) {
47 assert.False(t, EvaluatorAccessors.ClauseFindValue(nil, ldvalue.String("")))
48 })
49 }
50
51 func TestClauseGetValueAsRegexp(t *testing.T) {
52 for _, withPreprocessing := range []bool{false, true} {
53 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
54 clause := Clause{Op: OperatorMatches,
55 Values: []ldvalue.Value{ldvalue.String("a.*b"), ldvalue.String("**"), ldvalue.Int(1)}}
56 if withPreprocessing {
57 clause.preprocessed = preprocessClause(clause)
58 }
59
60 r := EvaluatorAccessors.ClauseGetValueAsRegexp(&clause, 0)
61 if assert.NotNil(t, r) {
62 assert.Equal(t, "a.*b", r.String())
63 }
64
65 assert.Nil(t, EvaluatorAccessors.ClauseGetValueAsRegexp(&clause, 1))
66 assert.Nil(t, EvaluatorAccessors.ClauseGetValueAsRegexp(&clause, 2))
67
68 assert.Nil(t, EvaluatorAccessors.ClauseGetValueAsRegexp(&clause, -1))
69 assert.Nil(t, EvaluatorAccessors.ClauseGetValueAsRegexp(&clause, 3))
70 })
71 }
72
73 t.Run("nil pointer", func(t *testing.T) {
74 assert.Nil(t, EvaluatorAccessors.ClauseGetValueAsRegexp(nil, 0))
75 })
76 }
77
78 func TestClauseGetValueAsSemanticVersion(t *testing.T) {
79 for _, withPreprocessing := range []bool{false, true} {
80 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
81 clause := Clause{Op: OperatorSemVerEqual,
82 Values: []ldvalue.Value{ldvalue.String("1.2.3"), ldvalue.Int(100000)}}
83 if withPreprocessing {
84 clause.preprocessed = preprocessClause(clause)
85 }
86
87 result, ok := EvaluatorAccessors.ClauseGetValueAsSemanticVersion(&clause, 0)
88 assert.True(t, ok)
89 expected, _ := TypeConversions.ValueToSemanticVersion(clause.Values[0])
90 assert.Equal(t, expected, result)
91
92 _, ok = EvaluatorAccessors.ClauseGetValueAsSemanticVersion(&clause, 1)
93 assert.False(t, ok)
94
95 _, ok = EvaluatorAccessors.ClauseGetValueAsSemanticVersion(&clause, -1)
96 assert.False(t, ok)
97 _, ok = EvaluatorAccessors.ClauseGetValueAsSemanticVersion(&clause, 2)
98 assert.False(t, ok)
99 })
100 }
101
102 t.Run("nil pointer", func(t *testing.T) {
103 _, ok := EvaluatorAccessors.ClauseGetValueAsSemanticVersion(nil, 0)
104 assert.False(t, ok)
105 })
106 }
107
108 func TestClauseGetValueAsTimestamp(t *testing.T) {
109 for _, withPreprocessing := range []bool{false, true} {
110 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
111 clause := Clause{Op: OperatorBefore,
112 Values: []ldvalue.Value{ldvalue.String("1970-01-01T00:00:00Z"), ldvalue.Int(100000), ldvalue.Bool(true)}}
113 if withPreprocessing {
114 clause.preprocessed = preprocessClause(clause)
115 }
116
117 result, ok := EvaluatorAccessors.ClauseGetValueAsTimestamp(&clause, 0)
118 assert.True(t, ok)
119 expected, _ := TypeConversions.ValueToTimestamp(clause.Values[0])
120 assert.Equal(t, expected, result)
121
122 result, ok = EvaluatorAccessors.ClauseGetValueAsTimestamp(&clause, 1)
123 assert.True(t, ok)
124 expected, _ = TypeConversions.ValueToTimestamp(clause.Values[1])
125 assert.Equal(t, expected, result)
126
127 _, ok = EvaluatorAccessors.ClauseGetValueAsTimestamp(&clause, 2)
128 assert.False(t, ok)
129
130 _, ok = EvaluatorAccessors.ClauseGetValueAsTimestamp(&clause, -1)
131 assert.False(t, ok)
132 _, ok = EvaluatorAccessors.ClauseGetValueAsTimestamp(&clause, 3)
133 assert.False(t, ok)
134 })
135 }
136
137 t.Run("nil pointer", func(t *testing.T) {
138 _, ok := EvaluatorAccessors.ClauseGetValueAsTimestamp(nil, 0)
139 assert.False(t, ok)
140 })
141 }
142
143 func TestSegmentFindKeyInExcluded(t *testing.T) {
144 foundValues := []string{"a", "b", "c"}
145 notFoundValues := []string{"d", "e", "f"}
146
147 for _, withPreprocessing := range []bool{false, true} {
148 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
149 segment := Segment{Excluded: foundValues}
150 if withPreprocessing {
151 PreprocessSegment(&segment)
152 }
153 for _, value := range foundValues {
154 assert.True(t, EvaluatorAccessors.SegmentFindKeyInExcluded(&segment, value), value)
155 }
156 for _, value := range notFoundValues {
157 assert.False(t, EvaluatorAccessors.SegmentFindKeyInExcluded(&segment, value), value)
158 }
159 })
160 }
161
162 t.Run("nil pointer", func(t *testing.T) {
163 assert.False(t, EvaluatorAccessors.SegmentFindKeyInExcluded(nil, ""))
164 })
165 }
166
167 func TestSegmentFindValueInIncluded(t *testing.T) {
168 foundValues := []string{"a", "b", "c"}
169 notFoundValues := []string{"d", "e", "f"}
170
171 for _, withPreprocessing := range []bool{false, true} {
172 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
173 segment := Segment{Included: foundValues}
174 if withPreprocessing {
175 PreprocessSegment(&segment)
176 }
177 for _, value := range foundValues {
178 assert.True(t, EvaluatorAccessors.SegmentFindKeyInIncluded(&segment, value), value)
179 }
180 for _, value := range notFoundValues {
181 assert.False(t, EvaluatorAccessors.SegmentFindKeyInIncluded(&segment, value), value)
182 }
183 })
184 }
185
186 t.Run("nil pointer", func(t *testing.T) {
187 assert.False(t, EvaluatorAccessors.SegmentFindKeyInIncluded(nil, ""))
188 })
189 }
190
191 func TestSegmentTargetFindKey(t *testing.T) {
192 foundValues := []string{"a", "b", "c"}
193 notFoundValues := []string{"d", "e", "f"}
194
195 for _, withPreprocessing := range []bool{false, true} {
196 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
197 target := SegmentTarget{Values: foundValues}
198 if withPreprocessing {
199 target.preprocessed.valuesMap = preprocessStringSet(target.Values)
200 }
201 for _, value := range foundValues {
202 assert.True(t, EvaluatorAccessors.SegmentTargetFindKey(&target, value), value)
203 }
204 for _, value := range notFoundValues {
205 assert.False(t, EvaluatorAccessors.SegmentTargetFindKey(&target, value), value)
206 }
207 })
208 }
209
210 t.Run("nil pointer", func(t *testing.T) {
211 assert.False(t, EvaluatorAccessors.SegmentTargetFindKey(nil, ""))
212 })
213 }
214
215 func TestTargetFindKey(t *testing.T) {
216 foundValues := []string{"a", "b", "c"}
217 notFoundValues := []string{"d", "e", "f"}
218
219 for _, withPreprocessing := range []bool{false, true} {
220 t.Run(fmt.Sprintf("preprocessed: %t", withPreprocessing), func(t *testing.T) {
221 target := Target{Values: foundValues}
222 if withPreprocessing {
223 target.preprocessed.valuesMap = preprocessStringSet(target.Values)
224 }
225 for _, value := range foundValues {
226 assert.True(t, EvaluatorAccessors.TargetFindKey(&target, value), value)
227 }
228 for _, value := range notFoundValues {
229 assert.False(t, EvaluatorAccessors.TargetFindKey(&target, value), value)
230 }
231 })
232 }
233
234 t.Run("nil pointer", func(t *testing.T) {
235 assert.False(t, EvaluatorAccessors.TargetFindKey(nil, ""))
236 })
237 }
238
View as plain text