flipper 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/Guardfile +3 -8
  2. data/README.md +26 -38
  3. data/examples/percentage_of_actors.rb +17 -12
  4. data/examples/percentage_of_random.rb +3 -7
  5. data/lib/flipper.rb +8 -1
  6. data/lib/flipper/adapter.rb +2 -208
  7. data/lib/flipper/adapters/decorator.rb +9 -0
  8. data/lib/flipper/adapters/instrumented.rb +92 -0
  9. data/lib/flipper/adapters/memoizable.rb +88 -0
  10. data/lib/flipper/adapters/memory.rb +89 -7
  11. data/lib/flipper/adapters/operation_logger.rb +31 -45
  12. data/lib/flipper/decorator.rb +6 -0
  13. data/lib/flipper/dsl.rb +29 -2
  14. data/lib/flipper/feature.rb +83 -49
  15. data/lib/flipper/gate.rb +24 -41
  16. data/lib/flipper/gates/actor.rb +24 -24
  17. data/lib/flipper/gates/boolean.rb +28 -15
  18. data/lib/flipper/gates/group.rb +25 -34
  19. data/lib/flipper/gates/percentage_of_actors.rb +21 -13
  20. data/lib/flipper/gates/percentage_of_random.rb +20 -12
  21. data/lib/flipper/instrumentation/log_subscriber.rb +14 -22
  22. data/lib/flipper/middleware/memoizer.rb +23 -0
  23. data/lib/flipper/spec/shared_adapter_specs.rb +141 -92
  24. data/lib/flipper/types/boolean.rb +5 -1
  25. data/lib/flipper/version.rb +1 -1
  26. data/spec/flipper/adapters/instrumented_spec.rb +92 -0
  27. data/spec/flipper/adapters/memoizable_spec.rb +184 -0
  28. data/spec/flipper/adapters/memory_spec.rb +1 -11
  29. data/spec/flipper/adapters/operation_logger_spec.rb +93 -0
  30. data/spec/flipper/dsl_spec.rb +18 -43
  31. data/spec/flipper/feature_spec.rb +25 -9
  32. data/spec/flipper/gate_spec.rb +8 -20
  33. data/spec/flipper/gates/actor_spec.rb +6 -14
  34. data/spec/flipper/gates/boolean_spec.rb +80 -13
  35. data/spec/flipper/gates/group_spec.rb +8 -18
  36. data/spec/flipper/gates/percentage_of_actors_spec.rb +12 -28
  37. data/spec/flipper/gates/percentage_of_random_spec.rb +6 -14
  38. data/spec/flipper/instrumentation/log_subscriber_spec.rb +15 -8
  39. data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +3 -6
  40. data/spec/flipper/middleware/{local_cache_spec.rb → memoizer_spec.rb} +25 -55
  41. data/spec/flipper/types/boolean_spec.rb +13 -3
  42. data/spec/flipper_spec.rb +7 -0
  43. data/spec/helper.rb +21 -3
  44. data/spec/integration_spec.rb +115 -116
  45. metadata +17 -27
  46. data/lib/flipper/adapters/memoized.rb +0 -55
  47. data/lib/flipper/key.rb +0 -38
  48. data/lib/flipper/middleware/local_cache.rb +0 -36
  49. data/lib/flipper/toggle.rb +0 -54
  50. data/lib/flipper/toggles/boolean.rb +0 -54
  51. data/lib/flipper/toggles/set.rb +0 -25
  52. data/lib/flipper/toggles/value.rb +0 -25
  53. data/spec/flipper/adapter_spec.rb +0 -463
  54. data/spec/flipper/adapters/memoized_spec.rb +0 -93
  55. data/spec/flipper/key_spec.rb +0 -23
  56. data/spec/flipper/toggle_spec.rb +0 -22
  57. data/spec/flipper/toggles/boolean_spec.rb +0 -40
  58. data/spec/flipper/toggles/set_spec.rb +0 -35
  59. data/spec/flipper/toggles/value_spec.rb +0 -55
@@ -38,16 +38,13 @@ describe Flipper::Instrumentation::MetriksSubscriber do
38
38
 
39
39
  it "updates adapter metrics when calls happen" do
40
40
  flipper[:stats].enable(user)
41
- # one for features and one for actors
42
- Metriks.timer("flipper.adapter.memory.set_add").count.should be(2)
41
+ Metriks.timer("flipper.adapter.memory.enable").count.should be(1)
43
42
 
