prefab-cloud-ruby 0.13.1 → 0.13.2

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 +39 -0
  3. data/.tool-versions +1 -0
  4. data/CODEOWNERS +1 -0
  5. data/Gemfile +11 -4
  6. data/Gemfile.lock +52 -32
  7. data/README.md +19 -1
  8. data/Rakefile +1 -0
  9. data/VERSION +1 -1
  10. data/compile_protos.sh +3 -0
  11. data/lib/prefab/auth_interceptor.rb +1 -0
  12. data/lib/prefab/cancellable_interceptor.rb +1 -0
  13. data/lib/prefab/client.rb +51 -38
  14. data/lib/prefab/config_client.rb +145 -73
  15. data/lib/prefab/config_helper.rb +29 -0
  16. data/lib/prefab/config_loader.rb +98 -13
  17. data/lib/prefab/config_resolver.rb +56 -49
  18. data/lib/prefab/error.rb +6 -0
  19. data/lib/prefab/errors/initialization_timeout_error.rb +13 -0
  20. data/lib/prefab/errors/invalid_api_key_error.rb +19 -0
  21. data/lib/prefab/errors/missing_default_error.rb +13 -0
  22. data/lib/prefab/feature_flag_client.rb +129 -11
  23. data/lib/prefab/internal_logger.rb +29 -0
  24. data/lib/prefab/logger_client.rb +10 -8
  25. data/lib/prefab/murmer3.rb +1 -0
  26. data/lib/prefab/noop_cache.rb +1 -0
  27. data/lib/prefab/noop_stats.rb +1 -0
  28. data/lib/prefab/options.rb +82 -0
  29. data/lib/prefab/ratelimit_client.rb +1 -0
  30. data/lib/prefab-cloud-ruby.rb +10 -0
  31. data/lib/prefab_pb.rb +214 -132
  32. data/lib/prefab_services_pb.rb +35 -6
  33. data/prefab-cloud-ruby.gemspec +29 -10
  34. data/run_test_harness_server.sh +8 -0
  35. data/test/.prefab.test.config.yaml +27 -1
  36. data/test/harness_server.rb +64 -0
  37. data/test/test_client.rb +98 -0
  38. data/test/test_config_client.rb +56 -0
  39. data/test/test_config_loader.rb +39 -25
  40. data/test/test_config_resolver.rb +134 -38
  41. data/test/test_feature_flag_client.rb +277 -35
  42. data/test/test_helper.rb +70 -4
  43. data/test/test_logger.rb +23 -29
  44. metadata +69 -14
  45. data/.ruby-version +0 -1
@@ -1,64 +1,306 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class TestFeatureFlagClient < Minitest::Test
4
5
 
6
+ def setup
7
+ super
8
+ @mock_base_client = MockBaseClient.new
9
+ @client = Prefab::FeatureFlagClient.new(@mock_base_client)
10
+ Prefab::FeatureFlagClient.send(:public, :is_on?) #publicize for testing
11
+ Prefab::FeatureFlagClient.send(:public, :segment_match?) #publicize for testing
12
+ Prefab::FeatureFlagClient.send(:public, :get_variant) #publicize for testing
13
+ end
14
+
5
15
  def test_pct
6
- client = Prefab::FeatureFlagClient.new(MockBaseClient.new)
7
- Prefab::FeatureFlagClient.send(:public, :is_on?)
8
16
  feature = "FlagName"
9
- flag = Prefab::FeatureFlag.new( pct: 0.5)
10
17
 
18
+ variants = [
19
+ Prefab::FeatureFlagVariant.new(bool: false),
20
+ Prefab::FeatureFlagVariant.new(bool: true)
21
+ ]
22
+ flag = Prefab::FeatureFlag.new(
23
+ active: true,
24
+ inactive_variant_idx: 1,
25
+ rules: [
26
+ Prefab::Rule.new(
27
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
28
+ variant_weights: [
29
+ Prefab::VariantWeight.new(weight: 86,
30
+ variant_idx: 2), #true
31
+ Prefab::VariantWeight.new(weight: 14,
32
+ variant_idx: 1), #false
33
+ ]
34
+ )
35
+ ]
36
+ )
37
+ # weights above chosen to be 86% in variant_idx 2. and 14% in variant_idx 1.
38
+ # since hashes high is 86.32 > 86 it just falls outside the 86% range and gets false
39
+
40
+ # "1FlagNamehashes high" hashes to 86.322% through dist
11
41
  assert_equal false,
