ldclient-rb 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -9
- data/lib/ldclient-rb/evaluation.rb +123 -77
- data/lib/ldclient-rb/events.rb +1 -0
- data/lib/ldclient-rb/flags_state.rb +2 -1
- data/lib/ldclient-rb/ldclient.rb +110 -54
- data/lib/ldclient-rb/version.rb +1 -1
- data/spec/evaluation_spec.rb +267 -95
- data/spec/ldclient_spec.rb +98 -17
- metadata +2 -2
data/lib/ldclient-rb/version.rb
CHANGED
data/spec/evaluation_spec.rb
CHANGED
@@ -2,6 +2,9 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe LaunchDarkly::Evaluation do
|
4
4
|
subject { LaunchDarkly::Evaluation }
|
5
|
+
|
6
|
+
include LaunchDarkly::Evaluation
|
7
|
+
|
5
8
|
let(:features) { LaunchDarkly::InMemoryFeatureStore.new }
|
6
9
|
|
7
10
|
let(:user) {
|
@@ -14,7 +17,13 @@ describe LaunchDarkly::Evaluation do
|
|
14
17
|
|
15
18
|
let(:logger) { LaunchDarkly::Config.default_logger }
|
16
19
|
|
17
|
-
|
20
|
+
def boolean_flag_with_rules(rules)
|
21
|
+
{ key: 'feature', on: true, rules: rules, fallthrough: { variation: 0 }, variations: [ false, true ] }
|
22
|
+
end
|
23
|
+
|
24
|
+
def boolean_flag_with_clauses(clauses)
|
25
|
+
boolean_flag_with_rules([{ id: 'ruleid', clauses: clauses, variation: 1 }])
|
26
|
+
end
|
18
27
|
|
19
28
|
describe "evaluate" do
|
20
29
|
it "returns off variation if flag is off" do
|
@@ -26,7 +35,10 @@ describe LaunchDarkly::Evaluation do
|
|
26
35
|
variations: ['a', 'b', 'c']
|
27
36
|
}
|
28
37
|
user = { key: 'x' }
|
29
|
-
|
38
|
+
detail = LaunchDarkly::EvaluationDetail.new('b', 1, { kind: 'OFF' })
|
39
|
+
result = evaluate(flag, user, features, logger)
|
40
|
+
expect(result.detail).to eq(detail)
|
41
|
+
expect(result.events).to eq([])
|
30
42
|
end
|
31
43
|
|
32
44
|
it "returns nil if flag is off and off variation is unspecified" do
|
@@ -37,7 +49,42 @@ describe LaunchDarkly::Evaluation do
|
|
37
49
|
variations: ['a', 'b', 'c']
|
38
50
|
}
|
39
51
|
user = { key: 'x' }
|
40
|
-
|
52
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil, { kind: 'OFF' })
|
53
|
+
result = evaluate(flag, user, features, logger)
|
54
|
+
expect(result.detail).to eq(detail)
|
55
|
+
expect(result.events).to eq([])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns an error if off variation is too high" do
|
59
|
+
flag = {
|
60
|
+
key: 'feature',
|
61
|
+
on: false,
|
62
|
+
offVariation: 999,
|
63
|
+
fallthrough: { variation: 0 },
|
64
|
+
variations: ['a', 'b', 'c']
|
65
|
+
}
|
66
|
+
user = { key: 'x' }
|
67
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
68
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
69
|
+
result = evaluate(flag, user, features, logger)
|
70
|
+
expect(result.detail).to eq(detail)
|
71
|
+
expect(result.events).to eq([])
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns an error if off variation is negative" do
|
75
|
+
flag = {
|
76
|
+
key: 'feature',
|
77
|
+
on: false,
|
78
|
+
offVariation: -1,
|
79
|
+
fallthrough: { variation: 0 },
|
80
|
+
variations: ['a', 'b', 'c']
|
81
|
+
}
|
82
|
+
user = { key: 'x' }
|
83
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
84
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
85
|
+
result = evaluate(flag, user, features, logger)
|
86
|
+
expect(result.detail).to eq(detail)
|
87
|
+
expect(result.events).to eq([])
|
41
88
|
end
|
42
89
|
|
43
90
|
it "returns off variation if prerequisite is not found" do
|
@@ -50,7 +97,11 @@ describe LaunchDarkly::Evaluation do
|
|
50
97
|
variations: ['a', 'b', 'c']
|
51
98
|
}
|
52
99
|
user = { key: 'x' }
|
53
|
-
|
100
|
+
detail = LaunchDarkly::EvaluationDetail.new('b', 1,
|
101
|
+
{ kind: 'PREREQUISITE_FAILED', prerequisiteKey: 'badfeature' })
|
102
|
+
result = evaluate(flag, user, features, logger)
|
103
|
+
expect(result.detail).to eq(detail)
|
104
|
+
expect(result.events).to eq([])
|
54
105
|
end
|
55
106
|
|
56
107
|
it "returns off variation and event if prerequisite of a prerequisite is not found" do
|
@@ -73,11 +124,47 @@ describe LaunchDarkly::Evaluation do
|
|
73
124
|
}
|
74
125
|
features.upsert(LaunchDarkly::FEATURES, flag1)
|
75
126
|
user = { key: 'x' }
|
127
|
+
detail = LaunchDarkly::EvaluationDetail.new('b', 1,
|
128
|
+
{ kind: 'PREREQUISITE_FAILED', prerequisiteKey: 'feature1' })
|
76
129
|
events_should_be = [{
|
77
130
|
kind: 'feature', key: 'feature1', variation: nil, value: nil, version: 2, prereqOf: 'feature0',
|
78
131
|
trackEvents: nil, debugEventsUntilDate: nil
|
79
132
|
}]
|
80
|
-
|
133
|
+
result = evaluate(flag, user, features, logger)
|
134
|
+
expect(result.detail).to eq(detail)
|
135
|
+
expect(result.events).to eq(events_should_be)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns off variation and event if prerequisite is off" do
|
139
|
+
flag = {
|
140
|
+
key: 'feature0',
|
141
|
+
on: true,
|
142
|
+
prerequisites: [{key: 'feature1', variation: 1}],
|
143
|
+
fallthrough: { variation: 0 },
|
144
|
+
offVariation: 1,
|
145
|
+
variations: ['a', 'b', 'c'],
|
146
|
+
version: 1
|
147
|
+
}
|
148
|
+
flag1 = {
|
149
|
+
key: 'feature1',
|
150
|
+
on: false,
|
151
|
+
# note that even though it returns the desired variation, it is still off and therefore not a match
|
152
|
+
offVariation: 1,
|
153
|
+
fallthrough: { variation: 0 },
|
154
|
+
variations: ['d', 'e'],
|
155
|
+
version: 2
|
156
|
+
}
|
157
|
+
features.upsert(LaunchDarkly::FEATURES, flag1)
|
158
|
+
user = { key: 'x' }
|
159
|
+
detail = LaunchDarkly::EvaluationDetail.new('b', 1,
|
160
|
+
{ kind: 'PREREQUISITE_FAILED', prerequisiteKey: 'feature1' })
|
161
|
+
events_should_be = [{
|
162
|
+
kind: 'feature', key: 'feature1', variation: 1, value: 'e', version: 2, prereqOf: 'feature0',
|
163
|
+
trackEvents: nil, debugEventsUntilDate: nil
|
164
|
+
}]
|
165
|
+
result = evaluate(flag, user, features, logger)
|
166
|
+
expect(result.detail).to eq(detail)
|
167
|
+
expect(result.events).to eq(events_should_be)
|
81
168
|
end
|
82
169
|
|
83
170
|
it "returns off variation and event if prerequisite is not met" do
|
@@ -99,11 +186,15 @@ describe LaunchDarkly::Evaluation do
|
|
99
186
|
}
|
100
187
|
features.upsert(LaunchDarkly::FEATURES, flag1)
|
101
188
|
user = { key: 'x' }
|
189
|
+
detail = LaunchDarkly::EvaluationDetail.new('b', 1,
|
190
|
+
{ kind: 'PREREQUISITE_FAILED', prerequisiteKey: 'feature1' })
|
102
191
|
events_should_be = [{
|
103
192
|
kind: 'feature', key: 'feature1', variation: 0, value: 'd', version: 2, prereqOf: 'feature0',
|
104
193
|
trackEvents: nil, debugEventsUntilDate: nil
|
105
194
|
}]
|
106
|
-
|
195
|
+
result = evaluate(flag, user, features, logger)
|
196
|
+
expect(result.detail).to eq(detail)
|
197
|
+
expect(result.events).to eq(events_should_be)
|
107
198
|
end
|
108
199
|
|
109
200
|
it "returns fallthrough variation and event if prerequisite is met and there are no rules" do
|
@@ -125,76 +216,195 @@ describe LaunchDarkly::Evaluation do
|
|
125
216
|
}
|
126
217
|
features.upsert(LaunchDarkly::FEATURES, flag1)
|
127
218
|
user = { key: 'x' }
|
219
|
+
detail = LaunchDarkly::EvaluationDetail.new('a', 0, { kind: 'FALLTHROUGH' })
|
128
220
|
events_should_be = [{
|
129
221
|
kind: 'feature', key: 'feature1', variation: 1, value: 'e', version: 2, prereqOf: 'feature0',
|
130
222
|
trackEvents: nil, debugEventsUntilDate: nil
|
131
223
|
}]
|
132
|
-
|
224
|
+
result = evaluate(flag, user, features, logger)
|
225
|
+
expect(result.detail).to eq(detail)
|
226
|
+
expect(result.events).to eq(events_should_be)
|
133
227
|
end
|
134
228
|
|
135
|
-
it "
|
229
|
+
it "returns an error if fallthrough variation is too high" do
|
136
230
|
flag = {
|
137
|
-
key: '
|
231
|
+
key: 'feature',
|
138
232
|
on: true,
|
139
|
-
|
140
|
-
{ values: [ 'whoever', 'userkey' ], variation: 2 }
|
141
|
-
],
|
142
|
-
fallthrough: { variation: 0 },
|
233
|
+
fallthrough: { variation: 999 },
|
143
234
|
offVariation: 1,
|
144
235
|
variations: ['a', 'b', 'c']
|
145
236
|
}
|
146
237
|
user = { key: 'userkey' }
|
147
|
-
|
238
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil, { kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
239
|
+
result = evaluate(flag, user, features, logger)
|
240
|
+
expect(result.detail).to eq(detail)
|
241
|
+
expect(result.events).to eq([])
|
148
242
|
end
|
149
243
|
|
150
|
-
it "
|
244
|
+
it "returns an error if fallthrough variation is negative" do
|
151
245
|
flag = {
|
152
|
-
key: '
|
246
|
+
key: 'feature',
|
153
247
|
on: true,
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
248
|
+
fallthrough: { variation: -1 },
|
249
|
+
offVariation: 1,
|
250
|
+
variations: ['a', 'b', 'c']
|
251
|
+
}
|
252
|
+
user = { key: 'userkey' }
|
253
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil, { kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
254
|
+
result = evaluate(flag, user, features, logger)
|
255
|
+
expect(result.detail).to eq(detail)
|
256
|
+
expect(result.events).to eq([])
|
257
|
+
end
|
258
|
+
|
259
|
+
it "returns an error if fallthrough has no variation or rollout" do
|
260
|
+
flag = {
|
261
|
+
key: 'feature',
|
262
|
+
on: true,
|
263
|
+
fallthrough: { },
|
264
|
+
offVariation: 1,
|
265
|
+
variations: ['a', 'b', 'c']
|
266
|
+
}
|
267
|
+
user = { key: 'userkey' }
|
268
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil, { kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
269
|
+
result = evaluate(flag, user, features, logger)
|
270
|
+
expect(result.detail).to eq(detail)
|
271
|
+
expect(result.events).to eq([])
|
272
|
+
end
|
273
|
+
|
274
|
+
it "returns an error if fallthrough has a rollout with no variations" do
|
275
|
+
flag = {
|
276
|
+
key: 'feature',
|
277
|
+
on: true,
|
278
|
+
fallthrough: { rollout: { variations: [] } },
|
279
|
+
offVariation: 1,
|
280
|
+
variations: ['a', 'b', 'c']
|
281
|
+
}
|
282
|
+
user = { key: 'userkey' }
|
283
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil, { kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
284
|
+
result = evaluate(flag, user, features, logger)
|
285
|
+
expect(result.detail).to eq(detail)
|
286
|
+
expect(result.events).to eq([])
|
287
|
+
end
|
288
|
+
|
289
|
+
it "matches user from targets" do
|
290
|
+
flag = {
|
291
|
+
key: 'feature',
|
292
|
+
on: true,
|
293
|
+
targets: [
|
294
|
+
{ values: [ 'whoever', 'userkey' ], variation: 2 }
|
165
295
|
],
|
166
296
|
fallthrough: { variation: 0 },
|
167
297
|
offVariation: 1,
|
168
298
|
variations: ['a', 'b', 'c']
|
169
299
|
}
|
170
300
|
user = { key: 'userkey' }
|
171
|
-
|
301
|
+
detail = LaunchDarkly::EvaluationDetail.new('c', 2, { kind: 'TARGET_MATCH' })
|
302
|
+
result = evaluate(flag, user, features, logger)
|
303
|
+
expect(result.detail).to eq(detail)
|
304
|
+
expect(result.events).to eq([])
|
305
|
+
end
|
306
|
+
|
307
|
+
it "matches user from rules" do
|
308
|
+
rule = { id: 'ruleid', clauses: [{ attribute: 'key', op: 'in', values: ['userkey'] }], variation: 1 }
|
309
|
+
flag = boolean_flag_with_rules([rule])
|
310
|
+
user = { key: 'userkey' }
|
311
|
+
detail = LaunchDarkly::EvaluationDetail.new(true, 1,
|
312
|
+
{ kind: 'RULE_MATCH', ruleIndex: 0, ruleId: 'ruleid' })
|
313
|
+
result = evaluate(flag, user, features, logger)
|
314
|
+
expect(result.detail).to eq(detail)
|
315
|
+
expect(result.events).to eq([])
|
316
|
+
end
|
317
|
+
|
318
|
+
it "returns an error if rule variation is too high" do
|
319
|
+
rule = { id: 'ruleid', clauses: [{ attribute: 'key', op: 'in', values: ['userkey'] }], variation: 999 }
|
320
|
+
flag = boolean_flag_with_rules([rule])
|
321
|
+
user = { key: 'userkey' }
|
322
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
323
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
324
|
+
result = evaluate(flag, user, features, logger)
|
325
|
+
expect(result.detail).to eq(detail)
|
326
|
+
expect(result.events).to eq([])
|
327
|
+
end
|
328
|
+
|
329
|
+
it "returns an error if rule variation is negative" do
|
330
|
+
rule = { id: 'ruleid', clauses: [{ attribute: 'key', op: 'in', values: ['userkey'] }], variation: -1 }
|
331
|
+
flag = boolean_flag_with_rules([rule])
|
332
|
+
user = { key: 'userkey' }
|
333
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
334
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
335
|
+
result = evaluate(flag, user, features, logger)
|
336
|
+
expect(result.detail).to eq(detail)
|
337
|
+
expect(result.events).to eq([])
|
338
|
+
end
|
339
|
+
|
340
|
+
it "returns an error if rule has neither variation nor rollout" do
|
341
|
+
rule = { id: 'ruleid', clauses: [{ attribute: 'key', op: 'in', values: ['userkey'] }] }
|
342
|
+
flag = boolean_flag_with_rules([rule])
|
343
|
+
user = { key: 'userkey' }
|
344
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
345
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
346
|
+
result = evaluate(flag, user, features, logger)
|
347
|
+
expect(result.detail).to eq(detail)
|
348
|
+
expect(result.events).to eq([])
|
349
|
+
end
|
350
|
+
|
351
|
+
it "returns an error if rule has a rollout with no variations" do
|
352
|
+
rule = { id: 'ruleid', clauses: [{ attribute: 'key', op: 'in', values: ['userkey'] }],
|
353
|
+
rollout: { variations: [] } }
|
354
|
+
flag = boolean_flag_with_rules([rule])
|
355
|
+
user = { key: 'userkey' }
|
356
|
+
detail = LaunchDarkly::EvaluationDetail.new(nil, nil,
|
357
|
+
{ kind: 'ERROR', errorKind: 'MALFORMED_FLAG' })
|
358
|
+
result = evaluate(flag, user, features, logger)
|
359
|
+
expect(result.detail).to eq(detail)
|
360
|
+
expect(result.events).to eq([])
|
172
361
|
end
|
173
362
|
end
|
174
363
|
|
175
|
-
describe "
|
364
|
+
describe "clause" do
|
176
365
|
it "can match built-in attribute" do
|
177
366
|
user = { key: 'x', name: 'Bob' }
|
178
367
|
clause = { attribute: 'name', op: 'in', values: ['Bob'] }
|
179
|
-
|
368
|
+
flag = boolean_flag_with_clauses([clause])
|
369
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be true
|
180
370
|
end
|
181
371
|
|
182
372
|
it "can match custom attribute" do
|
183
373
|
user = { key: 'x', name: 'Bob', custom: { legs: 4 } }
|
184
374
|
clause = { attribute: 'legs', op: 'in', values: [4] }
|
185
|
-
|
375
|
+
flag = boolean_flag_with_clauses([clause])
|
376
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be true
|
186
377
|
end
|
187
378
|
|
188
379
|
it "returns false for missing attribute" do
|
189
380
|
user = { key: 'x', name: 'Bob' }
|
190
381
|
clause = { attribute: 'legs', op: 'in', values: [4] }
|
191
|
-
|
382
|
+
flag = boolean_flag_with_clauses([clause])
|
383
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be false
|
384
|
+
end
|
385
|
+
|
386
|
+
it "returns false for unknown operator" do
|
387
|
+
user = { key: 'x', name: 'Bob' }
|
388
|
+
clause = { attribute: 'name', op: 'unknown', values: [4] }
|
389
|
+
flag = boolean_flag_with_clauses([clause])
|
390
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be false
|
391
|
+
end
|
392
|
+
|
393
|
+
it "does not stop evaluating rules after clause with unknown operator" do
|
394
|
+
user = { key: 'x', name: 'Bob' }
|
395
|
+
clause0 = { attribute: 'name', op: 'unknown', values: [4] }
|
396
|
+
rule0 = { clauses: [ clause0 ], variation: 1 }
|
397
|
+
clause1 = { attribute: 'name', op: 'in', values: ['Bob'] }
|
398
|
+
rule1 = { clauses: [ clause1 ], variation: 1 }
|
399
|
+
flag = boolean_flag_with_rules([rule0, rule1])
|
400
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be true
|
192
401
|
end
|
193
402
|
|
194
403
|
it "can be negated" do
|
195
404
|
user = { key: 'x', name: 'Bob' }
|
196
405
|
clause = { attribute: 'name', op: 'in', values: ['Bob'], negate: true }
|
197
|
-
|
406
|
+
flag = boolean_flag_with_clauses([clause])
|
407
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be false
|
198
408
|
end
|
199
409
|
|
200
410
|
it "retrieves segment from segment store for segmentMatch operator" do
|
@@ -208,23 +418,24 @@ describe LaunchDarkly::Evaluation do
|
|
208
418
|
|
209
419
|
user = { key: 'userkey' }
|
210
420
|
clause = { attribute: '', op: 'segmentMatch', values: ['segkey'] }
|
211
|
-
|
212
|
-
expect(
|
421
|
+
flag = boolean_flag_with_clauses([clause])
|
422
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be true
|
213
423
|
end
|
214
424
|
|
215
425
|
it "falls through with no errors if referenced segment is not found" do
|
216
426
|
user = { key: 'userkey' }
|
217
427
|
clause = { attribute: '', op: 'segmentMatch', values: ['segkey'] }
|
218
|
-
|
219
|
-
expect(
|
428
|
+
flag = boolean_flag_with_clauses([clause])
|
429
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be false
|
220
430
|
end
|
221
431
|
|
222
432
|
it "can be negated" do
|
223
433
|
user = { key: 'x', name: 'Bob' }
|
224
434
|
clause = { attribute: 'name', op: 'in', values: ['Bob'] }
|
435
|
+
flag = boolean_flag_with_clauses([clause])
|
225
436
|
expect {
|
226
437
|
clause[:negate] = true
|
227
|
-
}.to change {
|
438
|
+
}.to change {evaluate(flag, user, features, logger).detail.value}.from(true).to(false)
|
228
439
|
end
|
229
440
|
end
|
230
441
|
|
@@ -326,7 +537,8 @@ describe LaunchDarkly::Evaluation do
|
|
326
537
|
it "should return #{shouldBe} for #{value1} #{op} #{value2}" do
|
327
538
|
user = { key: 'x', custom: { foo: value1 } }
|
328
539
|
clause = { attribute: 'foo', op: op, values: [value2] }
|
329
|
-
|
540
|
+
flag = boolean_flag_with_clauses([clause])
|
541
|
+
expect(evaluate(flag, user, features, logger).detail.value).to be shouldBe
|
330
542
|
end
|
331
543
|
end
|
332
544
|
end
|
@@ -385,17 +597,6 @@ describe LaunchDarkly::Evaluation do
|
|
385
597
|
end
|
386
598
|
end
|
387
599
|
|
388
|
-
def make_flag(key)
|
389
|
-
{
|
390
|
-
key: key,
|
391
|
-
rules: [],
|
392
|
-
variations: [ false, true ],
|
393
|
-
on: true,
|
394
|
-
fallthrough: { variation: 0 },
|
395
|
-
version: 1
|
396
|
-
}
|
397
|
-
end
|
398
|
-
|
399
600
|
def make_segment(key)
|
400
601
|
{
|
401
602
|
key: key,
|
@@ -424,35 +625,30 @@ describe LaunchDarkly::Evaluation do
|
|
424
625
|
end
|
425
626
|
|
426
627
|
describe 'segment matching' do
|
427
|
-
|
428
|
-
segment = make_segment('segkey')
|
429
|
-
segment[:included] = [ user[:key] ]
|
628
|
+
def test_segment_match(segment)
|
430
629
|
features.upsert(LaunchDarkly::SEGMENTS, segment)
|
431
630
|
clause = make_segment_match_clause(segment)
|
631
|
+
flag = boolean_flag_with_clauses([clause])
|
632
|
+
evaluate(flag, user, features, logger).detail.value
|
633
|
+
end
|
432
634
|
|
433
|
-
|
434
|
-
|
635
|
+
it 'explicitly includes user' do
|
636
|
+
segment = make_segment('segkey')
|
637
|
+
segment[:included] = [ user[:key] ]
|
638
|
+
expect(test_segment_match(segment)).to be true
|
435
639
|
end
|
436
640
|
|
437
641
|
it 'explicitly excludes user' do
|
438
642
|
segment = make_segment('segkey')
|
439
643
|
segment[:excluded] = [ user[:key] ]
|
440
|
-
|
441
|
-
clause = make_segment_match_clause(segment)
|
442
|
-
|
443
|
-
result = clause_match_user(clause, user, features)
|
444
|
-
expect(result).to be false
|
644
|
+
expect(test_segment_match(segment)).to be false
|
445
645
|
end
|
446
646
|
|
447
647
|
it 'both includes and excludes user; include takes priority' do
|
448
648
|
segment = make_segment('segkey')
|
449
649
|
segment[:included] = [ user[:key] ]
|
450
650
|
segment[:excluded] = [ user[:key] ]
|
451
|
-
|
452
|
-
clause = make_segment_match_clause(segment)
|
453
|
-
|
454
|
-
result = clause_match_user(clause, user, features)
|
455
|
-
expect(result).to be true
|
651
|
+
expect(test_segment_match(segment)).to be true
|
456
652
|
end
|
457
653
|
|
458
654
|
it 'matches user by rule when weight is absent' do
|
@@ -462,11 +658,7 @@ describe LaunchDarkly::Evaluation do
|
|
462
658
|
}
|
463
659
|
segment = make_segment('segkey')
|
464
660
|
segment[:rules] = [ segRule ]
|
465
|
-
|
466
|
-
clause = make_segment_match_clause(segment)
|
467
|
-
|
468
|
-
result = clause_match_user(clause, user, features)
|
469
|
-
expect(result).to be true
|
661
|
+
expect(test_segment_match(segment)).to be true
|
470
662
|
end
|
471
663
|
|
472
664
|
it 'matches user by rule when weight is nil' do
|
@@ -477,11 +669,7 @@ describe LaunchDarkly::Evaluation do
|
|
477
669
|
}
|
478
670
|
segment = make_segment('segkey')
|
479
671
|
segment[:rules] = [ segRule ]
|
480
|
-
|
481
|
-
clause = make_segment_match_clause(segment)
|
482
|
-
|
483
|
-
result = clause_match_user(clause, user, features)
|
484
|
-
expect(result).to be true
|
672
|
+
expect(test_segment_match(segment)).to be true
|
485
673
|
end
|
486
674
|
|
487
675
|
it 'matches user with full rollout' do
|
@@ -492,11 +680,7 @@ describe LaunchDarkly::Evaluation do
|
|
492
680
|
}
|
493
681
|
segment = make_segment('segkey')
|
494
682
|
segment[:rules] = [ segRule ]
|
495
|
-
|
496
|
-
clause = make_segment_match_clause(segment)
|
497
|
-
|
498
|
-
result = clause_match_user(clause, user, features)
|
499
|
-
expect(result).to be true
|
683
|
+
expect(test_segment_match(segment)).to be true
|
500
684
|
end
|
501
685
|
|
502
686
|
it "doesn't match user with zero rollout" do
|
@@ -507,11 +691,7 @@ describe LaunchDarkly::Evaluation do
|
|
507
691
|
}
|
508
692
|
segment = make_segment('segkey')
|
509
693
|
segment[:rules] = [ segRule ]
|
510
|
-
|
511
|
-
clause = make_segment_match_clause(segment)
|
512
|
-
|
513
|
-
result = clause_match_user(clause, user, features)
|
514
|
-
expect(result).to be false
|
694
|
+
expect(test_segment_match(segment)).to be false
|
515
695
|
end
|
516
696
|
|
517
697
|
it "matches user with multiple clauses" do
|
@@ -522,11 +702,7 @@ describe LaunchDarkly::Evaluation do
|
|
522
702
|
}
|
523
703
|
segment = make_segment('segkey')
|
524
704
|
segment[:rules] = [ segRule ]
|
525
|
-
|
526
|
-
clause = make_segment_match_clause(segment)
|
527
|
-
|
528
|
-
result = clause_match_user(clause, user, features)
|
529
|
-
expect(result).to be true
|
705
|
+
expect(test_segment_match(segment)).to be true
|
530
706
|
end
|
531
707
|
|
532
708
|
it "doesn't match user with multiple clauses if a clause doesn't match" do
|
@@ -538,11 +714,7 @@ describe LaunchDarkly::Evaluation do
|
|
538
714
|
}
|
539
715
|
segment = make_segment('segkey')
|
540
716
|
segment[:rules] = [ segRule ]
|
541
|
-
|
542
|
-
clause = make_segment_match_clause(segment)
|
543
|
-
|
544
|
-
result = clause_match_user(clause, user, features)
|
545
|
-
expect(result).to be false
|
717
|
+
expect(test_segment_match(segment)).to be false
|
546
718
|
end
|
547
719
|
end
|
548
720
|
end
|