flipper 0.27.1 → 0.28.0
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/Changelog.md +20 -0
- data/Rakefile +3 -3
- data/benchmark/enabled_multiple_actors_ips.rb +20 -0
- data/examples/dsl.rb +3 -3
- data/examples/enabled_for_actor.rb +4 -2
- data/lib/flipper/dsl.rb +4 -4
- data/lib/flipper/errors.rb +3 -3
- data/lib/flipper/feature.rb +12 -10
- data/lib/flipper/feature_check_context.rb +8 -4
- data/lib/flipper/gate.rb +12 -11
- data/lib/flipper/gates/actor.rb +11 -8
- data/lib/flipper/gates/group.rb +4 -2
- data/lib/flipper/gates/percentage_of_actors.rb +4 -5
- data/lib/flipper/identifier.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +7 -3
- data/lib/flipper/instrumentation/subscriber.rb +0 -1
- data/lib/flipper/types/actor.rb +13 -13
- data/lib/flipper/types/group.rb +4 -4
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +3 -3
- data/spec/flipper/dsl_spec.rb +5 -5
- data/spec/flipper/feature_check_context_spec.rb +5 -5
- data/spec/flipper/feature_spec.rb +76 -32
- data/spec/flipper/gates/boolean_spec.rb +1 -1
- data/spec/flipper/gates/group_spec.rb +2 -3
- data/spec/flipper/gates/percentage_of_actors_spec.rb +61 -5
- data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +5 -5
- data/spec/flipper/types/actor_spec.rb +45 -45
- data/spec/flipper/types/group_spec.rb +2 -2
- data/spec/flipper_integration_spec.rb +62 -50
- metadata +3 -2
@@ -32,6 +32,52 @@ RSpec.describe Flipper::Feature do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
describe "#enabled?" do
|
36
|
+
context "for an actor" do
|
37
|
+
let(:actor) { Flipper::Actor.new("User;1") }
|
38
|
+
|
39
|
+
it 'returns true if feature is enabled' do
|
40
|
+
subject.enable
|
41
|
+
expect(subject.enabled?(actor)).to be(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns false if feature is disabled' do
|
45
|
+
subject.disable
|
46
|
+
expect(subject.enabled?(actor)).to be(false)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "for multiple actors" do
|
51
|
+
let(:actors) {
|
52
|
+
[
|
53
|
+
Flipper::Actor.new("User;1"),
|
54
|
+
Flipper::Actor.new("User;2"),
|
55
|
+
Flipper::Actor.new("User;3"),
|
56
|
+
]
|
57
|
+
}
|
58
|
+
|
59
|
+
it 'returns true if feature is enabled' do
|
60
|
+
subject.enable
|
61
|
+
expect(subject.enabled?(actors)).to be(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns true if feature is enabled for any actor' do
|
65
|
+
subject.enable_actor actors.first
|
66
|
+
expect(subject.enabled?(actors)).to be(true)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns true if feature is enabled for any actor with multiple arguments' do
|
70
|
+
subject.enable_actor actors.last
|
71
|
+
expect(subject.enabled?(*actors)).to be(true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns false if feature is disabled for all actors' do
|
75
|
+
subject.disable
|
76
|
+
expect(subject.enabled?(actors)).to be(false)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
35
81
|
describe '#to_s' do
|
36
82
|
it 'returns name as string' do
|
37
83
|
feature = described_class.new(:search, adapter)
|
@@ -148,29 +194,29 @@ RSpec.describe Flipper::Feature do
|
|
148
194
|
end
|
149
195
|
|
150
196
|
it 'is recorded for enable' do
|
151
|
-
|
152
|
-
gate = subject.gate_for(
|
197
|
+
actor = Flipper::Types::Actor.new(Flipper::Actor.new('1'))
|
198
|
+
gate = subject.gate_for(actor)
|
153
199
|
|
154
|
-
subject.enable(
|
200
|
+
subject.enable(actor)
|
155
201
|
|
156
202
|
event = instrumenter.events.last
|
157
203
|
expect(event).not_to be_nil
|
158
204
|
expect(event.name).to eq('feature_operation.flipper')
|
159
205
|
expect(event.payload[:feature_name]).to eq(:search)
|
160
206
|
expect(event.payload[:operation]).to eq(:enable)
|
161
|
-
expect(event.payload[:thing]).to eq(
|
207
|
+
expect(event.payload[:thing]).to eq(actor)
|
162
208
|
expect(event.payload[:result]).not_to be_nil
|
163
209
|
end
|
164
210
|
|
165
211
|
it 'always instruments flipper type instance for enable' do
|
166
|
-
|
167
|
-
gate = subject.gate_for(
|
212
|
+
actor = Flipper::Actor.new('1')
|
213
|
+
gate = subject.gate_for(actor)
|
168
214
|
|
169
|
-
subject.enable(
|
215
|
+
subject.enable(actor)
|
170
216
|
|
171
217
|
event = instrumenter.events.last
|
172
218
|
expect(event).not_to be_nil
|
173
|
-
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(
|
219
|
+
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(actor))
|
174
220
|
end
|
175
221
|
|
176
222
|
it 'is recorded for disable' do
|
@@ -219,15 +265,15 @@ RSpec.describe Flipper::Feature do
|
|
219
265
|
end
|
220
266
|
|
221
267
|
it 'always instruments flipper type instance for disable' do
|
222
|
-
|
223
|
-
gate = subject.gate_for(
|
268
|
+
actor = Flipper::Actor.new('1')
|
269
|
+
gate = subject.gate_for(actor)
|
224
270
|
|
225
|
-
subject.disable(
|
271
|
+
subject.disable(actor)
|
226
272
|
|
227
273
|
event = instrumenter.events.last
|
228
274
|
expect(event).not_to be_nil
|
229
275
|
expect(event.payload[:operation]).to eq(:disable)
|
230
|
-
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(
|
276
|
+
expect(event.payload[:thing]).to eq(Flipper::Types::Actor.new(actor))
|
231
277
|
end
|
232
278
|
|
233
279
|
it 'is recorded for add' do
|
@@ -275,17 +321,15 @@ RSpec.describe Flipper::Feature do
|
|
275
321
|
end
|
276
322
|
|
277
323
|
it 'is recorded for enabled?' do
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
subject.enabled?(thing)
|
324
|
+
actor = Flipper::Types::Actor.new(Flipper::Actor.new('1'))
|
325
|
+
subject.enabled?(actor)
|
282
326
|
|
283
327
|
event = instrumenter.events.last
|
284
328
|
expect(event).not_to be_nil
|
285
329
|
expect(event.name).to eq('feature_operation.flipper')
|
286
330
|
expect(event.payload[:feature_name]).to eq(:search)
|
287
331
|
expect(event.payload[:operation]).to eq(:enabled?)
|
288
|
-
expect(event.payload[:
|
332
|
+
expect(event.payload[:actors]).to eq([actor])
|
289
333
|
expect(event.payload[:result]).to eq(false)
|
290
334
|
end
|
291
335
|
|
@@ -293,8 +337,8 @@ RSpec.describe Flipper::Feature do
|
|
293
337
|
actor = Flipper::Types::Actor.new(user)
|
294
338
|
{
|
295
339
|
nil => nil,
|
296
|
-
user => actor,
|
297
|
-
actor => actor,
|
340
|
+
user => [actor],
|
341
|
+
actor => [actor],
|
298
342
|
}.each do |thing, wrapped_thing|
|
299
343
|
it "always instruments #{thing.inspect} as #{wrapped_thing.class} for enabled?" do
|
300
344
|
subject.enabled?(thing)
|
@@ -302,7 +346,7 @@ RSpec.describe Flipper::Feature do
|
|
302
346
|
event = instrumenter.events.last
|
303
347
|
expect(event).not_to be_nil
|
304
348
|
expect(event.payload[:operation]).to eq(:enabled?)
|
305
|
-
expect(event.payload[:
|
349
|
+
expect(event.payload[:actors]).to eq(wrapped_thing)
|
306
350
|
end
|
307
351
|
end
|
308
352
|
end
|
@@ -428,10 +472,10 @@ RSpec.describe Flipper::Feature do
|
|
428
472
|
|
429
473
|
context 'when one or more groups enabled' do
|
430
474
|
before do
|
431
|
-
@staff = Flipper.register(:staff) { |
|
432
|
-
@preview_features = Flipper.register(:preview_features) { |
|
433
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
434
|
-
@disabled = Flipper.register(:disabled) { |
|
475
|
+
@staff = Flipper.register(:staff) { |actor| true }
|
476
|
+
@preview_features = Flipper.register(:preview_features) { |actor| true }
|
477
|
+
@not_enabled = Flipper.register(:not_enabled) { |actor| true }
|
478
|
+
@disabled = Flipper.register(:disabled) { |actor| true }
|
435
479
|
subject.enable @staff
|
436
480
|
subject.enable @preview_features
|
437
481
|
subject.disable @disabled
|
@@ -467,10 +511,10 @@ RSpec.describe Flipper::Feature do
|
|
467
511
|
|
468
512
|
context 'when one or more groups enabled' do
|
469
513
|
before do
|
470
|
-
@staff = Flipper.register(:staff) { |
|
471
|
-
@preview_features = Flipper.register(:preview_features) { |
|
472
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
473
|
-
@disabled = Flipper.register(:disabled) { |
|
514
|
+
@staff = Flipper.register(:staff) { |actor| true }
|
515
|
+
@preview_features = Flipper.register(:preview_features) { |actor| true }
|
516
|
+
@not_enabled = Flipper.register(:not_enabled) { |actor| true }
|
517
|
+
@disabled = Flipper.register(:disabled) { |actor| true }
|
474
518
|
subject.enable @staff
|
475
519
|
subject.enable @preview_features
|
476
520
|
subject.disable @disabled
|
@@ -494,10 +538,10 @@ RSpec.describe Flipper::Feature do
|
|
494
538
|
|
495
539
|
context 'when one or more groups enabled' do
|
496
540
|
before do
|
497
|
-
@staff = Flipper.register(:staff) { |
|
498
|
-
@preview_features = Flipper.register(:preview_features) { |
|
499
|
-
@not_enabled = Flipper.register(:not_enabled) { |
|
500
|
-
@disabled = Flipper.register(:disabled) { |
|
541
|
+
@staff = Flipper.register(:staff) { |actor| true }
|
542
|
+
@preview_features = Flipper.register(:preview_features) { |actor| true }
|
543
|
+
@not_enabled = Flipper.register(:not_enabled) { |actor| true }
|
544
|
+
@disabled = Flipper.register(:disabled) { |actor| true }
|
501
545
|
subject.enable @staff
|
502
546
|
subject.enable @preview_features
|
503
547
|
subject.disable @disabled
|
@@ -9,7 +9,7 @@ RSpec.describe Flipper::Gates::Boolean do
|
|
9
9
|
Flipper::FeatureCheckContext.new(
|
10
10
|
feature_name: feature_name,
|
11
11
|
values: Flipper::GateValues.new(boolean: bool),
|
12
|
-
|
12
|
+
actors: [Flipper::Types::Actor.new(Flipper::Actor.new('1'))]
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
@@ -9,18 +9,17 @@ RSpec.describe Flipper::Gates::Group do
|
|
9
9
|
Flipper::FeatureCheckContext.new(
|
10
10
|
feature_name: feature_name,
|
11
11
|
values: Flipper::GateValues.new(groups: set),
|
12
|
-
|
12
|
+
actors: [Flipper::Types::Actor.new(Flipper::Actor.new('5'))]
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
16
16
|
describe '#open?' do
|
17
17
|
context 'with a group in adapter, but not registered' do
|
18
18
|
before do
|
19
|
-
Flipper.register(:staff) { |
|
19
|
+
Flipper.register(:staff) { |actor| true }
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'ignores group' do
|
23
|
-
thing = Flipper::Actor.new('5')
|
24
23
|
expect(subject.open?(context(Set[:newbs, :staff]))).to be(true)
|
25
24
|
end
|
26
25
|
end
|
@@ -5,11 +5,11 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
5
5
|
described_class.new
|
6
6
|
end
|
7
7
|
|
8
|
-
def context(percentage_of_actors_value, feature = feature_name,
|
8
|
+
def context(percentage_of_actors_value, feature = feature_name, actors = nil)
|
9
9
|
Flipper::FeatureCheckContext.new(
|
10
10
|
feature_name: feature,
|
11
11
|
values: Flipper::GateValues.new(percentage_of_actors: percentage_of_actors_value),
|
12
|
-
|
12
|
+
actors: Array(actors) || [Flipper::Types::Actor.new(Flipper::Actor.new('1'))]
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
@@ -20,7 +20,7 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
20
20
|
let(:number_of_actors) { 10_000 }
|
21
21
|
|
22
22
|
let(:actors) do
|
23
|
-
(1..number_of_actors).map { |n| Flipper::Actor.new(n) }
|
23
|
+
(1..number_of_actors).map { |n| Flipper::Types::Actor.new(Flipper::Actor.new(n.to_s)) }
|
24
24
|
end
|
25
25
|
|
26
26
|
let(:feature_one_enabled_actors) do
|
@@ -48,13 +48,69 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
context "with an array of actors" do
|
52
|
+
let(:percentage) { 0.05 }
|
53
|
+
let(:percentage_as_integer) { percentage * 100 }
|
54
|
+
let(:number_of_actors) { 3_000 }
|
55
|
+
|
56
|
+
let(:user_actors) do
|
57
|
+
(1..number_of_actors).map { |n| Flipper::Types::Actor.new(Flipper::Actor.new("User;#{n}")) }
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:team_actors) do
|
61
|
+
(1..number_of_actors).map { |n| Flipper::Types::Actor.new(Flipper::Actor.new("Team;#{n}")) }
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:org_actors) do
|
65
|
+
(1..number_of_actors).map { |n| Flipper::Types::Actor.new(Flipper::Actor.new("Org;#{n}")) }
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:actors) { user_actors + team_actors + org_actors }
|
69
|
+
|
70
|
+
let(:feature_one_enabled_actors) do
|
71
|
+
actors.each_slice(3).select do |group|
|
72
|
+
context = context(percentage_as_integer, :name_one, group)
|
73
|
+
subject.open?(context)
|
74
|
+
end.flatten
|
75
|
+
end
|
76
|
+
|
77
|
+
let(:feature_two_enabled_actors) do
|
78
|
+
actors.each_slice(3).select do |group|
|
79
|
+
context = context(percentage_as_integer, :name_two, group)
|
80
|
+
subject.open?(context)
|
81
|
+
end.flatten
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not enable both features for same set of actors' do
|
85
|
+
expect(feature_one_enabled_actors).not_to eq(feature_two_enabled_actors)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'enables feature for accurate number of actors for each feature' do
|
89
|
+
margin_of_error = 0.02 * actors.size # 2 percent margin of error
|
90
|
+
expected_enabled_size = actors.size * percentage
|
91
|
+
|
92
|
+
[
|
93
|
+
feature_one_enabled_actors.size,
|
94
|
+
feature_two_enabled_actors.size,
|
95
|
+
].each do |size|
|
96
|
+
expect(size).to be_within(margin_of_error).of(expected_enabled_size)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is consistent regardless of order of actors" do
|
101
|
+
actors = user_actors.first(10)
|
102
|
+
results = 100.times.map { |n| subject.open?(context(75, :some_feature, actors.shuffle)) }
|
103
|
+
expect(results.uniq).to eq([true])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
51
107
|
context 'for fractional percentage' do
|
52
108
|
let(:decimal) { 0.001 }
|
53
109
|
let(:percentage) { decimal * 100 }
|
54
110
|
let(:number_of_actors) { 10_000 }
|
55
111
|
|
56
112
|
let(:actors) do
|
57
|
-
(1..number_of_actors).map { |n| Flipper::Actor.new(n) }
|
113
|
+
(1..number_of_actors).map { |n| Flipper::Types::Actor.new(Flipper::Actor.new(n.to_s)) }
|
58
114
|
end
|
59
115
|
|
60
116
|
subject { described_class.new }
|
@@ -64,7 +120,7 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
64
120
|
expected_open_count = number_of_actors * decimal
|
65
121
|
|
66
122
|
open_count = actors.select do |actor|
|
67
|
-
context = context(percentage, :feature, actor)
|
123
|
+
context = context(percentage, :feature, [actor])
|
68
124
|
subject.open?(context)
|
69
125
|
end.size
|
70
126
|
|
@@ -5,11 +5,11 @@ RSpec.describe Flipper::Gates::PercentageOfTime do
|
|
5
5
|
described_class.new
|
6
6
|
end
|
7
7
|
|
8
|
-
def context(percentage_of_time_value, feature = feature_name,
|
8
|
+
def context(percentage_of_time_value, feature = feature_name, actors = nil)
|
9
9
|
Flipper::FeatureCheckContext.new(
|
10
10
|
feature_name: feature,
|
11
11
|
values: Flipper::GateValues.new(percentage_of_time: percentage_of_time_value),
|
12
|
-
|
12
|
+
actors: Array(actors) || [Flipper::Types::Actor.new(Flipper::Actor.new('1'))]
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
@@ -18,8 +18,8 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
before do
|
21
|
-
Flipper.register(:admins) do |
|
22
|
-
|
21
|
+
Flipper.register(:admins) do |actor|
|
22
|
+
actor.respond_to?(:admin?) && actor.admin?
|
23
23
|
end
|
24
24
|
|
25
25
|
@io = StringIO.new
|
@@ -46,7 +46,7 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
46
46
|
|
47
47
|
it 'logs feature calls with result after operation' do
|
48
48
|
feature_line = find_line('Flipper feature(search) enabled? false')
|
49
|
-
expect(feature_line).to include('[
|
49
|
+
expect(feature_line).to include('[ actors=nil ]')
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'logs adapter calls' do
|
@@ -56,7 +56,7 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
context 'feature enabled checks with
|
59
|
+
context 'feature enabled checks with an actor' do
|
60
60
|
let(:user) { Flipper::Types::Actor.new(Flipper::Actor.new('1')) }
|
61
61
|
|
62
62
|
before do
|
@@ -64,7 +64,7 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
64
64
|
flipper[:search].enabled?(user)
|
65
65
|
end
|
66
66
|
|
67
|
-
it 'logs
|
67
|
+
it 'logs actors for feature' do
|
68
68
|
feature_line = find_line('Flipper feature(search) enabled?')
|
69
69
|
expect(feature_line).to include(user.inspect)
|
70
70
|
end
|
@@ -2,11 +2,11 @@ require 'flipper/types/actor'
|
|
2
2
|
|
3
3
|
RSpec.describe Flipper::Types::Actor do
|
4
4
|
subject do
|
5
|
-
|
6
|
-
described_class.new(
|
5
|
+
actor = actor_class.new('2')
|
6
|
+
described_class.new(actor)
|
7
7
|
end
|
8
8
|
|
9
|
-
let(:
|
9
|
+
let(:actor_class) do
|
10
10
|
Class.new do
|
11
11
|
attr_reader :flipper_id
|
12
12
|
|
@@ -22,14 +22,14 @@ RSpec.describe Flipper::Types::Actor do
|
|
22
22
|
|
23
23
|
describe '.wrappable?' do
|
24
24
|
it 'returns true if actor' do
|
25
|
-
|
26
|
-
|
27
|
-
expect(described_class.wrappable?(
|
25
|
+
actor = actor_class.new('1')
|
26
|
+
actor_type_instance = described_class.new(actor)
|
27
|
+
expect(described_class.wrappable?(actor_type_instance)).to eq(true)
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'returns true if responds to flipper_id' do
|
31
|
-
|
32
|
-
expect(described_class.wrappable?(
|
31
|
+
actor = actor_class.new(10)
|
32
|
+
expect(described_class.wrappable?(actor)).to eq(true)
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'returns false if nil' do
|
@@ -38,27 +38,27 @@ RSpec.describe Flipper::Types::Actor do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
describe '.wrap' do
|
41
|
-
context 'for actor' do
|
42
|
-
it 'returns actor' do
|
43
|
-
|
44
|
-
expect(
|
45
|
-
expect(
|
41
|
+
context 'for actor type instance' do
|
42
|
+
it 'returns actor type instance' do
|
43
|
+
actor_type_instance = described_class.wrap(subject)
|
44
|
+
expect(actor_type_instance).to be_instance_of(described_class)
|
45
|
+
expect(actor_type_instance).to be(subject)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
context 'for other
|
50
|
-
it 'returns actor' do
|
51
|
-
|
52
|
-
|
53
|
-
expect(
|
49
|
+
context 'for other object' do
|
50
|
+
it 'returns actor type instance' do
|
51
|
+
actor = actor_class.new('1')
|
52
|
+
actor_type_instance = described_class.wrap(actor)
|
53
|
+
expect(actor_type_instance).to be_instance_of(described_class)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
it 'initializes with
|
59
|
-
|
60
|
-
|
61
|
-
expect(
|
58
|
+
it 'initializes with object that responds to flipper_id' do
|
59
|
+
actor = actor_class.new('1')
|
60
|
+
actor_type_instance = described_class.new(actor)
|
61
|
+
expect(actor_type_instance.value).to eq('1')
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'raises error when initialized with nil' do
|
@@ -68,48 +68,48 @@ RSpec.describe Flipper::Types::Actor do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'raises error when initalized with non-wrappable object' do
|
71
|
-
|
71
|
+
unwrappable_object = Struct.new(:id).new(1)
|
72
72
|
expect do
|
73
|
-
described_class.new(
|
73
|
+
described_class.new(unwrappable_object)
|
74
74
|
end.to raise_error(ArgumentError,
|
75
|
-
"#{
|
75
|
+
"#{unwrappable_object.inspect} must respond to flipper_id, but does not")
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'converts id to string' do
|
79
|
-
|
80
|
-
actor = described_class.new(
|
79
|
+
actor = actor_class.new(2)
|
80
|
+
actor = described_class.new(actor)
|
81
81
|
expect(actor.value).to eq('2')
|
82
82
|
end
|
83
83
|
|
84
|
-
it 'proxies everything to
|
85
|
-
|
86
|
-
actor = described_class.new(
|
84
|
+
it 'proxies everything to actor' do
|
85
|
+
actor = actor_class.new(10)
|
86
|
+
actor = described_class.new(actor)
|
87
87
|
expect(actor.admin?).to eq(true)
|
88
88
|
end
|
89
89
|
|
90
|
-
it 'exposes
|
91
|
-
|
92
|
-
|
93
|
-
expect(actor
|
90
|
+
it 'exposes actor' do
|
91
|
+
actor = actor_class.new(10)
|
92
|
+
actor_type_instance = described_class.new(actor)
|
93
|
+
expect(actor_type_instance.actor).to be(actor)
|
94
94
|
end
|
95
95
|
|
96
96
|
describe '#respond_to?' do
|
97
97
|
it 'returns true if responds to method' do
|
98
|
-
|
99
|
-
|
100
|
-
expect(
|
98
|
+
actor = actor_class.new('1')
|
99
|
+
actor_type_instance = described_class.new(actor)
|
100
|
+
expect(actor_type_instance.respond_to?(:value)).to eq(true)
|
101
101
|
end
|
102
102
|
|
103
|
-
it 'returns true if
|
104
|
-
|
105
|
-
|
106
|
-
expect(
|
103
|
+
it 'returns true if actor responds to method' do
|
104
|
+
actor = actor_class.new(10)
|
105
|
+
actor_type_instance = described_class.new(actor)
|
106
|
+
expect(actor_type_instance.respond_to?(:admin?)).to eq(true)
|
107
107
|
end
|
108
108
|
|
109
|
-
it 'returns false if does not respond to method and
|
110
|
-
|
111
|
-
|
112
|
-
expect(
|
109
|
+
it 'returns false if does not respond to method and actor does not respond to method' do
|
110
|
+
actor = actor_class.new(10)
|
111
|
+
actor_type_instance = described_class.new(actor)
|
112
|
+
expect(actor_type_instance.respond_to?(:frankenstein)).to eq(false)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
@@ -90,7 +90,7 @@ RSpec.describe Flipper::Types::Group do
|
|
90
90
|
context = Flipper::FeatureCheckContext.new(
|
91
91
|
feature_name: :my_feature,
|
92
92
|
values: Flipper::GateValues.new({}),
|
93
|
-
|
93
|
+
actors: [Flipper::Types::Actor.new(Flipper::Actor.new('1'))]
|
94
94
|
)
|
95
95
|
group = Flipper.register(:group_with_context) { |actor| actor }
|
96
96
|
yielded_actor = group.match?(admin_actor, context)
|
@@ -101,7 +101,7 @@ RSpec.describe Flipper::Types::Group do
|
|
101
101
|
context = Flipper::FeatureCheckContext.new(
|
102
102
|
feature_name: :my_feature,
|
103
103
|
values: Flipper::GateValues.new({}),
|
104
|
-
|
104
|
+
actors: [Flipper::Types::Actor.new(Flipper::Actor.new('1'))]
|
105
105
|
)
|
106
106
|
group = Flipper.register(:group_with_context) { |actor, context| [actor, context] }
|
107
107
|
yielded_actor, yielded_context = group.match?(admin_actor, context)
|