12
- client.is_on?(feature, "hashes high", [], flag)
42
+ evaluate(feature, "hashes high", [], flag, variants)
43
+ # "1FlagNamehashes low" hashes to 44.547% through dist
44
+ assert_equal true,
45
+ evaluate(feature, "hashes low", [], flag, variants)
13
46
 
47
+ end
48
+
49
+ def test_basic_active_inactive
50
+ feature = "FlagName"
51
+ variants = [
52
+ Prefab::FeatureFlagVariant.new(bool: false),
53
+ Prefab::FeatureFlagVariant.new(bool: true)
54
+ ]
55
+ flag = Prefab::FeatureFlag.new(
56
+ active: true,
57
+ inactive_variant_idx: 1,
58
+ rules: default_ff_rule(2)
59
+ )
14
60
  assert_equal true,
15
- client.is_on?(feature, "hashes low", [], flag)
61
+ evaluate(feature, "hashes high", [], flag, variants)
62
+ assert_equal true,
63
+ evaluate(feature, "hashes low", [], flag, variants)
64
+
65
+ variants = [
66
+ Prefab::FeatureFlagVariant.new(bool: false),
67
+ Prefab::FeatureFlagVariant.new(bool: true)
68
+ ]
69
+ flag = Prefab::FeatureFlag.new(
70
+ active: false,
71
+ inactive_variant_idx: 1,
72
+ rules: default_ff_rule(2)
73
+ )
74
+ assert_equal false,
75
+ evaluate(feature, "hashes high", [], flag, variants)
76
+ assert_equal false,
77
+ evaluate(feature, "hashes low", [], flag, variants)
16
78
  end
17
79
 
80
+ def test_inclusion_rule
81
+ feature = "FlagName"
82
+ variants = [
83
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
84
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
85
+ Prefab::FeatureFlagVariant.new(string: "default"),
86
+ ]
87
+ flag = Prefab::FeatureFlag.new(
88
+ active: true,
89
+ inactive_variant_idx: 1,
90
+ rules: [
91
+ Prefab::Rule.new(
92
+ variant_weights: [
93
+ Prefab::VariantWeight.new(weight: 1000,
94
+ variant_idx: 2)
95
+ ],
96
+ criteria: Prefab::Criteria.new(
97
+ operator: "LOOKUP_KEY_IN",
98
+ values: ["user:1"]
99
+ )
100
+ ),
101
+ Prefab::Rule.new(
102
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
103
+ variant_weights: [
104
+ Prefab::VariantWeight.new(weight: 1000,
105
+ variant_idx: 3)
106
+ ]
107
+ )
108
+
109
+ ],
110
+ )
18
111
 
19
- def test_off
20
- client = Prefab::FeatureFlagClient.new(MockBaseClient.new)
21
- Prefab::FeatureFlagClient.send(:public, :is_on?)
112
+ assert_equal "rule target",
113
+ evaluate(feature, "user:1", [], flag, variants)
114
+ assert_equal "default",
115
+ evaluate(feature, "user:2", [], flag, variants)
116
+
117
+ end
118
+
119
+ def test_property_is_one_of
22
120
  feature = "FlagName"
23
- flag = Prefab::FeatureFlag.new(pct: 0)
121
+ variants = [
122
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
123
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
124
+ Prefab::FeatureFlagVariant.new(string: "default"),
125
+ ]
126
+ flag = Prefab::FeatureFlag.new(
127
+ active: true,
128
+ inactive_variant_idx: 1,
129
+ rules: [
130
+ Prefab::Rule.new(
131
+ variant_weights: [
132
+ Prefab::VariantWeight.new(weight: 1000,
133
+ variant_idx: 2)
134
+ ],
135
+ criteria: Prefab::Criteria.new(
136
+ operator: "PROP_IS_ONE_OF",
137
+ values: ["a@example.com", "b@example.com"],
138
+ property: "email"
139
+ )
140
+ ),
141
+ Prefab::Rule.new(
142
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
143
+ variant_weights: [
144
+ Prefab::VariantWeight.new(weight: 1000,
145
+ variant_idx: 3)
146
+ ]
147
+ )
24
148
 
25
- assert_equal false,
26
- client.is_on?(feature, "hashes high", [], flag)
149
+ ],
150
+ )
27
151
 
