prefab-cloud-ruby 0.24.5 → 1.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/VERSION +1 -1
  4. data/compile_protos.sh +7 -0
  5. data/lib/prefab/client.rb +20 -46
  6. data/lib/prefab/config_client.rb +9 -12
  7. data/lib/prefab/config_resolver.rb +2 -1
  8. data/lib/prefab/config_value_unwrapper.rb +20 -9
  9. data/lib/prefab/context.rb +43 -7
  10. data/lib/prefab/context_shape_aggregator.rb +1 -1
  11. data/lib/prefab/criteria_evaluator.rb +24 -16
  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/feature_flag_client.rb +0 -2
  17. data/lib/prefab/log_path_aggregator.rb +1 -1
  18. data/lib/prefab/logger_client.rb +12 -13
  19. data/lib/prefab/options.rb +52 -43
  20. data/lib/prefab/periodic_sync.rb +30 -13
  21. data/lib/prefab/rate_limit_cache.rb +41 -0
  22. data/lib/prefab/resolved_config_presenter.rb +2 -4
  23. data/lib/prefab/weighted_value_resolver.rb +1 -1
  24. data/lib/prefab-cloud-ruby.rb +5 -5
  25. data/lib/prefab_pb.rb +11 -1
  26. data/prefab-cloud-ruby.gemspec +14 -9
  27. data/test/integration_test.rb +1 -3
  28. data/test/integration_test_helpers.rb +0 -1
  29. data/test/support/common_helpers.rb +174 -0
  30. data/test/support/mock_base_client.rb +44 -0
  31. data/test/support/mock_config_client.rb +19 -0
  32. data/test/support/mock_config_loader.rb +1 -0
  33. data/test/test_client.rb +354 -40
  34. data/test/test_config_client.rb +1 -0
  35. data/test/test_config_loader.rb +1 -0
  36. data/test/test_config_resolver.rb +25 -24
  37. data/test/test_config_value_unwrapper.rb +22 -32
  38. data/test/test_context.rb +1 -0
  39. data/test/test_context_shape_aggregator.rb +11 -1
  40. data/test/test_criteria_evaluator.rb +180 -133
  41. data/test/test_evaluation_summary_aggregator.rb +162 -0
  42. data/test/test_example_contexts_aggregator.rb +238 -0
  43. data/test/test_helper.rb +5 -131
  44. data/test/test_integration.rb +6 -4
  45. data/test/test_local_config_parser.rb +2 -2
  46. data/test/test_log_path_aggregator.rb +9 -1
  47. data/test/test_logger.rb +6 -5
  48. data/test/test_options.rb +33 -2
  49. data/test/test_rate_limit_cache.rb +44 -0
  50. data/test/test_weighted_value_resolver.rb +13 -7
  51. metadata +13 -8
  52. data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
  53. data/lib/prefab/evaluated_keys_aggregator.rb +0 -41
  54. data/lib/prefab/noop_cache.rb +0 -15
  55. data/lib/prefab/noop_stats.rb +0 -8
  56. data/test/test_evaluated_configs_aggregator.rb +0 -254
  57. data/test/test_evaluated_keys_aggregator.rb +0 -54
data/test/test_client.rb CHANGED
@@ -3,34 +3,54 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class TestClient < Minitest::Test
6
- def setup
7
- @client = new_client
8
- end
6
+ LOCAL_ONLY = Prefab::Options::DATASOURCES::LOCAL_ONLY
7
+
8
+ PROJECT_ENV_ID = 1
9
+ KEY = 'the-key'
10
+ DEFAULT_VALUE = 'default_value'
11
+ DESIRED_VALUE = 'desired_value'
12
+
13
+ IRRELEVANT = 'this should never show up'
14
+
15
+ DEFAULT_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
16
+ DESIRED_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
17
+
18
+ TRUE_CONFIG = PrefabProto::ConfigValue.new(bool: true)
19
+ FALSE_CONFIG = PrefabProto::ConfigValue.new(bool: false)
20
+
21
+ DEFAULT_ROW = PrefabProto::ConfigRow.new(
22
+ values: [
23
+ PrefabProto::ConditionalValue.new(value: DEFAULT_VALUE_CONFIG)
24
+ ]
25
+ )
9
26
 
