prefab-cloud-ruby 0.24.5 → 0.24.6

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/VERSION +1 -1
  4. data/compile_protos.sh +7 -0
  5. data/lib/prefab/client.rb +17 -4
  6. data/lib/prefab/config_client.rb +8 -9
  7. data/lib/prefab/config_value_unwrapper.rb +20 -9
  8. data/lib/prefab/context.rb +39 -7
  9. data/lib/prefab/context_shape_aggregator.rb +1 -1
  10. data/lib/prefab/criteria_evaluator.rb +24 -16
  11. data/lib/prefab/evaluated_keys_aggregator.rb +1 -1
  12. data/lib/prefab/evaluation.rb +48 -0
  13. data/lib/prefab/evaluation_summary_aggregator.rb +85 -0
  14. data/lib/prefab/example_contexts_aggregator.rb +76 -0
  15. data/lib/prefab/exponential_backoff.rb +5 -0
  16. data/lib/prefab/log_path_aggregator.rb +1 -1
  17. data/lib/prefab/logger_client.rb +12 -13
  18. data/lib/prefab/options.rb +27 -14
  19. data/lib/prefab/periodic_sync.rb +30 -13
  20. data/lib/prefab/rate_limit_cache.rb +41 -0
  21. data/lib/prefab/resolved_config_presenter.rb +2 -4
  22. data/lib/prefab/weighted_value_resolver.rb +1 -1
  23. data/lib/prefab-cloud-ruby.rb +5 -2
  24. data/lib/prefab_pb.rb +11 -1
  25. data/prefab-cloud-ruby.gemspec +14 -5
  26. data/test/support/common_helpers.rb +105 -0
  27. data/test/support/mock_base_client.rb +44 -0
  28. data/test/support/mock_config_client.rb +19 -0
  29. data/test/support/mock_config_loader.rb +1 -0
  30. data/test/test_client.rb +257 -2
  31. data/test/test_config_resolver.rb +25 -24
  32. data/test/test_config_value_unwrapper.rb +22 -32
  33. data/test/test_context_shape_aggregator.rb +0 -1
  34. data/test/test_criteria_evaluator.rb +179 -133
  35. data/test/test_evaluation_summary_aggregator.rb +162 -0
  36. data/test/test_example_contexts_aggregator.rb +238 -0
  37. data/test/test_helper.rb +5 -131
  38. data/test/test_local_config_parser.rb +2 -2
  39. data/test/test_logger.rb +5 -5
  40. data/test/test_options.rb +8 -0
  41. data/test/test_rate_limit_cache.rb +44 -0
  42. data/test/test_weighted_value_resolver.rb +13 -7
  43. metadata +13 -4
  44. data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
  45. data/test/test_evaluated_configs_aggregator.rb +0 -254
@@ -6,22 +6,32 @@ require 'timecop'
6
6
  class TestCriteriaEvaluator < Minitest::Test
7
7
  PROJECT_ENV_ID = 1
8
8
  TEST_ENV_ID = 2
9
- KEY = 'key'
9
+ KEY = 'the-key'
10
10
  DEFAULT_VALUE = 'default_value'
11
11
  DESIRED_VALUE = 'desired_value'
12
12
  WRONG_ENV_VALUE = 'wrong_env_value'
13
13
 
14
+ DEFAULT_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
15
+ DESIRED_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
16
+
17
+ TRUE_CONFIG = PrefabProto::ConfigValue.new(bool: true)
18
+ FALSE_CONFIG = PrefabProto::ConfigValue.new(bool: false)
19
+
14
20
  DEFAULT_ROW = PrefabProto::ConfigRow.new(
15
21
  values: [
16
- PrefabProto::ConditionalValue.new(
17
- value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
18
- )
22
+ PrefabProto::ConditionalValue.new(value: DEFAULT_VALUE_CONFIG)
19
23
  ]
20
24
  )
21
25
 
26
+ def setup
27
+ @base_client = FakeBaseClient.new
28
+ end
29
+
22
30
  def test_always_true