28
- assert_equal false,
29
- client.is_on?(feature, "hashes low", [], flag)
152
+ assert_equal "default",
153
+ evaluate(feature, "user:1", { email: "not@example.com" }, flag, variants)
154
+ assert_equal "default",
155
+ evaluate(feature, "user:2", {}, flag, variants)
156
+ assert_equal "rule target",
157
+ evaluate(feature, "user:2", { email: "b@example.com" }, flag, variants)
158
+ assert_equal "rule target",
159
+ evaluate(feature, "user:2", { "email" => "b@example.com" }, flag, variants)
160
+
161
+ end
162
+
163
+ def test_segment_match?
164
+ segment = Prefab::Segment.new(
165
+ criterion: [
166
+ Prefab::Criteria.new(
167
+ operator: "PROP_IS_ONE_OF",
168
+ values: ["a@example.com", "b@example.com"],
169
+ property: "email"
170
+ ),
171
+ Prefab::Criteria.new(
172
+ operator: "LOOKUP_KEY_IN",
173
+ values: ["user:2"]
174
+ )
175
+ ]
176
+ )
177
+ assert_equal false, @client.segment_match?(segment, "user:0", {})
178
+ assert_equal true, @client.segment_match?(segment, "user:2", {})
179
+ assert_equal false, @client.segment_match?(segment, "user:1", { email: "no@example.com" })
180
+ assert_equal true, @client.segment_match?(segment, "user:1", { email: "a@example.com" })
30
181
  end
31
182
 
183
+ def test_segments
184
+ segment_key = "prefab-segment-beta-group"
185
+ @mock_base_client.config_client.mock_this_config(segment_key,
186
+ Prefab::Segment.new(
187
+ criterion: [
188
+ Prefab::Criteria.new(
189
+ operator: Prefab::Criteria::CriteriaOperator::LOOKUP_KEY_IN,
190
+ values: ["user:1"]
191
+ )
192
+ ]
193
+ )
194
+ )
32
195
 
33
- def test_on
34
- client = Prefab::FeatureFlagClient.new(MockBaseClient.new)
35
- Prefab::FeatureFlagClient.send(:public, :is_on?)
36
196
  feature = "FlagName"
37
- flag = Prefab::FeatureFlag.new(pct: 1)
197
+ variants = [
198
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
199
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
200
+ Prefab::FeatureFlagVariant.new(string: "default"),
201
+ ]
202
+ flag = Prefab::FeatureFlag.new(
203
+ active: true,
204
+ inactive_variant_idx: 1,
205
+ rules: [
206
+ Prefab::Rule.new(
207
+ variant_weights: [
208
+ Prefab::VariantWeight.new(weight: 1000,
209
+ variant_idx: 2)
210
+ ],
211
+ criteria: Prefab::Criteria.new(
212
+ operator: "IN_SEG",
213
+ values: [segment_key]
214
+ )
215
+ ),
216
+ Prefab::Rule.new(
217
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
218
+ variant_weights: [
219
+ Prefab::VariantWeight.new(weight: 1000,
220
+ variant_idx: 3)
221
+ ]
222
+ )
38
223
 
39
- assert_equal true,
40
- client.is_on?(feature, "hashes high", [], flag)
224
+ ],
225
+ )
226
+
227
+ assert_equal "rule target",
228
+ evaluate(feature, "user:1", [], flag, variants)
229
+ assert_equal "default",
230
+ evaluate(feature, "user:2", [], flag, variants)
41
231
 
42
- assert_equal true,
43
- client.is_on?(feature, "hashes low", [], flag)
44
232
  end
45
233
 