10
27
  def test_get
11
28
  _, err = capture_io do
12
- assert_equal 'default', @client.get('does.not.exist', 'default')
13
- assert_equal 'test sample value', @client.get('sample')
14
- assert_equal 123, @client.get('sample_int')
29
+ client = new_client
30
+ assert_equal 'default', client.get('does.not.exist', 'default')
31
+ assert_equal 'test sample value', client.get('sample')
32
+ assert_equal 123, client.get('sample_int')
15
33
  end
16
34
  assert_equal '', err
17
35
  end
18
36
 
19
37
  def test_get_with_default
38
+ client = new_client
20
39
  # A `false` value is not replaced with the default
21
- assert_equal false, @client.get('false_value', 'red')
40
+ assert_equal false, client.get('false_value', 'red')
22
41
 
23
42
  # A falsy value is not replaced with the default
24
- assert_equal 0, @client.get('zero_value', 'red')
43
+ assert_equal 0, client.get('zero_value', 'red')
25
44
 
26
45
  # A missing value returns the default
27
- assert_equal 'buckets', @client.get('missing_value', 'buckets')
46
+ assert_equal 'buckets', client.get('missing_value', 'buckets')
28
47
  end
29
48
 
30
49
  def test_get_with_missing_default
50
+ client = new_client
31
51
  # it raises by default
32
52
  err = assert_raises(Prefab::Errors::MissingDefaultError) do
33
- assert_nil @client.get('missing_value')
53
+ assert_nil client.get('missing_value')
34
54
  end
35
55
 
36
56
  assert_match(/No value found for key/, err.message)
@@ -42,53 +62,87 @@ class TestClient < Minitest::Test
42
62
  end
43
63
 
44
64
  def test_enabled
45
- assert_equal false, @client.enabled?('does_not_exist')
46
- assert_equal true, @client.enabled?('enabled_flag')
47
- assert_equal false, @client.enabled?('disabled_flag')
48
- assert_equal false, @client.enabled?('flag_with_a_value')
65
+ client = new_client
66
+ assert_equal false, client.enabled?('does_not_exist')
67
+ assert_equal true, client.enabled?('enabled_flag')
68
+ assert_equal false, client.enabled?('disabled_flag')
69
+ assert_equal false, client.enabled?('flag_with_a_value')
49
70
  end
50
71
 
51
72
  def test_ff_enabled_with_user_key_match
52
- assert_equal_context_and_jit(false, :enabled?, 'user_key_match', { user: { key: 'jimmy' } })
53
- assert_equal_context_and_jit(true, :enabled?, 'user_key_match', { user: { key: 'abc123' } })
54
- assert_equal_context_and_jit(true, :enabled?, 'user_key_match', { user: { key: 'xyz987' } })
73
+ client = new_client
74
+
75
+ ctx = { user: { key: 'jimmy' } }
76
+ assert_equal false, client.enabled?('user_key_match', ctx)
77
+ assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
78
+
79
+ ctx = { user: { key: 'abc123' } }
80
+ assert_equal true, client.enabled?('user_key_match', ctx)
81
+ assert_equal true, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
82
+
83
+ ctx = { user: { key: 'xyz987' } }
84
+ assert_equal true, client.enabled?('user_key_match', ctx)
85
+ assert_equal true, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
55
86
  end
56
87
 
88
+ # NOTE: these are all `false` because we're doing a enabled? on a FF with string variants
89
+ # see test_ff_get_with_context for the raw value tests
57
90
  def test_ff_enabled_with_context
58
- assert_equal_context_and_jit(false, :enabled?, 'just_my_domain', user: { domain: 'gmail.com' })
59
- assert_equal_context_and_jit(false, :enabled?, 'just_my_domain', user: { domain: 'prefab.cloud' })
60
- assert_equal_context_and_jit(false, :enabled?, 'just_my_domain', user: { domain: 'example.com' })
91
+ client = new_client
92
+
93
+ ctx = { user: { domain: 'gmail.com' } }
94
+ assert_equal false, client.enabled?('just_my_domain', ctx)
95
+ assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
96
+
97
+ ctx = { user: { domain: 'prefab.cloud' } }
98
+ assert_equal false, client.enabled?('just_my_domain', ctx)
99
+ assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
100
+
101
+ ctx = { user: { domain: 'example.com' } }
102
+ assert_equal false, client.enabled?('just_my_domain', ctx)
103
+ assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
61
104
  end
