prefab-cloud-ruby 0.8.0 → 0.11.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.
@@ -13,111 +13,174 @@ class TestFeatureFlagClient < Minitest::Test
13
13
  def test_pct
14
14
  feature = "FlagName"
15
15
 
16
+ variants = [
17
+ Prefab::FeatureFlagVariant.new(bool: false),
18
+ Prefab::FeatureFlagVariant.new(bool: true)
19
+ ]
16
20
  flag = Prefab::FeatureFlag.new(
17
21
  active: true,
18
- variants: [
19
- Prefab::FeatureFlagVariant.new(bool: false),
20
- Prefab::FeatureFlagVariant.new(bool: true)
21
- ],
22
- inactive_variant_idx: 0,
23
- default: Prefab::VariantDistribution.new(variant_weights:
24
- Prefab::VariantWeights.new(weights: [
25
- Prefab::VariantWeight.new(weight: 500,
26
- variant_idx: 1),
27
- Prefab::VariantWeight.new(weight: 500,
28
- variant_idx: 0),
29
- ]
30
- )
31
- )
22
+ inactive_variant_idx: 1,
23
+ rules: [
24
+ Prefab::Rule.new(
25
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
26
+ variant_weights: [
27
+ Prefab::VariantWeight.new(weight: 86,
28
+ variant_idx: 2), #true
29
+ Prefab::VariantWeight.new(weight: 14,
30
+ variant_idx: 1), #false
31
+ ]
32
+ )
33
+ ]
32
34
  )
35
+ # weights above chosen to be 86% in variant_idx 2. and 14% in variant_idx 1.
36
+ # since hashes high is 86.32 > 86 it just falls outside the 86% range and gets false
33
37
 
38
+ # "1FlagNamehashes high" hashes to 86.322% through dist
34
39
  assert_equal false,
35
- @client.evaluate(feature, "hashes high", [], flag)
40
+ @client.evaluate(feature, "hashes high", [], flag, variants)
41
+ # "1FlagNamehashes low" hashes to 44.547% through dist
36
42
  assert_equal true,
37
- @client.evaluate(feature, "hashes low", [], flag)
43
+ @client.evaluate(feature, "hashes low", [], flag, variants)
44
+
38
45
  end
39
46
 
40
47
  def test_basic_active_inactive
41
48
  feature = "FlagName"
49
+ variants = [
50
+ Prefab::FeatureFlagVariant.new(bool: false),
51
+ Prefab::FeatureFlagVariant.new(bool: true)
52
+ ]
42
53
  flag = Prefab::FeatureFlag.new(
43
54
  active: true,
44
- variants: [
45
- Prefab::FeatureFlagVariant.new(bool: false),
46
- Prefab::FeatureFlagVariant.new(bool: true)
47
- ],
48
- inactive_variant_idx: 0,
49
- default: Prefab::VariantDistribution.new(variant_idx: 1)
55
+ inactive_variant_idx: 1,
56
+ rules: default_ff_rule(2)
50
57
  )
51
58
  assert_equal true,
52
- @client.evaluate(feature, "hashes high", [], flag)
59
+ @client.evaluate(feature, "hashes high", [], flag, variants)
53
60
  assert_equal true,
54
- @client.evaluate(feature, "hashes low", [], flag)
61
+ @client.evaluate(feature, "hashes low", [], flag, variants)
55
62
 
63
+ variants = [
64
+ Prefab::FeatureFlagVariant.new(bool: false),
65
+ Prefab::FeatureFlagVariant.new(bool: true)
66
+ ]
56
67
  flag = Prefab::FeatureFlag.new(
57
68
  active: false,
58
- variants: [
59
- Prefab::FeatureFlagVariant.new(bool: false),
60
- Prefab::FeatureFlagVariant.new(bool: true)
61
- ],
62
- inactive_variant_idx: 0,
63
- default: Prefab::VariantDistribution.new(variant_idx: 1)
69
+ inactive_variant_idx: 1,
70
+ rules: default_ff_rule(2)
64
71
  )
65
72
  assert_equal false,
66
- @client.evaluate(feature, "hashes high", [], flag)
73
+ @client.evaluate(feature, "hashes high", [], flag, variants)
67
74
  assert_equal false,
68
- @client.evaluate(feature, "hashes low", [], flag)
75
+ @client.evaluate(feature, "hashes low", [], flag, variants)
69
76
  end
70
77
 
71
78
  def test_user_targets
72
79
 
73
80
  feature = "FlagName"