23
31
  config = PrefabProto::Config.new(
32
+ id: 123,
24
33
  key: KEY,
34
+ config_type: PrefabProto::ConfigType::CONFIG,
25
35
  rows: [
26
36
  DEFAULT_ROW,
27
37
  PrefabProto::ConfigRow.new(
@@ -29,17 +39,16 @@ class TestCriteriaEvaluator < Minitest::Test
29
39
  values: [
30
40
  PrefabProto::ConditionalValue.new(
31
41
  criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
32
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
42
+ value: DESIRED_VALUE_CONFIG
33
43
  )
34
44
  ]
35
45
  )
36
46
  ]
37
47
  )
38
48
 
39
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
40
- namespace: nil)
49
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
41
50
 
42
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
51
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
43
52
  end
44
53
 
45
54
  def test_nested_props_in
@@ -58,19 +67,19 @@ class TestCriteriaEvaluator < Minitest::Test
58
67
  property_name: 'user.key'
59
68
  )
60
69
  ],
61
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
70
+ value: DESIRED_VALUE_CONFIG
62
71
  )
63
72
  ]
64
73
  )
65
74
  ]
66
75
  )
67
76
 
68
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
77
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
69
78
  namespace: nil)
70
79
 
71
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
72
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).string
73
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).string
80
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
81
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).unwrapped_value
82
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).unwrapped_value
74
83
  end
75
84
 
76
85
  def test_nested_props_not_in
@@ -89,26 +98,25 @@ class TestCriteriaEvaluator < Minitest::Test
89
98
  property_name: 'user.key'
90
99
  )
91
100
  ],
92
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
101
+ value: DESIRED_VALUE_CONFIG
93
102
  )
94
103
  ]
95
104
  )
96
105
  ]
97
106
  )
98
107
 
99
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
108
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
100
109
  namespace: nil)
101
110
 
102
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
103
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).string
104
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).string
111
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
112
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).unwrapped_value
113
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).unwrapped_value
105
114
  end
106
115
 
107
116
  def test_prop_is_one_of
108
117
  config = PrefabProto::Config.new(
109
118
  key: KEY,
110
119
  rows: [
111
- DEFAULT_ROW,
112
120
  PrefabProto::ConfigRow.new(
113
121
  project_env_id: PROJECT_ENV_ID,
114
122
  values: [
@@ -120,19 +128,20 @@ class TestCriteriaEvaluator < Minitest::Test
120
128
  property_name: 'user.email_suffix'
121
129
  )
122
130
  ],
123
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
131
+ value: DESIRED_VALUE_CONFIG
124
132
  )
125
133
  ]
126
- )
134
+ ),
135
+ DEFAULT_ROW
127
136
  ]
128
137
  )
129
138
 
130
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
139
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
131
140
  namespace: nil)
132
141
 
133
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
134
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).string
135
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).string
142
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
143
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).unwrapped_value
144
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).unwrapped_value
136
145
  end
137
146
 
138
147
  def test_prop_is_not_one_of
@@ -151,19 +160,19 @@ class TestCriteriaEvaluator < Minitest::Test
151
160
  property_name: 'user.email_suffix'
152
161
  )
153
162
  ],
154
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
163
+ value: DESIRED_VALUE_CONFIG
155
164
  )
156
165
  ]
157
166
  )
158
167
  ]
159
168
  )
160
169
 
161
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
170
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
162
171
  namespace: nil)
163
172
 
164
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
165
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).string
166
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).string
173
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
174
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).unwrapped_value
175
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).unwrapped_value
167
176
  end
168
177
 
169
178
  def test_prop_ends_with_one_of
@@ -182,19 +191,19 @@ class TestCriteriaEvaluator < Minitest::Test
182
191
  property_name: 'user.email'
183
192
  )
184
193
  ],
185
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
194
+ value: DESIRED_VALUE_CONFIG
186
195
  )
187
196
  ]
188
197
  )
189
198
  ]
190
199
  )
191
200
 
192
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
201
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
193
202
  namespace: nil)
194
203
 
195
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
196
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
197
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
204
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
205
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
206
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
198
207
  end
199
208
 
200
209
  def test_prop_does_not_end_with_one_of
@@ -213,19 +222,19 @@ class TestCriteriaEvaluator < Minitest::Test
213
222
  property_name: 'user.email'