44
43
  flipper[:stats].enabled?(user)
45
- Metriks.timer("flipper.adapter.memory.read").count.should be(1)
46
- # one for actors and one for groups
47
- Metriks.timer("flipper.adapter.memory.set_members").count.should be(2)
44
+ Metriks.timer("flipper.adapter.memory.get").count.should be(1)
48
45
 
49
46
  flipper[:stats].disable(user)
50
- Metriks.timer("flipper.adapter.memory.set_delete").count.should be(1)
47
+ Metriks.timer("flipper.adapter.memory.disable").count.should be(1)
51
48
  end
52
49
 
53
50
  it "updates gate metrics when calls happen" do
@@ -1,18 +1,12 @@
1
1
  require 'helper'
2
2
  require 'rack/test'
3
- require 'flipper/middleware/local_cache'
3
+ require 'flipper/middleware/memoizer'
4
4
  require 'flipper/adapters/operation_logger'
5
5
  require 'flipper/adapters/memory'
6
6
 
7
- describe Flipper::Middleware::LocalCache do
7
+ describe Flipper::Middleware::Memoizer do
8
8
  include Rack::Test::Methods
9
9
 
10
- class Enum < Struct.new(:iter)
11
- def each(&block)
12
- iter.call(&block)
13
- end
14
- end
15
-
16
10
  let(:source) { {} }
17
11
  let(:memory_adapter) { Flipper::Adapters::Memory.new(source) }
18
12
  let(:adapter) { Flipper::Adapters::OperationLogger.new(memory_adapter) }
@@ -36,8 +30,8 @@ describe Flipper::Middleware::LocalCache do
36
30
  end.to_app
37
31
  }
38
32
 
39
- before do
40
- adapter.reset
33
+ after do
34
+ flipper.adapter.memoize = nil
41
35
  end
42
36
 
43
37
  it "delegates" do
@@ -51,50 +45,42 @@ describe Flipper::Middleware::LocalCache do
51
45
  called.should be_true
52
46
  end
53
47
 
54
- it "enables memoization during delegation" do
55
- app = lambda { |env|
56
- flipper.adapter.using_local_cache?.should be_true
57
- [200, {}, nil]
58
- }
59
- middleware = described_class.new app, flipper
60
- middleware.call({})
61
- end
62
-
63
- it "enables local cache for body each" do
64
- app = lambda { |env|
65
- [200, {}, Enum.new(lambda { |&block|
66
- flipper.adapter.using_local_cache?.should be_true
67
- block.call "hello"
68
- })]
69
- }
70
- middleware = described_class.new app, flipper
71
- body = middleware.call({}).last
72
- body.each { |x| x.should eql('hello') }
73
- end
74
-
75
48
  it "disables local cache after body close" do
76
49
  app = lambda { |env| [200, {}, []] }
77
50
  middleware = described_class.new app, flipper
78
51
  body = middleware.call({}).last
79
52
 
80
- flipper.adapter.using_local_cache?.should be_true
53
+ flipper.adapter.memoizing?.should be_true
81
54
  body.close
82
- flipper.adapter.using_local_cache?.should be_false
55
+ flipper.adapter.memoizing?.should be_false
83
56
  end
84
57
 
85
58
  it "clears local cache after body close" do
86
59
  app = lambda { |env| [200, {}, []] }
87
60
  middleware = described_class.new app, flipper
88
61
  body = middleware.call({}).last
89
- flipper.adapter.local_cache['hello'] = 'world'
90
62
 
91
- flipper.adapter.local_cache.should_not be_empty
63
+ flipper.adapter.cache['hello'] = 'world'
92
64
  body.close
93
- flipper.adapter.local_cache.should be_empty
65
+ flipper.adapter.cache.should be_empty
66
+ end
67
+
68
+ it "clears the local cache with a successful request" do
69
+ flipper.adapter.cache['hello'] = 'world'
70
+ get '/'
71
+ flipper.adapter.cache.should be_empty
94
72
  end
95
73
 
96
- it "really does cache" do
74
+ it "clears the local cache even when the request raises an error" do
75
+ flipper.adapter.cache['hello'] = 'world'
76
+ get '/fail' rescue nil
77
+ flipper.adapter.cache.should be_empty
78
+ end
79
+
80
+ it "caches getting a feature for duration of request" do
97
81
  flipper[:stats].enable