81
+ variants = [
82
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
83
+ Prefab::FeatureFlagVariant.new(string: "user target"),
84
+ Prefab::FeatureFlagVariant.new(string: "default"),
85
+ ]
74
86
  flag = Prefab::FeatureFlag.new(
75
87
  active: true,
76
- variants: [
77
- Prefab::FeatureFlagVariant.new(string: "inactive"),
78
- Prefab::FeatureFlagVariant.new(string: "user target"),
79
- Prefab::FeatureFlagVariant.new(string: "default"),
80
- ],
81
- inactive_variant_idx: 0,
88
+ inactive_variant_idx: 1,
82
89
  user_targets: [
83
- variant_idx: 1,
90
+ variant_idx: 2,
84
91
  identifiers: ["user:1", "user:3"]
85
92
  ],
86
- default: Prefab::VariantDistribution.new(variant_idx: 2)
93
+ rules: default_ff_rule(3)
87
94
  )
88
95
 
89
96
  assert_equal "user target",
90
- @client.evaluate(feature, "user:1", [], flag)
97
+ @client.evaluate(feature, "user:1", [], flag, variants)
91
98
  assert_equal "default",
92
- @client.evaluate(feature, "user:2", [], flag)
99
+ @client.evaluate(feature, "user:2", [], flag, variants)
93
100
  assert_equal "user target",
94
- @client.evaluate(feature, "user:3", [], flag)
101
+ @client.evaluate(feature, "user:3", [], flag, variants)
95
102
  end
96
103
 
97
104
  def test_inclusion_rule
98
105
  feature = "FlagName"
