flipper 0.28.3 → 1.0.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.
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