214
223
  )
215
224
  ],
216
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
225
+ value: DESIRED_VALUE_CONFIG
217
226
  )
218
227
  ]
219
228
  )
220
229
  ]
221
230
  )
222
231
 
223
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
232
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
224
233
  namespace: nil)
225
234
 
226
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
227
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
228
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
235
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
236
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
237
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
229
238
  end
230
239
 
231
240
  def test_in_seg
@@ -238,7 +247,7 @@ class TestCriteriaEvaluator < Minitest::Test
238
247
  PrefabProto::ConfigRow.new(
239
248
  values: [
240
249
  PrefabProto::ConditionalValue.new(
241
- value: PrefabProto::ConfigValue.new(bool: true),
250
+ value: TRUE_CONFIG,
242
251
  criteria: [
243
252
  PrefabProto::Criterion.new(
244
253
  operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
@@ -247,9 +256,7 @@ class TestCriteriaEvaluator < Minitest::Test
247
256
  )
248
257
  ]
249
258
  ),
250
- PrefabProto::ConditionalValue.new(
251
- value: PrefabProto::ConfigValue.new(bool: false)
252
- )
259
+ PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
253
260
  ]
254
261
  )
255
262
  ]
@@ -260,23 +267,6 @@ class TestCriteriaEvaluator < Minitest::Test
260
267
  rows: [
261
268
  DEFAULT_ROW,
262
269
 
263
- # wrong env
264
- PrefabProto::ConfigRow.new(
265
- project_env_id: TEST_ENV_ID,
266
- values: [
267
- PrefabProto::ConditionalValue.new(
268
- criteria: [
269
- PrefabProto::Criterion.new(
270
- operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
271
- value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
272
- )
273
- ],
274
- value: PrefabProto::ConfigValue.new(string: WRONG_ENV_VALUE)
275
- )
276
- ]
277
- ),
278
-
279
- # correct env
280
270
  PrefabProto::ConfigRow.new(
281
271
  project_env_id: PROJECT_ENV_ID,
282
272
  values: [
@@ -287,7 +277,7 @@ class TestCriteriaEvaluator < Minitest::Test
287
277
  value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
288
278
  )
289
279
  ],
290
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
280
+ value: DESIRED_VALUE_CONFIG
291
281
  )
292
282
  ]
293
283
  )
@@ -295,12 +285,12 @@ class TestCriteriaEvaluator < Minitest::Test
295
285
  )
296
286
 
297
287
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
298
- base_client: FakeBaseClient.new, namespace: nil,
288
+ base_client: @base_client, namespace: nil,
299
289
  resolver: resolver_fake({ segment_key => segment_config }))
300
290
 
301
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
302
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
303
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
291
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
292
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
293
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
304
294
  end
305
295
 
306
296
  def test_not_in_seg
@@ -313,7 +303,7 @@ class TestCriteriaEvaluator < Minitest::Test
313
303
  PrefabProto::ConfigRow.new(
314
304
  values: [
315
305
  PrefabProto::ConditionalValue.new(
316
- value: PrefabProto::ConfigValue.new(bool: true),
306
+ value: TRUE_CONFIG,
317
307
  criteria: [
318
308
  PrefabProto::Criterion.new(
319
309
  operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
@@ -322,9 +312,7 @@ class TestCriteriaEvaluator < Minitest::Test
322
312
  )
323
313
  ]
324
314
  ),
325
- PrefabProto::ConditionalValue.new(
326
- value: PrefabProto::ConfigValue.new(bool: false)
327
- )
315
+ PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
328
316
  ]
329
317
  )
330
318
  ]
@@ -344,7 +332,7 @@ class TestCriteriaEvaluator < Minitest::Test
344
332
  value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
345
333
  )
346
334
  ],
347
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
335
+ value: DESIRED_VALUE_CONFIG
348
336
  )
349
337
  ]
350
338
  )
@@ -352,12 +340,12 @@ class TestCriteriaEvaluator < Minitest::Test
352
340
  )
353
341
 
354
342
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
355
- base_client: FakeBaseClient.new, namespace: nil,
343
+ base_client: @base_client, namespace: nil,
356
344
  resolver: resolver_fake({ segment_key => segment_config }))
