flipper 0.22.2 → 0.23.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +6 -1
  3. data/.github/workflows/examples.yml +1 -0
  4. data/.rspec +1 -0
  5. data/Changelog.md +18 -2
  6. data/Gemfile +2 -2
  7. data/README.md +15 -67
  8. data/docs/README.md +1 -0
  9. data/docs/images/banner.jpg +0 -0
  10. data/lib/flipper/adapters/dual_write.rb +9 -15
  11. data/lib/flipper/adapters/failover.rb +83 -0
  12. data/lib/flipper/adapters/http/client.rb +11 -1
  13. data/lib/flipper/adapters/http/error.rb +19 -1
  14. data/lib/flipper/adapters/memoizable.rb +8 -16
  15. data/lib/flipper/adapters/pstore.rb +2 -5
  16. data/lib/flipper/adapters/sync/interval_synchronizer.rb +1 -6
  17. data/lib/flipper/adapters/sync.rb +9 -15
  18. data/lib/flipper/instrumenters/memory.rb +6 -2
  19. data/lib/flipper/version.rb +1 -1
  20. data/spec/flipper/actor_spec.rb +0 -2
  21. data/spec/flipper/adapter_spec.rb +0 -2
  22. data/spec/flipper/adapters/dual_write_spec.rb +0 -2
  23. data/spec/flipper/adapters/failover_spec.rb +129 -0
  24. data/spec/flipper/adapters/http_spec.rb +39 -3
  25. data/spec/flipper/adapters/instrumented_spec.rb +0 -2
  26. data/spec/flipper/adapters/memoizable_spec.rb +0 -2
  27. data/spec/flipper/adapters/memory_spec.rb +0 -3
  28. data/spec/flipper/adapters/operation_logger_spec.rb +0 -2
  29. data/spec/flipper/adapters/pstore_spec.rb +0 -2
  30. data/spec/flipper/adapters/read_only_spec.rb +0 -1
  31. data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +0 -1
  32. data/spec/flipper/adapters/sync/interval_synchronizer_spec.rb +4 -5
  33. data/spec/flipper/adapters/sync/synchronizer_spec.rb +0 -1
  34. data/spec/flipper/adapters/sync_spec.rb +0 -2
  35. data/spec/flipper/configuration_spec.rb +0 -1
  36. data/spec/flipper/dsl_spec.rb +0 -1
  37. data/spec/flipper/feature_check_context_spec.rb +0 -2
  38. data/spec/flipper/feature_spec.rb +0 -1
  39. data/spec/flipper/gate_spec.rb +0 -2
  40. data/spec/flipper/gate_values_spec.rb +0 -1
  41. data/spec/flipper/gates/actor_spec.rb +0 -2
  42. data/spec/flipper/gates/boolean_spec.rb +0 -2
  43. data/spec/flipper/gates/group_spec.rb +0 -2
  44. data/spec/flipper/gates/percentage_of_actors_spec.rb +0 -2
  45. data/spec/flipper/gates/percentage_of_time_spec.rb +0 -2
  46. data/spec/flipper/identifier_spec.rb +0 -1
  47. data/spec/flipper/instrumentation/log_subscriber_spec.rb +0 -1
  48. data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +0 -1
  49. data/spec/flipper/instrumenters/memory_spec.rb +18 -1
  50. data/spec/flipper/instrumenters/noop_spec.rb +14 -8
  51. data/spec/flipper/middleware/memoizer_spec.rb +0 -2
  52. data/spec/flipper/middleware/setup_env_spec.rb +0 -2
  53. data/spec/flipper/railtie_spec.rb +17 -19
  54. data/spec/flipper/registry_spec.rb +0 -1
  55. data/spec/flipper/typecast_spec.rb +0 -1
  56. data/spec/flipper/types/actor_spec.rb +0 -1
  57. data/spec/flipper/types/boolean_spec.rb +0 -1
  58. data/spec/flipper/types/group_spec.rb +0 -1
  59. data/spec/flipper/types/percentage_of_actors_spec.rb +0 -1
  60. data/spec/flipper/types/percentage_of_time_spec.rb +0 -1
  61. data/spec/flipper/types/percentage_spec.rb +0 -1
  62. data/spec/flipper_integration_spec.rb +0 -1
  63. data/spec/flipper_spec.rb +0 -1
  64. data/spec/{helper.rb → spec_helper.rb} +2 -1
  65. data/spec/support/spec_helpers.rb +2 -6
  66. metadata +10 -13
  67. data/docs/Adapters.md +0 -124
  68. data/docs/Caveats.md +0 -4
  69. data/docs/Gates.md +0 -167
  70. data/docs/Instrumentation.md +0 -27
  71. data/docs/Optimization.md +0 -137
  72. data/docs/api/README.md +0 -884
  73. data/docs/http/README.md +0 -36
  74. data/docs/read-only/README.md +0 -24