62
105
 
63
106
  def test_ff_get_with_context
64
- assert_nil @client.get('just_my_domain', 'abc123', user: { domain: 'gmail.com' })
65
- assert_equal 'DEFAULT', @client.get('just_my_domain', 'abc123', { user: { domain: 'gmail.com' } }, 'DEFAULT')
107
+ client = new_client
66
108
 
67
- assert_equal_context_and_jit('new-version', :get, 'just_my_domain', { user: { domain: 'prefab.cloud' } })
68
- assert_equal_context_and_jit('new-version', :get, 'just_my_domain', { user: { domain: 'example.com' } })
109
+ ctx = { user: { domain: 'gmail.com' } }
110
+ assert_equal 'DEFAULT', client.get('just_my_domain', 'DEFAULT', ctx)
111
+ assert_equal 'DEFAULT', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
112
+
113
+ ctx = { user: { domain: 'prefab.cloud' } }
114
+ assert_equal 'new-version', client.get('just_my_domain', 'DEFAULT', ctx)
115
+ assert_equal 'new-version', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
116
+
117
+ ctx = { user: { domain: 'example.com' } }
118
+ assert_equal 'new-version', client.get('just_my_domain', 'DEFAULT', ctx)
119
+ assert_equal 'new-version', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
69
120
  end
70
121
 
71
122
  def test_deprecated_no_dot_notation_ff_enabled_with_jit_context
123
+ client = new_client
72
124
  # with no lookup key
73
- assert_equal false, @client.enabled?('deprecated_no_dot_notation', { domain: 'gmail.com' })
74
- assert_equal true, @client.enabled?('deprecated_no_dot_notation', { domain: 'prefab.cloud' })
75
- assert_equal true, @client.enabled?('deprecated_no_dot_notation', { domain: 'example.com' })
125
+ assert_equal false, client.enabled?('deprecated_no_dot_notation', { domain: 'gmail.com' })
126
+ assert_equal true, client.enabled?('deprecated_no_dot_notation', { domain: 'prefab.cloud' })
127
+ assert_equal true, client.enabled?('deprecated_no_dot_notation', { domain: 'example.com' })
76
128
 
77
- # with a lookup key
78
- assert_equal false, @client.enabled?('deprecated_no_dot_notation', 'some-lookup-key', { domain: 'gmail.com' })
79
- assert_equal true, @client.enabled?('deprecated_no_dot_notation', 'some-lookup-key', { domain: 'prefab.cloud' })
80
- assert_equal true, @client.enabled?('deprecated_no_dot_notation', 'some-lookup-key', { domain: 'example.com' })
129
+ assert_stderr [
130
+ "[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash.",
131
+ "[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash.",
132
+ "[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash."
133
+ ]
81
134
  end
82
135
 
83
136
  def test_getting_feature_flag_value
84
- assert_equal false, @client.enabled?('flag_with_a_value')
85
- assert_equal 'all-features', @client.get('flag_with_a_value')
137
+ client = new_client
138
+ assert_equal false, client.enabled?('flag_with_a_value')
139
+ assert_equal 'all-features', client.get('flag_with_a_value')
86
140
  end
87
141
 
88
142
  def test_initialization_with_an_options_object
89
143
  options_hash = {
90
144
  namespace: 'test-namespace',
91
- prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
145
+ prefab_datasources: LOCAL_ONLY
92
146
  }
93
147
 
94
148
  options = Prefab::Options.new(options_hash)
@@ -101,7 +155,7 @@ class TestClient < Minitest::Test
101
155
  def test_initialization_with_a_hash
102
156
  options_hash = {
103
157
  namespace: 'test-namespace',
104
- prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
158
+ prefab_datasources: LOCAL_ONLY
105
159
  }
106
160
 
107
161
  client = Prefab::Client.new(options_hash)
@@ -109,13 +163,273 @@ class TestClient < Minitest::Test
109
163
  assert_equal client.namespace, 'test-namespace'
110
164
  end
111
165
 
