flipper 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +4 -0
- data/Gemfile +1 -1
- data/docs/Adapters.md +2 -1
- data/examples/enabled_for_actor.rb +43 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +71 -71
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/adapters/instrumented_spec.rb +44 -44
- data/spec/flipper/adapters/memoizable_spec.rb +21 -21
- data/spec/flipper/adapters/memory_spec.rb +1 -1
- data/spec/flipper/adapters/operation_logger_spec.rb +11 -11
- data/spec/flipper/adapters/pstore_spec.rb +2 -2
- data/spec/flipper/dsl_spec.rb +34 -34
- data/spec/flipper/feature_spec.rb +167 -167
- data/spec/flipper/gate_spec.rb +5 -5
- data/spec/flipper/gate_values_spec.rb +17 -17
- data/spec/flipper/gates/actor_spec.rb +1 -1
- data/spec/flipper/gates/boolean_spec.rb +13 -13
- data/spec/flipper/gates/group_spec.rb +6 -6
- data/spec/flipper/gates/percentage_of_actors_spec.rb +3 -3
- data/spec/flipper/gates/percentage_of_time_spec.rb +1 -1
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +10 -10
- data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +14 -14
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +5 -3
- data/spec/flipper/instrumenters/memory_spec.rb +4 -4
- data/spec/flipper/instrumenters/noop_spec.rb +3 -3
- data/spec/flipper/middleware/memoizer_spec.rb +8 -8
- data/spec/flipper/registry_spec.rb +17 -17
- data/spec/flipper/typecast_spec.rb +4 -4
- data/spec/flipper/types/actor_spec.rb +14 -14
- data/spec/flipper/types/boolean_spec.rb +5 -5
- data/spec/flipper/types/group_spec.rb +8 -8
- data/spec/flipper/types/percentage_of_actors_spec.rb +1 -1
- data/spec/flipper/types/percentage_of_time_spec.rb +1 -1
- data/spec/flipper/types/percentage_spec.rb +8 -8
- data/spec/flipper_spec.rb +19 -19
- data/spec/helper.rb +14 -14
- data/spec/integration_spec.rb +80 -80
- metadata +4 -3
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/instrumenters/noop'
|
3
3
|
|
4
|
-
describe Flipper::Instrumenters::Noop do
|
4
|
+
RSpec.describe Flipper::Instrumenters::Noop do
|
5
5
|
describe ".instrument" do
|
6
6
|
context "with name" do
|
7
7
|
it "yields block" do
|
8
8
|
yielded = false
|
9
9
|
described_class.instrument(:foo) { yielded = true }
|
10
|
-
yielded.
|
10
|
+
expect(yielded).to eq(true)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -15,7 +15,7 @@ describe Flipper::Instrumenters::Noop do
|
|
15
15
|
it "yields block" do
|
16
16
|
yielded = false
|
17
17
|
described_class.instrument(:foo, {:pay => :load}) { yielded = true }
|
18
|
-
yielded.
|
18
|
+
expect(yielded).to eq(true)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -4,7 +4,7 @@ require 'flipper/middleware/memoizer'
|
|
4
4
|
require 'flipper/adapters/operation_logger'
|
5
5
|
require 'flipper/adapters/memory'
|
6
6
|
|
7
|
-
describe Flipper::Middleware::Memoizer do
|
7
|
+
RSpec.describe Flipper::Middleware::Memoizer do
|
8
8
|
include Rack::Test::Methods
|
9
9
|
|
10
10
|
let(:memory_adapter) { Flipper::Adapters::Memory.new }
|
@@ -26,7 +26,7 @@ describe Flipper::Middleware::Memoizer do
|
|
26
26
|
}
|
27
27
|
middleware = described_class.new app, flipper
|
28
28
|
middleware.call({})
|
29
|
-
called.
|
29
|
+
expect(called).to eq(true)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "disables local cache after body close" do
|
@@ -34,9 +34,9 @@ describe Flipper::Middleware::Memoizer do
|
|
34
34
|
middleware = described_class.new app, flipper
|
35
35
|
body = middleware.call({}).last
|
36
36
|
|
37
|
-
flipper.adapter.memoizing
|
37
|
+
expect(flipper.adapter.memoizing?).to eq(true)
|
38
38
|
body.close
|
39
|
-
flipper.adapter.memoizing
|
39
|
+
expect(flipper.adapter.memoizing?).to eq(false)
|
40
40
|
end
|
41
41
|
|
42
42
|
it "clears local cache after body close" do
|
@@ -46,19 +46,19 @@ describe Flipper::Middleware::Memoizer do
|
|
46
46
|
|
47
47
|
flipper.adapter.cache['hello'] = 'world'
|
48
48
|
body.close
|
49
|
-
flipper.adapter.cache.
|
49
|
+
expect(flipper.adapter.cache).to be_empty
|
50
50
|
end
|
51
51
|
|
52
52
|
it "clears the local cache with a successful request" do
|
53
53
|
flipper.adapter.cache['hello'] = 'world'
|
54
54
|
get '/'
|
55
|
-
flipper.adapter.cache.
|
55
|
+
expect(flipper.adapter.cache).to be_empty
|
56
56
|
end
|
57
57
|
|
58
58
|
it "clears the local cache even when the request raises an error" do
|
59
59
|
flipper.adapter.cache['hello'] = 'world'
|
60
60
|
get '/fail' rescue nil
|
61
|
-
flipper.adapter.cache.
|
61
|
+
expect(flipper.adapter.cache).to be_empty
|
62
62
|
end
|
63
63
|
|
64
64
|
it "caches getting a feature for duration of request" do
|
@@ -80,7 +80,7 @@ describe Flipper::Middleware::Memoizer do
|
|
80
80
|
middleware = described_class.new app, flipper
|
81
81
|
middleware.call({})
|
82
82
|
|
83
|
-
adapter.count(:get).
|
83
|
+
expect(adapter.count(:get)).to be(1)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/registry'
|
3
3
|
|
4
|
-
describe Flipper::Registry do
|
4
|
+
RSpec.describe Flipper::Registry do
|
5
5
|
subject { Flipper::Registry.new(source) }
|
6
6
|
|
7
7
|
let(:source) { {} }
|
@@ -10,13 +10,13 @@ describe Flipper::Registry do
|
|
10
10
|
it "adds to source" do
|
11
11
|
value = 'thing'
|
12
12
|
subject.add(:admins, value)
|
13
|
-
source[:admins].
|
13
|
+
expect(source[:admins]).to eq(value)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "converts key to symbol" do
|
17
17
|
value = 'thing'
|
18
18
|
subject.add('admins', value)
|
19
|
-
source[:admins].
|
19
|
+
expect(source[:admins]).to eq(value)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "raises exception if key already registered" do
|
@@ -35,11 +35,11 @@ describe Flipper::Registry do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "returns value" do
|
38
|
-
subject.get(:admins).
|
38
|
+
expect(subject.get(:admins)).to eq('thing')
|
39
39
|
end
|
40
40
|
|
41
41
|
it "returns value if given string key" do
|
42
|
-
subject.get('admins').
|
42
|
+
expect(subject.get('admins')).to eq('thing')
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -58,11 +58,11 @@ describe Flipper::Registry do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "returns true if the key exists" do
|
61
|
-
subject.key?(:admins).
|
61
|
+
expect(subject.key?(:admins)).to eq true
|
62
62
|
end
|
63
63
|
|
64
64
|
it "returns false if the key does not exists" do
|
65
|
-
subject.key?(:unknown_key).
|
65
|
+
expect(subject.key?(:unknown_key)).to eq false
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -77,10 +77,10 @@ describe Flipper::Registry do
|
|
77
77
|
subject.each do |key, value|
|
78
78
|
results[key] = value
|
79
79
|
end
|
80
|
-
results.
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
expect(results).to eq({
|
81
|
+
:admins => 'admins',
|
82
|
+
:devs => 'devs',
|
83
|
+
})
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -91,12 +91,12 @@ describe Flipper::Registry do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "returns the keys" do
|
94
|
-
subject.keys.map(&:to_s).sort.
|
94
|
+
expect(subject.keys.map(&:to_s).sort).to eq(['admins', 'devs'])
|
95
95
|
end
|
96
96
|
|
97
97
|
it "returns the keys as symbols" do
|
98
98
|
subject.keys.each do |key|
|
99
|
-
key.
|
99
|
+
expect(key).to be_instance_of(Symbol)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
@@ -108,7 +108,7 @@ describe Flipper::Registry do
|
|
108
108
|
end
|
109
109
|
|
110
110
|
it "returns the values" do
|
111
|
-
subject.values.map(&:to_s).sort.
|
111
|
+
expect(subject.values.map(&:to_s).sort).to eq(['admins', 'devs'])
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -127,8 +127,8 @@ describe Flipper::Registry do
|
|
127
127
|
values << value
|
128
128
|
end
|
129
129
|
|
130
|
-
keys.map(&:to_s).sort.
|
131
|
-
values.sort.
|
130
|
+
expect(keys.map(&:to_s).sort).to eq(['admins', 'devs'])
|
131
|
+
expect(values.sort).to eq(['admins', 'devs'])
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
@@ -139,7 +139,7 @@ describe Flipper::Registry do
|
|
139
139
|
|
140
140
|
it "clears the source" do
|
141
141
|
subject.clear
|
142
|
-
source.
|
142
|
+
expect(source).to be_empty
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/typecast'
|
3
3
|
|
4
|
-
describe Flipper::Typecast do
|
4
|
+
RSpec.describe Flipper::Typecast do
|
5
5
|
{
|
6
6
|
nil => false,
|
7
7
|
"" => false,
|
@@ -16,7 +16,7 @@ describe Flipper::Typecast do
|
|
16
16
|
}.each do |value, expected|
|
17
17
|
context "#to_boolean for #{value.inspect}" do
|
18
18
|
it "returns #{expected}" do
|
19
|
-
described_class.to_boolean(value).
|
19
|
+
expect(described_class.to_boolean(value)).to be(expected)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -31,7 +31,7 @@ describe Flipper::Typecast do
|
|
31
31
|
}.each do |value, expected|
|
32
32
|
context "#to_integer for #{value.inspect}" do
|
33
33
|
it "returns #{expected}" do
|
34
|
-
described_class.to_integer(value).
|
34
|
+
expect(described_class.to_integer(value)).to be(expected)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -44,7 +44,7 @@ describe Flipper::Typecast do
|
|
44
44
|
}.each do |value, expected|
|
45
45
|
context "#to_set for #{value.inspect}" do
|
46
46
|
it "returns #{expected}" do
|
47
|
-
described_class.to_set(value).
|
47
|
+
expect(described_class.to_set(value)).to eq(expected)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/types/actor'
|
3
3
|
|
4
|
-
describe Flipper::Types::Actor do
|
4
|
+
RSpec.describe Flipper::Types::Actor do
|
5
5
|
subject {
|
6
6
|
thing = thing_class.new('2')
|
7
7
|
described_class.new(thing)
|
@@ -25,16 +25,16 @@ describe Flipper::Types::Actor do
|
|
25
25
|
it "returns true if actor" do
|
26
26
|
thing = thing_class.new('1')
|
27
27
|
actor = described_class.new(thing)
|
28
|
-
described_class.wrappable?(actor).
|
28
|
+
expect(described_class.wrappable?(actor)).to eq(true)
|
29
29
|
end
|
30
30
|
|
31
31
|
it "returns true if responds to flipper_id" do
|
32
32
|
thing = thing_class.new(10)
|
33
|
-
described_class.wrappable?(thing).
|
33
|
+
expect(described_class.wrappable?(thing)).to eq(true)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "returns false if nil" do
|
37
|
-
described_class.wrappable?(nil).
|
37
|
+
expect(described_class.wrappable?(nil)).to be(false)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -42,8 +42,8 @@ describe Flipper::Types::Actor do
|
|
42
42
|
context "for actor" do
|
43
43
|
it "returns actor" do
|
44
44
|
actor = described_class.wrap(subject)
|
45
|
-
actor.
|
46
|
-
actor.
|
45
|
+
expect(actor).to be_instance_of(described_class)
|
46
|
+
expect(actor).to be(subject)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,7 +51,7 @@ describe Flipper::Types::Actor do
|
|
51
51
|
it "returns actor" do
|
52
52
|
thing = thing_class.new('1')
|
53
53
|
actor = described_class.wrap(thing)
|
54
|
-
actor.
|
54
|
+
expect(actor).to be_instance_of(described_class)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -59,7 +59,7 @@ describe Flipper::Types::Actor do
|
|
59
59
|
it "initializes with thing that responds to id" do
|
60
60
|
thing = thing_class.new('1')
|
61
61
|
actor = described_class.new(thing)
|
62
|
-
actor.value.
|
62
|
+
expect(actor.value).to eq('1')
|
63
63
|
end
|
64
64
|
|
65
65
|
it "raises error when initialized with nil" do
|
@@ -78,38 +78,38 @@ describe Flipper::Types::Actor do
|
|
78
78
|
it "converts id to string" do
|
79
79
|
thing = thing_class.new(2)
|
80
80
|
actor = described_class.new(thing)
|
81
|
-
actor.value.
|
81
|
+
expect(actor.value).to eq('2')
|
82
82
|
end
|
83
83
|
|
84
84
|
it "proxies everything to thing" do
|
85
85
|
thing = thing_class.new(10)
|
86
86
|
actor = described_class.new(thing)
|
87
|
-
actor.admin
|
87
|
+
expect(actor.admin?).to eq(true)
|
88
88
|
end
|
89
89
|
|
90
90
|
it "exposes thing" do
|
91
91
|
thing = thing_class.new(10)
|
92
92
|
actor = described_class.new(thing)
|
93
|
-
actor.thing.
|
93
|
+
expect(actor.thing).to be(thing)
|
94
94
|
end
|
95
95
|
|
96
96
|
describe "#respond_to?" do
|
97
97
|
it "returns true if responds to method" do
|
98
98
|
thing = thing_class.new('1')
|
99
99
|
actor = described_class.new(thing)
|
100
|
-
actor.respond_to?(:value).
|
100
|
+
expect(actor.respond_to?(:value)).to eq(true)
|
101
101
|
end
|
102
102
|
|
103
103
|
it "returns true if thing responds to method" do
|
104
104
|
thing = thing_class.new(10)
|
105
105
|
actor = described_class.new(thing)
|
106
|
-
actor.respond_to?(:admin?).
|
106
|
+
expect(actor.respond_to?(:admin?)).to eq(true)
|
107
107
|
end
|
108
108
|
|
109
109
|
it "returns false if does not respond to method and thing does not respond to method" do
|
110
110
|
thing = thing_class.new(10)
|
111
111
|
actor = described_class.new(thing)
|
112
|
-
actor.respond_to?(:frankenstein).
|
112
|
+
expect(actor.respond_to?(:frankenstein)).to eq(false)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
@@ -1,24 +1,24 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/types/boolean'
|
3
3
|
|
4
|
-
describe Flipper::Types::Boolean do
|
4
|
+
RSpec.describe Flipper::Types::Boolean do
|
5
5
|
it "defaults value to true" do
|
6
6
|
boolean = Flipper::Types::Boolean.new
|
7
|
-
boolean.value.
|
7
|
+
expect(boolean.value).to be(true)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "allows overriding default value" do
|
11
11
|
boolean = Flipper::Types::Boolean.new(false)
|
12
|
-
boolean.value.
|
12
|
+
expect(boolean.value).to be(false)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "returns true for nil value" do
|
16
16
|
boolean = Flipper::Types::Boolean.new(nil)
|
17
|
-
boolean.value.
|
17
|
+
expect(boolean.value).to be(true)
|
18
18
|
end
|
19
19
|
|
20
20
|
it "typecasts value" do
|
21
21
|
boolean = Flipper::Types::Boolean.new(1)
|
22
|
-
boolean.value.
|
22
|
+
expect(boolean.value).to be(true)
|
23
23
|
end
|
24
24
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/types/group'
|
3
3
|
|
4
|
-
describe Flipper::Types::Group do
|
4
|
+
RSpec.describe Flipper::Types::Group do
|
5
5
|
subject do
|
6
6
|
Flipper.register(:admins) { |actor| actor.admin? }
|
7
7
|
end
|
@@ -9,31 +9,31 @@ describe Flipper::Types::Group do
|
|
9
9
|
describe ".wrap" do
|
10
10
|
context "with group instance" do
|
11
11
|
it "returns group instance" do
|
12
|
-
described_class.wrap(subject).
|
12
|
+
expect(described_class.wrap(subject)).to eq(subject)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
context "with Symbol group name" do
|
17
17
|
it "returns group instance" do
|
18
|
-
described_class.wrap(subject.name).
|
18
|
+
expect(described_class.wrap(subject.name)).to eq(subject)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
context "with String group name" do
|
23
23
|
it "returns group instance" do
|
24
|
-
described_class.wrap(subject.name.to_s).
|
24
|
+
expect(described_class.wrap(subject.name.to_s)).to eq(subject)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
it "initializes with name" do
|
30
30
|
group = Flipper::Types::Group.new(:admins)
|
31
|
-
group.
|
31
|
+
expect(group).to be_instance_of(Flipper::Types::Group)
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "#name" do
|
35
35
|
it "returns name" do
|
36
|
-
subject.name.
|
36
|
+
expect(subject.name).to eq(:admins)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -42,11 +42,11 @@ describe Flipper::Types::Group do
|
|
42
42
|
let(:non_admin_actor) { double('Actor', :admin? => false) }
|
43
43
|
|
44
44
|
it "returns true if block matches" do
|
45
|
-
subject.match?(admin_actor).
|
45
|
+
expect(subject.match?(admin_actor)).to eq(true)
|
46
46
|
end
|
47
47
|
|
48
48
|
it "returns false if block does not match" do
|
49
|
-
subject.match?(non_admin_actor).
|
49
|
+
expect(subject.match?(non_admin_actor)).to eq(false)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/types/percentage_of_actors'
|
3
3
|
|
4
|
-
describe Flipper::Types::Percentage do
|
4
|
+
RSpec.describe Flipper::Types::Percentage do
|
5
5
|
subject {
|
6
6
|
described_class.new(5)
|
7
7
|
}
|
@@ -10,38 +10,38 @@ describe Flipper::Types::Percentage do
|
|
10
10
|
describe ".wrap" do
|
11
11
|
context "with percentage instance" do
|
12
12
|
it "returns percentage instance" do
|
13
|
-
described_class.wrap(subject).
|
13
|
+
expect(described_class.wrap(subject)).to eq(subject)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
context "with Integer" do
|
18
18
|
it "returns percentage instance" do
|
19
|
-
described_class.wrap(subject.value).
|
19
|
+
expect(described_class.wrap(subject.value)).to eq(subject)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
context "with String" do
|
24
24
|
it "returns percentage instance" do
|
25
|
-
described_class.wrap(subject.value.to_s).
|
25
|
+
expect(described_class.wrap(subject.value.to_s)).to eq(subject)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
describe "#eql?" do
|
31
31
|
it "returns true for same class and value" do
|
32
|
-
subject.eql?(described_class.new(subject.value)).
|
32
|
+
expect(subject.eql?(described_class.new(subject.value))).to eq(true)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns false for different value" do
|
36
|
-
subject.eql?(described_class.new(subject.value + 1)).
|
36
|
+
expect(subject.eql?(described_class.new(subject.value + 1))).to eq(false)
|
37
37
|
end
|
38
38
|
|
39
39
|
it "returns false for different class" do
|
40
|
-
subject.eql?(Object.new).
|
40
|
+
expect(subject.eql?(Object.new)).to eq(false)
|
41
41
|
end
|
42
42
|
|
43
43
|
it "is aliased to ==" do
|
44
|
-
(subject == described_class.new(subject.value)).
|
44
|
+
expect((subject == described_class.new(subject.value))).to eq(true)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|