@@ -0,0 +1,129 @@
1
+ require 'dalli'
2
+ require 'flipper/adapters/failover'
3
+ require 'net/http'
4
+ require 'pstore'
5
+ require 'redis'
6
+
7
+ RSpec.describe Flipper::Adapters::Failover do
8
+ subject { described_class.new(primary, secondary, options) }
9
+
10
+ let(:primary) { Flipper::Adapters::Memory.new }
11
+ let(:secondary) { Flipper::Adapters::Memory.new }
12
+ let(:options) { {} }
13
+ let(:flipper) { Flipper.new(subject) }
14
+
15
+ context 'when the primary is a functioning adapter' do
16
+ it_should_behave_like 'a flipper adapter'
17
+
18
+ it 'should not call the secondary' do
19
+ expect(secondary).not_to receive(:features)
20
+ subject.features
21
+ end
22
+
23
+ it 'should not write to secondary' do
24
+ expect(secondary).not_to receive(:add)
25
+ expect(secondary).not_to receive(:enable)
26
+
27
+ flipper[:flag].enable
28
+ end
29
+
30
+ context 'when dual_write is enabled' do
31
+ let(:options) { { dual_write: true } }
32
+
33
+ it_should_behave_like 'a flipper adapter'
34
+
35
+ it 'writes to both primary and secondary' do
36
+ expect(primary).to receive(:add).and_call_original
37
+ expect(primary).to receive(:enable).and_call_original
38
+
39
+ expect(secondary).to receive(:add)
40
+ expect(secondary).to receive(:enable)
41
+
42
+ flipper[:flag].enable
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'when primary fails during read operations' do
48
+ before do
49
+ allow(primary).to receive(:features).and_raise(Redis::ConnectionError)
50
+ allow(primary).to receive(:get).and_raise(Dalli::NetworkError)
51
+ end
52
+
53
+ it 'fails over to the secondary adapter for reads' do
54
+ expect(secondary).to receive(:features)
55
+ subject.features
56
+
57
+ flipper[:flag].enable
58
+ expect(secondary).to receive(:get).and_call_original
59
+ flipper[:flag].enabled?
60
+ end
61
+
62
+ context 'when dual_write is enabled' do
63
+ let(:options) { { dual_write: true } }
64
+
65
+ it_should_behave_like 'a flipper adapter'
66
+ end
67
+ end
68
+
69
+ context 'when primary fails during write operations' do
70
+ before do
71
+ allow(primary).to receive(:add).and_raise(PStore::Error)
72
+ end
73
+
74
+ let(:options) { { dual_write: true } }
75
+
76
+ it 'fails and does not write to secondary adapter' do
77
+ expect(secondary).not_to receive(:add)
78
+ expect(secondary).not_to receive(:enable)
79
+
80
+ expect { flipper[:flag].enable }.to raise_error(PStore::Error)
81
+ end
82
+ end
83
+
84
+ context 'when primary is instrumented and fails' do
85
+ before do
86
+ allow(memory_adapter).to receive(:get).and_raise(Net::ReadTimeout)
87
+ end
88
+
89
+ let(:memory_adapter) { Flipper::Adapters::Memory.new }
90
+ let(:primary) do
91
+ Flipper::Adapters::Instrumented.new(
92
+ memory_adapter,
93
+ instrumenter: instrumenter,
94
+ )
95
+ end
96
+ let(:instrumenter) { Flipper::Instrumenters::Memory.new }
97
+
98
+ it 'logs the raised exception' do
99
+ flipper[:flag].enabled?
100
+
101
+ expect(instrumenter.events.count).to be 1
102
+
103
+ payload = instrumenter.events[0].payload
104
+ expect(payload.keys).to include(:exception, :exception_object)
105
+ expect(payload[:exception_object]).to be_a Net::ReadTimeout
106
+ end
107
+ end
108
+
109
+ context 'when adapter raises a SyntaxError' do
110
+ before do
111
+ allow(primary).to receive(:features).and_raise(SyntaxError)
112
+ end
113
+
114
+ it 'does not rescue this type by default' do
115
+ expect {
116
+ subject.features
117
+ }.to raise_error(SyntaxError)
118
+ end
119
+
120
+ context 'when Failover adapter is configured to catch SyntaxError' do
121
+ let(:options) { { errors: [ SyntaxError ] } }
122
+
123
+ it 'fails over to secondary adapter' do
124
+ expect(secondary).to receive(:features)
125
+ subject.features
126
+ end
127
+ end
128
+ end
129
+ end
@@ -1,7 +1,5 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/http'
3
2
  require 'flipper/adapters/pstore'
