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
@@ -12,7 +12,7 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
12
12
|
|
13
13
|
it_should_behave_like 'a flipper adapter'
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'forwards missing methods to underlying adapter' do
|
16
16
|
adapter = Class.new do
|
17
17
|
def foo
|
18
18
|
:foo
|
@@ -22,22 +22,22 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
22
22
|
expect(operation_logger.foo).to eq(:foo)
|
23
23
|
end
|
24
24
|
|
25
|
-
describe
|
25
|
+
describe '#get' do
|
26
26
|
before do
|
27
27
|
@feature = flipper[:stats]
|
28
28
|
@result = subject.get(@feature)
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
31
|
+
it 'logs operation' do
|
32
32
|
expect(subject.count(:get)).to be(1)
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
35
|
+
it 'returns result' do
|
36
36
|
expect(@result).to eq(adapter.get(@feature))
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
describe
|
40
|
+
describe '#enable' do
|
41
41
|
before do
|
42
42
|
@feature = flipper[:stats]
|
43
43
|
@gate = @feature.gate(:boolean)
|
@@ -45,16 +45,16 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
45
45
|
@result = subject.enable(@feature, @gate, @thing)
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
48
|
+
it 'logs operation' do
|
49
49
|
expect(subject.count(:enable)).to be(1)
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it 'returns result' do
|
53
53
|
expect(@result).to eq(adapter.enable(@feature, @gate, @thing))
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
describe
|
57
|
+
describe '#disable' do
|
58
58
|
before do
|
59
59
|
@feature = flipper[:stats]
|
60
60
|
@gate = @feature.gate(:boolean)
|
@@ -62,41 +62,41 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
62
62
|
@result = subject.disable(@feature, @gate, @thing)
|
63
63
|
end
|
64
64
|
|
65
|
-
it
|
65
|
+
it 'logs operation' do
|
66
66
|
expect(subject.count(:disable)).to be(1)
|
67
67
|
end
|
68
68
|
|
69
|
-
it
|
69
|
+
it 'returns result' do
|
70
70
|
expect(@result).to eq(adapter.disable(@feature, @gate, @thing))
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
describe
|
74
|
+
describe '#features' do
|
75
75
|
before do
|
76
76
|
flipper[:stats].enable
|
77
77
|
@result = subject.features
|
78
78
|
end
|
79
79
|
|
80
|
-
it
|
80
|
+
it 'logs operation' do
|
81
81
|
expect(subject.count(:features)).to be(1)
|
82
82
|
end
|
83
83
|
|
84
|
-
it
|
84
|
+
it 'returns result' do
|
85
85
|
expect(@result).to eq(adapter.features)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
describe
|
89
|
+
describe '#add' do
|
90
90
|
before do
|
91
91
|
@feature = flipper[:stats]
|
92
92
|
@result = subject.add(@feature)
|
93
93
|
end
|
94
94
|
|
95
|
-
it
|
95
|
+
it 'logs operation' do
|
96
96
|
expect(subject.count(:add)).to be(1)
|
97
97
|
end
|
98
98
|
|
99
|
-
it
|
99
|
+
it 'returns result' do
|
100
100
|
expect(@result).to eq(adapter.add(@feature))
|
101
101
|
end
|
102
102
|
end
|
@@ -3,16 +3,16 @@ require 'flipper/adapters/pstore'
|
|
3
3
|
require 'flipper/spec/shared_adapter_specs'
|
4
4
|
|
5
5
|
RSpec.describe Flipper::Adapters::PStore do
|
6
|
-
subject
|
7
|
-
dir = FlipperRoot.join(
|
8
|
-
pstore_file = dir.join(
|
6
|
+
subject do
|
7
|
+
dir = FlipperRoot.join('tmp').tap(&:mkpath)
|
8
|
+
pstore_file = dir.join('flipper.pstore')
|
9
9
|
pstore_file.unlink if pstore_file.exist?
|
10
10
|
described_class.new(pstore_file)
|
11
|
-
|
11
|
+
end
|
12
12
|
|
13
13
|
it_should_behave_like 'a flipper adapter'
|
14
14
|
|
15
|
-
it
|
16
|
-
expect(described_class.new.path).to eq(
|
15
|
+
it 'defaults path to flipper.pstore' do
|
16
|
+
expect(described_class.new.path).to eq('flipper.pstore')
|
17
17
|
end
|
18
18
|
end
|
@@ -17,78 +17,72 @@ RSpec.describe Flipper::Adapters::ReadOnly do
|
|
17
17
|
subject { described_class.new(adapter) }
|
18
18
|
|
19
19
|
before do
|
20
|
-
Flipper.register(:admins)
|
20
|
+
Flipper.register(:admins) do |actor|
|
21
21
|
actor.respond_to?(:admin?) && actor.admin?
|
22
|
-
|
22
|
+
end
|
23
23
|
|
24
|
-
Flipper.register(:early_access)
|
24
|
+
Flipper.register(:early_access) do |actor|
|
25
25
|
actor.respond_to?(:early_access?) && actor.early_access?
|
26
|
-
|
26
|
+
end
|
27
27
|
end
|
28
28
|
|
29
29
|
after do
|
30
30
|
Flipper.unregister_groups
|
31
31
|
end
|
32
32
|
|
33
|
-
it
|
34
|
-
expect(subject.name).
|
33
|
+
it 'has name that is a symbol' do
|
34
|
+
expect(subject.name).not_to be_nil
|
35
35
|
expect(subject.name).to be_instance_of(Symbol)
|
36
36
|
end
|
37
37
|
|
38
|
-
it
|
38
|
+
it 'has included the flipper adapter module' do
|
39
39
|
expect(subject.class.ancestors).to include(Flipper::Adapter)
|
40
40
|
end
|
41
41
|
|
42
|
-
it
|
43
|
-
expect(subject.get(feature)).to eq(
|
44
|
-
:boolean => nil,
|
45
|
-
:groups => Set.new,
|
46
|
-
:actors => Set.new,
|
47
|
-
:percentage_of_actors => nil,
|
48
|
-
:percentage_of_time => nil,
|
49
|
-
})
|
42
|
+
it 'returns correct default values for the gates if none are enabled' do
|
43
|
+
expect(subject.get(feature)).to eq(subject.default_config)
|
50
44
|
end
|
51
45
|
|
52
|
-
it
|
53
|
-
|
46
|
+
it 'can get feature' do
|
47
|
+
actor22 = actor_class.new('22')
|
54
48
|
adapter.enable(feature, boolean_gate, flipper.boolean)
|
55
49
|
adapter.enable(feature, group_gate, flipper.group(:admins))
|
56
|
-
adapter.enable(feature, actor_gate, flipper.actor(
|
50
|
+
adapter.enable(feature, actor_gate, flipper.actor(actor22))
|
57
51
|
adapter.enable(feature, actors_gate, flipper.actors(25))
|
58
52
|
adapter.enable(feature, time_gate, flipper.time(45))
|
59
53
|
|
60
|
-
expect(subject.get(feature)).to eq(
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
:percentage_of_time => "45",
|
66
|
-
})
|
54
|
+
expect(subject.get(feature)).to eq(boolean: 'true',
|
55
|
+
groups: Set['admins'],
|
56
|
+
actors: Set['22'],
|
57
|
+
percentage_of_actors: '25',
|
58
|
+
percentage_of_time: '45')
|
67
59
|
end
|
68
60
|
|
69
|
-
it
|
61
|
+
it 'can get features' do
|
70
62
|
expect(subject.features).to eq(Set.new)
|
71
63
|
adapter.add(feature)
|
72
|
-
expect(subject.features).to eq(Set[
|
64
|
+
expect(subject.features).to eq(Set['stats'])
|
73
65
|
end
|
74
66
|
|
75
|
-
it
|
67
|
+
it 'raises error on add' do
|
76
68
|
expect { subject.add(feature) }.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
77
69
|
end
|
78
70
|
|
79
|
-
it
|
71
|
+
it 'raises error on remove' do
|
80
72
|
expect { subject.remove(feature) }.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
81
73
|
end
|
82
74
|
|
83
|
-
it
|
75
|
+
it 'raises on clear' do
|
84
76
|
expect { subject.clear(feature) }.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
85
77
|
end
|
86
78
|
|
87
|
-
it
|
88
|
-
expect { subject.enable(feature, boolean_gate, flipper.boolean) }
|
79
|
+
it 'raises error on enable' do
|
80
|
+
expect { subject.enable(feature, boolean_gate, flipper.boolean) }
|
81
|
+
.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
89
82
|
end
|
90
83
|
|
91
|
-
it
|
92
|
-
expect { subject.disable(feature, boolean_gate, flipper.boolean) }
|
84
|
+
it 'raises error on disable' do
|
85
|
+
expect { subject.disable(feature, boolean_gate, flipper.boolean) }
|
86
|
+
.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
93
87
|
end
|
94
88
|
end
|
data/spec/flipper/dsl_spec.rb
CHANGED
@@ -3,121 +3,110 @@ require 'flipper/dsl'
|
|
3
3
|
require 'flipper/adapters/memory'
|
4
4
|
|
5
5
|
RSpec.describe Flipper::DSL do
|
6
|
-
subject {
|
6
|
+
subject { described_class.new(adapter) }
|
7
7
|
|
8
8
|
let(:adapter) { Flipper::Adapters::Memory.new }
|
9
9
|
|
10
|
-
describe
|
11
|
-
it
|
10
|
+
describe '#initialize' do
|
11
|
+
it 'sets adapter' do
|
12
12
|
dsl = described_class.new(adapter)
|
13
13
|
expect(dsl.adapter).not_to be_nil
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
16
|
+
it 'defaults instrumenter to noop' do
|
17
17
|
dsl = described_class.new(adapter)
|
18
18
|
expect(dsl.instrumenter).to be(Flipper::Instrumenters::Noop)
|
19
19
|
end
|
20
20
|
|
21
|
-
context
|
22
|
-
let(:instrumenter) { double('Instrumentor', :
|
21
|
+
context 'with overriden instrumenter' do
|
22
|
+
let(:instrumenter) { double('Instrumentor', instrument: nil) }
|
23
23
|
|
24
|
-
it
|
25
|
-
dsl = described_class.new(adapter, :
|
24
|
+
it 'overrides default instrumenter' do
|
25
|
+
dsl = described_class.new(adapter, instrumenter: instrumenter)
|
26
26
|
expect(dsl.instrumenter).to be(instrumenter)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe
|
32
|
-
it_should_behave_like
|
31
|
+
describe '#feature' do
|
32
|
+
it_should_behave_like 'a DSL feature' do
|
33
33
|
let(:method_name) { :feature }
|
34
|
-
let(:instrumenter) { double('Instrumentor', :
|
34
|
+
let(:instrumenter) { double('Instrumentor', instrument: nil) }
|
35
35
|
let(:feature) { dsl.send(method_name, :stats) }
|
36
|
-
let(:dsl) {
|
36
|
+
let(:dsl) { described_class.new(adapter, instrumenter: instrumenter) }
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
describe
|
41
|
-
let(:instrumenter) { double('Instrumentor', :
|
42
|
-
let(:dsl) {
|
43
|
-
let(:names) { %i
|
40
|
+
describe '#preload' do
|
41
|
+
let(:instrumenter) { double('Instrumentor', instrument: nil) }
|
42
|
+
let(:dsl) { described_class.new(adapter, instrumenter: instrumenter) }
|
43
|
+
let(:names) { %i(stats shiny) }
|
44
44
|
let(:features) { dsl.preload(names) }
|
45
45
|
|
46
|
-
it
|
46
|
+
it 'returns array of features' do
|
47
47
|
expect(features).to all be_instance_of(Flipper::Feature)
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'sets names' do
|
51
51
|
expect(features.map(&:name)).to eq(names)
|
52
52
|
end
|
53
53
|
|
54
|
-
it
|
54
|
+
it 'sets adapter' do
|
55
55
|
features.each do |feature|
|
56
56
|
expect(feature.adapter.name).to eq(dsl.adapter.name)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
it
|
60
|
+
it 'sets instrumenter' do
|
61
61
|
features.each do |feature|
|
62
62
|
expect(feature.instrumenter).to eq(dsl.instrumenter)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'memoizes the feature' do
|
67
67
|
features.each do |feature|
|
68
68
|
expect(dsl.feature(feature.name)).to equal(feature)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
describe
|
74
|
-
it_should_behave_like
|
73
|
+
describe '#[]' do
|
74
|
+
it_should_behave_like 'a DSL feature' do
|
75
75
|
let(:method_name) { :[] }
|
76
|
-
let(:instrumenter) { double('Instrumentor', :
|
76
|
+
let(:instrumenter) { double('Instrumentor', instrument: nil) }
|
77
77
|
let(:feature) { dsl.send(method_name, :stats) }
|
78
|
-
let(:dsl) {
|
78
|
+
let(:dsl) { described_class.new(adapter, instrumenter: instrumenter) }
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
describe
|
83
|
-
it_should_behave_like
|
82
|
+
describe '#boolean' do
|
83
|
+
it_should_behave_like 'a DSL boolean method' do
|
84
84
|
let(:method_name) { :boolean }
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
describe
|
89
|
-
it_should_behave_like
|
88
|
+
describe '#bool' do
|
89
|
+
it_should_behave_like 'a DSL boolean method' do
|
90
90
|
let(:method_name) { :bool }
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
describe
|
95
|
-
context
|
94
|
+
describe '#group' do
|
95
|
+
context 'for registered group' do
|
96
96
|
before do
|
97
|
-
@group = Flipper.register(:admins) {
|
97
|
+
@group = Flipper.register(:admins) {}
|
98
98
|
end
|
99
99
|
|
100
|
-
it
|
101
|
-
expect(
|
102
|
-
|
103
|
-
|
104
|
-
it "always returns same instance for same name" do
|
105
|
-
expect(subject.group(:admins)).to equal(subject.group(:admins))
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
context "for unregistered group" do
|
110
|
-
it "raises error" do
|
111
|
-
expect {
|
112
|
-
subject.group(:admins)
|
113
|
-
}.to raise_error(Flipper::GroupNotRegistered)
|
100
|
+
it 'delegates to Flipper' do
|
101
|
+
expect(Flipper).to receive(:group).with(:admins).and_return(@group)
|
102
|
+
expect(subject.group(:admins)).to be(@group)
|
114
103
|
end
|
115
104
|
end
|
116
105
|
end
|
117
106
|
|
118
|
-
describe
|
119
|
-
context
|
120
|
-
it
|
107
|
+
describe '#actor' do
|
108
|
+
context 'for a thing' do
|
109
|
+
it 'returns actor instance' do
|
121
110
|
thing = Struct.new(:flipper_id).new(33)
|
122
111
|
actor = subject.actor(thing)
|
123
112
|
expect(actor).to be_instance_of(Flipper::Types::Actor)
|
@@ -125,85 +114,85 @@ RSpec.describe Flipper::DSL do
|
|
125
114
|
end
|
126
115
|
end
|
127
116
|
|
128
|
-
context
|
129
|
-
it
|
130
|
-
expect
|
117
|
+
context 'for nil' do
|
118
|
+
it 'raises argument error' do
|
119
|
+
expect do
|
131
120
|
subject.actor(nil)
|
132
|
-
|
121
|
+
end.to raise_error(ArgumentError)
|
133
122
|
end
|
134
123
|
end
|
135
124
|
|
136
|
-
context
|
137
|
-
it
|
138
|
-
expect
|
125
|
+
context 'for something that is not actor wrappable' do
|
126
|
+
it 'raises argument error' do
|
127
|
+
expect do
|
139
128
|
subject.actor(Object.new)
|
140
|
-
|
129
|
+
end.to raise_error(ArgumentError)
|
141
130
|
end
|
142
131
|
end
|
143
132
|
end
|
144
133
|
|
145
|
-
describe
|
134
|
+
describe '#time' do
|
146
135
|
before do
|
147
136
|
@result = subject.time(5)
|
148
137
|
end
|
149
138
|
|
150
|
-
it
|
139
|
+
it 'returns percentage of time' do
|
151
140
|
expect(@result).to be_instance_of(Flipper::Types::PercentageOfTime)
|
152
141
|
end
|
153
142
|
|
154
|
-
it
|
143
|
+
it 'sets value' do
|
155
144
|
expect(@result.value).to eq(5)
|
156
145
|
end
|
157
146
|
|
158
|
-
it
|
147
|
+
it 'is aliased to percentage_of_time' do
|
159
148
|
expect(@result).to eq(subject.percentage_of_time(@result.value))
|
160
149
|
end
|
161
150
|
end
|
162
151
|
|
163
|
-
describe
|
152
|
+
describe '#actors' do
|
164
153
|
before do
|
165
154
|
@result = subject.actors(17)
|
166
155
|
end
|
167
156
|
|
168
|
-
it
|
157
|
+
it 'returns percentage of actors' do
|
169
158
|
expect(@result).to be_instance_of(Flipper::Types::PercentageOfActors)
|
170
159
|
end
|
171
160
|
|
172
|
-
it
|
161
|
+
it 'sets value' do
|
173
162
|
expect(@result.value).to eq(17)
|
174
163
|
end
|
175
164
|
|
176
|
-
it
|
165
|
+
it 'is aliased to percentage_of_actors' do
|
177
166
|
expect(@result).to eq(subject.percentage_of_actors(@result.value))
|
178
167
|
end
|
179
168
|
end
|
180
169
|
|
181
|
-
describe
|
182
|
-
context
|
183
|
-
it
|
170
|
+
describe '#features' do
|
171
|
+
context 'with no features enabled/disabled' do
|
172
|
+
it 'defaults to empty set' do
|
184
173
|
expect(subject.features).to eq(Set.new)
|
185
174
|
end
|
186
175
|
end
|
187
176
|
|
188
|
-
context
|
177
|
+
context 'with features enabled and disabled' do
|
189
178
|
before do
|
190
179
|
subject[:stats].enable
|
191
180
|
subject[:cache].enable
|
192
181
|
subject[:search].disable
|
193
182
|
end
|
194
183
|
|
195
|
-
it
|
184
|
+
it 'returns set of feature instances' do
|
196
185
|
expect(subject.features).to be_instance_of(Set)
|
197
186
|
subject.features.each do |feature|
|
198
187
|
expect(feature).to be_instance_of(Flipper::Feature)
|
199
188
|
end
|
200
|
-
expect(subject.features.map(&:name).map(&:to_s).sort).to eq(
|
189
|
+
expect(subject.features.map(&:name).map(&:to_s).sort).to eq(%w(cache search stats))
|
201
190
|
end
|
202
191
|
end
|
203
192
|
end
|
204
193
|
|
205
|
-
describe
|
206
|
-
it
|
194
|
+
describe '#enable/disable' do
|
195
|
+
it 'enables and disables the feature' do
|
207
196
|
expect(subject[:stats].boolean_value).to eq(false)
|
208
197
|
subject.enable(:stats)
|
209
198
|
expect(subject[:stats].boolean_value).to eq(true)
|
@@ -213,35 +202,35 @@ RSpec.describe Flipper::DSL do
|
|
213
202
|
end
|
214
203
|
end
|
215
204
|
|
216
|
-
describe
|
217
|
-
it
|
205
|
+
describe '#enable_actor/disable_actor' do
|
206
|
+
it 'enables and disables the feature for actor' do
|
218
207
|
actor = Struct.new(:flipper_id).new(5)
|
219
208
|
|
220
209
|
expect(subject[:stats].actors_value).to be_empty
|
221
210
|
subject.enable_actor(:stats, actor)
|
222
|
-
expect(subject[:stats].actors_value).to eq(Set[
|
211
|
+
expect(subject[:stats].actors_value).to eq(Set['5'])
|
223
212
|
|
224
213
|
subject.disable_actor(:stats, actor)
|
225
214
|
expect(subject[:stats].actors_value).to be_empty
|
226
215
|
end
|
227
216
|
end
|
228
217
|
|
229
|
-
describe
|
230
|
-
it
|
218
|
+
describe '#enable_group/disable_group' do
|
219
|
+
it 'enables and disables the feature for group' do
|
231
220
|
actor = Struct.new(:flipper_id).new(5)
|
232
221
|
group = Flipper.register(:fives) { |actor| actor.flipper_id == 5 }
|
233
222
|
|
234
223
|
expect(subject[:stats].groups_value).to be_empty
|
235
224
|
subject.enable_group(:stats, :fives)
|
236
|
-
expect(subject[:stats].groups_value).to eq(Set[
|
225
|
+
expect(subject[:stats].groups_value).to eq(Set['fives'])
|
237
226
|
|
238
227
|
subject.disable_group(:stats, :fives)
|
239
228
|
expect(subject[:stats].groups_value).to be_empty
|
240
229
|
end
|
241
230
|
end
|
242
231
|
|
243
|
-
describe
|
244
|
-
it
|
232
|
+
describe '#enable_percentage_of_time/disable_percentage_of_time' do
|
233
|
+
it 'enables and disables the feature for percentage of time' do
|
245
234
|
expect(subject[:stats].percentage_of_time_value).to be(0)
|
246
235
|
subject.enable_percentage_of_time(:stats, 6)
|
247
236
|
expect(subject[:stats].percentage_of_time_value).to be(6)
|
@@ -251,8 +240,8 @@ RSpec.describe Flipper::DSL do
|
|
251
240
|
end
|
252
241
|
end
|
253
242
|
|
254
|
-
describe
|
255
|
-
it
|
243
|
+
describe '#enable_percentage_of_actors/disable_percentage_of_actors' do
|
244
|
+
it 'enables and disables the feature for percentage of time' do
|
256
245
|
expect(subject[:stats].percentage_of_actors_value).to be(0)
|
257
246
|
subject.enable_percentage_of_actors(:stats, 6)
|
258
247
|
expect(subject[:stats].percentage_of_actors_value).to be(6)
|
@@ -263,7 +252,7 @@ RSpec.describe Flipper::DSL do
|
|
263
252
|
end
|
264
253
|
|
265
254
|
describe '#remove' do
|
266
|
-
it
|
255
|
+
it 'removes the feature' do
|
267
256
|
subject.enable(:stats)
|
268
257
|
|
269
258
|
expect { subject.remove(:stats) }.to change { subject.enabled?(:stats) }.to(false)
|