112
- private
166
+ def test_evaluation_summary_aggregator
167
+ fake_api_key = '123-development-yourapikey-SDK'
168
+
169
+ # it is nil by default
170
+ assert_nil new_client(api_key: fake_api_key).evaluation_summary_aggregator
171
+
172
+ # it is nil when local_only even if collect_max_evaluation_summaries is true
173
+ assert_nil new_client(prefab_datasources: LOCAL_ONLY,
174
+ collect_evaluation_summaries: true, ).evaluation_summary_aggregator
175
+
176
+ # it is nil when collect_max_evaluation_summaries is false
177
+ assert_nil new_client(api_key: fake_api_key,
178
+ prefab_datasources: :all,
179
+ collect_evaluation_summaries: false).evaluation_summary_aggregator
180
+
181
+ # it is not nil when collect_max_evaluation_summaries is true and the datasource is not local_only
182
+ assert_equal Prefab::EvaluationSummaryAggregator,
183
+ new_client(api_key: fake_api_key,
184
+ prefab_datasources: :all,
185
+ collect_evaluation_summaries: true).evaluation_summary_aggregator.class
186
+
187
+ assert_logged [
188
+ "WARN 2023-08-09 15:18:12 -0400: cloud.prefab.client No success loading checkpoints"
189
+ ]
190
+ end
191
+
192
+ def test_get_with_basic_value
193
+ config = basic_value_config
194
+ client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
195
+ context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
196
+
197
+ assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, 'user' => { 'key' => 99 })
198
+
199
+ assert_summary client, {
200
+ [KEY, :CONFIG] => {
201
+ {
202
+ config_id: config.id,
203
+ config_row_index: 1,
204
+ selected_value: DESIRED_VALUE_CONFIG,
205
+ conditional_value_index: 0,
206
+ weighted_value_index: nil,
207
+ selected_index: nil
208
+ } => 1
209
+ }
210
+ }
211
+
212
+ assert_example_contexts client, [Prefab::Context.new({ user: { 'key' => 99 } })]
213
+ end
214
+
215
+ def test_get_with_basic_value_with_context
216
+ config = basic_value_config
217
+ client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
218
+ context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
219
+
220
+ client.with_context('user' => { 'key' => 99 }) do
221
+ assert_equal DESIRED_VALUE, client.get(config.key)
222
+ end
223
+
224
+ assert_summary client, {
225
+ [KEY, :CONFIG] => {
226
+ {
227
+ config_id: config.id,
228
+ config_row_index: 1,
229
+ selected_value: DESIRED_VALUE_CONFIG,
230
+ conditional_value_index: 0,
231
+ weighted_value_index: nil,
232
+ selected_index: nil
233
+ } => 1
234
+ }
235
+ }
236
+
237
+ assert_example_contexts client, [Prefab::Context.new({ user: { 'key' => 99 } })]
238
+ end
239
+
240
+ def test_get_with_weighted_values
241
+ config = PrefabProto::Config.new(
242
+ id: 123,
243
+ key: KEY,
244
+ config_type: PrefabProto::ConfigType::CONFIG,
245
+ rows: [
246
+ DEFAULT_ROW,
247
+ PrefabProto::ConfigRow.new(
248
+ project_env_id: PROJECT_ENV_ID,
249
+ values: [
250
+ PrefabProto::ConditionalValue.new(
251
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
252
+ value: PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 98], ['def', 1],
253
+ ['ghi', 1]]))
254
+ )
255
+ ]
256
+ )
257
+ ]
258
+ )
113
259
 
114
- def assert_equal_context_and_jit(expected, method, key, context)
115
- assert_equal expected, @client.send(method, key, context)
260
+ client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
261
+ context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
116
262
 
117
- Prefab::Context.with_context(context) do
118
- assert_equal expected, @client.send(method, key)
263
+ 2.times do
264
+ assert_equal 'abc', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '1' })
119
265
  end