106
+ variants = [
107
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
108
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
109
+ Prefab::FeatureFlagVariant.new(string: "default"),
110
+ ]
99
111
  flag = Prefab::FeatureFlag.new(
100
112
  active: true,
101
- variants: [
102
- Prefab::FeatureFlagVariant.new(string: "inactive"),
103
- Prefab::FeatureFlagVariant.new(string: "rule target"),
104
- Prefab::FeatureFlagVariant.new(string: "default"),
105
- ],
106
- inactive_variant_idx: 0,
107
- rules: [Prefab::Rule.new(
108
- distribution: Prefab::VariantDistribution.new(variant_idx: 1),
109
- criteria: Prefab::Criteria.new(
110
- operator: "IN",
111
- values: ["user:1"]
113
+ inactive_variant_idx: 1,
114
+ rules: [
115
+ Prefab::Rule.new(
116
+ variant_weights: [
117
+ Prefab::VariantWeight.new(weight: 1000,
118
+ variant_idx: 2)
119
+ ],
120
+ criteria: Prefab::Criteria.new(
121
+ operator: "LOOKUP_KEY_IN",
122
+ values: ["user:1"]
123
+ )
124
+ ),
125
+ Prefab::Rule.new(
126
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
127
+ variant_weights: [
128
+ Prefab::VariantWeight.new(weight: 1000,
129
+ variant_idx: 3)
130
+ ]
112
131
  )
113
- )],
114
- default: Prefab::VariantDistribution.new(variant_idx: 2)
132
+
133
+ ],
115
134
  )
116
135
 
117
136
  assert_equal "rule target",
118
- @client.evaluate(feature, "user:1", [], flag)
137
+ @client.evaluate(feature, "user:1", [], flag, variants)
119
138
  assert_equal "default",
120
- @client.evaluate(feature, "user:2", [], flag)
139
+ @client.evaluate(feature, "user:2", [], flag, variants)
140
+
141
+ end
142
+
143
+ def test_property_is_one_of
144
+ feature = "FlagName"
145
+ variants = [
146
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
147
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
148
+ Prefab::FeatureFlagVariant.new(string: "default"),
149
+ ]
150
+ flag = Prefab::FeatureFlag.new(
151
+ active: true,
152
+ inactive_variant_idx: 1,
153
+ rules: [
154
+ Prefab::Rule.new(
155
+ variant_weights: [
156
+ Prefab::VariantWeight.new(weight: 1000,
157
+ variant_idx: 2)
158
+ ],
159
+ criteria: Prefab::Criteria.new(
160
+ operator: "PROP_IS_ONE_OF",
161
+ values: ["a@example.com", "b@example.com"],
162
+ property: "email"
163
+ )
164
+ ),
165
+ Prefab::Rule.new(
166
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
167
+ variant_weights: [
168
+ Prefab::VariantWeight.new(weight: 1000,
169
+ variant_idx: 3)
170
+ ]
171
+ )
172
+
173
+ ],
174
+ )
175
+
176
+ assert_equal "default",
177
+ @client.evaluate(feature, "user:1", {email: "not@example.com"}, flag, variants)
178
+ assert_equal "default",
179
+ @client.evaluate(feature, "user:2", {}, flag, variants)
180
+ assert_equal "rule target",
181
+ @client.evaluate(feature, "user:2", {email: "b@example.com"}, flag, variants)
182
+ assert_equal "rule target",
183
+ @client.evaluate(feature, "user:2", {"email" => "b@example.com"}, flag, variants)
121
184
 
122
185
  end
123
186
 
@@ -135,86 +198,110 @@ class TestFeatureFlagClient < Minitest::Test
135
198
 
136
199
  def test_segments
137
200
  segment_key = "prefab-segment-beta-group"
138
- @mock_base_client.mock_this_config(segment_key,
139
- Prefab::Segment.new(
140
- name: "Beta Group",
141
- includes: ["user:1"]
142
- )
201
+ @mock_base_client.config_client.mock_this_config(segment_key,
202
+ Prefab::Segment.new(
203
+ name: "Beta Group",
204
+ includes: ["user:1"]
205
+ )
143
206
  )
144
207
 
145
208
  feature = "FlagName"
209
+ variants = [
210
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
211
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
212
+ Prefab::FeatureFlagVariant.new(string: "default"),
213
+ ]
146
214
  flag = Prefab::FeatureFlag.new(
147
215
  active: true,
148
- variants: [
149
- Prefab::FeatureFlagVariant.new(string: "inactive"),
150
- Prefab::FeatureFlagVariant.new(string: "rule target"),
151
- Prefab::FeatureFlagVariant.new(string: "default"),
152
- ],
153
- inactive_variant_idx: 0,
154
- rules: [Prefab::Rule.new(
155
- distribution: Prefab::VariantDistribution.new(variant_idx: 1),
156
- criteria: Prefab::Criteria.new(
157
- operator: "IN_SEG",
158
- values: [segment_key]
216
+ inactive_variant_idx: 1,
217
+ rules: [
218
+ Prefab::Rule.new(
219
+ variant_weights: [
220
+ Prefab::VariantWeight.new(weight: 1000,
221
+ variant_idx: 2)
222
+ ],
223
+ criteria: Prefab::Criteria.new(
224
+ operator: "IN_SEG",
225
+ values: [segment_key]
226
+ )
227
+ ),
228
+ Prefab::Rule.new(
229
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
230
+ variant_weights: [
231
+ Prefab::VariantWeight.new(weight: 1000,
232
+ variant_idx: 3)
233
+ ]
159
234
  )
160
- )],
161
- default: Prefab::VariantDistribution.new(variant_idx: 2)
235
+
236
+ ],
162
237
  )
163
238
 
164
239
  assert_equal "rule target",
165
- @client.evaluate(feature, "user:1", [], flag)
240
+ @client.evaluate(feature, "user:1", [], flag, variants)
166
241
  assert_equal "default",
167
- @client.evaluate(feature, "user:2", [], flag)
242
+ @client.evaluate(feature, "user:2", [], flag, variants)
168
243
 
169
244
  end
170
245
 
171
246
  def test_in_multiple_segments_has_or_behavior
172
247
  segment_key_one = "prefab-segment-segment-1"
173
- @mock_base_client.mock_this_config(segment_key_one,
174
- Prefab::Segment.new(
175
- name: "Segment-1",
176
- includes: ["user:1", "user:2"],
177
- excludes: ["user:3"]
178
- )
248
+ @mock_base_client.config_client.mock_this_config(segment_key_one,
249
+ Prefab::Segment.new(
250
+ name: "Segment-1",
251
+ includes: ["user:1", "user:2"],
252
+ excludes: ["user:3"]
253
+ )
179
254
  )
180
255
  segment_key_two = "prefab-segment-segment-2"
181
- @mock_base_client.mock_this_config(segment_key_two,
182
- Prefab::Segment.new(
183
- name: "Segment-2",
184
- includes: ["user:3", "user:4"],
185
- excludes: ["user:2"]
186
- )
256
+ @mock_base_client.config_client.mock_this_config(segment_key_two,
257
+ Prefab::Segment.new(
258
+ name: "Segment-2",
259
+ includes: ["user:3", "user:4"],
260
+ excludes: ["user:2"]
261
+ )
187
262
  )
188
263
 
189
264
  feature = "FlagName"
265
+ variants = [
266
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
267
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
268
+ Prefab::FeatureFlagVariant.new(string: "default"),
269
+ ]
190
270
  flag = Prefab::FeatureFlag.new(
191
271
  active: true,
192
- variants: [
193
- Prefab::FeatureFlagVariant.new(string: "inactive"),
194
- Prefab::FeatureFlagVariant.new(string: "rule target"),
195
- Prefab::FeatureFlagVariant.new(string: "default"),
196
- ],
197
- inactive_variant_idx: 0,
198
- rules: [Prefab::Rule.new(
199
- distribution: Prefab::VariantDistribution.new(variant_idx: 1),
200
- criteria: Prefab::Criteria.new(
201
- operator: "IN_SEG",
202
- values: [segment_key_one, segment_key_two]
272
+ inactive_variant_idx: 1,
273
+ rules: [
274
+ Prefab::Rule.new(
275
+ variant_weights: [
276
+ Prefab::VariantWeight.new(weight: 1000,
277
+ variant_idx: 2)
278
+ ],
279
+ criteria: Prefab::Criteria.new(
280
+ operator: "IN_SEG",
281
+ values: [segment_key_one, segment_key_two]
282
+ )
283
+ ),
284
+ Prefab::Rule.new(
285
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
286
+ variant_weights: [
287
+ Prefab::VariantWeight.new(weight: 1000,
288
+ variant_idx: 3)
289
+ ]
203
290
  )
204
- )],
205
- default: Prefab::VariantDistribution.new(variant_idx: 2)
291
+ ]
206
292
  )
207
293
 
208
294
  assert_equal "rule target",
209
- @client.evaluate(feature, "user:1", [], flag)
295
+ @client.evaluate(feature, "user:1", [], flag, variants)
210
296
  assert_equal "rule target",
211
- @client.evaluate(feature, "user:2", [], flag), "matches segment 1"
297
+ @client.evaluate(feature, "user:2", [], flag, variants), "matches segment 1"
212
298
  assert_equal "rule target",
213
- @client.evaluate(feature, "user:3", [], flag)
299
+ @client.evaluate(feature, "user:3", [], flag, variants)
214
300
  assert_equal "rule target",
215
- @client.evaluate(feature, "user:4", [], flag)
301
+ @client.evaluate(feature, "user:4", [], flag, variants)
216
302
  assert_equal "default",
217
- @client.evaluate(feature, "user:5", [], flag)
303
+ @client.evaluate(feature, "user:5", [], flag, variants)
218
304
 
219
305
  end
306
+
220
307
  end
data/test/test_helper.rb CHANGED
@@ -2,32 +2,68 @@ require 'minitest/autorun'
2
2
  require 'prefab-cloud-ruby'
3
3
 
4
4
  class MockBaseClient
5
- attr_reader :namespace, :logger, :environment
5
+ STAGING_ENV_ID = 1
6
+ PRODUCTION_ENV_ID = 2
7
+ TEST_ENV_ID = 3
8
+ attr_reader :namespace, :logger, :config_client
9
+
10
+ def initialize(namespace: "")
6
11
 
7
- def initialize(environment: "test", namespace: "")
8
- @environment = environment
9
12
  @namespace = namespace
10
13
  @logger = Logger.new($stdout)
11
- @config_values = {}
14
+ @config_client = MockConfigClient.new
12
15
  end
13
16
 
14
17
  def project_id
15
18
  1
16
19
  end
17
20
 
21
+ def log
22
+ @logger
23
+ end
24
+
18
25
  def log_internal level, message
19
26
  end
20
27
 
21
- def mock_this_config key, config_value
22
- @config_values[key] = config_value
28
+ def config_value key
29
+ @config_values[key]
23
30
  end
24
31
 
32
+ end
33
+
34
+ class MockConfigClient
35
+ def initialize(config_values = {})
36
+ @config_values = config_values
37
+ end
25
38
  def get(key)
26
39
  @config_values[key]
27
40
  end
41
+
42
+ def get_config(key)
43
+ Prefab::Config.new(value: @config_values[key], key: key)
44
+ end
45
+
46
+ def mock_this_config key, config_value
47
+ @config_values[key] = config_value
48
+ end
28
49
  end
29
50
 
30
51
  class MockConfigLoader
31
52
  def calc_config
32
53
  end
33
54
  end
55
+
56
+
57
+ private
58
+
59
+ def default_ff_rule(variant_idx)
60
+ [
61
+ Prefab::Rule.new(
62
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
63
+ variant_weights: [
64
+ Prefab::VariantWeight.new(weight: 1000,
65
+ variant_idx: variant_idx)
66
+ ]
67
+ )
68
+ ]
69
+ end
data/test/test_logger.rb CHANGED
@@ -39,13 +39,3 @@ class TestCLogger < Minitest::Test
39
39
  @logger.level_of("app.models.user")
40
40
  end
41
41
  end
42
-
43
- class MockConfigClient
44
- def initialize(hash)
45
- @hash = hash
46
- end
47
-
48
- def get(key)
49
- @hash[key]
50
- end
51
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-24 00:00:00.000000000 Z
11
+ date: 2022-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: ld-eventsource
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: grpc
49
63
  requirement: !ruby/object:Gem::Requirement