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.
- checksums.yaml +4 -4
- data/.github/workflows/examples.yml +2 -2
- data/Changelog.md +190 -165
- data/Gemfile +5 -3
- data/docs/images/flipper_cloud.png +0 -0
- data/examples/cloud/app.ru +12 -0
- data/examples/cloud/basic.rb +22 -0
- data/examples/cloud/cloud_setup.rb +4 -0
- data/examples/cloud/forked.rb +31 -0
- data/examples/cloud/import.rb +17 -0
- data/examples/cloud/threaded.rb +36 -0
- data/examples/dsl.rb +0 -14
- data/flipper-cloud.gemspec +19 -0
- data/flipper.gemspec +3 -2
- data/lib/flipper/cloud/configuration.rb +189 -0
- data/lib/flipper/cloud/dsl.rb +27 -0
- data/lib/flipper/cloud/instrumenter.rb +48 -0
- data/lib/flipper/cloud/message_verifier.rb +95 -0
- data/lib/flipper/cloud/middleware.rb +63 -0
- data/lib/flipper/cloud/routes.rb +14 -0
- data/lib/flipper/cloud.rb +53 -0
- data/lib/flipper/dsl.rb +0 -46
- data/lib/flipper/{railtie.rb → engine.rb} +19 -3
- data/lib/flipper/metadata.rb +5 -1
- data/lib/flipper/middleware/memoizer.rb +1 -1
- data/lib/flipper/spec/shared_adapter_specs.rb +43 -43
- data/lib/flipper/test/shared_adapter_test.rb +43 -43
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +3 -5
- data/spec/flipper/adapters/dual_write_spec.rb +2 -2
- data/spec/flipper/adapters/instrumented_spec.rb +1 -1
- data/spec/flipper/adapters/memoizable_spec.rb +6 -6
- data/spec/flipper/adapters/operation_logger_spec.rb +2 -2
- data/spec/flipper/adapters/read_only_spec.rb +6 -6
- data/spec/flipper/cloud/configuration_spec.rb +269 -0
- data/spec/flipper/cloud/dsl_spec.rb +82 -0
- data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
- data/spec/flipper/cloud/middleware_spec.rb +289 -0
- data/spec/flipper/cloud_spec.rb +180 -0
- data/spec/flipper/dsl_spec.rb +0 -75
- data/spec/flipper/engine_spec.rb +190 -0
- data/spec/flipper_integration_spec.rb +12 -12
- data/spec/flipper_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -12
- data/spec/support/climate_control.rb +7 -0
- metadata +54 -11
- data/.tool-versions +0 -1
- 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) {
|
28
|
-
let(:five_percent_of_time) {
|
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?(
|
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?(
|
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?(
|
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?(
|
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(
|
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(
|
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?(
|
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?(
|
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?(
|
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?(
|
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
|
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.
|
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-
|
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://
|
232
|
+
homepage: https://www.flippercloud.io/docs
|
200
233
|
licenses:
|
201
234
|
- MIT
|
202
235
|
metadata:
|
203
|
-
|
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.
|
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
|