flipper 1.2.0 → 1.2.2
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/Gemfile +0 -1
- data/lib/flipper/cli.rb +6 -2
- data/lib/flipper/test_help.rb +15 -8
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/cli_spec.rb +27 -2
- data/spec/flipper/cloud/configuration_spec.rb +27 -36
- data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +8 -9
- data/spec/flipper/cloud_spec.rb +2 -3
- data/spec/flipper/engine_spec.rb +35 -48
- data/test_rails/system/test_help_test.rb +8 -3
- metadata +3 -5
- data/spec/support/climate_control.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ff734c4221d1ea2694fdf4e9e463085f60242e698b8702389c53ccc6a17e87b
|
4
|
+
data.tar.gz: 5666852d9f7416d30919a188c5e3c46cb202d66d332c482aba56c3d496437282
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c48de5bfe83ff53d969d496f96a3df9335af8f1fe8d41559158930c9ae3dd94b91f245f7b4cfbceea1c85ab453a4dd94057e4a46e3f928d9b27ddc417f04c718
|
7
|
+
data.tar.gz: 2ed4dd3a74bbf07fe289d57b9545e073527971e5ab7f393ee96ea8f31904a9a550db4cda0ba492f080a14b1eb8b4982eb680e88b1c2bcfeea2e74e032207b1f4
|
data/Gemfile
CHANGED
data/lib/flipper/cli.rb
CHANGED
@@ -209,8 +209,12 @@ module Flipper
|
|
209
209
|
"#{count} #{count == 1 ? singular : plural}"
|
210
210
|
end
|
211
211
|
|
212
|
-
def colorize(text,
|
213
|
-
|
212
|
+
def colorize(text, colors)
|
213
|
+
if defined?(Bundler)
|
214
|
+
Bundler.ui.add_color(text, *colors)
|
215
|
+
else
|
216
|
+
text
|
217
|
+
end
|
214
218
|
end
|
215
219
|
|
216
220
|
def indent(text, spaces)
|
data/lib/flipper/test_help.rb
CHANGED
@@ -1,35 +1,42 @@
|
|
1
1
|
module Flipper
|
2
2
|
module TestHelp
|
3
|
+
extend self
|
4
|
+
|
3
5
|
def flipper_configure
|
4
|
-
#
|
5
|
-
|
6
|
+
# Use a shared Memory adapter for all tests. This is instantiated outside of the
|
7
|
+
# `configure` block so the same instance is returned in new threads.
|
8
|
+
adapter = Flipper::Adapters::Memory.new
|
6
9
|
|
7
10
|
Flipper.configure do |config|
|
8
|
-
config.adapter {
|
11
|
+
config.adapter { adapter }
|
9
12
|
config.default { Flipper.new(config.adapter) }
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
13
16
|
def flipper_reset
|
14
|
-
|
17
|
+
# Remove all features
|
18
|
+
Flipper.features.each(&:remove) rescue nil
|
19
|
+
|
20
|
+
# Reset previous DSL instance
|
21
|
+
Flipper.instance = nil
|
15
22
|
end
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
|
-
if defined?(RSpec)
|
26
|
+
if defined?(RSpec) && RSpec.respond_to?(:configure)
|
20
27
|
RSpec.configure do |config|
|
21
28
|
config.include Flipper::TestHelp
|
22
|
-
config.before(:
|
29
|
+
config.before(:suite) { Flipper::TestHelp.flipper_configure }
|
23
30
|
config.before(:each) { flipper_reset }
|
24
31
|
end
|
25
32
|
end
|
26
|
-
|
27
33
|
if defined?(ActiveSupport)
|
28
34
|
ActiveSupport.on_load(:active_support_test_case) do
|
35
|
+
Flipper::TestHelp.flipper_configure
|
36
|
+
|
29
37
|
ActiveSupport::TestCase.class_eval do
|
30
38
|
include Flipper::TestHelp
|
31
39
|
|
32
|
-
setup :flipper_configure
|
33
40
|
setup :flipper_reset
|
34
41
|
end
|
35
42
|
end
|
data/lib/flipper/version.rb
CHANGED
data/spec/flipper/cli_spec.rb
CHANGED
@@ -16,14 +16,14 @@ RSpec.describe Flipper::CLI do
|
|
16
16
|
describe "enable" do
|
17
17
|
describe "feature" do
|
18
18
|
it do
|
19
|
-
expect(subject).to have_attributes(status: 0, stdout: /feature.*enabled/)
|
19
|
+
expect(subject).to have_attributes(status: 0, stdout: /feature.*\e\[32m.*enabled/)
|
20
20
|
expect(Flipper).to be_enabled(:feature)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "-a User;1 feature" do
|
25
25
|
it do
|
26
|
-
expect(subject).to have_attributes(status: 0, stdout: /feature.*enabled.*User;1/m)
|
26
|
+
expect(subject).to have_attributes(status: 0, stdout: /feature.*\e\[33m.*enabled.*User;1/m)
|
27
27
|
expect(Flipper).to be_enabled(:feature, Flipper::Actor.new("User;1"))
|
28
28
|
end
|
29
29
|
end
|
@@ -142,6 +142,28 @@ RSpec.describe Flipper::CLI do
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
+
context "bundler is not installed" do
|
146
|
+
let(:argv) { "list" }
|
147
|
+
|
148
|
+
around do |example|
|
149
|
+
original_bundler = Bundler
|
150
|
+
begin
|
151
|
+
Object.send(:remove_const, :Bundler)
|
152
|
+
example.run
|
153
|
+
ensure
|
154
|
+
Object.const_set(:Bundler, original_bundler)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should not raise an error" do
|
159
|
+
Flipper.enable(:enabled_feature)
|
160
|
+
Flipper.enable_group(:enabled_groups, :admins)
|
161
|
+
Flipper.add(:disabled_feature)
|
162
|
+
|
163
|
+
expect(subject).to have_attributes(status: 0, stdout: /enabled_feature.*enabled_groups.*disabled_feature/m)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
145
167
|
def run(argv)
|
146
168
|
original_stdout = $stdout
|
147
169
|
original_stderr = $stderr
|
@@ -150,6 +172,9 @@ RSpec.describe Flipper::CLI do
|
|
150
172
|
$stderr = StringIO.new
|
151
173
|
status = 0
|
152
174
|
|
175
|
+
# Prentend this a TTY so we can test colorization
|
176
|
+
allow($stdout).to receive(:tty?).and_return(true)
|
177
|
+
|
153
178
|
begin
|
154
179
|
Flipper::CLI.run(argv)
|
155
180
|
rescue SystemExit => e
|
@@ -12,10 +12,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "can set token from ENV var" do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
15
|
+
ENV["FLIPPER_CLOUD_TOKEN"] = "from_env"
|
16
|
+
instance = described_class.new(required_options.reject { |k, v| k == :token })
|
17
|
+
expect(instance.token).to eq("from_env")
|
19
18
|
end
|
20
19
|
|
21
20
|
it "can set instrumenter" do
|
@@ -30,10 +29,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
30
29
|
end
|
31
30
|
|
32
31
|
it "can set read_timeout from ENV var" do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
32
|
+
ENV["FLIPPER_CLOUD_READ_TIMEOUT"] = "9"
|
33
|
+
instance = described_class.new(required_options.reject { |k, v| k == :read_timeout })
|
34
|
+
expect(instance.read_timeout).to eq(9)
|
37
35
|
end
|
38
36
|
|
39
37
|
it "can set open_timeout" do
|
@@ -42,10 +40,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
42
40
|
end
|
43
41
|
|
44
42
|
it "can set open_timeout from ENV var" do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
43
|
+
ENV["FLIPPER_CLOUD_OPEN_TIMEOUT"] = "9"
|
44
|
+
instance = described_class.new(required_options.reject { |k, v| k == :open_timeout })
|
45
|
+
expect(instance.open_timeout).to eq(9)
|
49
46
|
end
|
50
47
|
|
51
48
|
it "can set write_timeout" do
|
@@ -54,10 +51,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
54
51
|
end
|
55
52
|
|
56
53
|
it "can set write_timeout from ENV var" do
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
54
|
+
ENV["FLIPPER_CLOUD_WRITE_TIMEOUT"] = "9"
|
55
|
+
instance = described_class.new(required_options.reject { |k, v| k == :write_timeout })
|
56
|
+
expect(instance.write_timeout).to eq(9)
|
61
57
|
end
|
62
58
|
|
63
59
|
it "can set sync_interval" do
|
@@ -66,10 +62,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
66
62
|
end
|
67
63
|
|
68
64
|
it "can set sync_interval from ENV var" do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
65
|
+
ENV["FLIPPER_CLOUD_SYNC_INTERVAL"] = "15"
|
66
|
+
instance = described_class.new(required_options.reject { |k, v| k == :sync_interval })
|
67
|
+
expect(instance.sync_interval).to eq(15)
|
73
68
|
end
|
74
69
|
|
75
70
|
it "passes sync_interval into sync adapter" do
|
@@ -87,10 +82,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
87
82
|
end
|
88
83
|
|
89
84
|
it "defaults debug_output to STDOUT if FLIPPER_CLOUD_DEBUG_OUTPUT_STDOUT set to true" do
|
90
|
-
|
91
|
-
|
85
|
+
ENV["FLIPPER_CLOUD_DEBUG_OUTPUT_STDOUT"] = "true"
|
86
|
+
instance = described_class.new(required_options)
|
92
87
|
expect(instance.debug_output).to eq(STDOUT)
|
93
|
-
end
|
94
88
|
end
|
95
89
|
|
96
90
|
it "defaults adapter block" do
|
@@ -128,10 +122,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
128
122
|
end
|
129
123
|
|
130
124
|
it "can override URL using ENV var" do
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end
|
125
|
+
ENV["FLIPPER_CLOUD_URL"] = "https://example.com"
|
126
|
+
instance = described_class.new(required_options.reject { |k, v| k == :url })
|
127
|
+
expect(instance.url).to eq("https://example.com")
|
135
128
|
end
|
136
129
|
|
137
130
|
it "defaults sync_method to :poll" do
|
@@ -150,12 +143,11 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
150
143
|
end
|
151
144
|
|
152
145
|
it "sets sync_method to :webhook if FLIPPER_CLOUD_SYNC_SECRET set" do
|
153
|
-
|
154
|
-
|
146
|
+
ENV["FLIPPER_CLOUD_SYNC_SECRET"] = "abc"
|
147
|
+
instance = described_class.new(required_options)
|
155
148
|
|
156
|
-
|
157
|
-
|
158
|
-
end
|
149
|
+
expect(instance.sync_method).to eq(:webhook)
|
150
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
159
151
|
end
|
160
152
|
|
161
153
|
it "can set sync_secret" do
|
@@ -164,10 +156,9 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
164
156
|
end
|
165
157
|
|
166
158
|
it "can override sync_secret using ENV var" do
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
159
|
+
ENV["FLIPPER_CLOUD_SYNC_SECRET"] = "from_env"
|
160
|
+
instance = described_class.new(required_options.reject { |k, v| k == :sync_secret })
|
161
|
+
expect(instance.sync_secret).to eq("from_env")
|
171
162
|
end
|
172
163
|
|
173
164
|
it "can sync with cloud" do
|
@@ -49,19 +49,18 @@ RSpec.describe Flipper::Cloud::Telemetry::BackoffPolicy do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "from env" do
|
52
|
-
|
52
|
+
ENV.update(
|
53
53
|
"FLIPPER_BACKOFF_MIN_TIMEOUT_MS" => "1000",
|
54
54
|
"FLIPPER_BACKOFF_MAX_TIMEOUT_MS" => "2000",
|
55
55
|
"FLIPPER_BACKOFF_MULTIPLIER" => "1.9",
|
56
56
|
"FLIPPER_BACKOFF_RANDOMIZATION_FACTOR" => "0.1",
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
57
|
+
)
|
58
|
+
|
59
|
+
policy = described_class.new
|
60
|
+
expect(policy.min_timeout_ms).to eq(1000)
|
61
|
+
expect(policy.max_timeout_ms).to eq(2000)
|
62
|
+
expect(policy.multiplier).to eq(1.9)
|
63
|
+
expect(policy.randomization_factor).to eq(0.1)
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
data/spec/flipper/cloud_spec.rb
CHANGED
@@ -55,9 +55,8 @@ RSpec.describe Flipper::Cloud do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'can initialize with no token explicitly provided' do
|
58
|
-
|
59
|
-
|
60
|
-
end
|
58
|
+
ENV['FLIPPER_CLOUD_TOKEN'] = 'asdf'
|
59
|
+
expect(described_class.new).to be_instance_of(Flipper::Cloud::DSL)
|
61
60
|
end
|
62
61
|
|
63
62
|
it 'can set instrumenter' do
|
data/spec/flipper/engine_spec.rb
CHANGED
@@ -33,28 +33,25 @@ RSpec.describe Flipper::Engine do
|
|
33
33
|
let(:adapter) { Flipper.adapter.adapter }
|
34
34
|
|
35
35
|
it 'can set strict=true from ENV' do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
36
|
+
ENV['FLIPPER_STRICT'] = 'true'
|
37
|
+
subject
|
38
|
+
expect(config.strict).to eq(:raise)
|
39
|
+
expect(adapter).to be_instance_of(Flipper::Adapters::Strict)
|
41
40
|
end
|
42
41
|
|
43
42
|
it 'can set strict=warn from ENV' do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
43
|
+
ENV['FLIPPER_STRICT'] = 'warn'
|
44
|
+
subject
|
45
|
+
expect(config.strict).to eq(:warn)
|
46
|
+
expect(adapter).to be_instance_of(Flipper::Adapters::Strict)
|
47
|
+
expect(adapter.handler).to be(:warn)
|
50
48
|
end
|
51
49
|
|
52
50
|
it 'can set strict=false from ENV' do
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
51
|
+
ENV['FLIPPER_STRICT'] = 'false'
|
52
|
+
subject
|
53
|
+
expect(config.strict).to eq(false)
|
54
|
+
expect(adapter).to be_instance_of(Flipper::Adapters::Memory)
|
58
55
|
end
|
59
56
|
|
60
57
|
[true, :raise, :warn].each do |value|
|
@@ -104,39 +101,34 @@ RSpec.describe Flipper::Engine do
|
|
104
101
|
it_behaves_like 'config.strict'
|
105
102
|
|
106
103
|
it 'can set env_key from ENV' do
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
104
|
+
ENV['FLIPPER_ENV_KEY'] = 'flopper'
|
105
|
+
subject
|
106
|
+
expect(config.env_key).to eq('flopper')
|
111
107
|
end
|
112
108
|
|
113
109
|
it 'can set memoize from ENV' do
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
110
|
+
ENV['FLIPPER_MEMOIZE'] = 'false'
|
111
|
+
subject
|
112
|
+
expect(config.memoize).to eq(false)
|
118
113
|
end
|
119
114
|
|
120
115
|
it 'can set preload from ENV' do
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
116
|
+
ENV['FLIPPER_PRELOAD'] = 'false'
|
117
|
+
subject
|
118
|
+
expect(config.preload).to eq(false)
|
125
119
|
end
|
126
120
|
|
127
121
|
it 'can set instrumenter from ENV' do
|
128
122
|
stub_const('My::Cool::Instrumenter', Class.new)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
123
|
+
ENV['FLIPPER_INSTRUMENTER'] = 'My::Cool::Instrumenter'
|
124
|
+
subject
|
125
|
+
expect(config.instrumenter).to eq(My::Cool::Instrumenter)
|
133
126
|
end
|
134
127
|
|
135
128
|
it 'can set log from ENV' do
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
129
|
+
ENV['FLIPPER_LOG'] = 'false'
|
130
|
+
subject
|
131
|
+
expect(config.log).to eq(false)
|
140
132
|
end
|
141
133
|
|
142
134
|
it 'sets defaults' do
|
@@ -220,10 +212,8 @@ RSpec.describe Flipper::Engine do
|
|
220
212
|
end
|
221
213
|
|
222
214
|
context 'with cloud' do
|
223
|
-
|
224
|
-
|
225
|
-
example.run
|
226
|
-
end
|
215
|
+
before do
|
216
|
+
ENV["FLIPPER_CLOUD_TOKEN"] = "test-token"
|
227
217
|
end
|
228
218
|
|
229
219
|
# App for Rack::Test
|
@@ -248,10 +238,8 @@ RSpec.describe Flipper::Engine do
|
|
248
238
|
end
|
249
239
|
|
250
240
|
context "with CLOUD_SYNC_SECRET" do
|
251
|
-
|
252
|
-
|
253
|
-
example.run
|
254
|
-
end
|
241
|
+
before do
|
242
|
+
ENV["FLIPPER_CLOUD_SYNC_SECRET"] = "test-secret"
|
255
243
|
end
|
256
244
|
|
257
245
|
let(:request_body) do
|
@@ -296,10 +284,9 @@ RSpec.describe Flipper::Engine do
|
|
296
284
|
|
297
285
|
context "without FLIPPER_CLOUD_TOKEN" do
|
298
286
|
it "gracefully skips configuring webhook app" do
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
end
|
287
|
+
ENV["FLIPPER_CLOUD_TOKEN"] = nil
|
288
|
+
application.initialize!
|
289
|
+
expect(Flipper.instance).to be_a(Flipper::DSL)
|
303
290
|
|
304
291
|
post "/_flipper"
|
305
292
|
expect(last_response.status).to eq(404)
|
@@ -29,10 +29,15 @@ end
|
|
29
29
|
|
30
30
|
class TestHelpTest < ActionDispatch::SystemTestCase
|
31
31
|
# Any driver that runs the app in a separate thread will test what we want here.
|
32
|
-
driven_by :cuprite
|
32
|
+
driven_by :cuprite, options: { process_timeout: 30 }
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
setup do
|
35
|
+
# Reconfigure Flipper since other tests change the adapter.
|
36
|
+
flipper_configure
|
37
|
+
|
38
|
+
# Ensure this test uses this app instance
|
39
|
+
Rails.application = TestApp.instance
|
40
|
+
end
|
36
41
|
|
37
42
|
test "configures a shared adapter between tests and app" do
|
38
43
|
Flipper.disable(:test)
|
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: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -286,7 +286,6 @@ files:
|
|
286
286
|
- spec/flipper_spec.rb
|
287
287
|
- spec/spec_helper.rb
|
288
288
|
- spec/support/actor_names.yml
|
289
|
-
- spec/support/climate_control.rb
|
290
289
|
- spec/support/descriptions.yml
|
291
290
|
- spec/support/fake_backoff_policy.rb
|
292
291
|
- spec/support/fake_udp_socket.rb
|
@@ -307,7 +306,7 @@ metadata:
|
|
307
306
|
homepage_uri: https://www.flippercloud.io
|
308
307
|
source_code_uri: https://github.com/flippercloud/flipper
|
309
308
|
bug_tracker_uri: https://github.com/flippercloud/flipper/issues
|
310
|
-
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.
|
309
|
+
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.2
|
311
310
|
post_install_message:
|
312
311
|
rdoc_options: []
|
313
312
|
require_paths:
|
@@ -421,7 +420,6 @@ test_files:
|
|
421
420
|
- spec/flipper_spec.rb
|
422
421
|
- spec/spec_helper.rb
|
423
422
|
- spec/support/actor_names.yml
|
424
|
-
- spec/support/climate_control.rb
|
425
423
|
- spec/support/descriptions.yml
|
426
424
|
- spec/support/fake_backoff_policy.rb
|
427
425
|
- spec/support/fake_udp_socket.rb
|