flipper 0.10.2 → 0.11.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +42 -0
- data/.rubocop_todo.yml +188 -0
- data/Changelog.md +10 -0
- data/Gemfile +6 -3
- data/README.md +4 -3
- data/Rakefile +13 -13
- data/docs/Adapters.md +2 -1
- data/docs/DockerCompose.md +6 -3
- data/docs/Gates.md +25 -3
- data/docs/Optimization.md +27 -5
- data/docs/api/README.md +73 -32
- data/docs/http/README.md +34 -0
- data/docs/read-only/README.md +22 -0
- data/examples/percentage_of_actors_group.rb +49 -0
- data/flipper.gemspec +15 -15
- data/lib/flipper.rb +2 -5
- data/lib/flipper/adapter.rb +10 -0
- data/lib/flipper/adapters/http.rb +147 -0
- data/lib/flipper/adapters/http/client.rb +83 -0
- data/lib/flipper/adapters/http/error.rb +14 -0
- data/lib/flipper/adapters/instrumented.rb +36 -36
- data/lib/flipper/adapters/memoizable.rb +2 -6
- data/lib/flipper/adapters/memory.rb +10 -9
- data/lib/flipper/adapters/operation_logger.rb +1 -1
- data/lib/flipper/adapters/pstore.rb +12 -11
- data/lib/flipper/adapters/read_only.rb +6 -6
- data/lib/flipper/dsl.rb +1 -3
- data/lib/flipper/feature.rb +11 -16
- data/lib/flipper/gate.rb +3 -3
- data/lib/flipper/gate_values.rb +6 -6
- data/lib/flipper/gates/group.rb +2 -2
- data/lib/flipper/gates/percentage_of_actors.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +2 -4
- data/lib/flipper/instrumentation/metriks.rb +1 -1
- data/lib/flipper/instrumentation/statsd.rb +1 -1
- data/lib/flipper/instrumentation/statsd_subscriber.rb +1 -3
- data/lib/flipper/instrumentation/subscriber.rb +11 -10
- data/lib/flipper/instrumenters/memory.rb +1 -5
- data/lib/flipper/instrumenters/noop.rb +1 -1
- data/lib/flipper/middleware/memoizer.rb +11 -27
- data/lib/flipper/middleware/setup_env.rb +44 -0
- data/lib/flipper/registry.rb +8 -10
- data/lib/flipper/spec/shared_adapter_specs.rb +45 -67
- data/lib/flipper/test/shared_adapter_test.rb +25 -31
- data/lib/flipper/typecast.rb +2 -2
- data/lib/flipper/types/actor.rb +2 -4
- data/lib/flipper/types/group.rb +1 -1
- data/lib/flipper/types/percentage.rb +2 -1
- data/lib/flipper/version.rb +1 -1
- data/spec/fixtures/feature.json +31 -0
- data/spec/flipper/adapters/http_spec.rb +148 -0
- data/spec/flipper/adapters/instrumented_spec.rb +20 -20
- data/spec/flipper/adapters/memoizable_spec.rb +59 -59
- data/spec/flipper/adapters/operation_logger_spec.rb +16 -16
- data/spec/flipper/adapters/pstore_spec.rb +6 -6
- data/spec/flipper/adapters/read_only_spec.rb +28 -34
- data/spec/flipper/dsl_spec.rb +73 -84
- data/spec/flipper/feature_check_context_spec.rb +27 -27
- data/spec/flipper/feature_spec.rb +186 -196
- data/spec/flipper/gate_spec.rb +11 -11
- data/spec/flipper/gate_values_spec.rb +46 -45
- data/spec/flipper/gates/actor_spec.rb +2 -2
- data/spec/flipper/gates/boolean_spec.rb +24 -23
- data/spec/flipper/gates/group_spec.rb +19 -19
- data/spec/flipper/gates/percentage_of_actors_spec.rb +10 -10
- data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +20 -20
- data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +20 -20
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +11 -11
- data/spec/flipper/instrumenters/memory_spec.rb +5 -5
- data/spec/flipper/instrumenters/noop_spec.rb +6 -6
- data/spec/flipper/middleware/memoizer_spec.rb +83 -100
- data/spec/flipper/middleware/setup_env_spec.rb +76 -0
- data/spec/flipper/registry_spec.rb +35 -39
- data/spec/flipper/typecast_spec.rb +18 -18
- data/spec/flipper/types/actor_spec.rb +30 -29
- data/spec/flipper/types/boolean_spec.rb +8 -8
- data/spec/flipper/types/group_spec.rb +28 -28
- data/spec/flipper/types/percentage_spec.rb +14 -14
- data/spec/flipper_spec.rb +61 -54
- data/spec/helper.rb +26 -21
- data/spec/integration_spec.rb +121 -113
- data/spec/support/fake_udp_socket.rb +1 -1
- data/spec/support/spec_helpers.rb +32 -4
- data/test/adapters/pstore_test.rb +3 -3
- data/test/test_helper.rb +1 -1
- metadata +20 -5
@@ -3,65 +3,65 @@ require 'helper'
|
|
3
3
|
RSpec.describe Flipper::FeatureCheckContext do
|
4
4
|
let(:feature_name) { :new_profiles }
|
5
5
|
let(:values) { Flipper::GateValues.new({}) }
|
6
|
-
let(:thing) { Struct.new(:flipper_id).new(
|
7
|
-
let(:options)
|
6
|
+
let(:thing) { Struct.new(:flipper_id).new('5') }
|
7
|
+
let(:options) do
|
8
8
|
{
|
9
9
|
feature_name: feature_name,
|
10
10
|
values: values,
|
11
11
|
thing: thing,
|
12
12
|
}
|
13
|
-
|
13
|
+
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'initializes just fine' do
|
16
16
|
instance = described_class.new(options)
|
17
17
|
expect(instance.feature_name).to eq(feature_name)
|
18
18
|
expect(instance.values).to eq(values)
|
19
19
|
expect(instance.thing).to eq(thing)
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
22
|
+
it 'requires feature_name' do
|
23
23
|
options.delete(:feature_name)
|
24
|
-
expect
|
24
|
+
expect do
|
25
25
|
described_class.new(options)
|
26
|
-
|
26
|
+
end.to raise_error(KeyError)
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
29
|
+
it 'requires values' do
|
30
30
|
options.delete(:values)
|
31
|
-
expect
|
31
|
+
expect do
|
32
32
|
described_class.new(options)
|
33
|
-
|
33
|
+
end.to raise_error(KeyError)
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
36
|
+
it 'requires thing' do
|
37
37
|
options.delete(:thing)
|
38
|
-
expect
|
38
|
+
expect do
|
39
39
|
described_class.new(options)
|
40
|
-
|
40
|
+
end.to raise_error(KeyError)
|
41
41
|
end
|
42
42
|
|
43
|
-
it
|
44
|
-
|
45
|
-
expect(
|
43
|
+
it 'knows actors_value' do
|
44
|
+
args = options.merge(values: Flipper::GateValues.new(actors: Set['User:1']))
|
45
|
+
expect(described_class.new(args).actors_value).to eq(Set['User:1'])
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
49
|
-
|
50
|
-
expect(
|
48
|
+
it 'knows groups_value' do
|
49
|
+
args = options.merge(values: Flipper::GateValues.new(groups: Set['admins']))
|
50
|
+
expect(described_class.new(args).groups_value).to eq(Set['admins'])
|
51
51
|
end
|
52
52
|
|
53
|
-
it
|
54
|
-
instance = described_class.new(options.merge(values: Flipper::GateValues.new(
|
53
|
+
it 'knows boolean_value' do
|
54
|
+
instance = described_class.new(options.merge(values: Flipper::GateValues.new(boolean: true)))
|
55
55
|
expect(instance.boolean_value).to eq(true)
|
56
56
|
end
|
57
57
|
|
58
|
-
it
|
59
|
-
|
60
|
-
expect(
|
58
|
+
it 'knows percentage_of_actors_value' do
|
59
|
+
args = options.merge(values: Flipper::GateValues.new(percentage_of_actors: 14))
|
60
|
+
expect(described_class.new(args).percentage_of_actors_value).to eq(14)
|
61
61
|
end
|
62
62
|
|
63
|
-
it
|
64
|
-
|
65
|
-
expect(
|
63
|
+
it 'knows percentage_of_time_value' do
|
64
|
+
args = options.merge(values: Flipper::GateValues.new(percentage_of_time: 41))
|
65
|
+
expect(described_class.new(args).percentage_of_time_value).to eq(41)
|
66
66
|
end
|
67
67
|
end
|
@@ -8,51 +8,49 @@ RSpec.describe Flipper::Feature do
|
|
8
8
|
|
9
9
|
let(:adapter) { Flipper::Adapters::Memory.new }
|
10
10
|
|
11
|
-
describe
|
12
|
-
it
|
11
|
+
describe '#initialize' do
|
12
|
+
it 'sets name' do
|
13
13
|
feature = described_class.new(:search, adapter)
|
14
14
|
expect(feature.name).to eq(:search)
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
17
|
+
it 'sets adapter' do
|
18
18
|
feature = described_class.new(:search, adapter)
|
19
19
|
expect(feature.adapter).to eq(adapter)
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
22
|
+
it 'defaults instrumenter' do
|
23
23
|
feature = described_class.new(:search, adapter)
|
24
24
|
expect(feature.instrumenter).to be(Flipper::Instrumenters::Noop)
|
25
25
|
end
|
26
26
|
|
27
|
-
context
|
28
|
-
let(:instrumenter) { double('Instrumentor', :
|
27
|
+
context 'with overriden instrumenter' do
|
28
|
+
let(:instrumenter) { double('Instrumentor', instrument: nil) }
|
29
29
|
|
30
|
-
it
|
31
|
-
feature = described_class.new(:search, adapter,
|
32
|
-
:instrumenter => instrumenter,
|
33
|
-
})
|
30
|
+
it 'overrides default instrumenter' do
|
31
|
+
feature = described_class.new(:search, adapter, instrumenter: instrumenter)
|
34
32
|
expect(feature.instrumenter).to be(instrumenter)
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
|
-
describe
|
40
|
-
it
|
37
|
+
describe '#to_s' do
|
38
|
+
it 'returns name as string' do
|
41
39
|
feature = described_class.new(:search, adapter)
|
42
|
-
expect(feature.to_s).to eq(
|
40
|
+
expect(feature.to_s).to eq('search')
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
|
-
describe
|
47
|
-
it
|
44
|
+
describe '#to_param' do
|
45
|
+
it 'returns name as string' do
|
48
46
|
feature = described_class.new(:search, adapter)
|
49
|
-
expect(feature.to_param).to eq(
|
47
|
+
expect(feature.to_param).to eq('search')
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
|
-
describe
|
54
|
-
context
|
55
|
-
it
|
51
|
+
describe '#gate_for' do
|
52
|
+
context 'with percentage of actors' do
|
53
|
+
it 'returns percentage of actors gate' do
|
56
54
|
percentage = Flipper::Types::PercentageOfActors.new(10)
|
57
55
|
gate = subject.gate_for(percentage)
|
58
56
|
expect(gate).to be_instance_of(Flipper::Gates::PercentageOfActors)
|
@@ -60,8 +58,8 @@ RSpec.describe Flipper::Feature do
|
|
60
58
|
end
|
61
59
|
end
|
62
60
|
|
63
|
-
describe
|
64
|
-
it
|
61
|
+
describe '#gates' do
|
62
|
+
it 'returns array of gates' do
|
65
63
|
instance = described_class.new(:search, adapter)
|
66
64
|
expect(instance.gates).to be_instance_of(Array)
|
67
65
|
instance.gates.each do |gate|
|
@@ -71,28 +69,28 @@ RSpec.describe Flipper::Feature do
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
describe
|
75
|
-
context
|
76
|
-
it
|
72
|
+
describe '#gate' do
|
73
|
+
context 'with symbol name' do
|
74
|
+
it 'returns gate by name' do
|
77
75
|
expect(subject.gate(:boolean)).to be_instance_of(Flipper::Gates::Boolean)
|
78
76
|
end
|
79
77
|
end
|
80
78
|
|
81
|
-
context
|
82
|
-
it
|
79
|
+
context 'with string name' do
|
80
|
+
it 'returns gate by name' do
|
83
81
|
expect(subject.gate('boolean')).to be_instance_of(Flipper::Gates::Boolean)
|
84
82
|
end
|
85
83
|
end
|
86
84
|
|
87
|
-
context
|
88
|
-
it
|
85
|
+
context 'with name that does not exist' do
|
86
|
+
it 'returns nil' do
|
89
87
|
expect(subject.gate(:poo)).to be_nil
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
93
91
|
|
94
|
-
describe
|
95
|
-
it
|
92
|
+
describe '#inspect' do
|
93
|
+
it 'returns easy to read string representation' do
|
96
94
|
string = subject.inspect
|
97
95
|
expect(string).to include('Flipper::Feature')
|
98
96
|
expect(string).to include('name=:search')
|
@@ -107,15 +105,15 @@ RSpec.describe Flipper::Feature do
|
|
107
105
|
end
|
108
106
|
end
|
109
107
|
|
110
|
-
describe
|
108
|
+
describe 'instrumentation' do
|
111
109
|
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
112
110
|
|
113
|
-
subject
|
114
|
-
described_class.new(:search, adapter, :
|
115
|
-
|
111
|
+
subject do
|
112
|
+
described_class.new(:search, adapter, instrumenter: instrumenter)
|
113
|
+
end
|
116
114
|
|
117
|
-
it
|
118
|
-
thing = Flipper::Types::Actor.new(Struct.new(:flipper_id).new(
|
115
|
+
it 'is recorded for enable' do
|
116
|
+
thing = Flipper::Types::Actor.new(Struct.new(:flipper_id).new('1'))
|
119
117
|
gate = subject.gate_for(thing)
|
120
118
|
|
121
119
|
subject.enable(thing)
|
@@ -129,8 +127,8 @@ RSpec.describe Flipper::Feature do
|
|
129
127
|
expect(event.payload[:result]).not_to be_nil
|
130
128
|
end
|
131
129
|
|
132
|
-
it
|
133
|
-
thing = Struct.new(:flipper_id).new(
|
130
|
+
it 'always instruments flipper type instance for enable' do
|
131
|
+
thing = Struct.new(:flipper_id).new('1')
|
134
132
|
gate = subject.gate_for(thing)
|
135
133
|
|
136
134
|
subject.enable(thing)
|
@@ -140,7 +138,7 @@ RSpec.describe Flipper::Feature do
|
|
140
138
|
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(thing))
|
141
139
|
end
|
142
140
|
|
143
|
-
it
|
141
|
+
it 'is recorded for disable' do
|
144
142
|
thing = Flipper::Types::Boolean.new
|
145
143
|
gate = subject.gate_for(thing)
|
146
144
|
|
@@ -155,7 +153,7 @@ RSpec.describe Flipper::Feature do
|
|
155
153
|
expect(event.payload[:result]).not_to be_nil
|
156
154
|
end
|
157
155
|
|
158
|
-
user = Struct.new(:flipper_id).new(
|
156
|
+
user = Struct.new(:flipper_id).new('1')
|
159
157
|
actor = Flipper::Types::Actor.new(user)
|
160
158
|
boolean_true = Flipper::Types::Boolean.new(true)
|
161
159
|
boolean_false = Flipper::Types::Boolean.new(false)
|
@@ -185,8 +183,8 @@ RSpec.describe Flipper::Feature do
|
|
185
183
|
end
|
186
184
|
end
|
187
185
|
|
188
|
-
it
|
189
|
-
thing = Struct.new(:flipper_id).new(
|
186
|
+
it 'always instruments flipper type instance for disable' do
|
187
|
+
thing = Struct.new(:flipper_id).new('1')
|
190
188
|
gate = subject.gate_for(thing)
|
191
189
|
|
192
190
|
subject.disable(thing)
|
@@ -197,7 +195,7 @@ RSpec.describe Flipper::Feature do
|
|
197
195
|
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(thing))
|
198
196
|
end
|
199
197
|
|
200
|
-
it
|
198
|
+
it 'is recorded for remove' do
|
201
199
|
subject.remove
|
202
200
|
|
203
201
|
event = instrumenter.events.last
|
@@ -208,8 +206,8 @@ RSpec.describe Flipper::Feature do
|
|
208
206
|
expect(event.payload[:result]).not_to be_nil
|
209
207
|
end
|
210
208
|
|
211
|
-
it
|
212
|
-
thing = Flipper::Types::Actor.new(Struct.new(:flipper_id).new(
|
209
|
+
it 'is recorded for enabled?' do
|
210
|
+
thing = Flipper::Types::Actor.new(Struct.new(:flipper_id).new('1'))
|
213
211
|
gate = subject.gate_for(thing)
|
214
212
|
|
215
213
|
subject.enabled?(thing)
|
@@ -223,7 +221,7 @@ RSpec.describe Flipper::Feature do
|
|
223
221
|
expect(event.payload[:result]).to eq(false)
|
224
222
|
end
|
225
223
|
|
226
|
-
user = Struct.new(:flipper_id).new(
|
224
|
+
user = Struct.new(:flipper_id).new('1')
|
227
225
|
actor = Flipper::Types::Actor.new(user)
|
228
226
|
{
|
229
227
|
nil => nil,
|
@@ -241,176 +239,176 @@ RSpec.describe Flipper::Feature do
|
|
241
239
|
end
|
242
240
|
end
|
243
241
|
|
244
|
-
describe
|
245
|
-
context
|
242
|
+
describe '#state' do
|
243
|
+
context 'fully on' do
|
246
244
|
before do
|
247
245
|
subject.enable
|
248
246
|
end
|
249
247
|
|
250
|
-
it
|
248
|
+
it 'returns :on' do
|
251
249
|
expect(subject.state).to be(:on)
|
252
250
|
end
|
253
251
|
|
254
|
-
it
|
252
|
+
it 'returns true for on?' do
|
255
253
|
expect(subject.on?).to be(true)
|
256
254
|
end
|
257
255
|
|
258
|
-
it
|
256
|
+
it 'returns false for off?' do
|
259
257
|
expect(subject.off?).to be(false)
|
260
258
|
end
|
261
259
|
|
262
|
-
it
|
260
|
+
it 'returns false for conditional?' do
|
263
261
|
expect(subject.conditional?).to be(false)
|
264
262
|
end
|
265
263
|
end
|
266
264
|
|
267
|
-
context
|
265
|
+
context 'percentage of time set to 100' do
|
268
266
|
before do
|
269
267
|
subject.enable_percentage_of_time 100
|
270
268
|
end
|
271
269
|
|
272
|
-
it
|
270
|
+
it 'returns :on' do
|
273
271
|
expect(subject.state).to be(:on)
|
274
272
|
end
|
275
273
|
|
276
|
-
it
|
274
|
+
it 'returns true for on?' do
|
277
275
|
expect(subject.on?).to be(true)
|
278
276
|
end
|
279
277
|
|
280
|
-
it
|
278
|
+
it 'returns false for off?' do
|
281
279
|
expect(subject.off?).to be(false)
|
282
280
|
end
|
283
281
|
|
284
|
-
it
|
282
|
+
it 'returns false for conditional?' do
|
285
283
|
expect(subject.conditional?).to be(false)
|
286
284
|
end
|
287
285
|
end
|
288
286
|
|
289
|
-
context
|
287
|
+
context 'percentage of actors set to 100' do
|
290
288
|
before do
|
291
289
|
subject.enable_percentage_of_actors 100
|
292
290
|
end
|
293
291
|
|
294
|
-
it
|
292
|
+
it 'returns :on' do
|
295
293
|
expect(subject.state).to be(:on)
|
296
294
|
end
|
297
295
|
|
298
|
-
it
|
296
|
+
it 'returns true for on?' do
|
299
297
|
expect(subject.on?).to be(true)
|
300
298
|
end
|
301
299
|
|
302
|
-
it
|
300
|
+
it 'returns false for off?' do
|
303
301
|
expect(subject.off?).to be(false)
|
304
302
|
end
|
305
303
|
|
306
|
-
it
|
304
|
+
it 'returns false for conditional?' do
|
307
305
|
expect(subject.conditional?).to be(false)
|
308
306
|
end
|
309
307
|
end
|
310
308
|
|
311
|
-
context
|
309
|
+
context 'fully off' do
|
312
310
|
before do
|
313
311
|
subject.disable
|
314
312
|
end
|
315
313
|
|
316
|
-
it
|
314
|
+
it 'returns :off' do
|
317
315
|
expect(subject.state).to be(:off)
|
318
316
|
end
|
319
317
|
|
320
|
-
it
|
318
|
+
it 'returns false for on?' do
|
321
319
|
expect(subject.on?).to be(false)
|
322
320
|
end
|
323
321
|
|
324
|
-
it
|
322
|
+
it 'returns true for off?' do
|
325
323
|
expect(subject.off?).to be(true)
|
326
324
|
end
|
327
325
|
|
328
|
-
it
|
326
|
+
it 'returns false for conditional?' do
|
329
327
|
expect(subject.conditional?).to be(false)
|
330
328
|
end
|
331
329
|
end
|
332
330
|
|
333
|
-
context
|
331
|
+
context 'partially on' do
|
334
332
|
before do
|
335
333
|
subject.enable Flipper::Types::PercentageOfTime.new(5)
|
336
334
|
end
|
337
335
|
|
338
|
-
it
|
336
|
+
it 'returns :conditional' do
|
339
337
|
expect(subject.state).to be(:conditional)
|
340
338
|
end
|
341
339
|
|
342
|
-
it
|
340
|
+
it 'returns false for on?' do
|
343
341
|
expect(subject.on?).to be(false)
|
344
342
|
end
|
345
343
|
|
346
|
-
it
|
344
|
+
it 'returns false for off?' do
|
347
345
|
expect(subject.off?).to be(false)
|
348
346
|
end
|
349
347
|
|
350
|
-
it
|
348
|
+
it 'returns true for conditional?' do
|
351
349
|
expect(subject.conditional?).to be(true)
|
352
350
|
end
|
353
351
|
end
|
354
352
|
end
|
355
353
|
|
356
|
-
describe
|
357
|
-
context
|
358
|
-
it
|
354
|
+
describe '#enabled_groups' do
|
355
|
+
context 'when no groups enabled' do
|
356
|
+
it 'returns empty set' do
|
359
357
|
expect(subject.enabled_groups).to eq(Set.new)
|
360
358
|
end
|
361
359
|
end
|
362
360
|
|
363
|
-
context
|
361
|
+
context 'when one or more groups enabled' do
|
364
362
|
before do
|
365
|
-
@staff = Flipper.register(:staff) { |
|
366
|
-
@preview_features = Flipper.register(:preview_features) { |
|
367
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
368
|
-
@disabled = Flipper.register(:disabled) { |
|
363
|
+
@staff = Flipper.register(:staff) { |_thing| true }
|
364
|
+
@preview_features = Flipper.register(:preview_features) { |_thing| true }
|
365
|
+
@not_enabled = Flipper.register(:not_enabled) { |_thing| true }
|
366
|
+
@disabled = Flipper.register(:disabled) { |_thing| true }
|
369
367
|
subject.enable @staff
|
370
368
|
subject.enable @preview_features
|
371
369
|
subject.disable @disabled
|
372
370
|
end
|
373
371
|
|
374
|
-
it
|
372
|
+
it 'returns set of enabled groups' do
|
375
373
|
expect(subject.enabled_groups).to eq(Set.new([
|
376
|
-
|
377
|
-
|
378
|
-
|
374
|
+
@staff,
|
375
|
+
@preview_features,
|
376
|
+
]))
|
379
377
|
end
|
380
378
|
|
381
|
-
it
|
379
|
+
it 'does not include groups that have not been enabled' do
|
382
380
|
expect(subject.enabled_groups).not_to include(@not_enabled)
|
383
381
|
end
|
384
382
|
|
385
|
-
it
|
383
|
+
it 'does not include disabled groups' do
|
386
384
|
expect(subject.enabled_groups).not_to include(@disabled)
|
387
385
|
end
|
388
386
|
|
389
|
-
it
|
387
|
+
it 'is aliased to groups' do
|
390
388
|
expect(subject.enabled_groups).to eq(subject.groups)
|
391
389
|
end
|
392
390
|
end
|
393
391
|
end
|
394
392
|
|
395
|
-
describe
|
396
|
-
context
|
397
|
-
it
|
393
|
+
describe '#disabled_groups' do
|
394
|
+
context 'when no groups enabled' do
|
395
|
+
it 'returns empty set' do
|
398
396
|
expect(subject.disabled_groups).to eq(Set.new)
|
399
397
|
end
|
400
398
|
end
|
401
399
|
|
402
|
-
context
|
400
|
+
context 'when one or more groups enabled' do
|
403
401
|
before do
|
404
|
-
@staff = Flipper.register(:staff) { |
|
405
|
-
@preview_features = Flipper.register(:preview_features) { |
|
406
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
407
|
-
@disabled = Flipper.register(:disabled) { |
|
402
|
+
@staff = Flipper.register(:staff) { |_thing| true }
|
403
|
+
@preview_features = Flipper.register(:preview_features) { |_thing| true }
|
404
|
+
@not_enabled = Flipper.register(:not_enabled) { |_thing| true }
|
405
|
+
@disabled = Flipper.register(:disabled) { |_thing| true }
|
408
406
|
subject.enable @staff
|
409
407
|
subject.enable @preview_features
|
410
408
|
subject.disable @disabled
|
411
409
|
end
|
412
410
|
|
413
|
-
it
|
411
|
+
it 'returns set of groups that are not enabled' do
|
414
412
|
expect(subject.disabled_groups).to eq(Set[
|
415
413
|
@not_enabled,
|
416
414
|
@disabled,
|
@@ -419,158 +417,152 @@ RSpec.describe Flipper::Feature do
|
|
419
417
|
end
|
420
418
|
end
|
421
419
|
|
422
|
-
describe
|
423
|
-
context
|
424
|
-
it
|
420
|
+
describe '#groups_value' do
|
421
|
+
context 'when no groups enabled' do
|
422
|
+
it 'returns empty set' do
|
425
423
|
expect(subject.groups_value).to eq(Set.new)
|
426
424
|
end
|
427
425
|
end
|
428
426
|
|
429
|
-
context
|
427
|
+
context 'when one or more groups enabled' do
|
430
428
|
before do
|
431
|
-
@staff = Flipper.register(:staff) { |
|
432
|
-
@preview_features = Flipper.register(:preview_features) { |
|
433
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
434
|
-
@disabled = Flipper.register(:disabled) { |
|
429
|
+
@staff = Flipper.register(:staff) { |_thing| true }
|
430
|
+
@preview_features = Flipper.register(:preview_features) { |_thing| true }
|
431
|
+
@not_enabled = Flipper.register(:not_enabled) { |_thing| true }
|
432
|
+
@disabled = Flipper.register(:disabled) { |_thing| true }
|
435
433
|
subject.enable @staff
|
436
434
|
subject.enable @preview_features
|
437
435
|
subject.disable @disabled
|
438
436
|
end
|
439
437
|
|
440
|
-
it
|
438
|
+
it 'returns set of enabled groups' do
|
441
439
|
expect(subject.groups_value).to eq(Set.new([
|
442
|
-
|
443
|
-
|
444
|
-
|
440
|
+
@staff.name.to_s,
|
441
|
+
@preview_features.name.to_s,
|
442
|
+
]))
|
445
443
|
end
|
446
444
|
|
447
|
-
it
|
445
|
+
it 'does not include groups that have not been enabled' do
|
448
446
|
expect(subject.groups_value).not_to include(@not_enabled.name.to_s)
|
449
447
|
end
|
450
448
|
|
451
|
-
it
|
449
|
+
it 'does not include disabled groups' do
|
452
450
|
expect(subject.groups_value).not_to include(@disabled.name.to_s)
|
453
451
|
end
|
454
452
|
end
|
455
453
|
end
|
456
454
|
|
457
|
-
describe
|
458
|
-
context
|
459
|
-
it
|
455
|
+
describe '#actors_value' do
|
456
|
+
context 'when no groups enabled' do
|
457
|
+
it 'returns empty set' do
|
460
458
|
expect(subject.actors_value).to eq(Set.new)
|
461
459
|
end
|
462
460
|
end
|
463
461
|
|
464
|
-
context
|
462
|
+
context 'when one or more actors are enabled' do
|
465
463
|
before do
|
466
|
-
subject.enable Flipper::Types::Actor.new(Struct.new(:flipper_id).new(
|
467
|
-
subject.enable Flipper::Types::Actor.new(Struct.new(:flipper_id).new(
|
464
|
+
subject.enable Flipper::Types::Actor.new(Struct.new(:flipper_id).new('User:5'))
|
465
|
+
subject.enable Flipper::Types::Actor.new(Struct.new(:flipper_id).new('User:22'))
|
468
466
|
end
|
469
467
|
|
470
|
-
it
|
471
|
-
expect(subject.actors_value).to eq(Set.new([
|
468
|
+
it 'returns set of actor ids' do
|
469
|
+
expect(subject.actors_value).to eq(Set.new(['User:5', 'User:22']))
|
472
470
|
end
|
473
471
|
end
|
474
472
|
end
|
475
473
|
|
476
|
-
describe
|
477
|
-
context
|
478
|
-
it
|
474
|
+
describe '#boolean_value' do
|
475
|
+
context 'when not enabled or disabled' do
|
476
|
+
it 'returns false' do
|
479
477
|
expect(subject.boolean_value).to be(false)
|
480
478
|
end
|
481
479
|
end
|
482
480
|
|
483
|
-
context
|
481
|
+
context 'when enabled' do
|
484
482
|
before do
|
485
483
|
subject.enable
|
486
484
|
end
|
487
485
|
|
488
|
-
it
|
486
|
+
it 'returns true' do
|
489
487
|
expect(subject.boolean_value).to be(true)
|
490
488
|
end
|
491
489
|
end
|
492
490
|
|
493
|
-
context
|
491
|
+
context 'when disabled' do
|
494
492
|
before do
|
495
493
|
subject.disable
|
496
494
|
end
|
497
495
|
|
498
|
-
it
|
496
|
+
it 'returns false' do
|
499
497
|
expect(subject.boolean_value).to be(false)
|
500
498
|
end
|
501
499
|
end
|
502
500
|
end
|
503
501
|
|
504
|
-
describe
|
505
|
-
context
|
506
|
-
it
|
502
|
+
describe '#percentage_of_actors_value' do
|
503
|
+
context 'when not enabled or disabled' do
|
504
|
+
it 'returns nil' do
|
507
505
|
expect(subject.percentage_of_actors_value).to be(0)
|
508
506
|
end
|
509
507
|
end
|
510
508
|
|
511
|
-
context
|
509
|
+
context 'when enabled' do
|
512
510
|
before do
|
513
511
|
subject.enable Flipper::Types::PercentageOfActors.new(5)
|
514
512
|
end
|
515
513
|
|
516
|
-
it
|
514
|
+
it 'returns true' do
|
517
515
|
expect(subject.percentage_of_actors_value).to eq(5)
|
518
516
|
end
|
519
517
|
end
|
520
518
|
|
521
|
-
context
|
519
|
+
context 'when disabled' do
|
522
520
|
before do
|
523
521
|
subject.disable
|
524
522
|
end
|
525
523
|
|
526
|
-
it
|
524
|
+
it 'returns nil' do
|
527
525
|
expect(subject.percentage_of_actors_value).to be(0)
|
528
526
|
end
|
529
527
|
end
|
530
528
|
end
|
531
529
|
|
532
|
-
describe
|
533
|
-
context
|
534
|
-
it
|
530
|
+
describe '#percentage_of_time_value' do
|
531
|
+
context 'when not enabled or disabled' do
|
532
|
+
it 'returns nil' do
|
535
533
|
expect(subject.percentage_of_time_value).to be(0)
|
536
534
|
end
|
537
535
|
end
|
538
536
|
|
539
|
-
context
|
537
|
+
context 'when enabled' do
|
540
538
|
before do
|
541
539
|
subject.enable Flipper::Types::PercentageOfTime.new(5)
|
542
540
|
end
|
543
541
|
|
544
|
-
it
|
542
|
+
it 'returns true' do
|
545
543
|
expect(subject.percentage_of_time_value).to eq(5)
|
546
544
|
end
|
547
545
|
end
|
548
546
|
|
549
|
-
context
|
547
|
+
context 'when disabled' do
|
550
548
|
before do
|
551
549
|
subject.disable
|
552
550
|
end
|
553
551
|
|
554
|
-
it
|
552
|
+
it 'returns nil' do
|
555
553
|
expect(subject.percentage_of_time_value).to be(0)
|
556
554
|
end
|
557
555
|
end
|
558
556
|
end
|
559
557
|
|
560
|
-
describe
|
561
|
-
context
|
562
|
-
it
|
563
|
-
expect(subject.gate_values).to eq(Flipper::GateValues.new(
|
564
|
-
:actors => Set.new,
|
565
|
-
:groups => Set.new,
|
566
|
-
:boolean => nil,
|
567
|
-
:percentage_of_actors => nil,
|
568
|
-
:percentage_of_time => nil,
|
569
|
-
}))
|
558
|
+
describe '#gate_values' do
|
559
|
+
context 'when no gates are set in adapter' do
|
560
|
+
it 'returns default gate values' do
|
561
|
+
expect(subject.gate_values).to eq(Flipper::GateValues.new(adapter.default_config))
|
570
562
|
end
|
571
563
|
end
|
572
564
|
|
573
|
-
context
|
565
|
+
context 'with gate values set in adapter' do
|
574
566
|
before do
|
575
567
|
subject.enable Flipper::Types::Boolean.new(true)
|
576
568
|
subject.enable Flipper::Types::Actor.new(Struct.new(:flipper_id).new(5))
|
@@ -579,84 +571,82 @@ RSpec.describe Flipper::Feature do
|
|
579
571
|
subject.enable Flipper::Types::PercentageOfActors.new(25)
|
580
572
|
end
|
581
573
|
|
582
|
-
it
|
583
|
-
expect(subject.gate_values).to eq(Flipper::GateValues.new(
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
:percentage_of_actors => "25",
|
589
|
-
}))
|
574
|
+
it 'returns gate values' do
|
575
|
+
expect(subject.gate_values).to eq(Flipper::GateValues.new(actors: Set.new(['5']),
|
576
|
+
groups: Set.new(['admins']),
|
577
|
+
boolean: 'true',
|
578
|
+
percentage_of_time: '50',
|
579
|
+
percentage_of_actors: '25'))
|
590
580
|
end
|
591
581
|
end
|
592
582
|
end
|
593
583
|
|
594
|
-
describe
|
595
|
-
context
|
596
|
-
it
|
584
|
+
describe '#enable_actor/disable_actor' do
|
585
|
+
context 'with object that responds to flipper_id' do
|
586
|
+
it 'updates the gate values to include the actor' do
|
597
587
|
actor = Struct.new(:flipper_id).new(5)
|
598
588
|
expect(subject.gate_values.actors).to be_empty
|
599
589
|
subject.enable_actor(actor)
|
600
|
-
expect(subject.gate_values.actors).to eq(Set[
|
590
|
+
expect(subject.gate_values.actors).to eq(Set['5'])
|
601
591
|
subject.disable_actor(actor)
|
602
592
|
expect(subject.gate_values.actors).to be_empty
|
603
593
|
end
|
604
594
|
end
|
605
595
|
|
606
|
-
context
|
607
|
-
it
|
596
|
+
context 'with actor instance' do
|
597
|
+
it 'updates the gate values to include the actor' do
|
608
598
|
actor = Struct.new(:flipper_id).new(5)
|
609
599
|
instance = Flipper::Types::Actor.new(actor)
|
610
600
|
expect(subject.gate_values.actors).to be_empty
|
611
601
|
subject.enable_actor(instance)
|
612
|
-
expect(subject.gate_values.actors).to eq(Set[
|
602
|
+
expect(subject.gate_values.actors).to eq(Set['5'])
|
613
603
|
subject.disable_actor(instance)
|
614
604
|
expect(subject.gate_values.actors).to be_empty
|
615
605
|
end
|
616
606
|
end
|
617
607
|
end
|
618
608
|
|
619
|
-
describe
|
620
|
-
context
|
621
|
-
it
|
609
|
+
describe '#enable_group/disable_group' do
|
610
|
+
context 'with symbol group name' do
|
611
|
+
it 'updates the gate values to include the group' do
|
622
612
|
actor = Struct.new(:flipper_id).new(5)
|
623
613
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
624
614
|
expect(subject.gate_values.groups).to be_empty
|
625
615
|
subject.enable_group(:five_only)
|
626
|
-
expect(subject.gate_values.groups).to eq(Set[
|
616
|
+
expect(subject.gate_values.groups).to eq(Set['five_only'])
|
627
617
|
subject.disable_group(:five_only)
|
628
618
|
expect(subject.gate_values.groups).to be_empty
|
629
619
|
end
|
630
620
|
end
|
631
621
|
|
632
|
-
context
|
633
|
-
it
|
622
|
+
context 'with string group name' do
|
623
|
+
it 'updates the gate values to include the group' do
|
634
624
|
actor = Struct.new(:flipper_id).new(5)
|
635
625
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
636
626
|
expect(subject.gate_values.groups).to be_empty
|
637
|
-
subject.enable_group(
|
638
|
-
expect(subject.gate_values.groups).to eq(Set[
|
639
|
-
subject.disable_group(
|
627
|
+
subject.enable_group('five_only')
|
628
|
+
expect(subject.gate_values.groups).to eq(Set['five_only'])
|
629
|
+
subject.disable_group('five_only')
|
640
630
|
expect(subject.gate_values.groups).to be_empty
|
641
631
|
end
|
642
632
|
end
|
643
633
|
|
644
|
-
context
|
645
|
-
it
|
634
|
+
context 'with group instance' do
|
635
|
+
it 'updates the gate values for the group' do
|
646
636
|
actor = Struct.new(:flipper_id).new(5)
|
647
637
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
648
638
|
expect(subject.gate_values.groups).to be_empty
|
649
639
|
subject.enable_group(group)
|
650
|
-
expect(subject.gate_values.groups).to eq(Set[
|
640
|
+
expect(subject.gate_values.groups).to eq(Set['five_only'])
|
651
641
|
subject.disable_group(group)
|
652
642
|
expect(subject.gate_values.groups).to be_empty
|
653
643
|
end
|
654
644
|
end
|
655
645
|
end
|
656
646
|
|
657
|
-
describe
|
658
|
-
context
|
659
|
-
it
|
647
|
+
describe '#enable_percentage_of_time/disable_percentage_of_time' do
|
648
|
+
context 'with integer' do
|
649
|
+
it 'updates the gate values' do
|
660
650
|
expect(subject.gate_values.percentage_of_time).to be(0)
|
661
651
|
subject.enable_percentage_of_time(56)
|
662
652
|
expect(subject.gate_values.percentage_of_time).to be(56)
|
@@ -665,18 +655,18 @@ RSpec.describe Flipper::Feature do
|
|
665
655
|
end
|
666
656
|
end
|
667
657
|
|
668
|
-
context
|
669
|
-
it
|
658
|
+
context 'with string' do
|
659
|
+
it 'updates the gate values' do
|
670
660
|
expect(subject.gate_values.percentage_of_time).to be(0)
|
671
|
-
subject.enable_percentage_of_time(
|
661
|
+
subject.enable_percentage_of_time('56')
|
672
662
|
expect(subject.gate_values.percentage_of_time).to be(56)
|
673
663
|
subject.disable_percentage_of_time
|
674
664
|
expect(subject.gate_values.percentage_of_time).to be(0)
|
675
665
|
end
|
676
666
|
end
|
677
667
|
|
678
|
-
context
|
679
|
-
it
|
668
|
+
context 'with percentage of time instance' do
|
669
|
+
it 'updates the gate values' do
|
680
670
|
percentage = Flipper::Types::PercentageOfTime.new(56)
|
681
671
|
expect(subject.gate_values.percentage_of_time).to be(0)
|
682
672
|
subject.enable_percentage_of_time(percentage)
|
@@ -687,9 +677,9 @@ RSpec.describe Flipper::Feature do
|
|
687
677
|
end
|
688
678
|
end
|
689
679
|
|
690
|
-
describe
|
691
|
-
context
|
692
|
-
it
|
680
|
+
describe '#enable_percentage_of_actors/disable_percentage_of_actors' do
|
681
|
+
context 'with integer' do
|
682
|
+
it 'updates the gate values' do
|
693
683
|
expect(subject.gate_values.percentage_of_actors).to be(0)
|
694
684
|
subject.enable_percentage_of_actors(56)
|
695
685
|
expect(subject.gate_values.percentage_of_actors).to be(56)
|
@@ -698,18 +688,18 @@ RSpec.describe Flipper::Feature do
|
|
698
688
|
end
|
699
689
|
end
|
700
690
|
|
701
|
-
context
|
702
|
-
it
|
691
|
+
context 'with string' do
|
692
|
+
it 'updates the gate values' do
|
703
693
|
expect(subject.gate_values.percentage_of_actors).to be(0)
|
704
|
-
subject.enable_percentage_of_actors(
|
694
|
+
subject.enable_percentage_of_actors('56')
|
705
695
|
expect(subject.gate_values.percentage_of_actors).to be(56)
|
706
696
|
subject.disable_percentage_of_actors
|
707
697
|
expect(subject.gate_values.percentage_of_actors).to be(0)
|
708
698
|
end
|
709
699
|
end
|
710
700
|
|
711
|
-
context
|
712
|
-
it
|
701
|
+
context 'with percentage of actors instance' do
|
702
|
+
it 'updates the gate values' do
|
713
703
|
percentage = Flipper::Types::PercentageOfActors.new(56)
|
714
704
|
expect(subject.gate_values.percentage_of_actors).to be(0)
|
715
705
|
subject.enable_percentage_of_actors(percentage)
|
@@ -720,13 +710,13 @@ RSpec.describe Flipper::Feature do
|
|
720
710
|
end
|
721
711
|
end
|
722
712
|
|
723
|
-
describe
|
713
|
+
describe '#enabled/disabled_gates' do
|
724
714
|
before do
|
725
715
|
subject.enable_percentage_of_time 5
|
726
716
|
subject.enable_percentage_of_actors 5
|
727
717
|
end
|
728
718
|
|
729
|
-
it
|
719
|
+
it 'can return enabled gates' do
|
730
720
|
expect(subject.enabled_gates.map(&:name).to_set).to eq(Set[
|
731
721
|
:percentage_of_actors,
|
732
722
|
:percentage_of_time,
|
@@ -738,7 +728,7 @@ RSpec.describe Flipper::Feature do
|
|
738
728
|
])
|
739
729
|
end
|
740
730
|
|
741
|
-
it
|
731
|
+
it 'can return disabled gates' do
|
742
732
|
expect(subject.disabled_gates.map(&:name).to_set).to eq(Set[
|
743
733
|
:actor,
|
744
734
|
:boolean,
|