82
+
83
+ # clear the log of operations
98
84
  adapter.reset
99
85
 
100
86
  app = lambda { |env|
@@ -104,28 +90,12 @@ describe Flipper::Middleware::LocalCache do
104
90
  flipper[:stats].enabled?
105
91
  flipper[:stats].enabled?
106
92
  flipper[:stats].enabled?
107
-
108
93
  [200, {}, []]
109
94
  }
95
+
110
96
  middleware = described_class.new app, flipper
111
97
  middleware.call({})
112
98
 
113
- adapter.operations.should eq([
114
- Flipper::Adapters::OperationLogger::Read.new("stats/boolean"),
115
- ])
116
- end
117
-
118
- context "with a successful request" do
119
- it "clears the local cache" do
120
- flipper.adapter.local_cache.should_receive(:clear).twice
121
- get '/'
122
- end
123
- end
124
-
125
- context "when the request raises an error" do
126
- it "clears the local cache" do
127
- flipper.adapter.local_cache.should_receive(:clear).once
128
- get '/fail' rescue nil
129
- end
99
+ adapter.count(:get).should be(1)
130
100
  end
131
101
  end
@@ -2,8 +2,18 @@ require 'helper'
2
2
  require 'flipper/types/boolean'
3
3
 
4
4
  describe Flipper::Types::Boolean do
5
- it "initializes with nothing" do
6
- switch = Flipper::Types::Boolean.new
7
- switch.should be_instance_of(Flipper::Types::Boolean)
5
+ it "defaults value to true" do
6
+ boolean = Flipper::Types::Boolean.new
7
+ boolean.value.should be(true)
8
+ end
9
+
10
+ it "allows overriding default value" do
11
+ boolean = Flipper::Types::Boolean.new(false)
12
+ boolean.value.should be(false)
13
+ end
14
+
15
+ it "returns true for nil value" do
16
+ boolean = Flipper::Types::Boolean.new(nil)
17
+ boolean.value.should be(true)
8
18
  end
9
19
  end
data/spec/flipper_spec.rb CHANGED
@@ -46,6 +46,13 @@ describe Flipper do
46
46
  end
47
47
  end
48
48
 
49
+ describe ".unregister_groups" do
50
+ it "clear group registry" do
51
+ Flipper.groups.should_receive(:clear)
52
+ Flipper.unregister_groups
53
+ end
54
+ end
55
+
49
56
  describe ".group" do
50
57
  context "for registered group" do
51
58
  before do
data/spec/helper.rb CHANGED
@@ -24,7 +24,7 @@ RSpec.configure do |config|
24
24
  config.run_all_when_everything_filtered = true
25
25
 
26
26
  config.before(:each) do
27
- Flipper.groups = nil
27
+ Flipper.unregister_groups
28
28
  end
29
29
  end
30
30
 
@@ -67,7 +67,7 @@ shared_examples_for 'a DSL feature' do
67
67
  end
68
68
 
69
69
  it "sets adapter" do
70
- feature.adapter.should eq(dsl.adapter)
70
+ feature.adapter.name.should eq(dsl.adapter.name)
71
71
  end
72
72
 
73
73
  it "sets instrumenter" do
@@ -75,6 +75,24 @@ shared_examples_for 'a DSL feature' do
75
75
  end
76
76
 
77
77
  it "memoizes the feature" do
78
- dsl.feature(:stats).should equal(feature)
78
+ dsl.send(method_name, :stats).should equal(feature)
79
+ end
80
+
81
+ it "raises argument error if not string or symbol" do
82
+ expect {
83
+ dsl.send(method_name, Object.new)
84
+ }.to raise_error(ArgumentError, /must be a String or Symbol/)
85
+ end
86
+ end
87
+
88
+ shared_examples_for "a DSL boolean method" do
89
+ it "returns boolean with value set" do
90
+ result = subject.send(method_name, true)
91
+ result.should be_instance_of(Flipper::Types::Boolean)
92
+ result.value.should be(true)
93
+
94
+ result = subject.send(method_name, false)
95
+ result.should be_instance_of(Flipper::Types::Boolean)
96
+ result.value.should be(false)
79
97
  end
80
98
  end