46
- def test_whitelist
47
- client = Prefab::FeatureFlagClient.new(MockBaseClient.new)
48
- Prefab::FeatureFlagClient.send(:public, :is_on?)
234
+ def test_in_multiple_segments_has_or_behavior
235
+ segment_key_one = "prefab-segment-segment-1"
236
+ @mock_base_client.config_client.mock_this_config(segment_key_one,
237
+ Prefab::Segment.new(
238
+ criterion: [
239
+ Prefab::Criteria.new(
240
+ operator: Prefab::Criteria::CriteriaOperator::LOOKUP_KEY_IN,
241
+ values: ["user:1", "user:2"]
242
+ )
243
+ ]
244
+ )
245
+ )
246
+ segment_key_two = "prefab-segment-segment-2"
247
+ @mock_base_client.config_client.mock_this_config(segment_key_two,
248
+ Prefab::Segment.new(
249
+ criterion: [
250
+ Prefab::Criteria.new(
251
+ operator: Prefab::Criteria::CriteriaOperator::LOOKUP_KEY_IN,
252
+ values: ["user:3", "user:4"]
253
+ )
254
+ ]
255
+ )
256
+ )
257
+
49
258
  feature = "FlagName"
50
- flag = Prefab::FeatureFlag.new(pct: 0, whitelisted: ["beta", "user:1", "user:3"])
259
+ variants = [
260
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
261
+ Prefab::FeatureFlagVariant.new(string: "rule target"),
262
+ Prefab::FeatureFlagVariant.new(string: "default"),
263
+ ]
264
+ flag = Prefab::FeatureFlag.new(
265
+ active: true,
266
+ inactive_variant_idx: 1,
267
+ rules: [
268
+ Prefab::Rule.new(
269
+ variant_weights: [
270
+ Prefab::VariantWeight.new(weight: 1000,
271
+ variant_idx: 2)
272
+ ],
273
+ criteria: Prefab::Criteria.new(
274
+ operator: "IN_SEG",
275
+ values: [segment_key_one, segment_key_two]
276
+ )
277
+ ),
278
+ Prefab::Rule.new(
279
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
280
+ variant_weights: [
281
+ Prefab::VariantWeight.new(weight: 1000,
282
+ variant_idx: 3)
283
+ ]
284
+ )
51
285
 
52
- assert_equal false,
53
- client.is_on?(feature, "anything", [], flag)
54
- assert_equal true,
55
- client.is_on?(feature, "anything", ["beta"], flag)
56
- assert_equal true,
57
- client.is_on?(feature, "anything", ["alpha", "beta"], flag)
58
- assert_equal true,
59
- client.is_on?(feature, "anything", ["alpha", "user:1"], flag)
60
- assert_equal false,
61
- client.is_on?(feature, "anything", ["alpha", "user:2"], flag)
286
+ ],
287
+ )
288
+
289
+ assert_equal "rule target",
290
+ evaluate(feature, "user:1", [], flag, variants)
291
+ assert_equal "rule target",
292
+ evaluate(feature, "user:2", [], flag, variants), "matches segment 1"
293
+ assert_equal "rule target",
294
+ evaluate(feature, "user:3", [], flag, variants)
295
+ assert_equal "rule target",
296
+ evaluate(feature, "user:4", [], flag, variants)
297
+ assert_equal "default",
298
+ evaluate(feature, "user:5", [], flag, variants)
299
+
300
+ end
62
301
 
302
+ def evaluate(feature_name, lookup_key, attributes, flag, variants)
303
+ variant = @client.get_variant(feature_name, lookup_key, attributes, flag, variants)
304
+ @client.value_of_variant(variant)
63
305
  end
64
306
  end
data/test/test_helper.rb CHANGED
@@ -1,23 +1,89 @@
1
+ # frozen_string_literal: true
1
2
  require 'minitest/autorun'
2
3
  require 'prefab-cloud-ruby'
3
4
 
4
5
  class MockBaseClient
5
- attr_reader :namespace, :logger
6
+ STAGING_ENV_ID = 1
7
+ PRODUCTION_ENV_ID = 2
8
+ TEST_ENV_ID = 3
9
+ attr_reader :namespace, :logger, :config_client, :options
6
10
 
7
- def initialize(namespace: "")
11
+ def initialize(options = Prefab::Options.new)
12
+ @options = options
8
13
  @namespace = namespace
9
- @logger = Logger.new($stdout)
14
+ @logger = Prefab::LoggerClient.new($stdout)
15
+ @config_client = MockConfigClient.new
10
16
  end
11
17
 
12
- def account_id
18
+ def project_id
13
19
  1
14
20
  end
15
21
 
22
+ def log
23
+ @logger
24
+ end
25
+
16
26
  def log_internal level, message