266
+
267
+ 3.times do
268
+ assert_equal 'def', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '12' })
269
+ end
270
+
271
+ assert_equal 'ghi',
272
+ client.get(config.key, IRRELEVANT, 'user' => { 'key' => '4', admin: true })
273
+
274
+ assert_summary client, {
275
+ [KEY, :CONFIG] => {
276
+ {
277
+ config_id: config.id,
278
+ config_row_index: 1,
279
+ selected_value: PrefabProto::ConfigValue.new(string: 'abc'),
280
+ conditional_value_index: 0,
281
+ weighted_value_index: 0,
282
+ selected_index: nil
283
+ } => 2,
284
+
285
+ {
286
+ config_id: config.id,
287
+ config_row_index: 1,
288
+ selected_value: PrefabProto::ConfigValue.new(string: 'def'),
289
+ conditional_value_index: 0,
290
+ weighted_value_index: 1,
291
+ selected_index: nil
292
+ } => 3,
293
+
294
+ {
295
+ config_id: config.id,
296
+ config_row_index: 1,
297
+ selected_value: PrefabProto::ConfigValue.new(string: 'ghi'),
298
+ conditional_value_index: 0,
299
+ weighted_value_index: 2,
300
+ selected_index: nil
301
+ } => 1
302
+ }
303
+ }
304
+
305
+ assert_example_contexts client, [
306
+ Prefab::Context.new(user: { 'key' => '1' }),
307
+ Prefab::Context.new(user: { 'key' => '12' }),
308
+ Prefab::Context.new(user: { 'key' => '4', admin: true })
309
+ ]
310
+ end
311
+
312
+ def test_in_seg
313
+ segment_key = 'segment_key'
314
+
315
+ segment_config = PrefabProto::Config.new(
316
+ config_type: PrefabProto::ConfigType::SEGMENT,
317
+ key: segment_key,
318
+ rows: [
319
+ PrefabProto::ConfigRow.new(
320
+ values: [
321
+ PrefabProto::ConditionalValue.new(
322
+ value: TRUE_CONFIG,
323
+ criteria: [
324
+ PrefabProto::Criterion.new(
325
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
326
+ value_to_match: string_list(['hotmail.com', 'gmail.com']),
327
+ property_name: 'user.email'
328
+ )
329
+ ]
330
+ ),
331
+ PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
332
+ ]
333
+ )
334
+ ]
335
+ )
336
+
337
+ config = PrefabProto::Config.new(
338
+ key: KEY,
339
+ rows: [
340
+ DEFAULT_ROW,
341
+
342
+ PrefabProto::ConfigRow.new(
343
+ project_env_id: PROJECT_ENV_ID,
344
+ values: [
345
+ PrefabProto::ConditionalValue.new(
346
+ criteria: [
347
+ PrefabProto::Criterion.new(
348
+ operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
349
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
350
+ )
351
+ ],
352
+ value: DESIRED_VALUE_CONFIG
353
+ )
354
+ ]
355
+ )
356
+ ]
357
+ )
358
+
359
+ client = new_client(config: [config, segment_config], project_env_id: PROJECT_ENV_ID,
360
+ collect_evaluation_summaries: true, context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
361
+
362
+ assert_equal DEFAULT_VALUE, client.get(config.key)
363
+ assert_equal DEFAULT_VALUE,
364
+ client.get(config.key, IRRELEVANT, user: { key: 'abc', email: 'example@prefab.cloud' })
365
+ assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, user: { key: 'def', email: 'example@hotmail.com' })
366
+
367
+ assert_summary client, {
368
+ [segment_key, :SEGMENT] => {
369
+ { config_id: 0, config_row_index: 0, conditional_value_index: 1, selected_value: FALSE_CONFIG,
370
+ weighted_value_index: nil, selected_index: nil } => 2,
371
+ { config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: TRUE_CONFIG,
372
+ weighted_value_index: nil, selected_index: nil } => 1
373
+ },
374
+ [KEY, :NOT_SET_CONFIG_TYPE] => {
375
+ { config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: DEFAULT_VALUE_CONFIG,
376
+ weighted_value_index: nil, selected_index: nil } => 2,
377
+ { config_id: 0, config_row_index: 1, conditional_value_index: 0, selected_value: DESIRED_VALUE_CONFIG,
378
+ weighted_value_index: nil, selected_index: nil } => 1
379
+ }
380
+ }
381
+
382
+ assert_example_contexts client, [
383
+ Prefab::Context.new(user: { key: 'abc', email: 'example@prefab.cloud' }),
384
+ Prefab::Context.new(user: { key: 'def', email: 'example@hotmail.com' })
385
+ ]
386
+ end
387
+
388
+ def test_get_log_level
389
+ config = PrefabProto::Config.new(
390
+ id: 999,
391
+ key: 'log-level',
392
+ config_type: PrefabProto::ConfigType::LOG_LEVEL,
393
+ rows: [
394
+ PrefabProto::ConfigRow.new(
395
+ values: [
396
+ PrefabProto::ConditionalValue.new(
397
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
398
+ value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
399
+ )
400
+ ]
401
+ )
402
+ ]
403
+ )
404
+
405
+ client = new_client(config: config, project_env_id: PROJECT_ENV_ID,
406
+ collect_evaluation_summaries: true, allow_telemetry_in_local_mode: true)
407
+
408
+ assert_equal :DEBUG, client.get(config.key, IRRELEVANT)
409
+
410
+ # nothing is summarized for log levels
411
+ assert_summary client, {}
412
+ end
413
+
414
+ private
415
+
416
+ def basic_value_config
417
+ PrefabProto::Config.new(
418
+ id: 123,
419
+ key: KEY,
420
+ config_type: PrefabProto::ConfigType::CONFIG,
421
+ rows: [
422
+ DEFAULT_ROW,
423
+ PrefabProto::ConfigRow.new(
424
+ project_env_id: PROJECT_ENV_ID,
425
+ values: [
426
+ PrefabProto::ConditionalValue.new(
427
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
428
+ value: DESIRED_VALUE_CONFIG
429
+ )
430
+ ]
431
+ )
432
+ ]
433
+ )
120
434
  end
