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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/VERSION +1 -1
- data/compile_protos.sh +7 -0
- data/lib/prefab/client.rb +17 -4
- data/lib/prefab/config_client.rb +8 -9
- data/lib/prefab/config_value_unwrapper.rb +20 -9
- data/lib/prefab/context.rb +39 -7
- data/lib/prefab/context_shape_aggregator.rb +1 -1
- data/lib/prefab/criteria_evaluator.rb +24 -16
- data/lib/prefab/evaluated_keys_aggregator.rb +1 -1
- data/lib/prefab/evaluation.rb +48 -0
- data/lib/prefab/evaluation_summary_aggregator.rb +85 -0
- data/lib/prefab/example_contexts_aggregator.rb +76 -0
- data/lib/prefab/exponential_backoff.rb +5 -0
- data/lib/prefab/log_path_aggregator.rb +1 -1
- data/lib/prefab/logger_client.rb +12 -13
- data/lib/prefab/options.rb +27 -14
- data/lib/prefab/periodic_sync.rb +30 -13
- data/lib/prefab/rate_limit_cache.rb +41 -0
- data/lib/prefab/resolved_config_presenter.rb +2 -4
- data/lib/prefab/weighted_value_resolver.rb +1 -1
- data/lib/prefab-cloud-ruby.rb +5 -2
- data/lib/prefab_pb.rb +11 -1
- data/prefab-cloud-ruby.gemspec +14 -5
- data/test/support/common_helpers.rb +105 -0
- data/test/support/mock_base_client.rb +44 -0
- data/test/support/mock_config_client.rb +19 -0
- data/test/support/mock_config_loader.rb +1 -0
- data/test/test_client.rb +257 -2
- data/test/test_config_resolver.rb +25 -24
- data/test/test_config_value_unwrapper.rb +22 -32
- data/test/test_context_shape_aggregator.rb +0 -1
- data/test/test_criteria_evaluator.rb +179 -133
- data/test/test_evaluation_summary_aggregator.rb +162 -0
- data/test/test_example_contexts_aggregator.rb +238 -0
- data/test/test_helper.rb +5 -131
- data/test/test_local_config_parser.rb +2 -2
- data/test/test_logger.rb +5 -5
- data/test/test_options.rb +8 -0
- data/test/test_rate_limit_cache.rb +44 -0
- data/test/test_weighted_value_resolver.rb +13 -7
- metadata +13 -4
- data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
- data/test/test_evaluated_configs_aggregator.rb +0 -254
data/test/test_client.rb
CHANGED
@@ -3,6 +3,27 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class TestClient < Minitest::Test
|
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
|
+
)
|
26
|
+
|
6
27
|
def setup
|
7
28
|
@client = new_client
|
8
29
|
end
|
@@ -88,7 +109,7 @@ class TestClient < Minitest::Test
|
|
88
109
|
def test_initialization_with_an_options_object
|
89
110
|
options_hash = {
|
90
111
|
namespace: 'test-namespace',
|
91
|
-
prefab_datasources:
|
112
|
+
prefab_datasources: LOCAL_ONLY
|
92
113
|
}
|
93
114
|
|
94
115
|
options = Prefab::Options.new(options_hash)
|
@@ -101,7 +122,7 @@ class TestClient < Minitest::Test
|
|
101
122
|
def test_initialization_with_a_hash
|
102
123
|
options_hash = {
|
103
124
|
namespace: 'test-namespace',
|
104
|
-
prefab_datasources:
|
125
|
+
prefab_datasources: LOCAL_ONLY
|
105
126
|
}
|
106
127
|
|
107
128
|
client = Prefab::Client.new(options_hash)
|
@@ -109,6 +130,240 @@ class TestClient < Minitest::Test
|
|
109
130
|
assert_equal client.namespace, 'test-namespace'
|
110
131
|
end
|
111
132
|
|
133
|
+
def test_evaluation_summary_aggregator
|
134
|
+
fake_api_key = '123-development-yourapikey-SDK'
|
135
|
+
|
136
|
+
# it is nil by default
|
137
|
+
assert_nil Prefab::Client.new(api_key: fake_api_key).evaluation_summary_aggregator
|
138
|
+
|
139
|
+
# it is nil when local_only even if collect_max_evaluation_summaries is true
|
140
|
+
assert_nil Prefab::Client.new(prefab_datasources: LOCAL_ONLY,
|
141
|
+
collect_evaluation_summaries: true).evaluation_summary_aggregator
|
142
|
+
|
143
|
+
# it is nil when collect_max_evaluation_summaries is false
|
144
|
+
assert_nil Prefab::Client.new(api_key: fake_api_key,
|
145
|
+
collect_evaluation_summaries: false).evaluation_summary_aggregator
|
146
|
+
|
147
|
+
# it is not nil when collect_max_evaluation_summaries is true and the datasource is not local_only
|
148
|
+
assert_equal Prefab::EvaluationSummaryAggregator,
|
149
|
+
Prefab::Client.new(api_key: fake_api_key,
|
150
|
+
collect_evaluation_summaries: true).evaluation_summary_aggregator.class
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_get_with_basic_value
|
154
|
+
config = PrefabProto::Config.new(
|
155
|
+
id: 123,
|
156
|
+
key: KEY,
|
157
|
+
config_type: PrefabProto::ConfigType::CONFIG,
|
158
|
+
rows: [
|
159
|
+
DEFAULT_ROW,
|
160
|
+
PrefabProto::ConfigRow.new(
|
161
|
+
project_env_id: PROJECT_ENV_ID,
|
162
|
+
values: [
|
163
|
+
PrefabProto::ConditionalValue.new(
|
164
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
165
|
+
value: DESIRED_VALUE_CONFIG
|
166
|
+
)
|
167
|
+
]
|
168
|
+
)
|
169
|
+
]
|
170
|
+
)
|
171
|
+
|
172
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: :force,
|
173
|
+
collect_example_contexts: :force)
|
174
|
+
|
175
|
+
assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, 'user' => { 'key' => 99 })
|
176
|
+
|
177
|
+
assert_summary client, {
|
178
|
+
[KEY, :CONFIG] => {
|
179
|
+
{
|
180
|
+
config_id: config.id,
|
181
|
+
config_row_index: 1,
|
182
|
+
selected_value: DESIRED_VALUE_CONFIG,
|
183
|
+
conditional_value_index: 0,
|
184
|
+
weighted_value_index: nil,
|
185
|
+
selected_index: nil
|
186
|
+
} => 1
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
assert_example_contexts client, [Prefab::Context.new({ user: { 'key' => 99 } })]
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_get_with_weighted_values
|
194
|
+
config = PrefabProto::Config.new(
|
195
|
+
id: 123,
|
196
|
+
key: KEY,
|
197
|
+
config_type: PrefabProto::ConfigType::CONFIG,
|
198
|
+
rows: [
|
199
|
+
DEFAULT_ROW,
|
200
|
+
PrefabProto::ConfigRow.new(
|
201
|
+
project_env_id: PROJECT_ENV_ID,
|
202
|
+
values: [
|
203
|
+
PrefabProto::ConditionalValue.new(
|
204
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
205
|
+
value: PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 98], ['def', 1],
|
206
|
+
['ghi', 1]]))
|
207
|
+
)
|
208
|
+
]
|
209
|
+
)
|
210
|
+
]
|
211
|
+
)
|
212
|
+
|
213
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: :force,
|
214
|
+
collect_example_contexts: :force)
|
215
|
+
|
216
|
+
2.times do
|
217
|
+
assert_equal 'abc', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '1' })
|
218
|
+
end
|
219
|
+
|
220
|
+
3.times do
|
221
|
+
assert_equal 'def', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '12' })
|
222
|
+
end
|
223
|
+
|
224
|
+
assert_equal 'ghi',
|
225
|
+
client.get(config.key, IRRELEVANT, 'user' => { 'key' => '4', admin: true })
|
226
|
+
|
227
|
+
assert_summary client, {
|
228
|
+
[KEY, :CONFIG] => {
|
229
|
+
{
|
230
|
+
config_id: config.id,
|
231
|
+
config_row_index: 1,
|
232
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'abc'),
|
233
|
+
conditional_value_index: 0,
|
234
|
+
weighted_value_index: 0,
|
235
|
+
selected_index: nil
|
236
|
+
} => 2,
|
237
|
+
|
238
|
+
{
|
239
|
+
config_id: config.id,
|
240
|
+
config_row_index: 1,
|
241
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'def'),
|
242
|
+
conditional_value_index: 0,
|
243
|
+
weighted_value_index: 1,
|
244
|
+
selected_index: nil
|
245
|
+
} => 3,
|
246
|
+
|
247
|
+
{
|
248
|
+
config_id: config.id,
|
249
|
+
config_row_index: 1,
|
250
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'ghi'),
|
251
|
+
conditional_value_index: 0,
|
252
|
+
weighted_value_index: 2,
|
253
|
+
selected_index: nil
|
254
|
+
} => 1
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
assert_example_contexts client, [
|
259
|
+
Prefab::Context.new(user: { 'key' => '1' }),
|
260
|
+
Prefab::Context.new(user: { 'key' => '12' }),
|
261
|
+
Prefab::Context.new(user: { 'key' => '4', admin: true })
|
262
|
+
]
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_in_seg
|
266
|
+
segment_key = 'segment_key'
|
267
|
+
|
268
|
+
segment_config = PrefabProto::Config.new(
|
269
|
+
config_type: PrefabProto::ConfigType::SEGMENT,
|
270
|
+
key: segment_key,
|
271
|
+
rows: [
|
272
|
+
PrefabProto::ConfigRow.new(
|
273
|
+
values: [
|
274
|
+
PrefabProto::ConditionalValue.new(
|
275
|
+
value: TRUE_CONFIG,
|
276
|
+
criteria: [
|
277
|
+
PrefabProto::Criterion.new(
|
278
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
279
|
+
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
280
|
+
property_name: 'user.email'
|
281
|
+
)
|
282
|
+
]
|
283
|
+
),
|
284
|
+
PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
|
285
|
+
]
|
286
|
+
)
|
287
|
+
]
|
288
|
+
)
|
289
|
+
|
290
|
+
config = PrefabProto::Config.new(
|
291
|
+
key: KEY,
|
292
|
+
rows: [
|
293
|
+
DEFAULT_ROW,
|
294
|
+
|
295
|
+
PrefabProto::ConfigRow.new(
|
296
|
+
project_env_id: PROJECT_ENV_ID,
|
297
|
+
values: [
|
298
|
+
PrefabProto::ConditionalValue.new(
|
299
|
+
criteria: [
|
300
|
+
PrefabProto::Criterion.new(
|
301
|
+
operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
|
302
|
+
value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
|
303
|
+
)
|
304
|
+
],
|
305
|
+
value: DESIRED_VALUE_CONFIG
|
306
|
+
)
|
307
|
+
]
|
308
|
+
)
|
309
|
+
]
|
310
|
+
)
|
311
|
+
|
312
|
+
client = new_client(config: [config, segment_config], project_env_id: PROJECT_ENV_ID,
|
313
|
+
collect_evaluation_summaries: :force, collect_example_contexts: :force)
|
314
|
+
|
315
|
+
assert_equal DEFAULT_VALUE, client.get(config.key)
|
316
|
+
assert_equal DEFAULT_VALUE,
|
317
|
+
client.get(config.key, IRRELEVANT, user: { key: 'abc', email: 'example@prefab.cloud' })
|
318
|
+
assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, user: { key: 'def', email: 'example@hotmail.com' })
|
319
|
+
|
320
|
+
assert_summary client, {
|
321
|
+
[segment_key, :SEGMENT] => {
|
322
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 1, selected_value: FALSE_CONFIG,
|
323
|
+
weighted_value_index: nil, selected_index: nil } => 2,
|
324
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: TRUE_CONFIG,
|
325
|
+
weighted_value_index: nil, selected_index: nil } => 1
|
326
|
+
},
|
327
|
+
[KEY, :NOT_SET_CONFIG_TYPE] => {
|
328
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: DEFAULT_VALUE_CONFIG,
|
329
|
+
weighted_value_index: nil, selected_index: nil } => 2,
|
330
|
+
{ config_id: 0, config_row_index: 1, conditional_value_index: 0, selected_value: DESIRED_VALUE_CONFIG,
|
331
|
+
weighted_value_index: nil, selected_index: nil } => 1
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
assert_example_contexts client, [
|
336
|
+
Prefab::Context.new(user: { key: 'abc', email: 'example@prefab.cloud' }),
|
337
|
+
Prefab::Context.new(user: { key: 'def', email: 'example@hotmail.com' })
|
338
|
+
]
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_get_log_level
|
342
|
+
config = PrefabProto::Config.new(
|
343
|
+
id: 999,
|
344
|
+
key: 'log-level',
|
345
|
+
config_type: PrefabProto::ConfigType::LOG_LEVEL,
|
346
|
+
rows: [
|
347
|
+
PrefabProto::ConfigRow.new(
|
348
|
+
values: [
|
349
|
+
PrefabProto::ConditionalValue.new(
|
350
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
351
|
+
value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
|
352
|
+
)
|
353
|
+
]
|
354
|
+
)
|
355
|
+
]
|
356
|
+
)
|
357
|
+
|
358
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID,
|
359
|
+
collect_evaluation_summaries: :force)
|
360
|
+
|
361
|
+
assert_equal :DEBUG, client.get(config.key, IRRELEVANT)
|
362
|
+
|
363
|
+
# nothing is summarized for log levels
|
364
|
+
assert_summary client, {}
|
365
|
+
end
|
366
|
+
|
112
367
|
private
|
113
368
|
|
114
369
|
def assert_equal_context_and_jit(expected, method, key, context)
|
@@ -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', {}
|
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', {}
|
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', {}
|
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', {}
|
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', {}
|
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', {}
|
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', {}
|
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' } }
|
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' } }
|
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
|
-
|
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).
|
360
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).
|
361
|
-
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'pro' } }).
|
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).
|
404
|
-
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { user: { email: 'test@example.com' } }).
|
405
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).
|
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
|
423
|
-
assert_equal expected_value, resolver.get(key, properties).
|
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).
|
427
|
+
assert_equal expected_value, resolver.get(key).unwrapped_value
|
427
428
|
end
|
428
429
|
end
|
429
430
|
end
|
@@ -8,77 +8,67 @@ class TestConfigValueUnwrapper < Minitest::Test
|
|
8
8
|
|
9
9
|
def test_unwrapping_int
|
10
10
|
config_value = PrefabProto::ConfigValue.new(int: 123)
|
11
|
-
assert_equal 123,
|
11
|
+
assert_equal 123, unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_unwrapping_string
|
15
15
|
config_value = PrefabProto::ConfigValue.new(string: 'abc')
|
16
|
-
assert_equal 'abc',
|
16
|
+
assert_equal 'abc', unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_unwrapping_double
|
20
20
|
config_value = PrefabProto::ConfigValue.new(double: 1.23)
|
21
|
-
assert_equal 1.23,
|
21
|
+
assert_equal 1.23, unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_unwrapping_bool
|
25
25
|
config_value = PrefabProto::ConfigValue.new(bool: true)
|
26
|
-
assert_equal true,
|
26
|
+
assert_equal true, unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
27
27
|
|
28
28
|
config_value = PrefabProto::ConfigValue.new(bool: false)
|
29
|
-
assert_equal false,
|
29
|
+
assert_equal false, unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_unwrapping_log_level
|
33
33
|
config_value = PrefabProto::ConfigValue.new(log_level: :INFO)
|
34
|
-
assert_equal :INFO,
|
34
|
+
assert_equal :INFO, unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_unwrapping_string_list
|
38
38
|
config_value = PrefabProto::ConfigValue.new(string_list: PrefabProto::StringList.new(values: %w[a b c]))
|
39
|
-
assert_equal %w[a b c],
|
39
|
+
assert_equal %w[a b c], unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_unwrapping_weighted_values
|
43
43
|
# single value
|
44
44
|
config_value = PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 1]]))
|
45
45
|
|
46
|
-
assert_equal 'abc',
|
46
|
+
assert_equal 'abc', unwrap(config_value, CONFIG_KEY, EMPTY_CONTEXT)
|
47
47
|
|
48
48
|
# multiple values, evenly distributed
|
49
49
|
config_value = PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 1], ['def', 1], ['ghi', 1]]))
|
50
|
-
assert_equal 'def',
|
51
|
-
assert_equal 'ghi',
|
52
|
-
assert_equal 'abc',
|
53
|
-
assert_equal 'ghi',
|
50
|
+
assert_equal 'def', unwrap(config_value, CONFIG_KEY, context_with_key('user:000'))
|
51
|
+
assert_equal 'ghi', unwrap(config_value, CONFIG_KEY, context_with_key('user:456'))
|
52
|
+
assert_equal 'abc', unwrap(config_value, CONFIG_KEY, context_with_key('user:789'))
|
53
|
+
assert_equal 'ghi', unwrap(config_value, CONFIG_KEY, context_with_key('user:888'))
|
54
54
|
|
55
55
|
# multiple values, unevenly distributed
|
56
56
|
config_value = PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 1], ['def', 99], ['ghi', 1]]))
|
57
|
-
assert_equal 'def',
|
58
|
-
assert_equal 'def',
|
59
|
-
assert_equal 'def',
|
60
|
-
assert_equal 'def',
|
61
|
-
assert_equal 'ghi',
|
62
|
-
assert_equal 'abc',
|
57
|
+
assert_equal 'def', unwrap(config_value, CONFIG_KEY, context_with_key('user:123'))
|
58
|
+
assert_equal 'def', unwrap(config_value, CONFIG_KEY, context_with_key('user:456'))
|
59
|
+
assert_equal 'def', unwrap(config_value, CONFIG_KEY, context_with_key('user:789'))
|
60
|
+
assert_equal 'def', unwrap(config_value, CONFIG_KEY, context_with_key('user:012'))
|
61
|
+
assert_equal 'ghi', unwrap(config_value, CONFIG_KEY, context_with_key('user:428'))
|
62
|
+
assert_equal 'abc', unwrap(config_value, CONFIG_KEY, context_with_key('user:548'))
|
63
63
|
end
|
64
64
|
|
65
65
|
private
|
66
66
|
|
67
|
-
def weighted_values(values_and_weights, hash_by_property_name: 'user.key')
|
68
|
-
values = values_and_weights.map do |value, weight|
|
69
|
-
weighted_value(value, weight)
|
70
|
-
end
|
71
|
-
|
72
|
-
PrefabProto::WeightedValues.new(weighted_values: values, hash_by_property_name: hash_by_property_name)
|
73
|
-
end
|
74
|
-
|
75
|
-
def weighted_value(string, weight)
|
76
|
-
PrefabProto::WeightedValue.new(
|
77
|
-
value: PrefabProto::ConfigValue.new(string: string), weight: weight
|
78
|
-
)
|
79
|
-
end
|
80
|
-
|
81
67
|
def context_with_key(key)
|
82
68
|
Prefab::Context.new(user: { key: key })
|
83
69
|
end
|
70
|
+
|
71
|
+
def unwrap(config_value, config_key, context)
|
72
|
+
Prefab::ConfigValueUnwrapper.deepest_value(config_value, config_key, context).unwrap
|
73
|
+
end
|
84
74
|
end
|
@@ -127,7 +127,6 @@ class TestContextShapeAggregator < Minitest::Test
|
|
127
127
|
initialization_timeout_sec: 0,
|
128
128
|
on_init_failure: Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN,
|
129
129
|
api_key: '123-development-yourapikey-SDK',
|
130
|
-
shape_sync_interval: 1000 # we'll trigger sync manually in our test
|
131
130
|
}.merge(overrides))
|
132
131
|
end
|
133
132
|
|