@@ -2,16 +2,17 @@ require 'helper'
2
2
  require 'flipper/feature'
3
3
  require 'flipper/adapters/memory'
4
4
 
5
- describe Flipper::Feature do
6
- subject { described_class.new(:search, adapter) }
7
-
8
- let(:actor_class) { Struct.new(:flipper_id) }
9
-
5
+ describe Flipper do
10
6
  let(:source) { {} }
11
7
  let(:adapter) { Flipper::Adapters::Memory.new(source) }
12
8
 
13
- let(:admin_group) { Flipper.group(:admins) }
14
- let(:dev_group) { Flipper.group(:devs) }
9
+ let(:flipper) { Flipper.new(adapter) }
10
+ let(:feature) { flipper[:search] }
11
+
12
+ let(:actor_class) { Struct.new(:flipper_id) }
13
+
14
+ let(:admin_group) { flipper.group(:admins) }
15
+ let(:dev_group) { flipper.group(:devs) }
15
16
 
16
17
  let(:admin_thing) { double 'Non Flipper Thing', :flipper_id => 1, :admin? => true, :dev? => false }
17
18
  let(:dev_thing) { double 'Non Flipper Thing', :flipper_id => 10, :admin? => false, :dev? => true }
@@ -19,22 +20,18 @@ describe Flipper::Feature do
19
20
  let(:pitt) { actor_class.new(1) }
20
21
  let(:clooney) { actor_class.new(10) }
21
22
 
22
- let(:five_percent_of_actors) { Flipper::Types::PercentageOfActors.new(5) }
23
- let(:five_percent_of_random) { Flipper::Types::PercentageOfRandom.new(5) }
23
+ let(:five_percent_of_actors) { flipper.actors(5) }
24
+ let(:five_percent_of_random) { flipper.random(5) }
24
25
 
25
26
  before do
26
27
  Flipper.register(:admins) { |thing| thing.admin? }
27
28
  Flipper.register(:devs) { |thing| thing.dev? }
28
29
  end
29
30
 
30
- after do
31
- Flipper.groups = nil
32
- end
33
-
34
31
  describe "#enable" do
35
32
  context "with no arguments" do
36
33
  before do
37
- @result = subject.enable
34
+ @result = feature.enable
38
35
  end
39
36
 
40
37
  it "returns true" do
@@ -42,17 +39,17 @@ describe Flipper::Feature do
42
39
  end
43
40
 
44
41
  it "enables feature for all" do
45
- subject.enabled?.should be_true
42
+ feature.enabled?.should be_true
46
43
  end
47
44
 
48
45
  it "adds feature to set of features" do
49
- adapter.set_members('features').should include('search')
46
+ flipper.features.map(&:name).should include(:search)
50
47
  end
51
48
  end
52
49
 
53
50
  context "with a group" do
54
51
  before do
55
- @result = subject.enable(admin_group)
52
+ @result = feature.enable(admin_group)
56
53
  end
57
54
 
58
55
  it "returns true" do
@@ -60,33 +57,33 @@ describe Flipper::Feature do
60
57
  end
61
58
 
62
59
  it "enables feature for non flipper thing in group" do
63
- subject.enabled?(admin_thing).should be_true
60
+ feature.enabled?(admin_thing).should be_true
64
61
  end
65
62
 
66
63
  it "does not enable feature for non flipper thing in other group" do
67
- subject.enabled?(dev_thing).should be_false
64
+ feature.enabled?(dev_thing).should be_false
68
65
  end
69
66
 
70
67
  it "enables feature for flipper actor in group" do
71
- subject.enabled?(Flipper::Types::Actor.new(admin_thing)).should be_true
68
+ feature.enabled?(flipper.actor(admin_thing)).should be_true
72
69
  end
73
70
 
74
71
  it "does not enable for flipper actor not in group" do
75
- subject.enabled?(Flipper::Types::Actor.new(dev_thing)).should be_false
72
+ feature.enabled?(flipper.actor(dev_thing)).should be_false
76
73
  end
77
74
 
78
75
  it "does not enable feature for all" do
79
- subject.enabled?.should be_false
76
+ feature.enabled?.should be_false
80
77
  end
81
78
 
82
79
  it "adds feature to set of features" do
83
- adapter.set_members('features').should include('search')
80
+ flipper.features.map(&:name).should include(:search)
84
81
  end
85
82
  end
86
83
 