121
435
  end
@@ -4,6 +4,7 @@ require 'test_helper'
4
4
 
5
5
  class TestConfigClient < Minitest::Test
6
6
  def setup
7
+ super
7
8
  options = Prefab::Options.new(
8
9
  prefab_config_override_dir: 'none',
9
10
  prefab_config_classpath_dir: 'test',
@@ -4,6 +4,7 @@ require 'test_helper'
4
4
 
5
5
  class TestConfigLoader < Minitest::Test
6
6
  def setup
7
+ super
7
8
  options = Prefab::Options.new(
8
9
  prefab_config_override_dir: 'none',
9
10
  prefab_config_classpath_dir: 'test',
@@ -22,6 +22,10 @@ class TestConfigResolver < Minitest::Test
22
22
  ]
23
23
  )
24
24
 
25
+ class MockConfigLoader
26
+ def calc_config; end
27
+ end
28
+
25
29
  def test_resolution
26
30
  @loader = MockConfigLoader.new
27
31
 
@@ -117,31 +121,30 @@ class TestConfigResolver < Minitest::Test
117
121
 
118
122
  @loader.stub :calc_config, loaded_values do
119
123
  @resolverA = resolver_for_namespace('', @loader, project_env_id: PRODUCTION_ENV_ID)
120
- assert_equal_context_and_jit DEFAULT_VALUE, @resolverA, 'key', {}, :string
124
+ assert_equal_context_and_jit DEFAULT_VALUE, @resolverA, 'key', {}
121
125
 
122
126
  ## below here in the test env
123
127
  @resolverA = resolver_for_namespace('', @loader)
124
- assert_equal_context_and_jit 'value_none', @resolverA, 'key', {}, :string
128
+ assert_equal_context_and_jit 'value_none', @resolverA, 'key', {}
125
129
 
126
130
  @resolverA = resolver_for_namespace('projectA', @loader)
127
- assert_equal_context_and_jit 'valueA', @resolverA, 'key', {}, :string
131
+ assert_equal_context_and_jit 'valueA', @resolverA, 'key', {}
128
132
 
129
133
  @resolverB = resolver_for_namespace('projectB', @loader)
130
- assert_equal_context_and_jit 'valueB', @resolverB, 'key', {}, :string
134
+ assert_equal_context_and_jit 'valueB', @resolverB, 'key', {}
131
135
 
132
136
  @resolverBX = resolver_for_namespace('projectB.subprojectX', @loader)
133
- assert_equal_context_and_jit 'projectB.subprojectX', @resolverBX, 'key', {}, :string
137
+ assert_equal_context_and_jit 'projectB.subprojectX', @resolverBX, 'key', {}
134
138
 
