flipper 0.28.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/examples.yml +2 -2
  3. data/Changelog.md +190 -165
  4. data/Gemfile +5 -3
  5. data/docs/images/flipper_cloud.png +0 -0
  6. data/examples/cloud/app.ru +12 -0
  7. data/examples/cloud/basic.rb +22 -0
  8. data/examples/cloud/cloud_setup.rb +4 -0
  9. data/examples/cloud/forked.rb +31 -0
  10. data/examples/cloud/import.rb +17 -0
  11. data/examples/cloud/threaded.rb +36 -0
  12. data/examples/dsl.rb +0 -14
  13. data/flipper-cloud.gemspec +19 -0
  14. data/flipper.gemspec +3 -2
  15. data/lib/flipper/cloud/configuration.rb +189 -0
  16. data/lib/flipper/cloud/dsl.rb +27 -0
  17. data/lib/flipper/cloud/instrumenter.rb +48 -0
  18. data/lib/flipper/cloud/message_verifier.rb +95 -0
  19. data/lib/flipper/cloud/middleware.rb +63 -0
  20. data/lib/flipper/cloud/routes.rb +14 -0
  21. data/lib/flipper/cloud.rb +53 -0
  22. data/lib/flipper/dsl.rb +0 -46
  23. data/lib/flipper/{railtie.rb → engine.rb} +19 -3
  24. data/lib/flipper/metadata.rb +5 -1
  25. data/lib/flipper/middleware/memoizer.rb +1 -1
  26. data/lib/flipper/spec/shared_adapter_specs.rb +43 -43
  27. data/lib/flipper/test/shared_adapter_test.rb +43 -43
  28. data/lib/flipper/version.rb +1 -1
  29. data/lib/flipper.rb +3 -5
  30. data/spec/flipper/adapters/dual_write_spec.rb +2 -2
  31. data/spec/flipper/adapters/instrumented_spec.rb +1 -1
  32. data/spec/flipper/adapters/memoizable_spec.rb +6 -6
  33. data/spec/flipper/adapters/operation_logger_spec.rb +2 -2
  34. data/spec/flipper/adapters/read_only_spec.rb +6 -6
  35. data/spec/flipper/cloud/configuration_spec.rb +269 -0
  36. data/spec/flipper/cloud/dsl_spec.rb +82 -0
  37. data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
  38. data/spec/flipper/cloud/middleware_spec.rb +289 -0
  39. data/spec/flipper/cloud_spec.rb +180 -0
  40. data/spec/flipper/dsl_spec.rb +0 -75
  41. data/spec/flipper/engine_spec.rb +190 -0
  42. data/spec/flipper_integration_spec.rb +12 -12
  43. data/spec/flipper_spec.rb +0 -30
  44. data/spec/spec_helper.rb +0 -12
  45. data/spec/support/climate_control.rb +7 -0
  46. metadata +54 -11
  47. data/.tool-versions +0 -1
  48. data/spec/flipper/railtie_spec.rb +0 -109