357
345
 
358
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
359
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
360
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
346
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
347
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
348
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
361
349
  end
362
350
 
363
351
  def test_multiple_conditions_in_one_value
@@ -370,7 +358,7 @@ class TestCriteriaEvaluator < Minitest::Test
370
358
  PrefabProto::ConfigRow.new(
371
359
  values: [
372
360
  PrefabProto::ConditionalValue.new(
373
- value: PrefabProto::ConfigValue.new(bool: true),
361
+ value: TRUE_CONFIG,
374
362
  criteria: [
375
363
  PrefabProto::Criterion.new(
376
364
  operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
@@ -380,14 +368,12 @@ class TestCriteriaEvaluator < Minitest::Test
380
368
 
381
369
  PrefabProto::Criterion.new(
382
370
  operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
383
- value_to_match: PrefabProto::ConfigValue.new(bool: true),
371
+ value_to_match: TRUE_CONFIG,
384
372
  property_name: 'user.admin'
385
373
  )
386
374
  ]
387
375
  ),
388
- PrefabProto::ConditionalValue.new(
389
- value: PrefabProto::ConfigValue.new(bool: false)
390
- )
376
+ PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
391
377
  ]
392
378
  )
393
379
  ]
@@ -409,11 +395,11 @@ class TestCriteriaEvaluator < Minitest::Test
409
395
 
410
396
  PrefabProto::Criterion.new(
411
397
  operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
412
- value_to_match: PrefabProto::ConfigValue.new(bool: true),
398
+ value_to_match: TRUE_CONFIG,
413
399
  property_name: 'user.deleted'
414
400
  )
415
401
  ],
416
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
402
+ value: DESIRED_VALUE_CONFIG
417
403
  )
418
404
  ]
419
405
  )
@@ -421,18 +407,18 @@ class TestCriteriaEvaluator < Minitest::Test
421
407
  )
422
408
 
423
409
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
424
- base_client: FakeBaseClient.new, namespace: nil,
410
+ base_client: @base_client, namespace: nil,
425
411
  resolver: resolver_fake({ segment_key => segment_config }))
426
412
 
427
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
428
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
429
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).string
413
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
414
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
415
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).unwrapped_value
430
416
  assert_equal DEFAULT_VALUE,
431
- evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).string
432
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).string
433
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).string
417
+ evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).unwrapped_value
418
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).unwrapped_value
419
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).unwrapped_value
434
420
  assert_equal DEFAULT_VALUE,
435
- evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).string
421
+ evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).unwrapped_value
436
422
  end
437
423
 
438
424
  def test_multiple_conditions_in_multiple_values
@@ -445,7 +431,7 @@ class TestCriteriaEvaluator < Minitest::Test
445
431
  PrefabProto::ConfigRow.new(
446
432
  values: [
447
433
  PrefabProto::ConditionalValue.new(
448
- value: PrefabProto::ConfigValue.new(bool: true),
434
+ value: TRUE_CONFIG,
449
435
  criteria: [
450
436
  PrefabProto::Criterion.new(
451
437
  operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
@@ -455,18 +441,16 @@ class TestCriteriaEvaluator < Minitest::Test
455
441
  ]
456
442
  ),
457
443
  PrefabProto::ConditionalValue.new(
458
- value: PrefabProto::ConfigValue.new(bool: true),
444
+ value: TRUE_CONFIG,
459
445
  criteria: [
460
446
  PrefabProto::Criterion.new(
461
447
  operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
462
- value_to_match: PrefabProto::ConfigValue.new(bool: true),
448
+ value_to_match: TRUE_CONFIG,
463
449
  property_name: 'user.admin'
464
450
  )
465
451
  ]
466
452
  ),
467
- PrefabProto::ConditionalValue.new(
468
- value: PrefabProto::ConfigValue.new(bool: false)
469
- )
453
+ PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
470
454
  ]
471
455
  )
472
456
  ]
@@ -488,11 +472,11 @@ class TestCriteriaEvaluator < Minitest::Test
488
472
 