135
139
  @resolverBX = resolver_for_namespace('projectB.subprojectX', @loader)
136
- assert_equal_context_and_jit 'valueB2', @resolverBX, 'key2', {}, :string
140
+ assert_equal_context_and_jit 'valueB2', @resolverBX, 'key2', {}
137
141
 
138
142
  @resolverUndefinedSubProject = resolver_for_namespace('projectB.subprojectX.subsubQ',
139
143
  @loader)
140
- assert_equal_context_and_jit 'projectB.subprojectX', @resolverUndefinedSubProject, 'key',
141
- {}, :string
144
+ assert_equal_context_and_jit 'projectB.subprojectX', @resolverUndefinedSubProject, 'key', {}
142
145
 
143
146
  @resolverBX = resolver_for_namespace('projectC', @loader)
144
- assert_equal_context_and_jit 'value_none', @resolverBX, 'key', {}, :string
147
+ assert_equal_context_and_jit 'value_none', @resolverBX, 'key', {}
145
148
 
146
149
  assert_nil @resolverBX.get('key_that_doesnt_exist', nil)
147
150
 
@@ -244,9 +247,9 @@ class TestConfigResolver < Minitest::Test
244
247
  resolver.project_env_id = PRODUCTION_ENV_ID
245
248
 
246
249
  assert_equal_context_and_jit DEFAULT_VALUE, resolver, CONFIG_KEY,
247
- { user: { email: 'test@something-else.com' } }, :string
250
+ { user: { email: 'test@something-else.com' } }
248
251
  assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY,
249
- { user: { email: 'test@hotmail.com' } }, :string
252
+ { user: { email: 'test@hotmail.com' } }
250
253
  end
251
254
  end
252
255
 
@@ -312,10 +315,8 @@ class TestConfigResolver < Minitest::Test
312
315
  options = Prefab::Options.new
313
316
  resolver = Prefab::ConfigResolver.new(MockBaseClient.new(options), loader)
314
317
 
315
- assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@hotmail.com' } },
316
- :string
317
- assert_equal_context_and_jit NOT_IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@something-else.com' } },
318
- :string
318
+ assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@hotmail.com' } }
319
+ assert_equal_context_and_jit NOT_IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@something-else.com' } }
319
320
  end
320
321
  end
321
322
 
@@ -356,9 +357,9 @@ class TestConfigResolver < Minitest::Test
356
357
  resolver.project_env_id = TEST_ENV_ID
357
358
 
358
359
  Prefab::Context.with_context({ user: { email: 'test@example.com' } }) do
359
- assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).string
360
- assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).string
361
- assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'pro' } }).string
360
+ assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).unwrapped_value
361
+ assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).unwrapped_value
362
+ assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'pro' } }).unwrapped_value
362
363
  end
363
364
  end
364
365
  end
@@ -400,9 +401,9 @@ class TestConfigResolver < Minitest::Test
400
401
  resolver.project_env_id = TEST_ENV_ID
401
402
 
402
403
  Prefab::Context.with_context({ user: { email: 'test@hotmail.com' }, team: { plan: 'pro' } }) do
403
- assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).string
404
- assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { user: { email: 'test@example.com' } }).string
405
- assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).string
404
+ assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).unwrapped_value
405
+ assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { user: { email: 'test@example.com' } }).unwrapped_value
406
+ assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).unwrapped_value
406
407
  end
407
408
  end
408
409
  end
@@ -419,11 +420,11 @@ class TestConfigResolver < Minitest::Test
419
420
  resolver
420
421
  end
421
422
 
422
- def assert_equal_context_and_jit(expected_value, resolver, key, properties, type)
423
- assert_equal expected_value, resolver.get(key, properties).send(type)
423
+ def assert_equal_context_and_jit(expected_value, resolver, key, properties)
424
+ assert_equal expected_value, resolver.get(key, properties).unwrapped_value
424
425
 
425
426
  Prefab::Context.with_context(properties) do
426
- assert_equal expected_value, resolver.get(key).send(type)
427
+ assert_equal expected_value, resolver.get(key).unwrapped_value
427
428
  end
428
429
  end
429
430
  end