87
84
  context "with an actor" do
88
85
  before do
89
- @result = subject.enable(pitt)
86
+ @result = feature.enable(pitt)
90
87
  end
91
88
 
92
89
  it "returns true" do
@@ -94,21 +91,21 @@ describe Flipper::Feature do
94
91
  end
95
92
 
96
93
  it "enables feature for actor" do
97
- subject.enabled?(pitt).should be_true
94
+ feature.enabled?(pitt).should be_true
98
95
  end
99
96
 
100
97
  it "does not enable feature for other actors" do
101
- subject.enabled?(clooney).should be_false
98
+ feature.enabled?(clooney).should be_false
102
99
  end
103
100
 
104
101
  it "adds feature to set of features" do
105
- adapter.set_members('features').should include('search')
102
+ flipper.features.map(&:name).should include(:search)
106
103
  end
107
104
  end
108
105
 
109
106
  context "with a percentage of actors" do
110
107
  before do
111
- @result = subject.enable(five_percent_of_actors)
108
+ @result = feature.enable(five_percent_of_actors)
112
109
  end
113
110
 
114
111
  it "returns true" do
@@ -118,22 +115,21 @@ describe Flipper::Feature do
118
115
  it "enables feature for actor within percentage" do
119
116
  enabled = (1..100).select { |i|
120
117
  thing = actor_class.new(i)
121
- subject.enabled?(thing)
118
+ feature.enabled?(thing)
122
119
  }.size
123
120
 
124
121
  enabled.should be_within(2).of(5)
125
122
  end
126
123
 
127
124
  it "adds feature to set of features" do
128
- adapter.set_members('features').should include('search')
125
+ flipper.features.map(&:name).should include(:search)
129
126
  end
130
127
  end
131
128
 
132
129
  context "with a percentage of random" do
133
130
  before do
134
- @gate = Flipper::Gates::PercentageOfRandom.new(subject)
135
- Flipper::Gates::PercentageOfRandom.should_receive(:new).and_return(@gate)
136
- @result = subject.enable(five_percent_of_random)
131
+ @gate = feature.gate(:percentage_of_random)
132
+ @result = feature.enable(five_percent_of_random)
137
133
  end
138
134
 
139
135
  it "returns true" do
@@ -142,16 +138,16 @@ describe Flipper::Feature do
142
138
 
143
139
  it "enables feature for time within percentage" do
144
140
  @gate.stub(:rand => 0.04)
145
- subject.enabled?.should be_true
141
+ feature.enabled?.should be_true
146
142
  end
147
143
 
148
144
  it "does not enable feature for time not within percentage" do
149
145
  @gate.stub(:rand => 0.10)
150
- subject.enabled?.should be_false
146
+ feature.enabled?.should be_false
151
147
  end
152
148
 
153
149
  it "adds feature to set of features" do
154
- adapter.set_members('features').should include('search')
150
+ flipper.features.map(&:name).should include(:search)
155
151
  end
156
152
  end
157
153
 
@@ -159,7 +155,7 @@ describe Flipper::Feature do
159
155
  it "raises error" do
160
156
  thing = Object.new
161
157
  expect {
162
- subject.enable(thing)
158
+ feature.enable(thing)
163
159
  }.to raise_error(Flipper::GateNotFound, "Could not find gate for #{thing.inspect}")
164
160
  end
165
161
  end
@@ -169,14 +165,14 @@ describe Flipper::Feature do
169
165
  context "with no arguments" do
170
166
  before do
171
167
  # ensures that random gate is stubbed with result that would be true for pitt
172
- @gate = Flipper::Gates::PercentageOfRandom.new(subject)
168
+ @gate = feature.gate(:percentage_of_random)
173
169
  @gate.stub(:rand => 0.04)
174
- Flipper::Gates::PercentageOfRandom.should_receive(:new).and_return(@gate)
175
- subject.enable admin_group
176
- subject.enable pitt
177
- subject.enable five_percent_of_actors
178
- subject.enable five_percent_of_random
179
- @result = subject.disable
170
+
171
+ feature.enable admin_group
172
+ feature.enable pitt
173
+ feature.enable five_percent_of_actors
174
+ feature.enable five_percent_of_random
175
+ @result = feature.disable
180
176
  end
181
177
 
182
178
  it "returns true" do