17
27
  end
28
+
29
+ def config_value key
30
+ @config_values[key]
31
+ end
32
+
33
+ end
34
+
35
+ class MockConfigClient
36
+ def initialize(config_values = {})
37
+ @config_values = config_values
38
+ end
39
+ def get(key, default=nil)
40
+ @config_values.fetch(key, default)
41
+ end
42
+
43
+ def get_config(key)
44
+ Prefab::Config.new(value: @config_values[key], key: key)
45
+ end
46
+
47
+ def mock_this_config key, config_value
48
+ @config_values[key] = config_value
49
+ end
18
50
  end
19
51
 
20
52
  class MockConfigLoader
21
53
  def calc_config
22
54
  end
23
55
  end
56
+
57
+
58
+ private
59
+
60
+ def default_ff_rule(variant_idx)
61
+ [
62
+ Prefab::Rule.new(
63
+ criteria: Prefab::Criteria.new(operator: Prefab::Criteria::CriteriaOperator::ALWAYS_TRUE),
64
+ variant_weights: [
65
+ Prefab::VariantWeight.new(weight: 1000,
66
+ variant_idx: variant_idx)
67
+ ]
68
+ )
69
+ ]
70
+ end
71
+
72
+ def with_env(key, value)
73
+ old_value = ENV[key]
74
+
75
+ ENV[key] = value
76
+ ensure
77
+ ENV[key] = old_value
78
+ end
79
+
80
+ def new_client(overrides = {})
81
+ options = Prefab::Options.new(**{
82
+ prefab_config_override_dir: "none",
83
+ prefab_config_classpath_dir: "test",
84
+ defaults_env: "unit_tests",
85
+ prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
86
+ }.merge(overrides))
87
+
88
+ Prefab::Client.new(options)
89
+ end
data/test/test_logger.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class TestCLogger < Minitest::Test
@@ -18,34 +19,27 @@ class TestCLogger < Minitest::Test
18
19
  end
19
20
 
20
21
  def test_level_of
21
- assert_equal Logger::INFO,
22
- @logger.level_of("app.models.user"), "PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL is info"
23
-
24
- @logger.set_config_client(MockConfigClient.new({}))
25
- assert_equal Logger::WARN,
26
- @logger.level_of("app.models.user"), "default is warn"
27
-
28
- @logger.set_config_client(MockConfigClient.new("log_level.app" => "info"))
29
- assert_equal Logger::INFO,
30
- @logger.level_of("app.models.user")
31
-
32
- @logger.set_config_client(MockConfigClient.new("log_level.app" => "debug"))
33
- assert_equal Logger::DEBUG,
34
- @logger.level_of("app.models.user")
35
-
36
- @logger.set_config_client(MockConfigClient.new("log_level.app" => "debug",
37
- "log_level.app.models" => "warn"))
38
- assert_equal Logger::WARN,
39
- @logger.level_of("app.models.user")
40
- end
41
- end
42
-
43
- class MockConfigClient
44
- def initialize(hash)
45
- @hash = hash
46
- end
47
-
48
- def get(key)
49
- @hash[key]
22
+ with_env("PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL", "info") do
23
+ # env var overrides the default level
24
+ assert_equal Logger::INFO,
25
+ @logger.level_of("app.models.user"), "PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL is info"
26
+
27
+ @logger.set_config_client(MockConfigClient.new({}))
28
+ assert_equal Logger::WARN,
29
+ @logger.level_of("app.models.user"), "default is warn"
30
+
31
+ @logger.set_config_client(MockConfigClient.new("log_level.app" => "info"))
32
+ assert_equal Logger::INFO,
33
+ @logger.level_of("app.models.user")
34
+
35
+ @logger.set_config_client(MockConfigClient.new("log_level.app" => "debug"))
36
+ assert_equal Logger::DEBUG,
37
+ @logger.level_of("app.models.user")
38
+
39
+ @logger.set_config_client(MockConfigClient.new("log_level.app" => "debug",
40
+ "log_level.app.models" => "warn"))
41
+ assert_equal Logger::WARN,
42
+ @logger.level_of("app.models.user")
43
+ end
50
44
  end
51
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
@@ -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
@@ -59,21 +73,35 @@ dependencies:
59
73
  - !ruby/object:Gem::Version