489
473
  PrefabProto::Criterion.new(
490
474
  operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
491
- value_to_match: PrefabProto::ConfigValue.new(bool: true),
475
+ value_to_match: TRUE_CONFIG,
492
476
  property_name: 'user.deleted'
493
477
  )
494
478
  ],
495
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
479
+ value: DESIRED_VALUE_CONFIG
496
480
  )
497
481
  ]
498
482
  )
@@ -500,19 +484,19 @@ class TestCriteriaEvaluator < Minitest::Test
500
484
  )
501
485
 
502
486
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
503
- base_client: FakeBaseClient.new, namespace: nil,
487
+ base_client: @base_client, namespace: nil,
504
488
  resolver: resolver_fake({ segment_key => segment_config }))
505
489
 
506
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
507
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
508
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { admin: true })).string
509
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).string
490
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
491
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
492
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { admin: true })).unwrapped_value
493
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).unwrapped_value
510
494
  assert_equal DEFAULT_VALUE,
511
- evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).string
512
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).string
513
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).string
495
+ evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).unwrapped_value
496
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).unwrapped_value
497
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).unwrapped_value
514
498
  assert_equal DEFAULT_VALUE,
515
- evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).string
499
+ evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).unwrapped_value
516
500
  end
517
501
 
518
502
  def test_stringifying_property_values_and_names
@@ -531,7 +515,7 @@ class TestCriteriaEvaluator < Minitest::Test
531
515
  property_name: 'team.name'
532
516
  )
533
517
  ],
534
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
518
+ value: DESIRED_VALUE_CONFIG
535
519
  )
536
520
  ]
537
521
  )
@@ -539,15 +523,15 @@ class TestCriteriaEvaluator < Minitest::Test
539
523
  )
540
524
 
541
525
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
542
- namespace: nil, base_client: FakeBaseClient.new)
526
+ namespace: nil, base_client: @base_client)
543
527
 
544
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
545
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(team: { name: 'prefab.cloud' })).string
528
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
529
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context(team: { name: 'prefab.cloud' })).unwrapped_value
546
530
 
547
531
  [1, true, :hello].each do |value|
548
532
  [:name, 'name'].each do |property_name|
549
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value })).string
550
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value.to_s })).string
533
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value })).unwrapped_value
534
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value.to_s })).unwrapped_value
551
535
  end
552
536
  end
553
537
  end
@@ -564,7 +548,7 @@ class TestCriteriaEvaluator < Minitest::Test
564
548
  PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::IN_INT_RANGE,
565
549
  value_to_match: PrefabProto::ConfigValue.new(int_range: PrefabProto::IntRange.new(start: 30, end: 40)), property_name: 'user.age')
566
550
  ],
567
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
551
+ value: DESIRED_VALUE_CONFIG
568
552
  ),
569
553
 
570
554
  PrefabProto::ConditionalValue.new(
@@ -579,12 +563,12 @@ class TestCriteriaEvaluator < Minitest::Test
579
563
  )
580
564
 
581
565
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
582
- namespace: nil, base_client: FakeBaseClient.new)
566
+ namespace: nil, base_client: @base_client)
583
567
 
584
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
585
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 32 } })).string
586
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 29 } })).string
587
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 41 } })).string
568
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
569
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 32 } })).unwrapped_value
570
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 29 } })).unwrapped_value
571
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 41 } })).unwrapped_value
588
572
  end
589
573
 
590
574
  def test_in_int_range_for_time
@@ -605,7 +589,7 @@ class TestCriteriaEvaluator < Minitest::Test
605
589
  )
606
590
  ), property_name: 'prefab.current-time')
607
591
  ],
608
- value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
592
+ value: DESIRED_VALUE_CONFIG
609
593
  ),
610
594
 
611
595
  PrefabProto::ConditionalValue.new(
@@ -620,27 +604,82 @@ class TestCriteriaEvaluator < Minitest::Test
620
604
  )
621
605
 
622
606
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
623
- namespace: nil, base_client: FakeBaseClient.new)
607
+ namespace: nil, base_client: @base_client)
624
608
 
625
609
  Timecop.freeze(now) do
626
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
610
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
627
611
  end
628
612
 
629
613
  Timecop.freeze(now - 60) do