@@ -184,40 +180,40 @@ describe Flipper::Feature do
184
180
  end
185
181
 
186
182
  it "disables feature" do
187
- subject.enabled?.should be_false
183
+ feature.enabled?.should be_false
188
184
  end
189
185
 
190
186
  it "disables for individual actor" do
191
- subject.enabled?(pitt).should be_false
187
+ feature.enabled?(pitt).should be_false
192
188
  end
193
189
 
194
190
  it "disables actor in group" do
195
- subject.enabled?(admin_thing).should be_false
191
+ feature.enabled?(admin_thing).should be_false
196
192
  end
197
193
 
198
194
  it "disables actor in percentage of actors" do
199
195
  enabled = (1..100).select { |i|
200
196
  thing = actor_class.new(i)
201
- subject.enabled?(thing)
197
+ feature.enabled?(thing)
202
198
  }.size
203
199
 
204
200
  enabled.should be(0)
205
201
  end
206
202
 
207
203
  it "disables percentage of random" do
208
- subject.enabled?(pitt).should be_false
204
+ feature.enabled?(pitt).should be_false
209
205
  end
210
206
 
211
207
  it "adds feature to set of features" do
212
- adapter.set_members('features').should include('search')
208
+ flipper.features.map(&:name).should include(:search)
213
209
  end
214
210
  end
215
211
 
216
212
  context "with a group" do
217
213
  before do
218
- subject.enable dev_group
219
- subject.enable admin_group
220
- @result = subject.disable(admin_group)
214
+ feature.enable dev_group
215
+ feature.enable admin_group
216
+ @result = feature.disable(admin_group)
221
217
  end
222
218
 
223
219
  it "returns true" do
@@ -225,31 +221,31 @@ describe Flipper::Feature do
225
221
  end
226
222
 
227
223
  it "disables the feature for non flipper thing in the group" do
228
- subject.enabled?(admin_thing).should be_false
224
+ feature.enabled?(admin_thing).should be_false
229
225
  end
230
226
 
231
227
  it "does not disable feature for non flipper thing in other groups" do
232
- subject.enabled?(dev_thing).should be_true
228
+ feature.enabled?(dev_thing).should be_true
233
229
  end
234
230
 
235
231
  it "disables feature for flipper actor in group" do
236
- subject.enabled?(Flipper::Types::Actor.new(admin_thing)).should be_false
232
+ feature.enabled?(flipper.actor(admin_thing)).should be_false
237
233
  end
238
234
 
239
235
  it "does not disable feature for flipper actor in other groups" do
240
- subject.enabled?(Flipper::Types::Actor.new(dev_thing)).should be_true
236
+ feature.enabled?(flipper.actor(dev_thing)).should be_true
241
237
  end
242
238
 
243
239
  it "adds feature to set of features" do
244
- adapter.set_members('features').should include('search')
240
+ flipper.features.map(&:name).should include(:search)
245
241
  end
246
242
  end
247
243
 
248
244
  context "with an actor" do
249
245
  before do
250
- subject.enable pitt
251
- subject.enable clooney
252
- @result = subject.disable(pitt)
246
+ feature.enable pitt
247
+ feature.enable clooney
248
+ @result = feature.disable(pitt)
253
249
  end
254
250
 
255
251
  it "returns true" do
@@ -257,21 +253,21 @@ describe Flipper::Feature do
257
253
  end
258
254
 
259
255
  it "disables feature for actor" do
260
- subject.enabled?(pitt).should be_false
256
+ feature.enabled?(pitt).should be_false
261
257
  end
262
258
 
263
259
  it "does not disable feature for other actors" do
264
- subject.enabled?(clooney).should be_true
260
+ feature.enabled?(clooney).should be_true
265
261
  end
266
262
 
267
263
  it "adds feature to set of features" do
268
- adapter.set_members('features').should include('search')
264
+ flipper.features.map(&:name).should include(:search)
269
265
  end
270
266
  end
271
267
 
272
268
  context "with a percentage of actors" do
273
269
  before do
274
- @result = subject.disable(five_percent_of_actors)
270
+ @result = feature.disable(flipper.actors(0))
275
271
  end
276
272
 
277
273
  it "returns true" do
@@ -281,22 +277,21 @@ describe Flipper::Feature do
281
277
  it "disables feature" do