60
74
  version: '0'
61
75
  - !ruby/object:Gem::Dependency
62
- name: grpc-tools
76
+ name: google-protobuf
63
77
  requirement: !ruby/object:Gem::Requirement
64
78
  requirements:
65
- - - "~>"
79
+ - - ">="
66
80
  - !ruby/object:Gem::Version
67
- version: 1.17.1
68
- type: :development
81
+ version: '0'
82
+ type: :runtime
69
83
  prerelease: false
70
84
  version_requirements: !ruby/object:Gem::Requirement
71
85
  requirements:
72
- - - "~>"
86
+ - - ">="
73
87
  - !ruby/object:Gem::Version
74
- version: 1.17.1
88
+ version: '0'
75
89
  - !ruby/object:Gem::Dependency
76
- name: shoulda
90
+ name: googleapis-common-protos-types
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: grpc-tools
77
105
  requirement: !ruby/object:Gem::Requirement
78
106
  requirements:
79
107
  - - ">="
@@ -104,16 +132,16 @@ dependencies:
104
132
  name: bundler
105
133
  requirement: !ruby/object:Gem::Requirement
106
134
  requirements:
107
- - - "~>"
135
+ - - ">="
108
136
  - !ruby/object:Gem::Version
109
- version: '1.0'
137
+ version: '0'
110
138
  type: :development
111
139
  prerelease: false
112
140
  version_requirements: !ruby/object:Gem::Requirement
113
141
  requirements:
114
- - - "~>"
142
+ - - ">="
115
143
  - !ruby/object:Gem::Version
116
- version: '1.0'
144
+ version: '0'
117
145
  - !ruby/object:Gem::Dependency
118
146
  name: juwelier
119
147
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +170,20 @@ dependencies:
142
170
  - - ">="
143
171
  - !ruby/object:Gem::Version
144
172
  version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: thin
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
145
187
  description: RateLimits & Config as a service
146
188
  email: jdwyer@prefab.cloud
147
189
  executables: []
@@ -151,7 +193,9 @@ extra_rdoc_files:
151
193
  - README.md
152
194
  files:
153
195
  - ".envrc"
154
- - ".ruby-version"
196
+ - ".github/workflows/ruby.yml"
197
+ - ".tool-versions"
198
+ - CODEOWNERS
155
199
  - Gemfile
156
200
  - Gemfile.lock
157
201
  - LICENSE.txt
@@ -164,18 +208,29 @@ files:
164
208
  - lib/prefab/cancellable_interceptor.rb
165
209
  - lib/prefab/client.rb
166
210
  - lib/prefab/config_client.rb
211
+ - lib/prefab/config_helper.rb
167
212
  - lib/prefab/config_loader.rb
168
213
  - lib/prefab/config_resolver.rb
214
+ - lib/prefab/error.rb
215
+ - lib/prefab/errors/initialization_timeout_error.rb
216
+ - lib/prefab/errors/invalid_api_key_error.rb
217
+ - lib/prefab/errors/missing_default_error.rb
169
218
  - lib/prefab/feature_flag_client.rb
219
+ - lib/prefab/internal_logger.rb
170
220
  - lib/prefab/logger_client.rb
171
221
  - lib/prefab/murmer3.rb
172
222
  - lib/prefab/noop_cache.rb
173
223
  - lib/prefab/noop_stats.rb
224
+ - lib/prefab/options.rb
174
225
  - lib/prefab/ratelimit_client.rb
175
226
  - lib/prefab_pb.rb
176
227
  - lib/prefab_services_pb.rb
177
228
  - prefab-cloud-ruby.gemspec
229
+ - run_test_harness_server.sh
178
230
  - test/.prefab.test.config.yaml
231
+ - test/harness_server.rb
232
+ - test/test_client.rb
233
+ - test/test_config_client.rb
179
234
  - test/test_config_loader.rb
180
235
  - test/test_config_resolver.rb
181
236
  - test/test_feature_flag_client.rb
@@ -200,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
255
  - !ruby/object:Gem::Version
201
256
  version: '0'
202
257
  requirements: []
203
- rubygems_version: 3.1.6
258
+ rubygems_version: 3.2.32
204
259
  signing_key:
205
260
  specification_version: 4
206
261
  summary: Prefab Ruby Infrastructure
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.4.2