4
- require 'flipper/spec/shared_adapter_specs'
5
3
  require 'rack/handler/webrick'
6
4
 
7
5
  FLIPPER_SPEC_API_PORT = ENV.fetch('FLIPPER_SPEC_API_PORT', 9001).to_i
@@ -159,6 +157,19 @@ RSpec.describe Flipper::Adapters::Http do
159
157
  stub_request(:post, /app.com/)
160
158
  .to_return(status: 503, body: "{}", headers: {})
161
159
 
160
+ adapter = described_class.new(url: 'http://app.com/flipper')
161
+ feature = Flipper::Feature.new(:search, adapter)
162
+ gate = feature.gate(:boolean)
163
+ thing = gate.wrap(true)
164
+ expect {
165
+ adapter.enable(feature, gate, thing)
166
+ }.to raise_error(Flipper::Adapters::Http::Error, "Failed with status: 503")
167
+ end
168
+
169
+ it "doesn't raise json error if body cannot be parsed" do
170
+ stub_request(:post, /app.com/)
171
+ .to_return(status: 503, body: "barf", headers: {})
172
+
162
173
  adapter = described_class.new(url: 'http://app.com/flipper')
163
174
  feature = Flipper::Feature.new(:search, adapter)
164
175
  gate = feature.gate(:boolean)
@@ -167,6 +178,30 @@ RSpec.describe Flipper::Adapters::Http do
167
178
  adapter.enable(feature, gate, thing)
168
179
  }.to raise_error(Flipper::Adapters::Http::Error)
169
180
  end
181
+
182
+ it "includes response information if available when raising error" do
183
+ api_response = {
184
+ "code" => "error",
185
+ "message" => "This feature has reached the limit to the number of " +
186
+ "actors per feature. Check out groups as a more flexible " +
187
+ "way to enable many actors.",
188
+ "more_info" => "https://www.flippercloud.io/docs",
189
+ }
190
+ stub_request(:post, /app.com/)
191
+ .to_return(status: 503, body: JSON.dump(api_response), headers: {})
192
+
193
+ adapter = described_class.new(url: 'http://app.com/flipper')
194
+ feature = Flipper::Feature.new(:search, adapter)
195
+ gate = feature.gate(:boolean)
196
+ thing = gate.wrap(true)
197
+ error_message = "Failed with status: 503\n\nThis feature has reached the " +
198
+ "limit to the number of actors per feature. Check out " +
199
+ "groups as a more flexible way to enable many actors.\n" +
200
+ "https://www.flippercloud.io/docs"
201
+ expect {
202
+ adapter.enable(feature, gate, thing)
203
+ }.to raise_error(Flipper::Adapters::Http::Error, error_message)
204
+ end
170
205
  end
171
206
 
172
207
  describe "#disable" do
@@ -202,7 +237,8 @@ RSpec.describe Flipper::Adapters::Http do
202
237
  let(:feature) { flipper[:feature_panel] }
203
238
 
204
239
  before do