282
278
  enabled = (1..100).select { |i|
283
279
  thing = actor_class.new(i)
284
- subject.enabled?(thing)
280
+ feature.enabled?(thing)
285
281
  }.size
286
282
 
287
283
  enabled.should be(0)
288
284
  end
289
285
 
290
286
  it "adds feature to set of features" do
291
- adapter.set_members('features').should include('search')
287
+ flipper.features.map(&:name).should include(:search)
292
288
  end
293
289
  end
294
290
 
295
291
  context "with a percentage of time" do
296
292
  before do
297
- @gate = Flipper::Gates::PercentageOfRandom.new(subject)
298
- Flipper::Gates::PercentageOfRandom.should_receive(:new).and_return(@gate)
299
- @result = subject.disable(five_percent_of_random)
293
+ @gate = feature.gate(:percentage_of_random)
294
+ @result = feature.disable(flipper.random(0))
300
295
  end
301
296
 
302
297
  it "returns true" do
@@ -305,16 +300,16 @@ describe Flipper::Feature do
305
300
 
306
301
  it "disables feature for time within percentage" do
307
302
  @gate.stub(:rand => 0.04)
308
- subject.enabled?.should be_false
303
+ feature.enabled?.should be_false
309
304
  end
310
305
 
311
306
  it "disables feature for time not within percentage" do
312
307
  @gate.stub(:rand => 0.10)
313
- subject.enabled?.should be_false
308
+ feature.enabled?.should be_false
314
309
  end
315
310
 
316
311
  it "adds feature to set of features" do
317
- adapter.set_members('features').should include('search')
312
+ flipper.features.map(&:name).should include(:search)
318
313
  end
319
314
  end
320
315
 
@@ -322,7 +317,7 @@ describe Flipper::Feature do
322
317
  it "raises error" do
323
318
  thing = Object.new
324
319
  expect {
325
- subject.disable(thing)
320
+ feature.disable(thing)
326
321
  }.to raise_error(Flipper::GateNotFound, "Could not find gate for #{thing.inspect}")
327
322
  end
328
323
  end
@@ -331,132 +326,136 @@ describe Flipper::Feature do
331
326
  describe "#enabled?" do
332
327
  context "with no arguments" do
333
328
  it "defaults to false" do
334
- subject.enabled?.should be_false
329
+ feature.enabled?.should be_false
335
330
  end
336
331
  end
337
332
 
338
333
  context "with no arguments, but boolean enabled" do
339
334
  before do
340
- subject.enable
335
+ feature.enable
341
336
  end
342
337
 
343
338
  it "returns true" do
344
- subject.enabled?.should be_true
339
+ feature.enabled?.should be_true
345
340
  end
346
341
  end
347
342
 
348
343
  context "for actor in enabled group" do
349
344
  before do
350
- subject.enable admin_group
345
+ feature.enable admin_group
351
346
  end
352
347
 
353
348
  it "returns true" do
354
- subject.enabled?(Flipper::Types::Actor.new(admin_thing)).should be_true
349
+ feature.enabled?(flipper.actor(admin_thing)).should be_true
350
+ feature.enabled?(admin_thing).should be_true
355
351
  end
356
352
  end
357
353
 
358
354
  context "for actor in disabled group" do
359
355
  it "returns false" do
360
- subject.enabled?(Flipper::Types::Actor.new(dev_thing)).should be_false
356
+ feature.enabled?(flipper.actor(dev_thing)).should be_false
357
+ feature.enabled?(dev_thing).should be_false
361
358
  end
362
359
  end
363
360
 
364
361
  context "for enabled actor" do
365
362
  before do
366
- subject.enable pitt
363
+ feature.enable pitt
367
364
  end
368
365
 
369
366
  it "returns true" do
370
- subject.enabled?(pitt).should be_true
367
+ feature.enabled?(pitt).should be_true
371
368
  end
372
369
  end
373
370
 
374
371
  context "for not enabled actor" do
375
372
  it "returns false" do
376
- subject.enabled?(clooney).should be_false
373
+ feature.enabled?(clooney).should be_false
377
374
  end
378
375
 
379
376
  it "returns true if boolean enabled" do
380
- subject.enable
381
- subject.enabled?(clooney).should be_true
377
+ feature.enable
378
+ feature.enabled?(clooney).should be_true
382
379
  end
383
380
  end
384
381
 
385
382
  context "during enabled percentage of time" do
