prefab-cloud-ruby 0.24.3 → 0.24.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.rubocop.yml +13 -0
  4. data/CHANGELOG.md +78 -0
  5. data/Gemfile.lock +4 -4
  6. data/VERSION +1 -1
  7. data/bin/console +21 -0
  8. data/compile_protos.sh +6 -0
  9. data/lib/prefab/client.rb +25 -4
  10. data/lib/prefab/config_client.rb +17 -6
  11. data/lib/prefab/config_loader.rb +1 -1
  12. data/lib/prefab/config_resolver.rb +2 -4
  13. data/lib/prefab/config_value_wrapper.rb +18 -0
  14. data/lib/prefab/context.rb +22 -2
  15. data/lib/prefab/context_shape.rb +20 -0
  16. data/lib/prefab/context_shape_aggregator.rb +63 -0
  17. data/lib/prefab/criteria_evaluator.rb +61 -41
  18. data/lib/prefab/evaluated_configs_aggregator.rb +60 -0
  19. data/lib/prefab/evaluated_keys_aggregator.rb +41 -0
  20. data/lib/prefab/http_connection.rb +5 -1
  21. data/lib/prefab/local_config_parser.rb +13 -13
  22. data/lib/prefab/log_path_aggregator.rb +64 -0
  23. data/lib/prefab/logger_client.rb +11 -13
  24. data/lib/prefab/options.rb +37 -1
  25. data/lib/prefab/periodic_sync.rb +51 -0
  26. data/lib/prefab/time_helpers.rb +7 -0
  27. data/lib/prefab-cloud-ruby.rb +9 -2
  28. data/lib/prefab_pb.rb +33 -220
  29. data/prefab-cloud-ruby.gemspec +21 -5
  30. data/test/test_config_loader.rb +15 -15
  31. data/test/test_config_resolver.rb +102 -102
  32. data/test/test_config_value_unwrapper.rb +13 -13
  33. data/test/test_context.rb +42 -0
  34. data/test/test_context_shape.rb +51 -0
  35. data/test/test_context_shape_aggregator.rb +137 -0
  36. data/test/test_criteria_evaluator.rb +253 -150
  37. data/test/test_evaluated_configs_aggregator.rb +254 -0
  38. data/test/test_evaluated_keys_aggregator.rb +54 -0
  39. data/test/test_helper.rb +34 -2
  40. data/test/test_log_path_aggregator.rb +57 -0
  41. data/test/test_logger.rb +33 -33
  42. data/test/test_weighted_value_resolver.rb +2 -2
  43. metadata +21 -5
  44. data/lib/prefab/log_path_collector.rb +0 -102
  45. data/test/test_log_path_collector.rb +0 -58
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'test_helper'
4
+ require 'timecop'
4
5
 
5
6
  class TestCriteriaEvaluator < Minitest::Test
6
7
  PROJECT_ENV_ID = 1
@@ -10,63 +11,61 @@ class TestCriteriaEvaluator < Minitest::Test
10
11
  DESIRED_VALUE = 'desired_value'
11
12
  WRONG_ENV_VALUE = 'wrong_env_value'
12
13
 