630
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
614
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
631
615
  end
632
616
 
633
617
  Timecop.freeze(now - 61) do
634
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
618
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
635
619
  end
636
620
 
637
621
  Timecop.freeze(now + 59) do
638
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
622
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
639
623
  end
640
624
 
641
625
  Timecop.freeze(now + 60) do
642
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
626
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
627
+ end
628
+ end
629
+
630
+ def test_evaluating_a_log_level
631
+ config = PrefabProto::Config.new(
632
+ id: 999,
633
+ key: 'log-level',
634
+ config_type: PrefabProto::ConfigType::LOG_LEVEL,
635
+ rows: [
636
+ PrefabProto::ConfigRow.new(
637
+ values: [
638
+ PrefabProto::ConditionalValue.new(
639
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
640
+ value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
641
+ )
642
+ ]
643
+ )
644
+ ]
645
+ )
646
+
647
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
648
+
649
+ assert_equal :DEBUG, evaluator.evaluate(context({})).unwrapped_value
650
+ end
651
+
652
+ def test_evaluating_a_weighted_value
653
+ config = PrefabProto::Config.new(
654
+ id: 123,
655
+ key: KEY,
656
+ config_type: PrefabProto::ConfigType::CONFIG,
657
+ rows: [
658
+ PrefabProto::ConfigRow.new(
659
+ project_env_id: PROJECT_ENV_ID,
660
+ values: [
661
+ PrefabProto::ConditionalValue.new(
662
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
663
+ value: PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 98], ['def', 1], ['ghi', 1]]))
664
+ )
665
+ ]
666
+ )
667
+ ]
668
+ )
669
+
670
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
671
+
672
+ 2.times do
673
+ assert_equal 'abc', evaluator.evaluate(context('user' => { 'key' => '1' })).unwrapped_value
674
+ end
675
+
676
+ 3.times do
677
+ context = context({ 'user' => { 'key' => '12' } })
678
+ assert_equal 'def', evaluator.evaluate(context).unwrapped_value
643
679
  end
680
+
681
+ context = context({ 'user' => { 'key' => '4' } })
682
+ assert_equal 'ghi', evaluator.evaluate(context).unwrapped_value
644
683
  end
645
684
 
646
685
  private
@@ -650,8 +689,9 @@ class TestCriteriaEvaluator < Minitest::Test
650
689
  end
651
690
 
652
691
  class FakeResolver
653
- def initialize(config)
692
+ def initialize(config, base_client)
654
693
  @config = config
694
+ @base_client = base_client
655
695
  end
656
696
 
657
697
  def raw(key)
@@ -661,16 +701,12 @@ class TestCriteriaEvaluator < Minitest::Test
661
701
  def get(key, properties = {})
662
702
  # This only gets called for segments, so we don't need to pass in a resolver
663
703
  Prefab::CriteriaEvaluator.new(@config[key], project_env_id: nil, resolver: nil,
664
- namespace: nil, base_client: FakeBaseClient.new).evaluate(properties)
704
+ namespace: nil, base_client: @base_client).evaluate(properties)
665
705
  end
666
706
  end
667
707
 
668
708
  def resolver_fake(config)
669
- FakeResolver.new(config)
670
- end
671
-
672
- def context(properties)
673
- Prefab::Context.new(properties)
709
+ FakeResolver.new(config, @base_client)
674
710
  end
675
711
 
676
712
  class FakeLogger
@@ -678,11 +714,21 @@ class TestCriteriaEvaluator < Minitest::Test
678
714
  # loudly complain about unexpected log messages
679
715
  raise msg
680
716
  end
717
+
718
+ def log_internal(*args); end
681
719
  end
682
720
 
683
721
  class FakeBaseClient
684
722
  def log
685
723
  FakeLogger.new
686
724
  end
725
+
726
+ def evaluation_summary_aggregator
727
+ @evaluation_summary_aggregator ||= Prefab::EvaluationSummaryAggregator.new(client: self, max_keys: 9999, sync_interval: 9999)
728
+ end
729
+
730
+ def instance_hash
731
+ 'fake-base-client-instance_hash'
732
+ end
687
733
  end
688
734
  end