386
383
  before do
387
- @gate = Flipper::Gates::PercentageOfRandom.new(subject)
384
+ # ensure percentage of random returns enabled percentage
385
+ @gate = feature.gate(:percentage_of_random)
388
386
  @gate.stub(:rand => 0.04)
389
- Flipper::Gates::PercentageOfRandom.should_receive(:new).and_return(@gate)
390
- subject.enable five_percent_of_random
387
+
388
+ feature.enable five_percent_of_random
391
389
  end
392
390
 
393
391
  it "returns true" do
394
- subject.enabled?.should be_true
395
- subject.enabled?(nil).should be_true
396
- subject.enabled?(pitt).should be_true
397
- subject.enabled?(admin_thing).should be_true
392
+ feature.enabled?.should be_true
393
+ feature.enabled?(nil).should be_true
394
+ feature.enabled?(pitt).should be_true
395
+ feature.enabled?(admin_thing).should be_true
398
396
  end
399
397
  end
400
398
 
401
399
  context "during not enabled percentage of time" do
402
400
  before do
403
- @gate = Flipper::Gates::PercentageOfRandom.new(subject)
401
+ # ensure percentage of random returns not enabled percentage
402
+ @gate = feature.gate(:percentage_of_random)
404
403
  @gate.stub(:rand => 0.10)
405
- Flipper::Gates::PercentageOfRandom.should_receive(:new).and_return(@gate)
406
- subject.enable five_percent_of_random
404
+
405
+ feature.enable five_percent_of_random
407
406
  end
408
407
 
409
408
  it "returns false" do
410
- subject.enabled?.should be_false
411
- subject.enabled?(nil).should be_false
412
- subject.enabled?(pitt).should be_false
413
- subject.enabled?(admin_thing).should be_false
409
+ feature.enabled?.should be_false
410
+ feature.enabled?(nil).should be_false
411
+ feature.enabled?(pitt).should be_false
412
+ feature.enabled?(admin_thing).should be_false
414
413
  end
415
414
 
416
415
  it "returns true if boolean enabled" do
417
- subject.enable
418
- subject.enabled?.should be_true
419
- subject.enabled?(nil).should be_true
420
- subject.enabled?(pitt).should be_true
421
- subject.enabled?(admin_thing).should be_true
416
+ feature.enable
417
+ feature.enabled?.should be_true
418
+ feature.enabled?(nil).should be_true
419
+ feature.enabled?(pitt).should be_true
420
+ feature.enabled?(admin_thing).should be_true
422
421
  end
423
422
  end
424
423
 
425
424
  context "for a non flipper thing" do
426
425
  before do
427
- subject.enable admin_group
426
+ feature.enable admin_group
428
427
  end
429
428
 
430
429
  it "returns true if in enabled group" do
431
- subject.enabled?(admin_thing).should be_true
430
+ feature.enabled?(admin_thing).should be_true
432
431
  end
433
432
 
434
433
  it "returns false if not in enabled group" do
435
- subject.enabled?(dev_thing).should be_false
434
+ feature.enabled?(dev_thing).should be_false
436
435
  end
437
436
 
438
437
  it "returns true if boolean enabled" do
439
- subject.enable
440
- subject.enabled?(admin_thing).should be_true
441
- subject.enabled?(dev_thing).should be_true
438
+ feature.enable
439
+ feature.enabled?(admin_thing).should be_true
440
+ feature.enabled?(dev_thing).should be_true
442
441
  end
443
442
  end
444
443
  end
445
444
 
446
445
  context "enabling multiple groups, disabling everything, then enabling one group" do
447
446
  before do
448
- subject.enable(admin_group)
449
- subject.enable(dev_group)
450
- subject.disable
451
- subject.enable(admin_group)
447
+ feature.enable(admin_group)
448
+ feature.enable(dev_group)
449
+ feature.disable
450
+ feature.enable(admin_group)
452
451
  end
453
452
 
454
453
  it "enables feature for object in enabled group" do
455
- subject.enabled?(admin_thing).should be_true
454
+ feature.enabled?(admin_thing).should be_true
456
455
  end
457
456
 
458
457
  it "does not enable feature for object in not enabled group" do
459
- subject.enabled?(dev_thing).should be_false
458
+ feature.enabled?(dev_thing).should be_false
460
459
  end
461
460
  end
462
461
  end