13
- DEFAULT_ROW = Prefab::ConfigRow.new(
14
+ DEFAULT_ROW = PrefabProto::ConfigRow.new(
14
15
  values: [
15
- Prefab::ConditionalValue.new(
16
- value: Prefab::ConfigValue.new(string: DEFAULT_VALUE)
16
+ PrefabProto::ConditionalValue.new(
17
+ value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
17
18
  )
18
19
  ]
19
20
  )
20
21
 
21
22
  def test_always_true
22
- config = Prefab::Config.new(
23
+ config = PrefabProto::Config.new(
23
24
  key: KEY,
24
25
  rows: [
25
26
  DEFAULT_ROW,
26
- Prefab::ConfigRow.new(
27
+ PrefabProto::ConfigRow.new(
27
28
  project_env_id: PROJECT_ENV_ID,
28
29
  values: [
29
- Prefab::ConditionalValue.new(
30
- criteria: [
31
- Prefab::Criterion.new(operator: Prefab::Criterion::CriterionOperator::ALWAYS_TRUE)
32
- ],
33
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
30
+ PrefabProto::ConditionalValue.new(
31
+ criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
32
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
34
33
  )
35
34
  ]
36
35
  )
37
36
  ]
38
37
  )
39
38
 
40
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
39
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
41
40
  namespace: nil)
42
41
 
43
42
  assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
44
43
  end
45
44
 
46
45
  def test_nested_props_in
47
- config = Prefab::Config.new(
46
+ config = PrefabProto::Config.new(
48
47
  key: KEY,
49
48
  rows: [
50
49
  DEFAULT_ROW,
51
- Prefab::ConfigRow.new(
50
+ PrefabProto::ConfigRow.new(
52
51
  project_env_id: PROJECT_ENV_ID,
53
52
  values: [
54
- Prefab::ConditionalValue.new(
53
+ PrefabProto::ConditionalValue.new(
55
54
  criteria: [
56
- Prefab::Criterion.new(
57
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
55
+ PrefabProto::Criterion.new(
56
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
58
57
  value_to_match: string_list(%w[ok fine]),
59
58
  property_name: 'user.key'
60
59
  )
61
60
  ],
62
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
61
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
63
62
  )
64
63
  ]
65
64
  )
66
65
  ]
67
66
  )
68
67
 
69
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
68
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
70
69
  namespace: nil)
71
70
 
72
71
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -75,29 +74,29 @@ class TestCriteriaEvaluator < Minitest::Test
75
74
  end
76
75
 
77
76
  def test_nested_props_not_in
78
- config = Prefab::Config.new(
77
+ config = PrefabProto::Config.new(
79
78
  key: KEY,
80
79
  rows: [
81
80
  DEFAULT_ROW,
82
- Prefab::ConfigRow.new(
81
+ PrefabProto::ConfigRow.new(
83
82
  project_env_id: PROJECT_ENV_ID,
84
83
  values: [
85
- Prefab::ConditionalValue.new(
84
+ PrefabProto::ConditionalValue.new(
86
85
  criteria: [
87
- Prefab::Criterion.new(
88
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
86
+ PrefabProto::Criterion.new(
87
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
89
88
  value_to_match: string_list(%w[wrong bad]),
90
89
  property_name: 'user.key'
91
90
  )
92
91
  ],
93
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
92
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
94
93
  )
95
94
  ]
96
95
  )
97
96
  ]
98
97
  )
99
98
 
100
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
99
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
101
100
  namespace: nil)
102
101
 
103
102
  assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
@@ -106,29 +105,29 @@ class TestCriteriaEvaluator < Minitest::Test
106
105
  end
107
106
 
108
107
  def test_prop_is_one_of
109
- config = Prefab::Config.new(
108
+ config = PrefabProto::Config.new(
110
109
  key: KEY,
111
110
  rows: [
112
111
  DEFAULT_ROW,
113
- Prefab::ConfigRow.new(
112
+ PrefabProto::ConfigRow.new(
114
113
  project_env_id: PROJECT_ENV_ID,
115
114
  values: [
116
- Prefab::ConditionalValue.new(
115
+ PrefabProto::ConditionalValue.new(
117
116
  criteria: [
118
- Prefab::Criterion.new(
119
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
117
+ PrefabProto::Criterion.new(
118
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
120
119
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
121
120
  property_name: 'user.email_suffix'
122
121
  )
123
122
  ],
124
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
123
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
125
124
  )
126
125
  ]
127
126
  )
128
127
  ]
129
128
  )
130
129
 
131
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
130
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
132
131
  namespace: nil)
133
132
 
134
133
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -137,29 +136,29 @@ class TestCriteriaEvaluator < Minitest::Test
137
136
  end
138
137
 
139
138
  def test_prop_is_not_one_of
140
- config = Prefab::Config.new(
139
+ config = PrefabProto::Config.new(
141
140
  key: KEY,
142
141
  rows: [
143
142
  DEFAULT_ROW,
144
- Prefab::ConfigRow.new(
143
+ PrefabProto::ConfigRow.new(
145
144
  project_env_id: PROJECT_ENV_ID,
146
145
  values: [
147
- Prefab::ConditionalValue.new(
146
+ PrefabProto::ConditionalValue.new(
148
147
  criteria: [
149
- Prefab::Criterion.new(
150
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
148
+ PrefabProto::Criterion.new(
149
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
151
150
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
152
151
  property_name: 'user.email_suffix'
153
152
  )
154
153
  ],
155
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
154
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
156
155
  )
157
156
  ]
158
157
  )
159
158
  ]
160
159
  )
161
160
 
162
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
161
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
163
162
  namespace: nil)
164
163
 
165
164
  assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
@@ -168,29 +167,29 @@ class TestCriteriaEvaluator < Minitest::Test
168
167
  end
169
168
 
170
169
  def test_prop_ends_with_one_of
171
- config = Prefab::Config.new(
170
+ config = PrefabProto::Config.new(
172
171
  key: KEY,
173
172
  rows: [
174
173
  DEFAULT_ROW,
175
- Prefab::ConfigRow.new(
174
+ PrefabProto::ConfigRow.new(
176
175
  project_env_id: PROJECT_ENV_ID,
177
176
  values: [
178
- Prefab::ConditionalValue.new(
177
+ PrefabProto::ConditionalValue.new(
179
178
  criteria: [
180
- Prefab::Criterion.new(
181
- operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
179
+ PrefabProto::Criterion.new(
180
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
182
181
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
183
182
  property_name: 'user.email'
184
183
  )
185
184
  ],
186
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
185
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
187
186
  )
188
187
  ]
189
188
  )
190
189
  ]
191
190
  )
192
191
 
193
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
192
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
194
193
  namespace: nil)
195
194
 
196
195
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -199,29 +198,29 @@ class TestCriteriaEvaluator < Minitest::Test
199
198
  end
200
199
 
201
200
  def test_prop_does_not_end_with_one_of
202
- config = Prefab::Config.new(
201
+ config = PrefabProto::Config.new(
203
202
  key: KEY,
204
203
  rows: [
205
204
  DEFAULT_ROW,
206
- Prefab::ConfigRow.new(
205
+ PrefabProto::ConfigRow.new(
207
206
  project_env_id: PROJECT_ENV_ID,
208
207
  values: [
209
- Prefab::ConditionalValue.new(
208
+ PrefabProto::ConditionalValue.new(
210
209
  criteria: [
211
- Prefab::Criterion.new(
212
- operator: Prefab::Criterion::CriterionOperator::PROP_DOES_NOT_END_WITH_ONE_OF,
210
+ PrefabProto::Criterion.new(
211
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_DOES_NOT_END_WITH_ONE_OF,
213
212
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
214
213
  property_name: 'user.email'
215
214
  )
216
215
  ],
217
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
216
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
218
217
  )
219
218
  ]
220
219
  )
221
220
  ]
222
221
  )
223
222
 
224
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
223
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: FakeBaseClient.new,
225
224
  namespace: nil)
226
225
 
227
226
  assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
@@ -232,63 +231,63 @@ class TestCriteriaEvaluator < Minitest::Test
232
231
  def test_in_seg
233
232
  segment_key = 'segment_key'
234
233
 
235
- segment_config = Prefab::Config.new(
236
- config_type: Prefab::ConfigType::SEGMENT,
234
+ segment_config = PrefabProto::Config.new(
235
+ config_type: PrefabProto::ConfigType::SEGMENT,
237
236
  key: segment_key,
238
237
  rows: [
239
- Prefab::ConfigRow.new(
238
+ PrefabProto::ConfigRow.new(
240
239
  values: [
241
- Prefab::ConditionalValue.new(
242
- value: Prefab::ConfigValue.new(bool: true),
240
+ PrefabProto::ConditionalValue.new(
241
+ value: PrefabProto::ConfigValue.new(bool: true),
243
242
  criteria: [
244
- Prefab::Criterion.new(
245
- operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
243
+ PrefabProto::Criterion.new(
244
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
246
245
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
247
246
  property_name: 'user.email'
248
247
  )
249
248
  ]
250
249
  ),
251
- Prefab::ConditionalValue.new(
252
- value: Prefab::ConfigValue.new(bool: false)
250
+ PrefabProto::ConditionalValue.new(
251
+ value: PrefabProto::ConfigValue.new(bool: false)
253
252
  )
254
253
  ]
255
254
  )
256
255
  ]
257
256
  )
258
257
 
259
- config = Prefab::Config.new(
258
+ config = PrefabProto::Config.new(
260
259
  key: KEY,
261
260
  rows: [
262
261
  DEFAULT_ROW,
263
262
 
264
263
  # wrong env
265
- Prefab::ConfigRow.new(
264
+ PrefabProto::ConfigRow.new(
266
265
  project_env_id: TEST_ENV_ID,
267
266
  values: [
268
- Prefab::ConditionalValue.new(
267
+ PrefabProto::ConditionalValue.new(
269
268
  criteria: [
270
- Prefab::Criterion.new(
271
- operator: Prefab::Criterion::CriterionOperator::IN_SEG,
272
- value_to_match: Prefab::ConfigValue.new(string: segment_key)
269
+ PrefabProto::Criterion.new(
270
+ operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
271
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
273
272
  )
274
273
  ],
275
- value: Prefab::ConfigValue.new(string: WRONG_ENV_VALUE)
274
+ value: PrefabProto::ConfigValue.new(string: WRONG_ENV_VALUE)
276
275
  )
277
276
  ]
278
277
  ),
279
278
 
280
279
  # correct env
281
- Prefab::ConfigRow.new(
280
+ PrefabProto::ConfigRow.new(
282
281
  project_env_id: PROJECT_ENV_ID,
283
282
  values: [
284
- Prefab::ConditionalValue.new(
283
+ PrefabProto::ConditionalValue.new(
285
284
  criteria: [
286
- Prefab::Criterion.new(
287
- operator: Prefab::Criterion::CriterionOperator::IN_SEG,
288
- value_to_match: Prefab::ConfigValue.new(string: segment_key)
285
+ PrefabProto::Criterion.new(
286
+ operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
287
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
289
288
  )
290
289
  ],
291
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
290
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
292
291
  )
293
292
  ]
294
293
  )
@@ -296,7 +295,7 @@ class TestCriteriaEvaluator < Minitest::Test
296
295
  )
297
296
 
298
297
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
299
- base_client: nil, namespace: nil,
298
+ base_client: FakeBaseClient.new, namespace: nil,
300
299
  resolver: resolver_fake({ segment_key => segment_config }))
301
300
 
302
301
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -307,45 +306,45 @@ class TestCriteriaEvaluator < Minitest::Test
307
306
  def test_not_in_seg
308
307
  segment_key = 'segment_key'
309
308
 
310
- segment_config = Prefab::Config.new(
311
- config_type: Prefab::ConfigType::SEGMENT,
309
+ segment_config = PrefabProto::Config.new(
310
+ config_type: PrefabProto::ConfigType::SEGMENT,
312
311
  key: segment_key,
313
312
  rows: [
314
- Prefab::ConfigRow.new(
313
+ PrefabProto::ConfigRow.new(
315
314
  values: [
316
- Prefab::ConditionalValue.new(
317
- value: Prefab::ConfigValue.new(bool: true),
315
+ PrefabProto::ConditionalValue.new(
316
+ value: PrefabProto::ConfigValue.new(bool: true),
318
317
  criteria: [
319
- Prefab::Criterion.new(
320
- operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
318
+ PrefabProto::Criterion.new(
319
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
321
320
  value_to_match: string_list(['hotmail.com', 'gmail.com']),
322
321
  property_name: 'user.email'
323
322
  )
324
323
  ]
325
324
  ),
326
- Prefab::ConditionalValue.new(
327
- value: Prefab::ConfigValue.new(bool: false)
325
+ PrefabProto::ConditionalValue.new(
326
+ value: PrefabProto::ConfigValue.new(bool: false)
328
327
  )
329
328
  ]
330
329
  )
331
330
  ]
332
331
  )
333
332
 
334
- config = Prefab::Config.new(
333
+ config = PrefabProto::Config.new(
335
334
  key: KEY,
336
335
  rows: [
337
336
  DEFAULT_ROW,
338
- Prefab::ConfigRow.new(
337
+ PrefabProto::ConfigRow.new(
339
338
  project_env_id: PROJECT_ENV_ID,
340
339
  values: [
341
- Prefab::ConditionalValue.new(
340
+ PrefabProto::ConditionalValue.new(
342
341
  criteria: [
343
- Prefab::Criterion.new(
344
- operator: Prefab::Criterion::CriterionOperator::NOT_IN_SEG,
345
- value_to_match: Prefab::ConfigValue.new(string: segment_key)
342
+ PrefabProto::Criterion.new(
343
+ operator: PrefabProto::Criterion::CriterionOperator::NOT_IN_SEG,
344
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
346
345
  )
347
346
  ],
348
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
347
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
349
348
  )
350
349
  ]
351
350
  )
@@ -353,7 +352,7 @@ class TestCriteriaEvaluator < Minitest::Test
353
352
  )
354
353
 
355
354
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
356
- base_client: nil, namespace: nil,
355
+ base_client: FakeBaseClient.new, namespace: nil,
357
356
  resolver: resolver_fake({ segment_key => segment_config }))
358
357
 
359
358
  assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
@@ -364,57 +363,57 @@ class TestCriteriaEvaluator < Minitest::Test
364
363
  def test_multiple_conditions_in_one_value
365
364
  segment_key = 'segment_key'
366
365
 
367
- segment_config = Prefab::Config.new(
368
- config_type: Prefab::ConfigType::SEGMENT,
366
+ segment_config = PrefabProto::Config.new(
367
+ config_type: PrefabProto::ConfigType::SEGMENT,
369
368
  key: segment_key,
370
369
  rows: [
371
- Prefab::ConfigRow.new(
370
+ PrefabProto::ConfigRow.new(
372
371
  values: [
373
- Prefab::ConditionalValue.new(
374
- value: Prefab::ConfigValue.new(bool: true),
372
+ PrefabProto::ConditionalValue.new(
373
+ value: PrefabProto::ConfigValue.new(bool: true),
375
374
  criteria: [
376
- Prefab::Criterion.new(
377
- operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
375
+ PrefabProto::Criterion.new(
376
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
378
377
  value_to_match: string_list(['prefab.cloud', 'gmail.com']),
379
378
  property_name: 'user.email'
380
379
  ),
381
380
 
382
- Prefab::Criterion.new(
383
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
384
- value_to_match: Prefab::ConfigValue.new(bool: true),
381
+ PrefabProto::Criterion.new(
382
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
383
+ value_to_match: PrefabProto::ConfigValue.new(bool: true),
385
384
  property_name: 'user.admin'
386
385
  )
387
386
  ]
388
387
  ),
389
- Prefab::ConditionalValue.new(
390
- value: Prefab::ConfigValue.new(bool: false)
388
+ PrefabProto::ConditionalValue.new(
389
+ value: PrefabProto::ConfigValue.new(bool: false)
391
390
  )
392
391
  ]
393
392
  )
394
393
  ]
395
394
  )
396
395
 
397
- config = Prefab::Config.new(
396
+ config = PrefabProto::Config.new(
398
397
  key: KEY,
399
398
  rows: [
400
399
  DEFAULT_ROW,
401
- Prefab::ConfigRow.new(
400
+ PrefabProto::ConfigRow.new(
402
401
  project_env_id: PROJECT_ENV_ID,
403
402
  values: [
404
- Prefab::ConditionalValue.new(
403
+ PrefabProto::ConditionalValue.new(
405
404
  criteria: [
406
- Prefab::Criterion.new(
407
- operator: Prefab::Criterion::CriterionOperator::IN_SEG,
408
- value_to_match: Prefab::ConfigValue.new(string: segment_key)
405
+ PrefabProto::Criterion.new(
406
+ operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
407
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
409
408
  ),
410
409
 
411
- Prefab::Criterion.new(
412
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
413
- value_to_match: Prefab::ConfigValue.new(bool: true),
410
+ PrefabProto::Criterion.new(
411
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
412
+ value_to_match: PrefabProto::ConfigValue.new(bool: true),
414
413
  property_name: 'user.deleted'
415
414
  )
416
415
  ],
417
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
416
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
418
417
  )
419
418
  ]
420
419
  )
@@ -422,7 +421,7 @@ class TestCriteriaEvaluator < Minitest::Test
422
421
  )
423
422
 
424
423
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
425
- base_client: nil, namespace: nil,
424
+ base_client: FakeBaseClient.new, namespace: nil,
426
425
  resolver: resolver_fake({ segment_key => segment_config }))
427
426
 
428
427
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -439,61 +438,61 @@ class TestCriteriaEvaluator < Minitest::Test
439
438
  def test_multiple_conditions_in_multiple_values
440
439
  segment_key = 'segment_key'
441
440
 
442
- segment_config = Prefab::Config.new(
443
- config_type: Prefab::ConfigType::SEGMENT,
441
+ segment_config = PrefabProto::Config.new(
442
+ config_type: PrefabProto::ConfigType::SEGMENT,
444
443
  key: segment_key,
445
444
  rows: [
446
- Prefab::ConfigRow.new(
445
+ PrefabProto::ConfigRow.new(
447
446
  values: [
448
- Prefab::ConditionalValue.new(
449
- value: Prefab::ConfigValue.new(bool: true),
447
+ PrefabProto::ConditionalValue.new(
448
+ value: PrefabProto::ConfigValue.new(bool: true),
450
449
  criteria: [
451
- Prefab::Criterion.new(
452
- operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
450
+ PrefabProto::Criterion.new(
451
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
453
452
  value_to_match: string_list(['prefab.cloud', 'gmail.com']),
454
453
  property_name: 'user.email'
455
454
  )
456
455
  ]
457
456
  ),
458
- Prefab::ConditionalValue.new(
459
- value: Prefab::ConfigValue.new(bool: true),
457
+ PrefabProto::ConditionalValue.new(
458
+ value: PrefabProto::ConfigValue.new(bool: true),
460
459
  criteria: [
461
- Prefab::Criterion.new(
462
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
463
- value_to_match: Prefab::ConfigValue.new(bool: true),
460
+ PrefabProto::Criterion.new(
461
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
462
+ value_to_match: PrefabProto::ConfigValue.new(bool: true),
464
463
  property_name: 'user.admin'
465
464
  )
466
465
  ]
467
466
  ),
468
- Prefab::ConditionalValue.new(
469
- value: Prefab::ConfigValue.new(bool: false)
467
+ PrefabProto::ConditionalValue.new(
468
+ value: PrefabProto::ConfigValue.new(bool: false)
470
469
  )
471
470
  ]
472
471
  )
473
472
  ]
474
473
  )
475
474
 
476
- config = Prefab::Config.new(
475
+ config = PrefabProto::Config.new(
477
476
  key: KEY,
478
477
  rows: [
479
478
  DEFAULT_ROW,
480
- Prefab::ConfigRow.new(
479
+ PrefabProto::ConfigRow.new(
481
480
  project_env_id: PROJECT_ENV_ID,
482
481
  values: [
483
- Prefab::ConditionalValue.new(
482
+ PrefabProto::ConditionalValue.new(
484
483
  criteria: [
485
- Prefab::Criterion.new(
486
- operator: Prefab::Criterion::CriterionOperator::IN_SEG,
487
- value_to_match: Prefab::ConfigValue.new(string: segment_key)
484
+ PrefabProto::Criterion.new(
485
+ operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
486
+ value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
488
487
  ),
489
488
 
490
- Prefab::Criterion.new(
491
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
492
- value_to_match: Prefab::ConfigValue.new(bool: true),
489
+ PrefabProto::Criterion.new(
490
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
491
+ value_to_match: PrefabProto::ConfigValue.new(bool: true),
493
492
  property_name: 'user.deleted'
494
493
  )
495
494
  ],
496
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
495
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
497
496
  )
498
497
  ]
499
498
  )
@@ -501,7 +500,7 @@ class TestCriteriaEvaluator < Minitest::Test
501
500
  )
502
501
 
503
502
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
504
- base_client: nil, namespace: nil,
503
+ base_client: FakeBaseClient.new, namespace: nil,
505
504
  resolver: resolver_fake({ segment_key => segment_config }))
506
505
 
507
506
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
@@ -517,22 +516,22 @@ class TestCriteriaEvaluator < Minitest::Test
517
516
  end
518
517
 
519
518
  def test_stringifying_property_values_and_names
520
- config = Prefab::Config.new(
519
+ config = PrefabProto::Config.new(
521
520
  key: KEY,
522
521
  rows: [
523
522
  DEFAULT_ROW,
524
- Prefab::ConfigRow.new(
523
+ PrefabProto::ConfigRow.new(
525
524
  project_env_id: PROJECT_ENV_ID,
526
525
  values: [
527
- Prefab::ConditionalValue.new(
526
+ PrefabProto::ConditionalValue.new(
528
527
  criteria: [
529
- Prefab::Criterion.new(
530
- operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
528
+ PrefabProto::Criterion.new(
529
+ operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
531
530
  value_to_match: string_list(%w[1 true hello]),
532
531
  property_name: 'team.name'
533
532
  )
534
533
  ],
535
- value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
534
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
536
535
  )
537
536
  ]
538
537
  )
@@ -540,7 +539,7 @@ class TestCriteriaEvaluator < Minitest::Test
540
539
  )
541
540
 
542
541
  evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
543
- namespace: nil, base_client: nil)
542
+ namespace: nil, base_client: FakeBaseClient.new)
544
543
 
545
544
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
546
545
  assert_equal DEFAULT_VALUE, evaluator.evaluate(context(team: { name: 'prefab.cloud' })).string
@@ -553,10 +552,101 @@ class TestCriteriaEvaluator < Minitest::Test
553
552
  end
554
553
  end
555
554
 
555
+ def test_in_int_range
556
+ config = PrefabProto::Config.new(
557
+ key: KEY,
558
+ rows: [
559
+ PrefabProto::ConfigRow.new(
560
+ project_env_id: PROJECT_ENV_ID,
561
+ values: [
562
+ PrefabProto::ConditionalValue.new(
563
+ criteria: [
564
+ PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::IN_INT_RANGE,
565
+ value_to_match: PrefabProto::ConfigValue.new(int_range: PrefabProto::IntRange.new(start: 30, end: 40)), property_name: 'user.age')
566
+ ],
567
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
568
+ ),
569
+
570
+ PrefabProto::ConditionalValue.new(
571
+ criteria: [
572
+ PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)
573
+ ],
574
+ value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
575
+ )
576
+ ]
577
+ )
578
+ ]
579
+ )
580
+
581
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
582
+ namespace: nil, base_client: FakeBaseClient.new)
583
+
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
588
+ end
589
+
590
+ def test_in_int_range_for_time
591
+ now = Time.now
592
+
593
+ config = PrefabProto::Config.new(
594
+ key: KEY,
595
+ rows: [
596
+ PrefabProto::ConfigRow.new(
597
+ project_env_id: PROJECT_ENV_ID,
598
+ values: [
599
+ PrefabProto::ConditionalValue.new(
600
+ criteria: [
601
+ PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::IN_INT_RANGE,
602
+ value_to_match: PrefabProto::ConfigValue.new(
603
+ int_range: PrefabProto::IntRange.new(
604
+ start: (now.to_i - 60) * 1000, end: (now.to_i + 60) * 1000
605
+ )
606
+ ), property_name: 'prefab.current-time')
607
+ ],
608
+ value: PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
609
+ ),
610
+
611
+ PrefabProto::ConditionalValue.new(
612
+ criteria: [
613
+ PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)
614
+ ],
615
+ value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
616
+ )
617
+ ]
618
+ )
619
+ ]
620
+ )
621
+
622
+ evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
623
+ namespace: nil, base_client: FakeBaseClient.new)
624
+
625
+ Timecop.freeze(now) do
626
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
627
+ end
628
+
629
+ Timecop.freeze(now - 60) do
630
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
631
+ end
632
+
633
+ Timecop.freeze(now - 61) do
634
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
635
+ end
636
+
637
+ Timecop.freeze(now + 59) do
638
+ assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
639
+ end
640
+
641
+ Timecop.freeze(now + 60) do
642
+ assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
643
+ end
644
+ end
645
+
556
646
  private
557
647
 
558
648
  def string_list(values)
559
- Prefab::ConfigValue.new(string_list: Prefab::StringList.new(values: values))
649
+ PrefabProto::ConfigValue.new(string_list: PrefabProto::StringList.new(values: values))
560
650
  end
561
651
 
562
652
  class FakeResolver
@@ -571,7 +661,7 @@ class TestCriteriaEvaluator < Minitest::Test
571
661
  def get(key, properties = {})
572
662
  # This only gets called for segments, so we don't need to pass in a resolver
573
663
  Prefab::CriteriaEvaluator.new(@config[key], project_env_id: nil, resolver: nil,
574
- namespace: nil, base_client: nil).evaluate(properties)
664
+ namespace: nil, base_client: FakeBaseClient.new).evaluate(properties)
575
665
  end
576
666
  end
577
667
 
@@ -582,4 +672,17 @@ class TestCriteriaEvaluator < Minitest::Test
582
672
  def context(properties)
583
673
  Prefab::Context.new(properties)
584
674
  end
675
+
676
+ class FakeLogger
677
+ def info(msg)
678
+ # loudly complain about unexpected log messages
679
+ raise msg
680
+ end
681
+ end
682
+
683
+ class FakeBaseClient
684
+ def log
685
+ FakeLogger.new
686
+ end
687
+ end
585
688
  end