flipper 0.10.2 → 0.11.0.beta1
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/.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,
|