@@ -0,0 +1,190 @@
1
+ require 'rails'
2
+ require 'flipper/engine'
3
+
4
+ RSpec.describe Flipper::Engine do
5
+ let(:application) do
6
+ Class.new(Rails::Application) do
7
+ config.eager_load = false
8
+ config.logger = ActiveSupport::Logger.new($stdout)
9
+ end
10
+ end
11
+
12
+ before do
13
+ Rails.application = nil
14
+ ActiveSupport::Dependencies.autoload_paths = ActiveSupport::Dependencies.autoload_paths.dup
15
+ ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_once_paths.dup
16
+ end
17
+
18
+ let(:config) { application.config.flipper }
19
+
20
+ subject { application.initialize! }
21
+
22
+ context 'cloudless' do
23
+ it 'can set env_key from ENV' do
24
+ with_env 'FLIPPER_ENV_KEY' => 'flopper' do
25
+ subject
26
+ expect(config.env_key).to eq('flopper')
27
+ end
28
+ end
29
+
30
+ it 'can set memoize from ENV' do
31
+ with_env 'FLIPPER_MEMOIZE' => 'false' do
32
+ subject
33
+ expect(config.memoize).to eq(false)
34
+ end
35
+ end
36
+
37
+ it 'can set preload from ENV' do
38
+ with_env 'FLIPPER_PRELOAD' => 'false' do
39
+ subject
40
+ expect(config.preload).to eq(false)
41
+ end
42
+ end
43
+
44
+ it 'can set instrumenter from ENV' do
45
+ stub_const('My::Cool::Instrumenter', Class.new)
46
+ with_env 'FLIPPER_INSTRUMENTER' => 'My::Cool::Instrumenter' do
47
+ subject
48
+ expect(config.instrumenter).to eq(My::Cool::Instrumenter)
49
+ end
50
+ end
51
+
52
+ it 'can set log from ENV' do
53
+ with_env 'FLIPPER_LOG' => 'false' do
54
+ subject
55
+ expect(config.log).to eq(false)
56
+ end
57
+ end
58
+
59
+ it 'sets defaults' do
60
+ subject # initialize
61
+ expect(config.env_key).to eq("flipper")
62
+ expect(config.memoize).to be(true)
63
+ expect(config.preload).to be(true)
64
+ end
65
+
66
+ it "configures instrumentor on default instance" do
67
+ subject # initialize
68
+ expect(Flipper.instance.instrumenter).to eq(ActiveSupport::Notifications)
69
+ end
70
+
71
+ it 'uses Memoizer middleware if config.memoize = true' do
72
+ initializer { config.memoize = true }
73
+ expect(subject.middleware).to include(Flipper::Middleware::Memoizer)
74
+ end
75
+
76
+ it 'does not use Memoizer middleware if config.memoize = false' do
77
+ initializer { config.memoize = false }
78
+ expect(subject.middleware).not_to include(Flipper::Middleware::Memoizer)
79
+ end
80
+
81
+ it 'passes config to memoizer' do
82
+ initializer do
83
+ config.update(
84
+ env_key: 'my_flipper',
85
+ preload: [:stats, :search]
86
+ )
87
+ end
88
+
89
+ expect(subject.middleware).to include(Flipper::Middleware::Memoizer)
90
+ middleware = subject.middleware.detect { |m| m.klass == Flipper::Middleware::Memoizer }
91
+ expect(middleware.args[0]).to eq({
92
+ env_key: config.env_key,
93
+ preload: config.preload,
94
+ if: nil
95
+ })
96
+ end
97
+
98
+ it "defines #flipper_id on AR::Base" do
99
+ subject
100
+ require 'active_record'
101
+ expect(ActiveRecord::Base.ancestors).to include(Flipper::Identifier)
102
+ end
103
+ end
104
+
105
+ context 'with cloud' do
106
+ around do |example|
107
+ with_env "FLIPPER_CLOUD_TOKEN" => "test-token" do
108
+ example.run
109
+ end
110
+ end
111
+
112
+ # App for Rack::Test
113
+ let(:app) { application.routes }
114
+
115
+ it "initializes cloud configuration" do
116
+ stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")
117
+
118
+ application.initialize!
119
+
120
+ expect(Flipper.instance).to be_a(Flipper::Cloud::DSL)
121
+ expect(Flipper.instance.instrumenter).to be(ActiveSupport::Notifications)
122
+ end
123
+
124
+ context "with CLOUD_SYNC_SECRET" do
125
+ around do |example|
126
+ with_env "FLIPPER_CLOUD_SYNC_SECRET" => "test-secret" do
127
+ example.run
128
+ end
129
+ end
130
+
131
+ let(:request_body) do
132
+ JSON.generate({
133
+ "environment_id" => 1,
134
+ "webhook_id" => 1,
135
+ "delivery_id" => SecureRandom.uuid,
136
+ "action" => "sync",
137
+ })
138
+ end
139
+ let(:timestamp) { Time.now }
140
+
141
+ let(:signature) {
142
+ Flipper::Cloud::MessageVerifier.new(secret: ENV["FLIPPER_CLOUD_SYNC_SECRET"]).generate(request_body, timestamp)
143
+ }
144
+ let(:signature_header_value) {
145
+ Flipper::Cloud::MessageVerifier.new(secret: "").header(signature, timestamp)
146
+ }
147
+
148
+ it "configures webhook app" do
149
+ application.initialize!
150
+
151
+ stub = stub_request(:get, "https://www.flippercloud.io/adapter/features?exclude_gate_names=true").with({
152
+ headers: { "Flipper-Cloud-Token" => ENV["FLIPPER_CLOUD_TOKEN"] },
153
+ }).to_return(status: 200, body: JSON.generate({ features: {} }), headers: {})
154
+
155
+ post "/_flipper", request_body, { "HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value }
156
+
157
+ expect(last_response.status).to eq(200)
158
+ expect(stub).to have_been_requested
159
+ end
160
+ end
161
+
162
+ context "without CLOUD_SYNC_SECRET" do
163
+ it "does not configure webhook app" do
164
+ application.initialize!
165
+
166
+ post "/_flipper"
167
+ expect(last_response.status).to eq(404)
168
+ end
169
+ end
170
+
171
+ context "without FLIPPER_CLOUD_TOKEN" do
172
+ it "gracefully skips configuring webhook app" do
173
+ with_env "FLIPPER_CLOUD_TOKEN" => nil do
174
+ application.initialize!
175
+ expect(Flipper.instance).to be_a(Flipper::DSL)
176
+ end
177
+
178
+ post "/_flipper"
179
+ expect(last_response.status).to eq(404)
180
+ end
181
+ end
182
+ end
183
+
184
+ # Add app initializer in the same order as config/initializers/*
185
+ def initializer(&block)
186
+ application.initializer 'spec', before: :load_config_initializers do
187
+ block.call
188
+ end
189
+ end
190
+ end
@@ -24,8 +24,8 @@ RSpec.describe Flipper do
24
24
  let(:pitt) { Flipper::Actor.new(1) }
25
25
  let(:clooney) { Flipper::Actor.new(10) }
26
26
 
27
- let(:five_percent_of_actors) { flipper.actors(5) }
28
- let(:five_percent_of_time) { flipper.time(5) }
27
+ let(:five_percent_of_actors) { Flipper::Types::PercentageOfActors.new(5) }
28
+ let(:five_percent_of_time) { Flipper::Types::PercentageOfTime.new(5) }
29
29
 
30
30
  before do
31
31
  described_class.register(:admins, &:admin?)
@@ -69,11 +69,11 @@ RSpec.describe Flipper do
69
69
  end
70
70
 
71
71
  it 'enables feature for flipper actor in group' do
72
- expect(feature.enabled?(flipper.actor(admin_actor))).to eq(true)
72
+ expect(feature.enabled?(Flipper::Types::Actor.new(admin_actor))).to eq(true)
73
73
  end
74
74
 
75
75
  it 'does not enable for flipper actor not in group' do
76
- expect(feature.enabled?(flipper.actor(dev_actor))).to eq(false)
76
+ expect(feature.enabled?(Flipper::Types::Actor.new(dev_actor))).to eq(false)
77
77
  end
78
78
 
79
79
  it 'does not enable feature for all' do
@@ -256,11 +256,11 @@ RSpec.describe Flipper do
256
256
  end
257
257
 
258
258
  it 'disables feature for flipper actor in group' do
259
- expect(feature.enabled?(flipper.actor(admin_actor))).to eq(false)
259
+ expect(feature.enabled?(Flipper::Types::Actor.new(admin_actor))).to eq(false)
260
260
  end
261
261
 
262
262
  it 'does not disable feature for flipper actor in other groups' do
263
- expect(feature.enabled?(flipper.actor(dev_actor))).to eq(true)
263
+ expect(feature.enabled?(Flipper::Types::Actor.new(dev_actor))).to eq(true)
264
264
  end
265
265
 
266
266
  it 'adds feature to set of features' do
@@ -294,7 +294,7 @@ RSpec.describe Flipper do
294
294
 
295
295
  context 'with a percentage of actors' do
296
296
  before do
297
- @result = feature.disable(flipper.actors(0))
297
+ @result = feature.disable(Flipper::Types::PercentageOfActors.new(0))
298
298
  end
299
299
 
300
300
  it 'returns true' do
@@ -318,7 +318,7 @@ RSpec.describe Flipper do
318
318
  context 'with a percentage of time' do
319
319
  before do
320
320
  @gate = feature.gate(:percentage_of_time)
321
- @result = feature.disable(flipper.time(0))
321
+ @result = feature.disable(Flipper::Types::PercentageOfTime.new(0))
322
322
  end
323
323
 
324
324
  it 'returns true' do
@@ -373,12 +373,12 @@ RSpec.describe Flipper do
373
373
  end
374
374
 
375
375
  it 'returns true' do
376
- expect(feature.enabled?(flipper.actor(admin_actor))).to eq(true)
376
+ expect(feature.enabled?(Flipper::Types::Actor.new(admin_actor))).to eq(true)
377
377
  expect(feature.enabled?(admin_actor)).to eq(true)
378
378
  end
379
379
 
380
380
  it 'returns true for truthy block values' do
381
- expect(feature.enabled?(flipper.actor(admin_truthy_actor))).to eq(true)
381
+ expect(feature.enabled?(Flipper::Types::Actor.new(admin_truthy_actor))).to eq(true)
382
382
  end
383
383
 
384
384
  it 'returns true if any actor is in enabled group' do
@@ -388,12 +388,12 @@ RSpec.describe Flipper do
388
388
 
389
389
  context 'for actor in disabled group' do
390
390
  it 'returns false' do
391
- expect(feature.enabled?(flipper.actor(dev_actor))).to eq(false)
391
+ expect(feature.enabled?(Flipper::Types::Actor.new(dev_actor))).to eq(false)
392
392
  expect(feature.enabled?(dev_actor)).to eq(false)
393
393
  end
394
394
 
395
395
  it 'returns false for falsey block values' do
396
- expect(feature.enabled?(flipper.actor(admin_falsey_actor))).to eq(false)
396
+ expect(feature.enabled?(Flipper::Types::Actor.new(admin_falsey_actor))).to eq(false)
397
397
  end
398
398
  end
399
399
 
data/spec/flipper_spec.rb CHANGED
@@ -88,14 +88,6 @@ RSpec.describe Flipper do
88
88
  expect(described_class.instance.enabled?(:search)).to be(false)
89
89
  end
90
90
 
91
- it 'delegates bool to instance' do
92
- expect(described_class.bool).to eq(described_class.instance.bool)
93
- end
94
-
95
- it 'delegates boolean to instance' do
96
- expect(described_class.boolean).to eq(described_class.instance.boolean)
97
- end
98
-
99
91
  it 'delegates enable_actor to instance' do
100
92
  described_class.enable_actor(:search, actor)
101
93
  expect(described_class.instance.enabled?(:search, actor)).to be(true)
@@ -106,10 +98,6 @@ RSpec.describe Flipper do
106
98
  expect(described_class.instance.enabled?(:search, actor)).to be(false)
107
99
  end
108
100
 
109
- it 'delegates actor to instance' do
110
- expect(described_class.actor(actor)).to eq(described_class.instance.actor(actor))
111
- end
112
-
113
101
  it 'delegates enable_group to instance' do
114
102
  described_class.enable_group(:search, group)
115
103
  expect(described_class.instance[:search].enabled_groups).to include(group)
@@ -130,15 +118,6 @@ RSpec.describe Flipper do
130
118
  expect(described_class.instance[:search].percentage_of_actors_value).to be(0)
131
119
  end
132
120
 
133
- it 'delegates actors to instance' do
134
- expect(described_class.actors(5)).to eq(described_class.instance.actors(5))
135
- end
136
-
137
- it 'delegates percentage_of_actors to instance' do
138
- expected = described_class.instance.percentage_of_actors(5)
139
- expect(described_class.percentage_of_actors(5)).to eq(expected)
140
- end
141
-
142
121
  it 'delegates enable_percentage_of_time to instance' do
143
122
  described_class.enable_percentage_of_time(:search, 5)
144
123
  expect(described_class.instance[:search].percentage_of_time_value).to be(5)
@@ -149,15 +128,6 @@ RSpec.describe Flipper do
149
128
  expect(described_class.instance[:search].percentage_of_time_value).to be(0)
150
129
  end
151
130
 
152
- it 'delegates time to instance' do
153
- expect(described_class.time(56)).to eq(described_class.instance.time(56))
154
- end
155
-
156
- it 'delegates percentage_of_time to instance' do
157
- expected = described_class.instance.percentage_of_time(56)
158
- expect(described_class.percentage_of_time(56)).to eq(expected)
159
- end
160
-
161
131
  it 'delegates features to instance' do
162
132
  described_class.instance.add(:search)
163
133
  expect(described_class.features).to eq(described_class.instance.features)
data/spec/spec_helper.rb CHANGED
@@ -91,15 +91,3 @@ RSpec.shared_examples_for 'a DSL feature' do
91
91
  end.to raise_error(ArgumentError, /must be a String or Symbol/)
92
92
  end
93
93
  end
94
-
95
- RSpec.shared_examples_for 'a DSL boolean method' do
96
- it 'returns boolean with value set' do
97
- result = subject.send(method_name, true)
98
- expect(result).to be_instance_of(Flipper::Types::Boolean)
99
- expect(result.value).to be(true)
100
-
101
- result = subject.send(method_name, false)
102
- expect(result).to be_instance_of(Flipper::Types::Boolean)
103
- expect(result.value).to be(false)
104
- end
105
- end
@@ -0,0 +1,7 @@
1
+ require 'climate_control'
2
+
3
+ RSpec.configure do |config|
4
+ def with_env(options = {}, &block)
5
+ ClimateControl.modify(options, &block)
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-21 00:00:00.000000000 Z
11
+ date: 2023-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -24,9 +24,22 @@ dependencies:
24
24
  - - "<"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: brow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.4.1
27
41
  description:
28
- email:
29
- - nunemaker@gmail.com
42
+ email: support@flippercloud.io
30
43
  executables: []
31
44
  extensions: []
32
45
  extra_rdoc_files: []
@@ -36,7 +49,6 @@ files:
36
49
  - ".github/workflows/ci.yml"
37
50
  - ".github/workflows/examples.yml"
38
51
  - ".rspec"
39
- - ".tool-versions"
40
52
  - CODE_OF_CONDUCT.md
41
53
  - Changelog.md
42
54
  - Dockerfile
@@ -53,10 +65,17 @@ files:
53
65
  - docs/DockerCompose.md
54
66
  - docs/README.md
55
67
  - docs/images/banner.jpg
68
+ - docs/images/flipper_cloud.png
56
69
  - examples/api/basic.ru
57
70
  - examples/api/custom_memoized.ru
58
71
  - examples/api/memoized.ru
59
72
  - examples/basic.rb
73
+ - examples/cloud/app.ru
74
+ - examples/cloud/basic.rb
75
+ - examples/cloud/cloud_setup.rb
76
+ - examples/cloud/forked.rb
77
+ - examples/cloud/import.rb
78
+ - examples/cloud/threaded.rb
60
79
  - examples/configuring_default.rb
61
80
  - examples/dsl.rb
62
81
  - examples/enabled_for_actor.rb
@@ -73,6 +92,7 @@ files:
73
92
  - examples/percentage_of_actors_enabled_check.rb
74
93
  - examples/percentage_of_actors_group.rb
75
94
  - examples/percentage_of_time.rb
95
+ - flipper-cloud.gemspec
76
96
  - flipper.gemspec
77
97
  - lib/flipper.rb
78
98
  - lib/flipper/actor.rb
@@ -95,8 +115,16 @@ files:
95
115
  - lib/flipper/adapters/sync/feature_synchronizer.rb
96
116
  - lib/flipper/adapters/sync/interval_synchronizer.rb
97
117
  - lib/flipper/adapters/sync/synchronizer.rb
118
+ - lib/flipper/cloud.rb
119
+ - lib/flipper/cloud/configuration.rb
120
+ - lib/flipper/cloud/dsl.rb
121
+ - lib/flipper/cloud/instrumenter.rb
122
+ - lib/flipper/cloud/message_verifier.rb
123
+ - lib/flipper/cloud/middleware.rb
124
+ - lib/flipper/cloud/routes.rb
98
125
  - lib/flipper/configuration.rb
99
126
  - lib/flipper/dsl.rb
127
+ - lib/flipper/engine.rb
100
128
  - lib/flipper/errors.rb
101
129
  - lib/flipper/export.rb
102
130
  - lib/flipper/exporter.rb
@@ -122,7 +150,6 @@ files:
122
150
  - lib/flipper/middleware/memoizer.rb
123
151
  - lib/flipper/middleware/setup_env.rb
124
152
  - lib/flipper/poller.rb
125
- - lib/flipper/railtie.rb
126
153
  - lib/flipper/registry.rb
127
154
  - lib/flipper/spec/shared_adapter_specs.rb
128
155
  - lib/flipper/test/shared_adapter_test.rb
@@ -153,8 +180,14 @@ files:
153
180
  - spec/flipper/adapters/sync/interval_synchronizer_spec.rb
154
181
  - spec/flipper/adapters/sync/synchronizer_spec.rb
155
182
  - spec/flipper/adapters/sync_spec.rb
183
+ - spec/flipper/cloud/configuration_spec.rb
184
+ - spec/flipper/cloud/dsl_spec.rb
185
+ - spec/flipper/cloud/message_verifier_spec.rb
186
+ - spec/flipper/cloud/middleware_spec.rb
187
+ - spec/flipper/cloud_spec.rb
156
188
  - spec/flipper/configuration_spec.rb
157
189
  - spec/flipper/dsl_spec.rb
190
+ - spec/flipper/engine_spec.rb
158
191
  - spec/flipper/export_spec.rb
159
192
  - spec/flipper/exporter_spec.rb
160
193
  - spec/flipper/exporters/json/export_spec.rb
@@ -176,7 +209,6 @@ files:
176
209
  - spec/flipper/middleware/memoizer_spec.rb
177
210
  - spec/flipper/middleware/setup_env_spec.rb
178
211
  - spec/flipper/poller_spec.rb
179
- - spec/flipper/railtie_spec.rb
180
212
  - spec/flipper/registry_spec.rb
181
213
  - spec/flipper/typecast_spec.rb
182
214
  - spec/flipper/types/actor_spec.rb
@@ -188,6 +220,7 @@ files:
188
220
  - spec/flipper_integration_spec.rb
189
221
  - spec/flipper_spec.rb
190
222
  - spec/spec_helper.rb
223
+ - spec/support/climate_control.rb
191
224
  - spec/support/descriptions.yml
192
225
  - spec/support/fake_udp_socket.rb
193
226
  - spec/support/skippable.rb
@@ -196,11 +229,15 @@ files:
196
229
  - test/adapters/pstore_test.rb
197
230
  - test/test_helper.rb
198
231
  - test_rails/helper.rb
199
- homepage: https://github.com/jnunemaker/flipper
232
+ homepage: https://www.flippercloud.io/docs
200
233
  licenses:
201
234
  - MIT
202
235
  metadata:
203
- changelog_uri: https://github.com/jnunemaker/flipper/blob/main/Changelog.md
236
+ documentation_uri: https://www.flippercloud.io/docs
237
+ homepage_uri: https://www.flippercloud.io
238
+ source_code_uri: https://github.com/flippercloud/flipper
239
+ bug_tracker_uri: https://github.com/flippercloud/flipper/issues
240
+ changelog_uri: https://github.com/flippercloud/flipper/blob/main/Changelog.md
204
241
  post_install_message:
205
242
  rdoc_options: []
206
243
  require_paths:
@@ -216,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
253
  - !ruby/object:Gem::Version
217
254
  version: '0'
218
255
  requirements: []
219
- rubygems_version: 3.3.7
256
+ rubygems_version: 3.4.10
220
257
  signing_key:
221
258
  specification_version: 4
222
259
  summary: Feature flipper for ANYTHING
@@ -239,8 +276,14 @@ test_files:
239
276
  - spec/flipper/adapters/sync/interval_synchronizer_spec.rb
240
277
  - spec/flipper/adapters/sync/synchronizer_spec.rb
241
278
  - spec/flipper/adapters/sync_spec.rb
279
+ - spec/flipper/cloud/configuration_spec.rb
280
+ - spec/flipper/cloud/dsl_spec.rb
281
+ - spec/flipper/cloud/message_verifier_spec.rb
282
+ - spec/flipper/cloud/middleware_spec.rb
283
+ - spec/flipper/cloud_spec.rb
242
284
  - spec/flipper/configuration_spec.rb
243
285
  - spec/flipper/dsl_spec.rb
286
+ - spec/flipper/engine_spec.rb
244
287
  - spec/flipper/export_spec.rb
245
288
  - spec/flipper/exporter_spec.rb
246
289
  - spec/flipper/exporters/json/export_spec.rb
@@ -262,7 +305,6 @@ test_files:
262
305
  - spec/flipper/middleware/memoizer_spec.rb
263
306
  - spec/flipper/middleware/setup_env_spec.rb
264
307
  - spec/flipper/poller_spec.rb
265
- - spec/flipper/railtie_spec.rb
266
308
  - spec/flipper/registry_spec.rb
267
309
  - spec/flipper/typecast_spec.rb
268
310
  - spec/flipper/types/actor_spec.rb
@@ -274,6 +316,7 @@ test_files:
274
316
  - spec/flipper_integration_spec.rb
275
317
  - spec/flipper_spec.rb
276
318
  - spec/spec_helper.rb
319
+ - spec/support/climate_control.rb
277
320
  - spec/support/descriptions.yml
278
321
  - spec/support/fake_udp_socket.rb
279
322
  - spec/support/skippable.rb
data/.tool-versions DELETED
@@ -1 +0,0 @@
1
- ruby 3.1.2
@@ -1,109 +0,0 @@
1
- require 'rails'
2
- require 'flipper/railtie'
3
-
4
- RSpec.describe Flipper::Railtie do
5
- let(:application) do
6
- Class.new(Rails::Application).create(railties: [Flipper::Railtie]) do
7
- config.eager_load = false
8
- end
9
- end
10
-
11
- before do
12
- ActiveSupport::Dependencies.autoload_paths = ActiveSupport::Dependencies.autoload_paths.dup
13
- ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_once_paths.dup
14
- end
15
-
16
- let(:config) { application.config.flipper }
17
-
18
- subject { application.initialize! }
19
-
20
- describe 'initializers' do
21
- it 'can set env_key from ENV' do
22
- ENV['FLIPPER_ENV_KEY'] = 'flopper'
23
-
24
- subject
25
- expect(config.env_key).to eq('flopper')
26
- end
27
-
28
- it 'can set memoize from ENV' do
29
- ENV['FLIPPER_MEMOIZE'] = 'false'
30
-
31
- subject
32
- expect(config.memoize).to eq(false)
33
- end
34
-
35
- it 'can set preload from ENV' do
36
- ENV['FLIPPER_PRELOAD'] = 'false'
37
-
38
- subject
39
- expect(config.preload).to eq(false)
40
- end
41
-
42
- it 'can set instrumenter from ENV' do
43
- stub_const('My::Cool::Instrumenter', Class.new)
44
- ENV['FLIPPER_INSTRUMENTER'] = 'My::Cool::Instrumenter'
45
-
46
- subject
47
- expect(config.instrumenter).to eq(My::Cool::Instrumenter)
48
- end
49
-
50
- it 'can set log from ENV' do
51
- ENV['FLIPPER_LOG'] = 'false'
52
-
53
- subject
54
- expect(config.log).to eq(false)
55
- end
56
-
57
- it 'sets defaults' do
58
- subject # initialize
59
- expect(config.env_key).to eq("flipper")
60
- expect(config.memoize).to be(true)
61
- expect(config.preload).to be(true)
62
- end
63
-
64
- it "configures instrumentor on default instance" do
65
- subject # initialize
66
- expect(Flipper.instance.instrumenter).to eq(ActiveSupport::Notifications)
67
- end
68
-
69
- it 'uses Memoizer middleware if config.memoize = true' do
70
- initializer { config.memoize = true }
71
- expect(subject.middleware).to include(Flipper::Middleware::Memoizer)
72
- end
73
-
74
- it 'does not use Memoizer middleware if config.memoize = false' do
75
- initializer { config.memoize = false }
76
- expect(subject.middleware).not_to include(Flipper::Middleware::Memoizer)
77
- end
78
-
79
- it 'passes config to memoizer' do
80
- initializer do
81
- config.update(
82
- env_key: 'my_flipper',
83
- preload: [:stats, :search]
84
- )
85
- end
86
-
87
- expect(subject.middleware).to include(Flipper::Middleware::Memoizer)
88
- middleware = subject.middleware.detect { |m| m.klass == Flipper::Middleware::Memoizer }
89
- expect(middleware.args[0]).to eq({
90
- env_key: config.env_key,
91
- preload: config.preload,
92
- if: nil
93
- })
94
- end
95
-
96
- it "defines #flipper_id on AR::Base" do
97
- subject
98
- require 'active_record'
99
- expect(ActiveRecord::Base.ancestors).to include(Flipper::Identifier)
100
- end
101
- end
102
-
103
- # Add app initializer in the same order as config/initializers/*
104
- def initializer(&block)
105
- application.initializer 'spec', before: :load_config_initializers do
106
- block.call
107
- end
108
- end
109
- end