205
- stub_request(:get, %r{\Ahttp://app.com*}).to_return(body: fixture_file('feature.json'))
240
+ stub_request(:get, %r{\Ahttp://app.com*}).
241
+ to_return(body: fixture_file('feature.json'))
206
242
  end
207
243
 
208
244
  it 'allows client to set request headers' do
@@ -1,7 +1,5 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/instrumented'
3
2
  require 'flipper/instrumenters/memory'
4
- require 'flipper/spec/shared_adapter_specs'
5
3
 
6
4
  RSpec.describe Flipper::Adapters::Instrumented do
7
5
  let(:instrumenter) { Flipper::Instrumenters::Memory.new }
@@ -1,7 +1,5 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/memoizable'
3
2
  require 'flipper/adapters/operation_logger'
4
- require 'flipper/spec/shared_adapter_specs'
5
3
 
6
4
  RSpec.describe Flipper::Adapters::Memoizable do
7
5
  let(:features_key) { described_class::FeaturesKey }
@@ -1,6 +1,3 @@
1
- require 'helper'
2
- require 'flipper/spec/shared_adapter_specs'
3
-
4
1
  RSpec.describe Flipper::Adapters::Memory do
5
2
  let(:source) { {} }
6
3
  subject { described_class.new(source) }
@@ -1,6 +1,4 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/operation_logger'
3
- require 'flipper/spec/shared_adapter_specs'
4
2
 
5
3
  RSpec.describe Flipper::Adapters::OperationLogger do
6
4
  let(:operations) { [] }
@@ -1,6 +1,4 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/pstore'
3
- require 'flipper/spec/shared_adapter_specs'
4
2
 
5
3
  RSpec.describe Flipper::Adapters::PStore do
6
4
  subject do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/read_only'
3
2
 
4
3
  RSpec.describe Flipper::Adapters::ReadOnly do
@@ -1,4 +1,3 @@
1
- require "helper"
2
1
  require "flipper/adapters/memory"
3
2
  require "flipper/adapters/operation_logger"
4
3
  require "flipper/adapters/sync/feature_synchronizer"
@@ -1,10 +1,10 @@
1
- require "helper"
2
1
  require "flipper/adapters/sync/interval_synchronizer"
3
2
 
4
3
  RSpec.describe Flipper::Adapters::Sync::IntervalSynchronizer do
5
4
  let(:events) { [] }
6
- let(:synchronizer) { -> { events << described_class.now } }
5
+ let(:synchronizer) { -> { events << now } }
7
6
  let(:interval) { 10 }
7
+ let(:now) { subject.send(:now) }
8
8
 
9
9
  subject { described_class.new(synchronizer, interval: interval) }
10
10
 
@@ -15,19 +15,18 @@ RSpec.describe Flipper::Adapters::Sync::IntervalSynchronizer do
15
15
  end
16
16
 
17
17
  it "only invokes wrapped synchronizer every interval seconds" do
18
- now = described_class.now
19
18
  subject.call
20
19
  events.clear
21
20
 
22
21
  # move time to one millisecond less than last sync + interval
23
22
  1.upto(interval) do |i|
24
- allow(described_class).to receive(:now).and_return(now + i - 1)
23
+ allow(subject).to receive(:now).and_return(now + i - 1)
25
24
  subject.call
26
25
  end
27
26
  expect(events.size).to be(0)
28
27
 
29
28
  # move time to last sync + interval in milliseconds
30
- allow(described_class).to receive(:now).and_return(now + interval)
29
+ allow(subject).to receive(:now).and_return(now + interval)
31
30
  subject.call
32
31
  expect(events.size).to be(1)
33
32
  end
@@ -1,4 +1,3 @@
1
- require "helper"
2
1
  require "flipper/adapters/memory"
3
2
  require "flipper/instrumenters/memory"
4
3
  require "flipper/adapters/sync/synchronizer"
@@ -1,7 +1,5 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/sync'
3
2
  require 'flipper/adapters/operation_logger'
4
- require 'flipper/spec/shared_adapter_specs'
5
3
  require 'active_support/notifications'
6
4
 
7
5
  RSpec.describe Flipper::Adapters::Sync do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/configuration'
3
2
 
4
3
  RSpec.describe Flipper::Configuration do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/dsl'
3
2
 
4
3
  RSpec.describe Flipper::DSL do
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::FeatureCheckContext do
4
2
  let(:feature_name) { :new_profiles }
5
3
  let(:values) { Flipper::GateValues.new({}) }
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/feature'
3
2
  require 'flipper/instrumenters/memory'
4
3
 
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gate do
4
2
  let(:feature_name) { :stats }
5
3
 
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/gate_values'
3
2
 
4
3
  RSpec.describe Flipper::GateValues do
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gates::Actor do
4
2
  let(:feature_name) { :search }
5
3
 
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gates::Boolean do
4
2
  let(:feature_name) { :search }
5
3
 
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gates::Group do
4
2
  let(:feature_name) { :search }
5
3
 
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gates::PercentageOfActors do
4
2
  let(:feature_name) { :search }
5
3
 
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Gates::PercentageOfTime do
4
2
  let(:feature_name) { :search }
5
3
 
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/identifier'
3
2
 
4
3
  RSpec.describe Flipper::Identifier do
@@ -1,5 +1,4 @@
1
1
  require 'logger'
2
- require 'helper'
3
2
  require 'flipper/adapters/instrumented'
4
3
  require 'flipper/instrumentation/log_subscriber'
5
4
 
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/instrumented'
3
2
  require 'flipper/instrumentation/statsd'
4
3
  require 'statsd'
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/instrumenters/memory'
3
2
 
4
3
  RSpec.describe Flipper::Instrumenters::Memory do
@@ -22,5 +21,23 @@ RSpec.describe Flipper::Instrumenters::Memory do
22
21
  event = described_class::Event.new(name, payload, block_result)
23
22
  expect(instrumenter.events).to eq([event])
24
23
  end
24
+
25
+ context 'when an error is raised' do
26
+ subject do
27
+ instrumenter.instrument(:name) { raise IOError }
28
+ end
29
+
30
+ let(:instrumenter) { described_class.new }
31
+
32
+ it 'captures and propagates the error' do
33
+ expect { subject }.to raise_error(IOError)
34
+
35
+ expect(instrumenter.events.count).to be 1
36
+
37
+ payload = instrumenter.events[0].payload
38
+ expect(payload.keys).to include(:exception, :exception_object)
39
+ expect(payload[:exception_object]).to be_a IOError
40
+ end
41
+ end
25
42
  end
26
43
  end
@@ -1,20 +1,26 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Instrumenters::Noop do
4
2
  describe '.instrument' do
5
3
  context 'with name' do
6
4
  it 'yields block' do
7
- yielded = false
8
- described_class.instrument(:foo) { yielded = true }
9
- expect(yielded).to eq(true)
5
+ expect { |block|
6
+ described_class.instrument(:foo, &block)
7
+ }.to yield_control
10
8
  end
11
9
  end
12
10
 
13
11
  context 'with name and payload' do
12
+ let(:payload) { { pay: :load } }
13
+
14
14
  it 'yields block' do
15
- yielded = false
16
- described_class.instrument(:foo, pay: :load) { yielded = true }
17
- expect(yielded).to eq(true)
15
+ expect { |block|
16
+ described_class.instrument(:foo, payload, &block)
17
+ }.to yield_control
18
+ end
19
+
20
+ it 'yields the payload' do
21
+ described_class.instrument(:foo, payload) do |block_payload|
22
+ expect(block_payload).to eq payload
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'rack/test'
3
2
  require 'active_support/cache'
4
3
  require 'active_support/cache/dalli_store'
@@ -362,7 +361,6 @@ RSpec.describe Flipper::Middleware::Memoizer do
362
361
  end.to_app
363
362
  end
364
363
 
365
-
366
364
  context 'and unless option' do
367
365
  before do
368
366
  options[:unless] = ->(request) { request.path.start_with?("/assets") }
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Middleware::SetupEnv do
4
2
  context 'with flipper instance' do
5
3
  let(:app) do
@@ -1,32 +1,30 @@
1
- require 'helper'
2
1
  require 'rails'
3
2
  require 'flipper/railtie'
4
3
 
5
4
  RSpec.describe Flipper::Railtie do
6
5
  let(:application) do
7
- app = Class.new(Rails::Application).new(
6
+ Class.new(Rails::Application).new(
8
7
  railties: [Flipper::Railtie],
9
- ordered_railties: [Flipper::Railtie]
10
- )
11
- app.config.eager_load = false
12
- app.config.logger = ActiveSupport::Logger.new($stdout)
13
- app.run_load_hooks!
8
+ ).tap do |app|
9
+ app.config.eager_load = false
10
+ app.run_load_hooks!
11
+ end
14
12
  end
15
13
 
16
14
  before do
17
- Rails.application = nil
15
+ ActiveSupport::Dependencies.autoload_paths = ActiveSupport::Dependencies.autoload_paths.dup
16
+ ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_once_paths.dup
18
17
  end
19
18
 
20
- subject do
21
- application.initialize!
22
- application
23
- end
19
+ let(:config) { application.config.flipper }
20
+
21
+ subject { application.initialize! }
24
22
 
25
23
  describe 'initializers' do
26
24
  it 'sets defaults' do
27
- expect(application.config.flipper.env_key).to eq("flipper")
28
- expect(application.config.flipper.memoize).to be(true)
29
- expect(application.config.flipper.preload).to be(true)
25
+ expect(config.env_key).to eq("flipper")
26
+ expect(config.memoize).to be(true)
27
+ expect(config.preload).to be(true)
30
28
  end
31
29
 
32
30
  it "configures instrumentor on default instance" do
@@ -36,19 +34,19 @@ RSpec.describe Flipper::Railtie do
36
34
  end
37
35
 
38
36
  it 'uses Memoizer middleware if config.memoize = true' do
39
- expect(subject.middleware.last).to eq(Flipper::Middleware::Memoizer)
37
+ expect(subject.middleware).to include(Flipper::Middleware::Memoizer)
40
38
  end
41
39
 
42
40
  it 'does not use Memoizer middleware if config.memoize = false' do
43
41
  # load but don't initialize
44
- application.config.flipper.memoize = false
42
+ config.memoize = false
45
43
 
46
- expect(subject.middleware.last).not_to eq(Flipper::Middleware::Memoizer)
44
+ expect(subject.middleware).not_to include(Flipper::Middleware::Memoizer)
47
45
  end
48
46
 
49
47
  it 'passes config to memoizer' do
50
48
  # load but don't initialize
51
- application.config.flipper.update(
49
+ config.update(
52
50
  env_key: 'my_flipper',
53
51
  preload: [:stats, :search]
54
52
  )
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/registry'
3
2
 
4
3
  RSpec.describe Flipper::Registry do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/typecast'
3
2
 
4
3
  RSpec.describe Flipper::Typecast do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/actor'
3
2
 
4
3
  RSpec.describe Flipper::Types::Actor do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/boolean'
3
2
 
4
3
  RSpec.describe Flipper::Types::Boolean do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/group'
3
2
 
4
3
  RSpec.describe Flipper::Types::Group do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/percentage_of_actors'
3
2
 
4
3
  RSpec.describe Flipper::Types::PercentageOfActors do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/percentage_of_time'
3
2
 
4
3
  RSpec.describe Flipper::Types::PercentageOfTime do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/types/percentage_of_actors'
3
2
 
4
3
  RSpec.describe Flipper::Types::Percentage do
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/feature'
3
2
 
4
3
  RSpec.describe Flipper do
data/spec/flipper_spec.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'helper'
2
1
  require 'flipper/cloud'
3
2
 
4
3
  RSpec.describe Flipper do
@@ -14,8 +14,9 @@ require 'webmock/rspec'
14
14
  WebMock.disable_net_connect!(allow_localhost: true)
15
15
 
16
16
  require 'flipper'
17
- require 'flipper/ui'
18
17
  require 'flipper/api'
18
+ require 'flipper/spec/shared_adapter_specs'
19
+ require 'flipper/ui'
19
20
 
20
21
  Dir[FlipperRoot.join('spec/support/**/*.rb')].sort.each { |f| require f }
21
22
 
@@ -1,4 +1,4 @@
1
- require 'climate_control'
1
+ require 'ice_age'
2
2
  require 'json'
3
3
  require 'rack/test'
4
4
 
@@ -31,7 +31,7 @@ module SpecHelpers
31
31
  end
32
32
 
33
33
  def api_error_code_reference_url
34
- 'https://github.com/jnunemaker/flipper/tree/master/docs/api#error-code-reference'
34
+ 'https://flippercloud.io/docs/api#error-code-reference'
35
35
  end
36
36
 
37
37
  def api_not_found_response
@@ -58,10 +58,6 @@ module SpecHelpers
58
58
  }
59
59
  end
60
60
 
61
- def with_modified_env(options, &block)
62
- ClimateControl.modify(options, &block)
63
- end
64
-
65
61
  def silence
66
62
  # Store the original stderr and stdout in order to restore them later
67
63
  original_stderr = $stderr