flipper 0.10.2 → 0.11.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +42 -0
- data/.rubocop_todo.yml +188 -0
- data/Changelog.md +10 -0
- data/Gemfile +6 -3
- data/README.md +4 -3
- data/Rakefile +13 -13
- data/docs/Adapters.md +2 -1
- data/docs/DockerCompose.md +6 -3
- data/docs/Gates.md +25 -3
- data/docs/Optimization.md +27 -5
- data/docs/api/README.md +73 -32
- data/docs/http/README.md +34 -0
- data/docs/read-only/README.md +22 -0
- data/examples/percentage_of_actors_group.rb +49 -0
- data/flipper.gemspec +15 -15
- data/lib/flipper.rb +2 -5
- data/lib/flipper/adapter.rb +10 -0
- data/lib/flipper/adapters/http.rb +147 -0
- data/lib/flipper/adapters/http/client.rb +83 -0
- data/lib/flipper/adapters/http/error.rb +14 -0
- data/lib/flipper/adapters/instrumented.rb +36 -36
- data/lib/flipper/adapters/memoizable.rb +2 -6
- data/lib/flipper/adapters/memory.rb +10 -9
- data/lib/flipper/adapters/operation_logger.rb +1 -1
- data/lib/flipper/adapters/pstore.rb +12 -11
- data/lib/flipper/adapters/read_only.rb +6 -6
- data/lib/flipper/dsl.rb +1 -3
- data/lib/flipper/feature.rb +11 -16
- data/lib/flipper/gate.rb +3 -3
- data/lib/flipper/gate_values.rb +6 -6
- data/lib/flipper/gates/group.rb +2 -2
- data/lib/flipper/gates/percentage_of_actors.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +2 -4
- data/lib/flipper/instrumentation/metriks.rb +1 -1
- data/lib/flipper/instrumentation/statsd.rb +1 -1
- data/lib/flipper/instrumentation/statsd_subscriber.rb +1 -3
- data/lib/flipper/instrumentation/subscriber.rb +11 -10
- data/lib/flipper/instrumenters/memory.rb +1 -5
- data/lib/flipper/instrumenters/noop.rb +1 -1
- data/lib/flipper/middleware/memoizer.rb +11 -27
- data/lib/flipper/middleware/setup_env.rb +44 -0
- data/lib/flipper/registry.rb +8 -10
- data/lib/flipper/spec/shared_adapter_specs.rb +45 -67
- data/lib/flipper/test/shared_adapter_test.rb +25 -31
- data/lib/flipper/typecast.rb +2 -2
- data/lib/flipper/types/actor.rb +2 -4
- data/lib/flipper/types/group.rb +1 -1
- data/lib/flipper/types/percentage.rb +2 -1
- data/lib/flipper/version.rb +1 -1
- data/spec/fixtures/feature.json +31 -0
- data/spec/flipper/adapters/http_spec.rb +148 -0
- data/spec/flipper/adapters/instrumented_spec.rb +20 -20
- data/spec/flipper/adapters/memoizable_spec.rb +59 -59
- data/spec/flipper/adapters/operation_logger_spec.rb +16 -16
- data/spec/flipper/adapters/pstore_spec.rb +6 -6
- data/spec/flipper/adapters/read_only_spec.rb +28 -34
- data/spec/flipper/dsl_spec.rb +73 -84
- data/spec/flipper/feature_check_context_spec.rb +27 -27
- data/spec/flipper/feature_spec.rb +186 -196
- data/spec/flipper/gate_spec.rb +11 -11
- data/spec/flipper/gate_values_spec.rb +46 -45
- data/spec/flipper/gates/actor_spec.rb +2 -2
- data/spec/flipper/gates/boolean_spec.rb +24 -23
- data/spec/flipper/gates/group_spec.rb +19 -19
- data/spec/flipper/gates/percentage_of_actors_spec.rb +10 -10
- data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +20 -20
- data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +20 -20
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +11 -11
- data/spec/flipper/instrumenters/memory_spec.rb +5 -5
- data/spec/flipper/instrumenters/noop_spec.rb +6 -6
- data/spec/flipper/middleware/memoizer_spec.rb +83 -100
- data/spec/flipper/middleware/setup_env_spec.rb +76 -0
- data/spec/flipper/registry_spec.rb +35 -39
- data/spec/flipper/typecast_spec.rb +18 -18
- data/spec/flipper/types/actor_spec.rb +30 -29
- data/spec/flipper/types/boolean_spec.rb +8 -8
- data/spec/flipper/types/group_spec.rb +28 -28
- data/spec/flipper/types/percentage_spec.rb +14 -14
- data/spec/flipper_spec.rb +61 -54
- data/spec/helper.rb +26 -21
- data/spec/integration_spec.rb +121 -113
- data/spec/support/fake_udp_socket.rb +1 -1
- data/spec/support/spec_helpers.rb +32 -4
- data/test/adapters/pstore_test.rb +3 -3
- data/test/test_helper.rb +1 -1
- metadata +20 -5
@@ -2,23 +2,23 @@ require 'helper'
|
|
2
2
|
require 'flipper/types/boolean'
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Types::Boolean do
|
5
|
-
it
|
6
|
-
boolean =
|
5
|
+
it 'defaults value to true' do
|
6
|
+
boolean = described_class.new
|
7
7
|
expect(boolean.value).to be(true)
|
8
8
|
end
|
9
9
|
|
10
|
-
it
|
11
|
-
boolean =
|
10
|
+
it 'allows overriding default value' do
|
11
|
+
boolean = described_class.new(false)
|
12
12
|
expect(boolean.value).to be(false)
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
16
|
-
boolean =
|
15
|
+
it 'returns true for nil value' do
|
16
|
+
boolean = described_class.new(nil)
|
17
17
|
expect(boolean.value).to be(true)
|
18
18
|
end
|
19
19
|
|
20
|
-
it
|
21
|
-
boolean =
|
20
|
+
it 'typecasts value' do
|
21
|
+
boolean = described_class.new(1)
|
22
22
|
expect(boolean.value).to be(true)
|
23
23
|
end
|
24
24
|
end
|
@@ -2,85 +2,85 @@ require 'helper'
|
|
2
2
|
require 'flipper/types/group'
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Types::Group do
|
5
|
-
let(:fake_context) { double(
|
5
|
+
let(:fake_context) { double('FeatureCheckContext') }
|
6
6
|
|
7
7
|
subject do
|
8
|
-
Flipper.register(:admins
|
8
|
+
Flipper.register(:admins, &:admin?)
|
9
9
|
end
|
10
10
|
|
11
|
-
describe
|
12
|
-
context
|
13
|
-
it
|
11
|
+
describe '.wrap' do
|
12
|
+
context 'with group instance' do
|
13
|
+
it 'returns group instance' do
|
14
14
|
expect(described_class.wrap(subject)).to eq(subject)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
context
|
19
|
-
it
|
18
|
+
context 'with Symbol group name' do
|
19
|
+
it 'returns group instance' do
|
20
20
|
expect(described_class.wrap(subject.name)).to eq(subject)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
context
|
25
|
-
it
|
24
|
+
context 'with String group name' do
|
25
|
+
it 'returns group instance' do
|
26
26
|
expect(described_class.wrap(subject.name.to_s)).to eq(subject)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
group =
|
33
|
-
expect(group).to be_instance_of(
|
31
|
+
it 'initializes with name' do
|
32
|
+
group = described_class.new(:admins)
|
33
|
+
expect(group).to be_instance_of(described_class)
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
37
|
-
it
|
36
|
+
describe '#name' do
|
37
|
+
it 'returns name' do
|
38
38
|
expect(subject.name).to eq(:admins)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
describe
|
43
|
-
let(:admin_actor) { double('Actor',
|
44
|
-
let(:non_admin_actor) { double('Actor',
|
42
|
+
describe '#match?' do
|
43
|
+
let(:admin_actor) { double('Actor', admin?: true) }
|
44
|
+
let(:non_admin_actor) { double('Actor', admin?: false) }
|
45
45
|
|
46
|
-
it
|
46
|
+
it 'returns true if block matches' do
|
47
47
|
expect(subject.match?(admin_actor, fake_context)).to eq(true)
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'returns false if block does not match' do
|
51
51
|
expect(subject.match?(non_admin_actor, fake_context)).to eq(false)
|
52
52
|
end
|
53
53
|
|
54
|
-
it
|
55
|
-
group =
|
54
|
+
it 'returns true for truthy block results' do
|
55
|
+
group = described_class.new(:examples) do |actor|
|
56
56
|
actor.email =~ /@example\.com/
|
57
57
|
end
|
58
|
-
expect(group.match?(double('Actor', :
|
58
|
+
expect(group.match?(double('Actor', email: 'foo@example.com'), fake_context)).to be_truthy
|
59
59
|
end
|
60
60
|
|
61
|
-
it
|
62
|
-
group =
|
61
|
+
it 'returns false for falsey block results' do
|
62
|
+
group = described_class.new(:examples) do |_actor|
|
63
63
|
nil
|
64
64
|
end
|
65
65
|
expect(group.match?(double('Actor'), fake_context)).to be_falsey
|
66
66
|
end
|
67
67
|
|
68
|
-
it
|
68
|
+
it 'can yield without context as block argument' 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(Struct.new(:flipper_id).new(1))
|
72
|
+
thing: Flipper::Types::Actor.new(Struct.new(:flipper_id).new(1))
|
73
73
|
)
|
74
74
|
group = Flipper.register(:group_with_context) { |actor| actor }
|
75
75
|
yielded_actor = group.match?(admin_actor, context)
|
76
76
|
expect(yielded_actor).to be(admin_actor)
|
77
77
|
end
|
78
78
|
|
79
|
-
it
|
79
|
+
it 'can yield with context as block argument' 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(Struct.new(:flipper_id).new(1))
|
83
|
+
thing: Flipper::Types::Actor.new(Struct.new(:flipper_id).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)
|
@@ -2,45 +2,45 @@ require 'helper'
|
|
2
2
|
require 'flipper/types/percentage_of_actors'
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Types::Percentage do
|
5
|
-
subject
|
5
|
+
subject do
|
6
6
|
described_class.new(5)
|
7
|
-
|
7
|
+
end
|
8
8
|
it_should_behave_like 'a percentage'
|
9
9
|
|
10
|
-
describe
|
11
|
-
context
|
12
|
-
it
|
10
|
+
describe '.wrap' do
|
11
|
+
context 'with percentage instance' do
|
12
|
+
it 'returns percentage instance' do
|
13
13
|
expect(described_class.wrap(subject)).to eq(subject)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
context
|
18
|
-
it
|
17
|
+
context 'with Integer' do
|
18
|
+
it 'returns percentage instance' do
|
19
19
|
expect(described_class.wrap(subject.value)).to eq(subject)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
context
|
24
|
-
it
|
23
|
+
context 'with String' do
|
24
|
+
it 'returns percentage instance' do
|
25
25
|
expect(described_class.wrap(subject.value.to_s)).to eq(subject)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
describe
|
31
|
-
it
|
30
|
+
describe '#eql?' do
|
31
|
+
it 'returns true for same class and value' do
|
32
32
|
expect(subject.eql?(described_class.new(subject.value))).to eq(true)
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
35
|
+
it 'returns false for different value' do
|
36
36
|
expect(subject.eql?(described_class.new(subject.value + 1))).to eq(false)
|
37
37
|
end
|
38
38
|
|
39
|
-
it
|
39
|
+
it 'returns false for different class' do
|
40
40
|
expect(subject.eql?(Object.new)).to eq(false)
|
41
41
|
end
|
42
42
|
|
43
|
-
it
|
43
|
+
it 'is aliased to ==' do
|
44
44
|
expect((subject == described_class.new(subject.value))).to eq(true)
|
45
45
|
end
|
46
46
|
end
|
data/spec/flipper_spec.rb
CHANGED
@@ -1,109 +1,116 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
RSpec.describe Flipper do
|
4
|
-
describe
|
5
|
-
it
|
6
|
-
instance =
|
4
|
+
describe '.new' do
|
5
|
+
it 'returns new instance of dsl' do
|
6
|
+
instance = described_class.new(double('Adapter'))
|
7
7
|
expect(instance).to be_instance_of(Flipper::DSL)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
describe
|
12
|
-
it
|
13
|
-
group =
|
14
|
-
expect(
|
11
|
+
describe '.group_exists' do
|
12
|
+
it 'returns true if the group is already created' do
|
13
|
+
group = described_class.register('admins', &:admin?)
|
14
|
+
expect(described_class.group_exists?(:admins)).to eq(true)
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
expect(
|
17
|
+
it 'returns false when the group is not yet registered' do
|
18
|
+
expect(described_class.group_exists?(:non_existing)).to eq(false)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
describe
|
23
|
-
it
|
24
|
-
expect(
|
22
|
+
describe '.groups_registry' do
|
23
|
+
it 'returns a registry instance' do
|
24
|
+
expect(described_class.groups_registry).to be_instance_of(Flipper::Registry)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
describe
|
29
|
-
it
|
28
|
+
describe '.groups_registry=' do
|
29
|
+
it 'sets groups_registry registry' do
|
30
30
|
registry = Flipper::Registry.new
|
31
|
-
|
32
|
-
expect(
|
31
|
+
described_class.groups_registry = registry
|
32
|
+
expect(described_class.instance_variable_get('@groups_registry')).to eq(registry)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
37
|
-
it
|
36
|
+
describe '.register' do
|
37
|
+
it 'adds a group to the group_registry' do
|
38
38
|
registry = Flipper::Registry.new
|
39
|
-
|
40
|
-
group =
|
39
|
+
described_class.groups_registry = registry
|
40
|
+
group = described_class.register(:admins, &:admin?)
|
41
41
|
expect(registry.get(:admins)).to eq(group)
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
44
|
+
it 'adds a group to the group_registry for string name' do
|
45
45
|
registry = Flipper::Registry.new
|
46
|
-
|
47
|
-
group =
|
46
|
+
described_class.groups_registry = registry
|
47
|
+
group = described_class.register('admins', &:admin?)
|
48
48
|
expect(registry.get(:admins)).to eq(group)
|
49
49
|
end
|
50
50
|
|
51
|
-
it
|
52
|
-
|
51
|
+
it 'raises exception if group already registered' do
|
52
|
+
described_class.register(:admins) {}
|
53
53
|
|
54
|
-
expect
|
55
|
-
|
56
|
-
|
54
|
+
expect do
|
55
|
+
described_class.register(:admins) {}
|
56
|
+
end.to raise_error(Flipper::DuplicateGroup, 'Group :admins has already been registered')
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
describe
|
61
|
-
it
|
62
|
-
expect(
|
63
|
-
|
60
|
+
describe '.unregister_groups' do
|
61
|
+
it 'clear group registry' do
|
62
|
+
expect(described_class.groups_registry).to receive(:clear)
|
63
|
+
described_class.unregister_groups
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
describe
|
68
|
-
context
|
67
|
+
describe '.group' do
|
68
|
+
context 'for registered group' do
|
69
69
|
before do
|
70
|
-
@group =
|
70
|
+
@group = described_class.register(:admins) {}
|
71
71
|
end
|
72
72
|
|
73
|
-
it
|
74
|
-
expect(
|
73
|
+
it 'returns group' do
|
74
|
+
expect(described_class.group(:admins)).to eq(@group)
|
75
75
|
end
|
76
76
|
|
77
|
-
it
|
78
|
-
expect(
|
77
|
+
it 'returns group with string key' do
|
78
|
+
expect(described_class.group('admins')).to eq(@group)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
context
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
context 'for unregistered group' do
|
83
|
+
before do
|
84
|
+
@group = described_class.group(:cats)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns group' do
|
88
|
+
expect(@group).to be_instance_of(Flipper::Types::Group)
|
89
|
+
expect(@group.name).to eq(:cats)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'does not add group to registry' do
|
93
|
+
expect(described_class.group_exists?(@group.name)).to be(false)
|
87
94
|
end
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
91
|
-
describe
|
92
|
-
it
|
93
|
-
admins =
|
94
|
-
preview_features =
|
95
|
-
expect(
|
98
|
+
describe '.groups' do
|
99
|
+
it 'returns array of group instances' do
|
100
|
+
admins = described_class.register(:admins, &:admin?)
|
101
|
+
preview_features = described_class.register(:preview_features, &:preview_features?)
|
102
|
+
expect(described_class.groups).to eq(Set[
|
96
103
|
admins,
|
97
104
|
preview_features,
|
98
105
|
])
|
99
106
|
end
|
100
107
|
end
|
101
108
|
|
102
|
-
describe
|
103
|
-
it
|
104
|
-
|
105
|
-
|
106
|
-
expect(
|
109
|
+
describe '.group_names' do
|
110
|
+
it 'returns array of group names' do
|
111
|
+
described_class.register(:admins, &:admin?)
|
112
|
+
described_class.register(:preview_features, &:preview_features?)
|
113
|
+
expect(described_class.group_names).to eq(Set[
|
107
114
|
:admins,
|
108
115
|
:preview_features,
|
109
116
|
])
|
data/spec/helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
2
2
|
|
3
3
|
require 'pp'
|
4
4
|
require 'pathname'
|
@@ -9,11 +9,14 @@ require 'bundler'
|
|
9
9
|
|
10
10
|
Bundler.setup(:default)
|
11
11
|
|
12
|
+
require 'webmock/rspec'
|
13
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
14
|
+
|
12
15
|
require 'flipper'
|
13
16
|
require 'flipper-ui'
|
14
17
|
require 'flipper-api'
|
15
18
|
|
16
|
-
Dir[FlipperRoot.join(
|
19
|
+
Dir[FlipperRoot.join('spec/support/**/*.rb')].each { |f| require f }
|
17
20
|
|
18
21
|
RSpec.configure do |config|
|
19
22
|
config.before(:example) do
|
@@ -27,64 +30,66 @@ RSpec.configure do |config|
|
|
27
30
|
end
|
28
31
|
|
29
32
|
RSpec.shared_examples_for 'a percentage' do
|
30
|
-
it
|
33
|
+
it 'initializes with value' do
|
31
34
|
percentage = described_class.new(12)
|
32
35
|
expect(percentage).to be_instance_of(described_class)
|
33
36
|
end
|
34
37
|
|
35
|
-
it
|
38
|
+
it 'converts string values to integers when initializing' do
|
36
39
|
percentage = described_class.new('15')
|
37
40
|
expect(percentage.value).to eq(15)
|
38
41
|
end
|
39
42
|
|
40
|
-
it
|
43
|
+
it 'has a value' do
|
41
44
|
percentage = described_class.new(19)
|
42
45
|
expect(percentage.value).to eq(19)
|
43
46
|
end
|
44
47
|
|
45
|
-
it
|
46
|
-
expect
|
48
|
+
it 'raises exception for value higher than 100' do
|
49
|
+
expect do
|
47
50
|
described_class.new(101)
|
48
|
-
|
51
|
+
end.to raise_error(ArgumentError,
|
52
|
+
'value must be a positive number less than or equal to 100, but was 101')
|
49
53
|
end
|
50
54
|
|
51
|
-
it
|
52
|
-
expect
|
55
|
+
it 'raises exception for negative value' do
|
56
|
+
expect do
|
53
57
|
described_class.new(-1)
|
54
|
-
|
58
|
+
end.to raise_error(ArgumentError,
|
59
|
+
'value must be a positive number less than or equal to 100, but was -1')
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
58
63
|
RSpec.shared_examples_for 'a DSL feature' do
|
59
|
-
it
|
64
|
+
it 'returns instance of feature' do
|
60
65
|
expect(feature).to be_instance_of(Flipper::Feature)
|
61
66
|
end
|
62
67
|
|
63
|
-
it
|
68
|
+
it 'sets name' do
|
64
69
|
expect(feature.name).to eq(:stats)
|
65
70
|
end
|
66
71
|
|
67
|
-
it
|
72
|
+
it 'sets adapter' do
|
68
73
|
expect(feature.adapter.name).to eq(dsl.adapter.name)
|
69
74
|
end
|
70
75
|
|
71
|
-
it
|
76
|
+
it 'sets instrumenter' do
|
72
77
|
expect(feature.instrumenter).to eq(dsl.instrumenter)
|
73
78
|
end
|
74
79
|
|
75
|
-
it
|
80
|
+
it 'memoizes the feature' do
|
76
81
|
expect(dsl.send(method_name, :stats)).to equal(feature)
|
77
82
|
end
|
78
83
|
|
79
|
-
it
|
80
|
-
expect
|
84
|
+
it 'raises argument error if not string or symbol' do
|
85
|
+
expect do
|
81
86
|
dsl.send(method_name, Object.new)
|
82
|
-
|
87
|
+
end.to raise_error(ArgumentError, /must be a String or Symbol/)
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
86
|
-
RSpec.shared_examples_for
|
87
|
-
it
|
91
|
+
RSpec.shared_examples_for 'a DSL boolean method' do
|
92
|
+
it 'returns boolean with value set' do
|
88
93
|
result = subject.send(method_name, true)
|
89
94
|
expect(result).to be_instance_of(Flipper::Types::Boolean)
|
90
95
|
expect(result.value).to be(true)
|