flipper 0.11.0.beta1 → 0.11.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +11 -5
- data/docs/Adapters.md +30 -0
- data/examples/importing.rb +37 -0
- data/lib/flipper.rb +1 -0
- data/lib/flipper/actor.rb +16 -0
- data/lib/flipper/adapter.rb +65 -7
- data/lib/flipper/dsl.rb +13 -0
- data/lib/flipper/feature.rb +7 -0
- data/lib/flipper/middleware/memoizer.rb +7 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +6 -8
- data/lib/flipper/test/shared_adapter_test.rb +6 -7
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/actor_spec.rb +48 -0
- data/spec/flipper/adapter_spec.rb +114 -0
- data/spec/flipper/adapters/http_spec.rb +1 -1
- data/spec/flipper/adapters/read_only_spec.rb +1 -3
- data/spec/flipper/dsl_spec.rb +22 -7
- data/spec/flipper/feature_check_context_spec.rb +1 -1
- data/spec/flipper/feature_spec.rb +42 -14
- data/spec/flipper/gates/boolean_spec.rb +1 -1
- data/spec/flipper/gates/group_spec.rb +2 -2
- data/spec/flipper/gates/percentage_of_actors_spec.rb +2 -2
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +2 -2
- data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +1 -1
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +1 -1
- data/spec/flipper/middleware/memoizer_spec.rb +13 -0
- data/spec/flipper/types/group_spec.rb +2 -2
- data/spec/integration_spec.rb +5 -8
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ff62d3ba23318ccb0c071a989e83364739c731a
|
4
|
+
data.tar.gz: ecefd31c44930c4d6a3dc70c55175b3d3d1ba44f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6cf59627197fb719492b2438b931c51645c2aa8860943b89845a01f4ef8f1696080aec6b53965ea1e918aaa647325c23d1b3731dd85ae5b787f426333c43bb3
|
7
|
+
data.tar.gz: 73b5f76153abc395ef61069e4dc1338335d9a2c21932d853891435a7f9529f6fdf322e402562515db0af62cd95c0f8ab8e937432bb6e0636304e75917ffd7121
|
data/Changelog.md
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
## 0.11
|
2
2
|
|
3
|
-
|
3
|
+
### Backwards Compatibility Breaks
|
4
|
+
|
5
|
+
* * Set flipper from env for API and UI (https://github.com/jnunemaker/flipper/pull/223 and https://github.com/jnunemaker/flipper/pull/229). It is documented, but now the memoizing middleware requires that the SetupEnv middleware is used first.
|
6
|
+
* Drop support for Ruby 2.0 as it is end of lined (https://github.com/jnunemaker/flipper/commit/c2c81ed89938155ce91acb5173ac38580f630e3d).
|
7
|
+
* Allow unregistered groups (https://github.com/jnunemaker/flipper/pull/244). Only break in compatiblity is that previously unregistered groups could not be enabled and now they can be.
|
8
|
+
|
9
|
+
### Additions/Changes
|
10
|
+
|
11
|
+
* Use primary keys with sequel adapter (https://github.com/jnunemaker/flipper/pull/210). Should be backwards compatible, but if you want it to work this way you will need to migrate your database to the new schema.
|
4
12
|
* Add redis cache adapter (https://github.com/jnunemaker/flipper/pull/211).
|
5
13
|
* Finish API and HTTP adapter that speaks to API.
|
6
|
-
*
|
7
|
-
* Add
|
8
|
-
* Allow unregistered groups (https://github.com/jnunemaker/flipper/pull/244).
|
9
|
-
* Drop support for Ruby 2.0 as it is end of lined (https://github.com/jnunemaker/flipper/commit/c2c81ed89938155ce91acb5173ac38580f630e3d).
|
14
|
+
* Add flipper cloud adapter (https://github.com/jnunemaker/flipper/pull/249). Nothing to see here yet, but good stuff soon. ;)
|
15
|
+
* Add importing (https://github.com/jnunemaker/flipper/pull/251).
|
10
16
|
|
11
17
|
## 0.10.2
|
12
18
|
|
data/docs/Adapters.md
CHANGED
@@ -91,3 +91,33 @@ end
|
|
91
91
|
A good place to start when creating your own adapter is to copy one of the adapters mentioned above and replace the client specific code with whatever client you are attempting to adapt.
|
92
92
|
|
93
93
|
I would also recommend setting `fail_fast = true` in your RSpec configuration as that will just give you one failure at a time to work through. It is also handy to have the shared adapter spec file open.
|
94
|
+
|
95
|
+
## Swapping Adapters
|
96
|
+
|
97
|
+
If you find yourself using one adapter and would like to swap to another, you can do that! Flipper adapters support importing another adapter's data. This will wipe the adapter you are wanting to swap to, if it isn't already clean, so please be careful.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# Say you are using redis...
|
101
|
+
redis_adapter = Flipper::Adapters::Redis.new(Redis.new)
|
102
|
+
redis_flipper = Flipper.new(redis_adapter)
|
103
|
+
|
104
|
+
# And redis has some stuff enabled...
|
105
|
+
redis_flipper.enable(:search)
|
106
|
+
redis_flipper.enable_percentage_of_time(:verbose_logging, 5)
|
107
|
+
redis_flipper.enable_percentage_of_actors(:new_feature, 5)
|
108
|
+
redis_flipper.enable_actor(:issues, Flipper::Actor.new('1'))
|
109
|
+
redis_flipper.enable_actor(:issues, Flipper::Actor.new('2'))
|
110
|
+
redis_flipper.enable_group(:request_tracing, :staff)
|
111
|
+
|
112
|
+
# And you would like to switch to active record...
|
113
|
+
ar_adapter = Flipper::Adapters::ActiveRecord.new
|
114
|
+
ar_flipper = Flipper.new(ar_adapter)
|
115
|
+
|
116
|
+
# NOTE: This wipes active record clean and copies features/gates from redis into active record.
|
117
|
+
ar_flipper.import(redis_flipper)
|
118
|
+
|
119
|
+
# active record is now identical to redis.
|
120
|
+
ar_flipper.features.each do |feature|
|
121
|
+
pp feature: feature.key, values: feature.gate_values
|
122
|
+
end
|
123
|
+
```
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path('../example_setup', __FILE__)
|
2
|
+
|
3
|
+
require 'flipper'
|
4
|
+
require 'flipper/adapters/redis'
|
5
|
+
require 'flipper/adapters/active_record'
|
6
|
+
|
7
|
+
# Active Record boiler plate, feel free to ignore.
|
8
|
+
ActiveRecord::Base.establish_connection({
|
9
|
+
adapter: 'sqlite3',
|
10
|
+
database: ':memory:',
|
11
|
+
})
|
12
|
+
require 'generators/flipper/templates/migration'
|
13
|
+
CreateFlipperTables.up
|
14
|
+
|
15
|
+
# Say you are using redis...
|
16
|
+
redis_adapter = Flipper::Adapters::Redis.new(Redis.new)
|
17
|
+
redis_flipper = Flipper.new(redis_adapter)
|
18
|
+
|
19
|
+
# And redis has some stuff enabled...
|
20
|
+
redis_flipper.enable(:search)
|
21
|
+
redis_flipper.enable_percentage_of_time(:verbose_logging, 5)
|
22
|
+
redis_flipper.enable_percentage_of_actors(:new_feature, 5)
|
23
|
+
redis_flipper.enable_actor(:issues, Flipper::Actor.new('1'))
|
24
|
+
redis_flipper.enable_actor(:issues, Flipper::Actor.new('2'))
|
25
|
+
redis_flipper.enable_group(:request_tracing, :staff)
|
26
|
+
|
27
|
+
# And you would like to switch to active record...
|
28
|
+
ar_adapter = Flipper::Adapters::ActiveRecord.new
|
29
|
+
ar_flipper = Flipper.new(ar_adapter)
|
30
|
+
|
31
|
+
# NOTE: This wipes active record clean and copies features/gates from redis into active record.
|
32
|
+
ar_flipper.import(redis_flipper)
|
33
|
+
|
34
|
+
# active record is now identical to redis.
|
35
|
+
ar_flipper.features.each do |feature|
|
36
|
+
pp feature: feature.key, values: feature.gate_values
|
37
|
+
end
|
data/lib/flipper.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Simple class for turning a flipper_id into an actor that can be based
|
2
|
+
# to Flipper::Feature#enabled?.
|
3
|
+
module Flipper
|
4
|
+
class Actor
|
5
|
+
attr_reader :flipper_id
|
6
|
+
|
7
|
+
def initialize(flipper_id)
|
8
|
+
@flipper_id = flipper_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def eql?(other)
|
12
|
+
self.class.eql?(other.class) && @flipper_id == other.flipper_id
|
13
|
+
end
|
14
|
+
alias_method :==, :eql?
|
15
|
+
end
|
16
|
+
end
|
data/lib/flipper/adapter.rb
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
module Flipper
|
2
2
|
# Adding a module include so we have some hooks for stuff down the road
|
3
3
|
module Adapter
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# Public: Default config for a feature's gate values.
|
10
|
+
def default_config
|
11
|
+
{
|
12
|
+
boolean: nil,
|
13
|
+
groups: Set.new,
|
14
|
+
actors: Set.new,
|
15
|
+
percentage_of_actors: nil,
|
16
|
+
percentage_of_time: nil,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
4
21
|
# Public: Get multiple features in one call. Defaults to one get per
|
5
22
|
# feature. Feel free to override per adapter to make this more efficient and
|
6
23
|
# reduce network calls.
|
@@ -12,14 +29,55 @@ module Flipper
|
|
12
29
|
result
|
13
30
|
end
|
14
31
|
|
32
|
+
# Public: Wipe features and gate values and then import features and gate
|
33
|
+
# values from provided adapter.
|
34
|
+
#
|
35
|
+
# Returns nothing.
|
36
|
+
def import(source_adapter)
|
37
|
+
wipe
|
38
|
+
copy_features_and_gates(source_adapter)
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Default config for a feature's gate values.
|
15
43
|
def default_config
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
44
|
+
self.class.default_config
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Private: Copy source adapter features and gate values into self.
|
50
|
+
def copy_features_and_gates(source_adapter)
|
51
|
+
source_adapter.features.each do |key|
|
52
|
+
source_feature = Flipper::Feature.new(key, source_adapter)
|
53
|
+
destination_feature = Flipper::Feature.new(key, self)
|
54
|
+
|
55
|
+
case source_feature.state
|
56
|
+
when :on
|
57
|
+
destination_feature.enable
|
58
|
+
when :conditional
|
59
|
+
source_feature.groups_value.each do |value|
|
60
|
+
destination_feature.enable_group(value)
|
61
|
+
end
|
62
|
+
|
63
|
+
source_feature.actors_value.each do |value|
|
64
|
+
destination_feature.enable_actor(Flipper::Actor.new(value))
|
65
|
+
end
|
66
|
+
|
67
|
+
destination_feature.enable_percentage_of_actors(source_feature.percentage_of_actors_value)
|
68
|
+
destination_feature.enable_percentage_of_time(source_feature.percentage_of_time_value)
|
69
|
+
when :off
|
70
|
+
destination_feature.add
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Private: Completely wipe adapter features and gate values.
|
76
|
+
def wipe
|
77
|
+
features.each do |key|
|
78
|
+
feature = Flipper::Feature.new(key, self)
|
79
|
+
remove(feature)
|
80
|
+
end
|
23
81
|
end
|
24
82
|
end
|
25
83
|
end
|
data/lib/flipper/dsl.rb
CHANGED
@@ -139,6 +139,15 @@ module Flipper
|
|
139
139
|
feature(name).disable_percentage_of_actors
|
140
140
|
end
|
141
141
|
|
142
|
+
# Public: Add a feature.
|
143
|
+
#
|
144
|
+
# name - The String or Symbol name of the feature.
|
145
|
+
#
|
146
|
+
# Returns result of add.
|
147
|
+
def add(name)
|
148
|
+
feature(name).add
|
149
|
+
end
|
150
|
+
|
142
151
|
# Public: Remove a feature.
|
143
152
|
#
|
144
153
|
# name - The String or Symbol name of the feature.
|
@@ -241,5 +250,9 @@ module Flipper
|
|
241
250
|
def features
|
242
251
|
adapter.features.map { |name| feature(name) }.to_set
|
243
252
|
end
|
253
|
+
|
254
|
+
def import(flipper)
|
255
|
+
adapter.import(flipper.adapter)
|
256
|
+
end
|
244
257
|
end
|
245
258
|
end
|
data/lib/flipper/feature.rb
CHANGED
@@ -69,6 +69,13 @@ module Flipper
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
# Public: Adds this feature.
|
73
|
+
#
|
74
|
+
# Returns the result of Adapter#add.
|
75
|
+
def add
|
76
|
+
instrument(:add) { adapter.add(self) }
|
77
|
+
end
|
78
|
+
|
72
79
|
# Public: Removes this feature.
|
73
80
|
#
|
74
81
|
# Returns the result of Adapter#remove.
|
@@ -8,6 +8,9 @@ module Flipper
|
|
8
8
|
# using the Flipper::Middleware::SetupEnv middleware.
|
9
9
|
#
|
10
10
|
# app - The app this middleware is included in.
|
11
|
+
# opts - The Hash of options.
|
12
|
+
# :preload_all - Boolean of whether or not to preload all features.
|
13
|
+
# :preload - Array of Symbol feature names to preload.
|
11
14
|
#
|
12
15
|
# Examples
|
13
16
|
#
|
@@ -20,6 +23,10 @@ module Flipper
|
|
20
23
|
# use Flipper::Middleware::Memoizer, preload: [:stats, :search, :some_feature]
|
21
24
|
#
|
22
25
|
def initialize(app, opts = {})
|
26
|
+
if opts.is_a?(Flipper::DSL) || opts.is_a?(Proc)
|
27
|
+
raise 'Flipper::Middleware::Memoizer no longer initializes with a flipper instance or block. Read more at: https://git.io/vSo31.' # rubocop:disable LineLength
|
28
|
+
end
|
29
|
+
|
23
30
|
@app = app
|
24
31
|
@opts = opts
|
25
32
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# Requires the following methods:
|
2
2
|
# * subject - The instance of the adapter
|
3
3
|
RSpec.shared_examples_for 'a flipper adapter' do
|
4
|
-
let(:actor_class) { Struct.new(:flipper_id) }
|
5
|
-
|
6
4
|
let(:flipper) { Flipper.new(subject) }
|
7
5
|
let(:feature) { flipper[:stats] }
|
8
6
|
|
@@ -52,7 +50,7 @@ RSpec.shared_examples_for 'a flipper adapter' do
|
|
52
50
|
end
|
53
51
|
|
54
52
|
it 'fully disables all enabled things when boolean gate disabled' do
|
55
|
-
actor22 =
|
53
|
+
actor22 = Flipper::Actor.new('22')
|
56
54
|
expect(subject.enable(feature, boolean_gate, flipper.boolean)).to eq(true)
|
57
55
|
expect(subject.enable(feature, group_gate, flipper.group(:admins))).to eq(true)
|
58
56
|
expect(subject.enable(feature, actor_gate, flipper.actor(actor22))).to eq(true)
|
@@ -81,8 +79,8 @@ RSpec.shared_examples_for 'a flipper adapter' do
|
|
81
79
|
end
|
82
80
|
|
83
81
|
it 'can enable, disable and get value for actor gate' do
|
84
|
-
actor22 =
|
85
|
-
actor_asdf =
|
82
|
+
actor22 = Flipper::Actor.new('22')
|
83
|
+
actor_asdf = Flipper::Actor.new('asdf')
|
86
84
|
|
87
85
|
expect(subject.enable(feature, actor_gate, flipper.actor(actor22))).to eq(true)
|
88
86
|
expect(subject.enable(feature, actor_gate, flipper.actor(actor_asdf))).to eq(true)
|
@@ -158,7 +156,7 @@ RSpec.shared_examples_for 'a flipper adapter' do
|
|
158
156
|
end
|
159
157
|
|
160
158
|
it 'converts the actor value to a string' do
|
161
|
-
expect(subject.enable(feature, actor_gate, flipper.actor(
|
159
|
+
expect(subject.enable(feature, actor_gate, flipper.actor(Flipper::Actor.new(22)))).to eq(true)
|
162
160
|
result = subject.get(feature)
|
163
161
|
expect(result[:actors]).to eq(Set['22'])
|
164
162
|
end
|
@@ -198,7 +196,7 @@ RSpec.shared_examples_for 'a flipper adapter' do
|
|
198
196
|
end
|
199
197
|
|
200
198
|
it 'clears all the gate values for the feature on remove' do
|
201
|
-
actor22 =
|
199
|
+
actor22 = Flipper::Actor.new('22')
|
202
200
|
expect(subject.enable(feature, boolean_gate, flipper.boolean)).to eq(true)
|
203
201
|
expect(subject.enable(feature, group_gate, flipper.group(:admins))).to eq(true)
|
204
202
|
expect(subject.enable(feature, actor_gate, flipper.actor(actor22))).to eq(true)
|
@@ -211,7 +209,7 @@ RSpec.shared_examples_for 'a flipper adapter' do
|
|
211
209
|
end
|
212
210
|
|
213
211
|
it 'can clear all the gate values for a feature' do
|
214
|
-
actor22 =
|
212
|
+
actor22 = Flipper::Actor.new('22')
|
215
213
|
subject.add(feature)
|
216
214
|
expect(subject.features).to include(feature.key)
|
217
215
|
|
@@ -5,7 +5,6 @@ module Flipper
|
|
5
5
|
def setup
|
6
6
|
super
|
7
7
|
@flipper = Flipper.new(@adapter)
|
8
|
-
@actor_class = Struct.new(:flipper_id)
|
9
8
|
@feature = @flipper[:stats]
|
10
9
|
@boolean_gate = @feature.gate(:boolean)
|
11
10
|
@group_gate = @feature.gate(:group)
|
@@ -48,7 +47,7 @@ module Flipper
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def test_fully_disables_all_enabled_things_when_boolean_gate_disabled
|
51
|
-
actor22 =
|
50
|
+
actor22 = Flipper::Actor.new('22')
|
52
51
|
assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
|
53
52
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
54
53
|
assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor22))
|
@@ -75,8 +74,8 @@ module Flipper
|
|
75
74
|
end
|
76
75
|
|
77
76
|
def test_can_enable_disable_and_get_value_for_an_actor_gate
|
78
|
-
actor22 =
|
79
|
-
actor_asdf =
|
77
|
+
actor22 = Flipper::Actor.new('22')
|
78
|
+
actor_asdf = Flipper::Actor.new('asdf')
|
80
79
|
|
81
80
|
assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor22))
|
82
81
|
assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor_asdf))
|
@@ -153,7 +152,7 @@ module Flipper
|
|
153
152
|
|
154
153
|
def test_converts_the_actor_value_to_a_string
|
155
154
|
assert_equal true,
|
156
|
-
@adapter.enable(@feature, @actor_gate, @flipper.actor(
|
155
|
+
@adapter.enable(@feature, @actor_gate, @flipper.actor(Flipper::Actor.new(22)))
|
157
156
|
result = @adapter.get(@feature)
|
158
157
|
assert_equal Set['22'], result[:actors]
|
159
158
|
end
|
@@ -193,7 +192,7 @@ module Flipper
|
|
193
192
|
end
|
194
193
|
|
195
194
|
def test_clears_all_the_gate_values_for_the_feature_on_remove
|
196
|
-
actor22 =
|
195
|
+
actor22 = Flipper::Actor.new('22')
|
197
196
|
assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
|
198
197
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
199
198
|
assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor22))
|
@@ -206,7 +205,7 @@ module Flipper
|
|
206
205
|
end
|
207
206
|
|
208
207
|
def test_can_clear_all_the_gate_values_for_a_feature
|
209
|
-
actor22 =
|
208
|
+
actor22 = Flipper::Actor.new('22')
|
210
209
|
@adapter.add(@feature)
|
211
210
|
assert_includes @adapter.features, @feature.key
|
212
211
|
|
data/lib/flipper/version.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RSpec.describe Flipper::Actor do
|
4
|
+
it 'initializes with and knows flipper_id' do
|
5
|
+
actor = described_class.new("User;235")
|
6
|
+
expect(actor.flipper_id).to eq("User;235")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#eql?' do
|
10
|
+
it 'returns true if same class and flipper_id' do
|
11
|
+
actor1 = described_class.new("User;235")
|
12
|
+
actor2 = described_class.new("User;235")
|
13
|
+
expect(actor1.eql?(actor2)).to be(true)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns false if same class but different flipper_id' do
|
17
|
+
actor1 = described_class.new("User;235")
|
18
|
+
actor2 = described_class.new("User;1")
|
19
|
+
expect(actor1.eql?(actor2)).to be(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns false for different class' do
|
23
|
+
actor1 = described_class.new("User;235")
|
24
|
+
actor2 = Struct.new(:flipper_id).new("User;235")
|
25
|
+
expect(actor1.eql?(actor2)).to be(false)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#==' do
|
30
|
+
it 'returns true if same class and flipper_id' do
|
31
|
+
actor1 = described_class.new("User;235")
|
32
|
+
actor2 = described_class.new("User;235")
|
33
|
+
expect(actor1.==(actor2)).to be(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns false if same class but different flipper_id' do
|
37
|
+
actor1 = described_class.new("User;235")
|
38
|
+
actor2 = described_class.new("User;1")
|
39
|
+
expect(actor1.==(actor2)).to be(false)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns false for different class' do
|
43
|
+
actor1 = described_class.new("User;235")
|
44
|
+
actor2 = Struct.new(:flipper_id).new("User;235")
|
45
|
+
expect(actor1.==(actor2)).to be(false)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/adapters/memory'
|
3
|
+
|
4
|
+
RSpec.describe Flipper::Adapter do
|
5
|
+
let(:source_flipper) { build_flipper }
|
6
|
+
let(:destination_flipper) { build_flipper }
|
7
|
+
let(:default_config) do
|
8
|
+
{
|
9
|
+
boolean: nil,
|
10
|
+
groups: Set.new,
|
11
|
+
actors: Set.new,
|
12
|
+
percentage_of_actors: nil,
|
13
|
+
percentage_of_time: nil,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.default_config' do
|
18
|
+
it 'returns default config' do
|
19
|
+
adapter_class = Class.new do
|
20
|
+
include described_class
|
21
|
+
end
|
22
|
+
expect(adapter_class.default_config).to eq(default_config)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#default_config' do
|
27
|
+
it 'returns default config' do
|
28
|
+
adapter_class = Class.new do
|
29
|
+
include described_class
|
30
|
+
end
|
31
|
+
expect(adapter_class.new.default_config).to eq(default_config)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#import' do
|
36
|
+
it 'returns nothing' do
|
37
|
+
result = destination_flipper.import(source_flipper)
|
38
|
+
expect(result).to be(nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can import from one adapter to another' do
|
42
|
+
source_flipper.enable(:search)
|
43
|
+
destination_flipper.import(source_flipper)
|
44
|
+
expect(destination_flipper[:search].boolean_value).to eq(true)
|
45
|
+
expect(destination_flipper.features.map(&:key).sort).to eq(%w(search))
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'can import features that have been added but their state is off' do
|
49
|
+
source_flipper.add(:search)
|
50
|
+
destination_flipper.import(source_flipper)
|
51
|
+
expect(destination_flipper.features.map(&:key)).to eq(["search"])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can import multiple features' do
|
55
|
+
source_flipper.enable(:yep)
|
56
|
+
source_flipper.enable_group(:preview_features, :developers)
|
57
|
+
source_flipper.enable_group(:preview_features, :marketers)
|
58
|
+
source_flipper.enable_group(:preview_features, :company)
|
59
|
+
source_flipper.enable_group(:preview_features, :early_access)
|
60
|
+
source_flipper.enable_actor(:preview_features, Flipper::Actor.new('1'))
|
61
|
+
source_flipper.enable_actor(:preview_features, Flipper::Actor.new('2'))
|
62
|
+
source_flipper.enable_actor(:preview_features, Flipper::Actor.new('3'))
|
63
|
+
source_flipper.enable_percentage_of_actors(:issues_next, 25)
|
64
|
+
source_flipper.enable_percentage_of_time(:verbose_logging, 5)
|
65
|
+
|
66
|
+
destination_flipper.import(source_flipper)
|
67
|
+
|
68
|
+
feature = destination_flipper[:preview_features]
|
69
|
+
expect(feature.boolean_value).to be(false)
|
70
|
+
expect(feature.actors_value).to eq(Set['1', '2', '3'])
|
71
|
+
expected_groups = Set['developers', 'marketers', 'company', 'early_access']
|
72
|
+
expect(feature.groups_value).to eq(expected_groups)
|
73
|
+
expect(feature.percentage_of_actors_value).to be(0)
|
74
|
+
expect(feature.percentage_of_time_value).to be(0)
|
75
|
+
|
76
|
+
feature = destination_flipper[:issues_next]
|
77
|
+
expect(feature.boolean_value).to eq(false)
|
78
|
+
expect(feature.actors_value).to eq(Set.new)
|
79
|
+
expect(feature.groups_value).to eq(Set.new)
|
80
|
+
expect(feature.percentage_of_actors_value).to be(25)
|
81
|
+
expect(feature.percentage_of_time_value).to be(0)
|
82
|
+
|
83
|
+
feature = destination_flipper[:verbose_logging]
|
84
|
+
expect(feature.boolean_value).to eq(false)
|
85
|
+
expect(feature.actors_value).to eq(Set.new)
|
86
|
+
expect(feature.groups_value).to eq(Set.new)
|
87
|
+
expect(feature.percentage_of_actors_value).to be(0)
|
88
|
+
expect(feature.percentage_of_time_value).to be(5)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'wipes existing enablements for adapter' do
|
92
|
+
destination_flipper.enable(:stats)
|
93
|
+
destination_flipper.enable_percentage_of_time(:verbose_logging, 5)
|
94
|
+
source_flipper.enable_percentage_of_time(:stats, 5)
|
95
|
+
source_flipper.enable_percentage_of_actors(:verbose_logging, 25)
|
96
|
+
|
97
|
+
destination_flipper.import(source_flipper)
|
98
|
+
|
99
|
+
feature = destination_flipper[:stats]
|
100
|
+
expect(feature.boolean_value).to be(false)
|
101
|
+
expect(feature.percentage_of_time_value).to be(5)
|
102
|
+
|
103
|
+
feature = destination_flipper[:verbose_logging]
|
104
|
+
expect(feature.percentage_of_time_value).to be(0)
|
105
|
+
expect(feature.percentage_of_actors_value).to be(25)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'wipes existing features for adapter' do
|
109
|
+
destination_flipper.add(:stats)
|
110
|
+
destination_flipper.import(source_flipper)
|
111
|
+
expect(destination_flipper.features.map(&:key)).to eq([])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -60,7 +60,7 @@ RSpec.describe Flipper::Adapters::Http do
|
|
60
60
|
headers = {
|
61
61
|
'Accept' => 'application/json',
|
62
62
|
'Content-Type' => 'application/json',
|
63
|
-
'User-Agent' =>
|
63
|
+
'User-Agent' => "Flipper HTTP Adapter v#{Flipper::VERSION}",
|
64
64
|
}
|
65
65
|
stub_request(:get, "http://app.com/flipper/features/feature_panel")
|
66
66
|
.with(headers: headers)
|
@@ -2,8 +2,6 @@ require 'helper'
|
|
2
2
|
require 'flipper/adapters/read_only'
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Adapters::ReadOnly do
|
5
|
-
let(:actor_class) { Struct.new(:flipper_id) }
|
6
|
-
|
7
5
|
let(:adapter) { Flipper::Adapters::Memory.new }
|
8
6
|
let(:flipper) { Flipper.new(subject) }
|
9
7
|
let(:feature) { flipper[:stats] }
|
@@ -44,7 +42,7 @@ RSpec.describe Flipper::Adapters::ReadOnly do
|
|
44
42
|
end
|
45
43
|
|
46
44
|
it 'can get feature' do
|
47
|
-
actor22 =
|
45
|
+
actor22 = Flipper::Actor.new('22')
|
48
46
|
adapter.enable(feature, boolean_gate, flipper.boolean)
|
49
47
|
adapter.enable(feature, group_gate, flipper.group(:admins))
|
50
48
|
adapter.enable(feature, actor_gate, flipper.actor(actor22))
|
data/spec/flipper/dsl_spec.rb
CHANGED
@@ -107,7 +107,7 @@ RSpec.describe Flipper::DSL do
|
|
107
107
|
describe '#actor' do
|
108
108
|
context 'for a thing' do
|
109
109
|
it 'returns actor instance' do
|
110
|
-
thing =
|
110
|
+
thing = Flipper::Actor.new(33)
|
111
111
|
actor = subject.actor(thing)
|
112
112
|
expect(actor).to be_instance_of(Flipper::Types::Actor)
|
113
113
|
expect(actor.value).to eq('33')
|
@@ -204,7 +204,7 @@ RSpec.describe Flipper::DSL do
|
|
204
204
|
|
205
205
|
describe '#enable_actor/disable_actor' do
|
206
206
|
it 'enables and disables the feature for actor' do
|
207
|
-
actor =
|
207
|
+
actor = Flipper::Actor.new(5)
|
208
208
|
|
209
209
|
expect(subject[:stats].actors_value).to be_empty
|
210
210
|
subject.enable_actor(:stats, actor)
|
@@ -217,7 +217,7 @@ RSpec.describe Flipper::DSL do
|
|
217
217
|
|
218
218
|
describe '#enable_group/disable_group' do
|
219
219
|
it 'enables and disables the feature for group' do
|
220
|
-
actor =
|
220
|
+
actor = Flipper::Actor.new(5)
|
221
221
|
group = Flipper.register(:fives) { |actor| actor.flipper_id == 5 }
|
222
222
|
|
223
223
|
expect(subject[:stats].groups_value).to be_empty
|
@@ -251,13 +251,28 @@ RSpec.describe Flipper::DSL do
|
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
+
describe '#add' do
|
255
|
+
it 'adds the feature' do
|
256
|
+
expect(subject.features).to eq(Set.new)
|
257
|
+
subject.add(:stats)
|
258
|
+
expect(subject.features).to eq(Set[subject[:stats]])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
254
262
|
describe '#remove' do
|
255
263
|
it 'removes the feature' do
|
256
|
-
subject.
|
257
|
-
|
258
|
-
|
264
|
+
subject.adapter.add(subject[:stats])
|
265
|
+
expect(subject.features).to eq(Set[subject[:stats]])
|
266
|
+
subject.remove(:stats)
|
267
|
+
expect(subject.features).to eq(Set.new)
|
268
|
+
end
|
269
|
+
end
|
259
270
|
|
260
|
-
|
271
|
+
describe '#import' do
|
272
|
+
it 'delegates to adapter' do
|
273
|
+
destination_flipper = build_flipper
|
274
|
+
expect(subject.adapter).to receive(:import).with(destination_flipper.adapter)
|
275
|
+
subject.import(destination_flipper)
|
261
276
|
end
|
262
277
|
end
|
263
278
|
end
|
@@ -3,7 +3,7 @@ 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) {
|
6
|
+
let(:thing) { Flipper::Actor.new('5') }
|
7
7
|
let(:options) do
|
8
8
|
{
|
9
9
|
feature_name: feature_name,
|
@@ -89,6 +89,23 @@ RSpec.describe Flipper::Feature do
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
describe '#add' do
|
93
|
+
it 'adds feature to adapter' do
|
94
|
+
expect(adapter.features).to eq(Set.new)
|
95
|
+
subject.add
|
96
|
+
expect(adapter.features).to eq(Set[subject.key])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#remove' do
|
101
|
+
it 'removes feature from adapter' do
|
102
|
+
adapter.add(subject)
|
103
|
+
expect(adapter.features).to eq(Set[subject.key])
|
104
|
+
subject.remove
|
105
|
+
expect(adapter.features).to eq(Set.new)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
92
109
|
describe '#inspect' do
|
93
110
|
it 'returns easy to read string representation' do
|
94
111
|
string = subject.inspect
|
@@ -113,7 +130,7 @@ RSpec.describe Flipper::Feature do
|
|
113
130
|
end
|
114
131
|
|
115
132
|
it 'is recorded for enable' do
|
116
|
-
thing = Flipper::Types::Actor.new(
|
133
|
+
thing = Flipper::Types::Actor.new(Flipper::Actor.new('1'))
|
117
134
|
gate = subject.gate_for(thing)
|
118
135
|
|
119
136
|
subject.enable(thing)
|
@@ -128,7 +145,7 @@ RSpec.describe Flipper::Feature do
|
|
128
145
|
end
|
129
146
|
|
130
147
|
it 'always instruments flipper type instance for enable' do
|
131
|
-
thing =
|
148
|
+
thing = Flipper::Actor.new('1')
|
132
149
|
gate = subject.gate_for(thing)
|
133
150
|
|
134
151
|
subject.enable(thing)
|
@@ -153,7 +170,7 @@ RSpec.describe Flipper::Feature do
|
|
153
170
|
expect(event.payload[:result]).not_to be_nil
|
154
171
|
end
|
155
172
|
|
156
|
-
user =
|
173
|
+
user = Flipper::Actor.new('1')
|
157
174
|
actor = Flipper::Types::Actor.new(user)
|
158
175
|
boolean_true = Flipper::Types::Boolean.new(true)
|
159
176
|
boolean_false = Flipper::Types::Boolean.new(false)
|
@@ -184,7 +201,7 @@ RSpec.describe Flipper::Feature do
|
|
184
201
|
end
|
185
202
|
|
186
203
|
it 'always instruments flipper type instance for disable' do
|
187
|
-
thing =
|
204
|
+
thing = Flipper::Actor.new('1')
|
188
205
|
gate = subject.gate_for(thing)
|
189
206
|
|
190
207
|
subject.disable(thing)
|
@@ -195,6 +212,17 @@ RSpec.describe Flipper::Feature do
|
|
195
212
|
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(thing))
|
196
213
|
end
|
197
214
|
|
215
|
+
it 'is recorded for add' do
|
216
|
+
subject.add
|
217
|
+
|
218
|
+
event = instrumenter.events.last
|
219
|
+
expect(event).not_to be_nil
|
220
|
+
expect(event.name).to eq('feature_operation.flipper')
|
221
|
+
expect(event.payload[:feature_name]).to eq(:search)
|
222
|
+
expect(event.payload[:operation]).to eq(:add)
|
223
|
+
expect(event.payload[:result]).not_to be_nil
|
224
|
+
end
|
225
|
+
|
198
226
|
it 'is recorded for remove' do
|
199
227
|
subject.remove
|
200
228
|
|
@@ -207,7 +235,7 @@ RSpec.describe Flipper::Feature do
|
|
207
235
|
end
|
208
236
|
|
209
237
|
it 'is recorded for enabled?' do
|
210
|
-
thing = Flipper::Types::Actor.new(
|
238
|
+
thing = Flipper::Types::Actor.new(Flipper::Actor.new('1'))
|
211
239
|
gate = subject.gate_for(thing)
|
212
240
|
|
213
241
|
subject.enabled?(thing)
|
@@ -221,7 +249,7 @@ RSpec.describe Flipper::Feature do
|
|
221
249
|
expect(event.payload[:result]).to eq(false)
|
222
250
|
end
|
223
251
|
|
224
|
-
user =
|
252
|
+
user = Flipper::Actor.new('1')
|
225
253
|
actor = Flipper::Types::Actor.new(user)
|
226
254
|
{
|
227
255
|
nil => nil,
|
@@ -461,8 +489,8 @@ RSpec.describe Flipper::Feature do
|
|
461
489
|
|
462
490
|
context 'when one or more actors are enabled' do
|
463
491
|
before do
|
464
|
-
subject.enable Flipper::Types::Actor.new(
|
465
|
-
subject.enable Flipper::Types::Actor.new(
|
492
|
+
subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User:5'))
|
493
|
+
subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User:22'))
|
466
494
|
end
|
467
495
|
|
468
496
|
it 'returns set of actor ids' do
|
@@ -565,7 +593,7 @@ RSpec.describe Flipper::Feature do
|
|
565
593
|
context 'with gate values set in adapter' do
|
566
594
|
before do
|
567
595
|
subject.enable Flipper::Types::Boolean.new(true)
|
568
|
-
subject.enable Flipper::Types::Actor.new(
|
596
|
+
subject.enable Flipper::Types::Actor.new(Flipper::Actor.new(5))
|
569
597
|
subject.enable Flipper::Types::Group.new(:admins)
|
570
598
|
subject.enable Flipper::Types::PercentageOfTime.new(50)
|
571
599
|
subject.enable Flipper::Types::PercentageOfActors.new(25)
|
@@ -584,7 +612,7 @@ RSpec.describe Flipper::Feature do
|
|
584
612
|
describe '#enable_actor/disable_actor' do
|
585
613
|
context 'with object that responds to flipper_id' do
|
586
614
|
it 'updates the gate values to include the actor' do
|
587
|
-
actor =
|
615
|
+
actor = Flipper::Actor.new(5)
|
588
616
|
expect(subject.gate_values.actors).to be_empty
|
589
617
|
subject.enable_actor(actor)
|
590
618
|
expect(subject.gate_values.actors).to eq(Set['5'])
|
@@ -595,7 +623,7 @@ RSpec.describe Flipper::Feature do
|
|
595
623
|
|
596
624
|
context 'with actor instance' do
|
597
625
|
it 'updates the gate values to include the actor' do
|
598
|
-
actor =
|
626
|
+
actor = Flipper::Actor.new(5)
|
599
627
|
instance = Flipper::Types::Actor.new(actor)
|
600
628
|
expect(subject.gate_values.actors).to be_empty
|
601
629
|
subject.enable_actor(instance)
|
@@ -609,7 +637,7 @@ RSpec.describe Flipper::Feature do
|
|
609
637
|
describe '#enable_group/disable_group' do
|
610
638
|
context 'with symbol group name' do
|
611
639
|
it 'updates the gate values to include the group' do
|
612
|
-
actor =
|
640
|
+
actor = Flipper::Actor.new(5)
|
613
641
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
614
642
|
expect(subject.gate_values.groups).to be_empty
|
615
643
|
subject.enable_group(:five_only)
|
@@ -621,7 +649,7 @@ RSpec.describe Flipper::Feature do
|
|
621
649
|
|
622
650
|
context 'with string group name' do
|
623
651
|
it 'updates the gate values to include the group' do
|
624
|
-
actor =
|
652
|
+
actor = Flipper::Actor.new(5)
|
625
653
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
626
654
|
expect(subject.gate_values.groups).to be_empty
|
627
655
|
subject.enable_group('five_only')
|
@@ -633,7 +661,7 @@ RSpec.describe Flipper::Feature do
|
|
633
661
|
|
634
662
|
context 'with group instance' do
|
635
663
|
it 'updates the gate values for the group' do
|
636
|
-
actor =
|
664
|
+
actor = Flipper::Actor.new(5)
|
637
665
|
group = Flipper.register(:five_only) { |actor| actor.flipper_id == 5 }
|
638
666
|
expect(subject.gate_values.groups).to be_empty
|
639
667
|
subject.enable_group(group)
|
@@ -11,7 +11,7 @@ RSpec.describe Flipper::Gates::Boolean do
|
|
11
11
|
Flipper::FeatureCheckContext.new(
|
12
12
|
feature_name: feature_name,
|
13
13
|
values: Flipper::GateValues.new(boolean: bool),
|
14
|
-
thing: Flipper::Types::Actor.new(
|
14
|
+
thing: Flipper::Types::Actor.new(Flipper::Actor.new(1))
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -11,7 +11,7 @@ RSpec.describe Flipper::Gates::Group do
|
|
11
11
|
Flipper::FeatureCheckContext.new(
|
12
12
|
feature_name: feature_name,
|
13
13
|
values: Flipper::GateValues.new(groups: set),
|
14
|
-
thing: Flipper::Types::Actor.new(
|
14
|
+
thing: Flipper::Types::Actor.new(Flipper::Actor.new('5'))
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -22,7 +22,7 @@ RSpec.describe Flipper::Gates::Group do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'ignores group' do
|
25
|
-
thing =
|
25
|
+
thing = Flipper::Actor.new('5')
|
26
26
|
expect(subject.open?(context(Set[:newbs, :staff]))).to be(true)
|
27
27
|
end
|
28
28
|
end
|
@@ -11,7 +11,7 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
11
11
|
Flipper::FeatureCheckContext.new(
|
12
12
|
feature_name: feature,
|
13
13
|
values: Flipper::GateValues.new(percentage_of_actors: integer),
|
14
|
-
thing: thing || Flipper::Types::Actor.new(
|
14
|
+
thing: thing || Flipper::Types::Actor.new(Flipper::Actor.new(1))
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -22,7 +22,7 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
22
22
|
let(:number_of_actors) { 100 }
|
23
23
|
|
24
24
|
let(:actors) do
|
25
|
-
(1..number_of_actors).map { |n|
|
25
|
+
(1..number_of_actors).map { |n| Flipper::Actor.new(n) }
|
26
26
|
end
|
27
27
|
|
28
28
|
let(:feature_one_enabled_actors) do
|
@@ -49,7 +49,7 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
context 'feature enabled checks with a thing' do
|
52
|
-
let(:user) { Flipper::Types::Actor.new(
|
52
|
+
let(:user) { Flipper::Types::Actor.new(Flipper::Actor.new('1')) }
|
53
53
|
|
54
54
|
before do
|
55
55
|
clear_logs
|
@@ -63,7 +63,7 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
context 'changing feature enabled state' do
|
66
|
-
let(:user) { Flipper::Types::Actor.new(
|
66
|
+
let(:user) { Flipper::Types::Actor.new(Flipper::Actor.new('1')) }
|
67
67
|
|
68
68
|
before do
|
69
69
|
clear_logs
|
@@ -11,7 +11,7 @@ RSpec.describe Flipper::Instrumentation::MetriksSubscriber do
|
|
11
11
|
Flipper.new(adapter, instrumenter: ActiveSupport::Notifications)
|
12
12
|
end
|
13
13
|
|
14
|
-
let(:user) { user =
|
14
|
+
let(:user) { user = Flipper::Actor.new('1') }
|
15
15
|
|
16
16
|
before do
|
17
17
|
Metriks::Registry.default.clear
|
@@ -15,7 +15,7 @@ RSpec.describe Flipper::Instrumentation::StatsdSubscriber do
|
|
15
15
|
Flipper.new(adapter, instrumenter: ActiveSupport::Notifications)
|
16
16
|
end
|
17
17
|
|
18
|
-
let(:user) { user =
|
18
|
+
let(:user) { user = Flipper::Actor.new('1') }
|
19
19
|
|
20
20
|
before do
|
21
21
|
described_class.client = statsd_client
|
@@ -18,6 +18,19 @@ RSpec.describe Flipper::Middleware::Memoizer do
|
|
18
18
|
flipper.adapter.memoize = nil
|
19
19
|
end
|
20
20
|
|
21
|
+
it 'raises if initialized with app and flipper instance' do
|
22
|
+
expect do
|
23
|
+
described_class.new(app, flipper)
|
24
|
+
end.to raise_error(/no longer initializes with a flipper/)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'raises if initialized with app and block' do
|
28
|
+
block = -> { flipper }
|
29
|
+
expect do
|
30
|
+
described_class.new(app, block)
|
31
|
+
end.to raise_error(/no longer initializes with a flipper/)
|
32
|
+
end
|
33
|
+
|
21
34
|
RSpec.shared_examples_for 'flipper middleware' do
|
22
35
|
it 'delegates' do
|
23
36
|
called = false
|
@@ -69,7 +69,7 @@ RSpec.describe Flipper::Types::Group do
|
|
69
69
|
context = Flipper::FeatureCheckContext.new(
|
70
70
|
feature_name: :my_feature,
|
71
71
|
values: Flipper::GateValues.new({}),
|
72
|
-
thing: Flipper::Types::Actor.new(
|
72
|
+
thing: Flipper::Types::Actor.new(Flipper::Actor.new(1))
|
73
73
|
)
|
74
74
|
group = Flipper.register(:group_with_context) { |actor| actor }
|
75
75
|
yielded_actor = group.match?(admin_actor, context)
|
@@ -80,7 +80,7 @@ RSpec.describe Flipper::Types::Group do
|
|
80
80
|
context = Flipper::FeatureCheckContext.new(
|
81
81
|
feature_name: :my_feature,
|
82
82
|
values: Flipper::GateValues.new({}),
|
83
|
-
thing: Flipper::Types::Actor.new(
|
83
|
+
thing: Flipper::Types::Actor.new(Flipper::Actor.new(1))
|
84
84
|
)
|
85
85
|
group = Flipper.register(:group_with_context) { |actor, context| [actor, context] }
|
86
86
|
yielded_actor, yielded_context = group.match?(admin_actor, context)
|
data/spec/integration_spec.rb
CHANGED
@@ -6,9 +6,6 @@ RSpec.describe Flipper do
|
|
6
6
|
let(:adapter) { Flipper::Adapters::Memory.new }
|
7
7
|
let(:flipper) { described_class.new(adapter) }
|
8
8
|
let(:feature) { flipper[:search] }
|
9
|
-
|
10
|
-
let(:actor_class) { Struct.new(:flipper_id) }
|
11
|
-
|
12
9
|
let(:admin_group) { flipper.group(:admins) }
|
13
10
|
let(:dev_group) { flipper.group(:devs) }
|
14
11
|
|
@@ -26,8 +23,8 @@ RSpec.describe Flipper do
|
|
26
23
|
double 'Non Flipper Thing', flipper_id: 1, admin?: nil, dev?: false
|
27
24
|
end
|
28
25
|
|
29
|
-
let(:pitt) {
|
30
|
-
let(:clooney) {
|
26
|
+
let(:pitt) { Flipper::Actor.new(1) }
|
27
|
+
let(:clooney) { Flipper::Actor.new(10) }
|
31
28
|
|
32
29
|
let(:five_percent_of_actors) { flipper.actors(5) }
|
33
30
|
let(:five_percent_of_time) { flipper.time(5) }
|
@@ -123,7 +120,7 @@ RSpec.describe Flipper do
|
|
123
120
|
|
124
121
|
it 'enables feature for actor within percentage' do
|
125
122
|
enabled = (1..100).select do |i|
|
126
|
-
thing =
|
123
|
+
thing = Flipper::Actor.new(i)
|
127
124
|
feature.enabled?(thing)
|
128
125
|
end.size
|
129
126
|
|
@@ -202,7 +199,7 @@ RSpec.describe Flipper do
|
|
202
199
|
|
203
200
|
it 'disables actor in percentage of actors' do
|
204
201
|
enabled = (1..100).select do |i|
|
205
|
-
thing =
|
202
|
+
thing = Flipper::Actor.new(i)
|
206
203
|
feature.enabled?(thing)
|
207
204
|
end.size
|
208
205
|
|
@@ -285,7 +282,7 @@ RSpec.describe Flipper do
|
|
285
282
|
|
286
283
|
it 'disables feature' do
|
287
284
|
enabled = (1..100).select do |i|
|
288
|
-
thing =
|
285
|
+
thing = Flipper::Actor.new(i)
|
289
286
|
feature.enabled?(thing)
|
290
287
|
end.size
|
291
288
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.0.
|
4
|
+
version: 0.11.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Feature flipper is the act of enabling/disabling features in your application,
|
14
14
|
ideally without re-deploying or changing anything in your code base. Flipper makes
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- examples/group.rb
|
45
45
|
- examples/group_dynamic_lookup.rb
|
46
46
|
- examples/group_with_members.rb
|
47
|
+
- examples/importing.rb
|
47
48
|
- examples/individual_actor.rb
|
48
49
|
- examples/instrumentation.rb
|
49
50
|
- examples/percentage_of_actors.rb
|
@@ -52,6 +53,7 @@ files:
|
|
52
53
|
- examples/percentage_of_time.rb
|
53
54
|
- flipper.gemspec
|
54
55
|
- lib/flipper.rb
|
56
|
+
- lib/flipper/actor.rb
|
55
57
|
- lib/flipper/adapter.rb
|
56
58
|
- lib/flipper/adapters/http.rb
|
57
59
|
- lib/flipper/adapters/http/client.rb
|
@@ -96,6 +98,8 @@ files:
|
|
96
98
|
- lib/flipper/types/percentage_of_time.rb
|
97
99
|
- lib/flipper/version.rb
|
98
100
|
- spec/fixtures/feature.json
|
101
|
+
- spec/flipper/actor_spec.rb
|
102
|
+
- spec/flipper/adapter_spec.rb
|
99
103
|
- spec/flipper/adapters/http_spec.rb
|
100
104
|
- spec/flipper/adapters/instrumented_spec.rb
|
101
105
|
- spec/flipper/adapters/memoizable_spec.rb
|
@@ -163,6 +167,8 @@ specification_version: 4
|
|
163
167
|
summary: Feature flipper for ANYTHING
|
164
168
|
test_files:
|
165
169
|
- spec/fixtures/feature.json
|
170
|
+
- spec/flipper/actor_spec.rb
|
171
|
+
- spec/flipper/adapter_spec.rb
|
166
172
|
- spec/flipper/adapters/http_spec.rb
|
167
173
|
- spec/flipper/adapters/instrumented_spec.rb
|
168
174
|
- spec/flipper/adapters/memoizable_spec.rb
|