prefab-cloud-ruby 0.23.8 → 0.24.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/README.md +10 -8
- data/VERSION +1 -1
- data/lib/prefab/client.rb +55 -21
- data/lib/prefab/config_client.rb +13 -25
- data/lib/prefab/config_resolver.rb +28 -28
- data/lib/prefab/config_value_unwrapper.rb +8 -5
- data/lib/prefab/context.rb +119 -0
- data/lib/prefab/criteria_evaluator.rb +23 -17
- data/lib/prefab/feature_flag_client.rb +7 -7
- data/lib/prefab/local_config_parser.rb +2 -17
- data/lib/prefab/logger_client.rb +3 -6
- data/lib/prefab/resolved_config_presenter.rb +84 -0
- data/lib/prefab/weighted_value_resolver.rb +4 -4
- data/lib/prefab-cloud-ruby.rb +6 -0
- data/prefab-cloud-ruby.gemspec +6 -3
- data/test/.prefab.unit_tests.config.yaml +3 -2
- data/test/integration_test.rb +4 -8
- data/test/test_client.rb +28 -27
- data/test/test_config_resolver.rb +106 -54
- data/test/test_config_value_unwrapper.rb +15 -15
- data/test/test_context.rb +158 -0
- data/test/test_criteria_evaluator.rb +93 -78
- data/test/test_feature_flag_client.rb +14 -20
- data/test/test_helper.rb +1 -1
- data/test/test_integration.rb +30 -14
- data/test/test_local_config_parser.rb +6 -8
- data/test/test_log_path_collector.rb +4 -7
- data/test/test_logger.rb +12 -12
- metadata +5 -2
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestContext < Minitest::Test
|
6
|
+
EXAMPLE_PROPERTIES = { user: { key: 'some-user-key', name: 'Ted' }, team: { key: 'abc', plan: 'pro' } }.freeze
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Prefab::Context.current = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_initialize_with_empty_context
|
13
|
+
context = Prefab::Context.new({})
|
14
|
+
assert_empty context.contexts
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_initialize_with_named_context
|
18
|
+
named_context = Prefab::Context::NamedContext.new('test', foo: 'bar')
|
19
|
+
context = Prefab::Context.new(named_context)
|
20
|
+
assert_equal 1, context.contexts.size
|
21
|
+
assert_equal named_context, context.contexts['test']
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_initialize_with_hash
|
25
|
+
context = Prefab::Context.new(test: { foo: 'bar' })
|
26
|
+
assert_equal 1, context.contexts.size
|
27
|
+
assert_equal 'bar', context.contexts['test'].get('foo')
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_initialize_with_multiple_hashes
|
31
|
+
context = Prefab::Context.new(test: { foo: 'bar' }, other: { foo: 'baz' })
|
32
|
+
assert_equal 2, context.contexts.size
|
33
|
+
assert_equal 'bar', context.contexts['test'].get('foo')
|
34
|
+
assert_equal 'baz', context.contexts['other'].get('foo')
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_initialize_with_invalid_hash
|
38
|
+
_, err = capture_io do
|
39
|
+
Prefab::Context.new({ foo: 'bar', baz: 'qux' })
|
40
|
+
end
|
41
|
+
|
42
|
+
assert_match '[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash',
|
43
|
+
err
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_initialize_with_invalid_argument
|
47
|
+
assert_raises(ArgumentError) { Prefab::Context.new([]) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_current
|
51
|
+
context = Prefab::Context.current
|
52
|
+
assert_instance_of Prefab::Context, context
|
53
|
+
assert_empty context.to_h
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_current_set
|
57
|
+
context = Prefab::Context.new(EXAMPLE_PROPERTIES)
|
58
|
+
Prefab::Context.current = context
|
59
|
+
assert_instance_of Prefab::Context, context
|
60
|
+
assert_equal stringify(EXAMPLE_PROPERTIES), context.to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_merge_with_current
|
64
|
+
context = Prefab::Context.new(EXAMPLE_PROPERTIES)
|
65
|
+
Prefab::Context.current = context
|
66
|
+
assert_equal stringify(EXAMPLE_PROPERTIES), context.to_h
|
67
|
+
|
68
|
+
new_context = Prefab::Context.merge_with_current({ user: { key: 'brand-new', other: 'different' },
|
69
|
+
address: { city: 'New York' } })
|
70
|
+
assert_equal stringify({
|
71
|
+
# Note that the user's `name` from the original
|
72
|
+
# context is not included. This is because we don't _merge_ the new
|
73
|
+
# properties if they collide with an existing context name. We _replace_
|
74
|
+
# them.
|
75
|
+
user: { key: 'brand-new', other: 'different' },
|
76
|
+
team: EXAMPLE_PROPERTIES[:team],
|
77
|
+
address: { city: 'New York' }
|
78
|
+
}),
|
79
|
+
new_context.to_h
|
80
|
+
|
81
|
+
# the original/current context is unchanged
|
82
|
+
assert_equal stringify(EXAMPLE_PROPERTIES), Prefab::Context.current.to_h
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_with_context
|
86
|
+
Prefab::Context.with_context(EXAMPLE_PROPERTIES) do
|
87
|
+
context = Prefab::Context.current
|
88
|
+
assert_equal(stringify(EXAMPLE_PROPERTIES), context.to_h)
|
89
|
+
assert_equal('some-user-key', context['user.key'])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_with_context_nesting
|
94
|
+
Prefab::Context.with_context(EXAMPLE_PROPERTIES) do
|
95
|
+
Prefab::Context.with_context({ user: { key: 'abc', other: 'different' } }) do
|
96
|
+
context = Prefab::Context.current
|
97
|
+
assert_equal({ 'user' => { 'key' => 'abc', 'other' => 'different' } }, context.to_h)
|
98
|
+
end
|
99
|
+
|
100
|
+
context = Prefab::Context.current
|
101
|
+
assert_equal(stringify(EXAMPLE_PROPERTIES), context.to_h)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_setting
|
106
|
+
context = Prefab::Context.new({})
|
107
|
+
context.set('user', { key: 'value' })
|
108
|
+
context[:other] = { key: 'different', something: 'other' }
|
109
|
+
assert_equal(stringify({ user: { key: 'value' }, other: { key: 'different', something: 'other' } }), context.to_h)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_getting
|
113
|
+
context = Prefab::Context.new(EXAMPLE_PROPERTIES)
|
114
|
+
assert_equal('some-user-key', context.get('user.key'))
|
115
|
+
assert_equal('some-user-key', context['user.key'])
|
116
|
+
assert_equal('pro', context.get('team.plan'))
|
117
|
+
assert_equal('pro', context['team.plan'])
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_dot_notation_getting
|
121
|
+
context = Prefab::Context.new({ 'user' => { 'key' => 'value' } })
|
122
|
+
assert_equal('value', context.get('user.key'))
|
123
|
+
assert_equal('value', context['user.key'])
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_dot_notation_getting_with_symbols
|
127
|
+
context = Prefab::Context.new({ user: { key: 'value' } })
|
128
|
+
assert_equal('value', context.get('user.key'))
|
129
|
+
assert_equal('value', context['user.key'])
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_merge
|
133
|
+
context = Prefab::Context.new(EXAMPLE_PROPERTIES)
|
134
|
+
context.merge!(:other, { key: 'different' })
|
135
|
+
assert_equal(stringify(EXAMPLE_PROPERTIES.merge(other: { key: 'different' })), context.to_h)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_clear
|
139
|
+
context = Prefab::Context.new(EXAMPLE_PROPERTIES)
|
140
|
+
context.clear
|
141
|
+
|
142
|
+
assert_empty context.to_h
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
def stringify(hash)
|
148
|
+
hash.map { |k, v| [k.to_s, stringify_keys(v)] }.to_h
|
149
|
+
end
|
150
|
+
|
151
|
+
def stringify_keys(value)
|
152
|
+
if value.is_a?(Hash)
|
153
|
+
value.transform_keys(&:to_s)
|
154
|
+
else
|
155
|
+
value
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -37,12 +37,13 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
37
37
|
]
|
38
38
|
)
|
39
39
|
|
40
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
40
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
41
|
+
namespace: nil)
|
41
42
|
|
42
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({}).string
|
43
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
|
43
44
|
end
|
44
45
|
|
45
|
-
def
|
46
|
+
def test_nested_props_in
|
46
47
|
config = Prefab::Config.new(
|
47
48
|
key: KEY,
|
48
49
|
rows: [
|
@@ -53,9 +54,9 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
53
54
|
Prefab::ConditionalValue.new(
|
54
55
|
criteria: [
|
55
56
|
Prefab::Criterion.new(
|
56
|
-
operator: Prefab::Criterion::CriterionOperator::
|
57
|
+
operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
57
58
|
value_to_match: string_list(%w[ok fine]),
|
58
|
-
property_name:
|
59
|
+
property_name: 'user.key'
|
59
60
|
)
|
60
61
|
],
|
61
62
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -65,14 +66,15 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
65
66
|
]
|
66
67
|
)
|
67
68
|
|
68
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
69
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
70
|
+
namespace: nil)
|
69
71
|
|
70
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
71
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({
|
72
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({
|
72
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
73
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).string
|
74
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).string
|
73
75
|
end
|
74
76
|
|
75
|
-
def
|
77
|
+
def test_nested_props_not_in
|
76
78
|
config = Prefab::Config.new(
|
77
79
|
key: KEY,
|
78
80
|
rows: [
|
@@ -83,9 +85,9 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
83
85
|
Prefab::ConditionalValue.new(
|
84
86
|
criteria: [
|
85
87
|
Prefab::Criterion.new(
|
86
|
-
operator: Prefab::Criterion::CriterionOperator::
|
88
|
+
operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
|
87
89
|
value_to_match: string_list(%w[wrong bad]),
|
88
|
-
property_name:
|
90
|
+
property_name: 'user.key'
|
89
91
|
)
|
90
92
|
],
|
91
93
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -95,11 +97,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
95
97
|
]
|
96
98
|
)
|
97
99
|
|
98
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
100
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
101
|
+
namespace: nil)
|
99
102
|
|
100
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({}).string
|
101
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({
|
102
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({
|
103
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
|
104
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).string
|
105
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).string
|
103
106
|
end
|
104
107
|
|
105
108
|
def test_prop_is_one_of
|
@@ -115,7 +118,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
115
118
|
Prefab::Criterion.new(
|
116
119
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
117
120
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
118
|
-
property_name: 'email_suffix'
|
121
|
+
property_name: 'user.email_suffix'
|
119
122
|
)
|
120
123
|
],
|
121
124
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -125,11 +128,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
125
128
|
]
|
126
129
|
)
|
127
130
|
|
128
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
131
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
132
|
+
namespace: nil)
|
129
133
|
|
130
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
131
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email_suffix: 'prefab.cloud' }).string
|
132
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email_suffix: 'hotmail.com' }).string
|
134
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
135
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).string
|
136
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).string
|
133
137
|
end
|
134
138
|
|
135
139
|
def test_prop_is_not_one_of
|
@@ -145,7 +149,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
145
149
|
Prefab::Criterion.new(
|
146
150
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
|
147
151
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
148
|
-
property_name: 'email_suffix'
|
152
|
+
property_name: 'user.email_suffix'
|
149
153
|
)
|
150
154
|
],
|
151
155
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -155,11 +159,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
155
159
|
]
|
156
160
|
)
|
157
161
|
|
158
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
162
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
163
|
+
namespace: nil)
|
159
164
|
|
160
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({}).string
|
161
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email_suffix: 'prefab.cloud' }).string
|
162
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email_suffix: 'hotmail.com' }).string
|
165
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
|
166
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).string
|
167
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).string
|
163
168
|
end
|
164
169
|
|
165
170
|
def test_prop_ends_with_one_of
|
@@ -175,7 +180,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
175
180
|
Prefab::Criterion.new(
|
176
181
|
operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
177
182
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
178
|
-
property_name: 'email'
|
183
|
+
property_name: 'user.email'
|
179
184
|
)
|
180
185
|
],
|
181
186
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -185,11 +190,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
185
190
|
]
|
186
191
|
)
|
187
192
|
|
188
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
193
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
194
|
+
namespace: nil)
|
189
195
|
|
190
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
191
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
192
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@hotmail.com' }).string
|
196
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
197
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
198
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
|
193
199
|
end
|
194
200
|
|
195
201
|
def test_prop_does_not_end_with_one_of
|
@@ -205,7 +211,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
205
211
|
Prefab::Criterion.new(
|
206
212
|
operator: Prefab::Criterion::CriterionOperator::PROP_DOES_NOT_END_WITH_ONE_OF,
|
207
213
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
208
|
-
property_name: 'email'
|
214
|
+
property_name: 'user.email'
|
209
215
|
)
|
210
216
|
],
|
211
217
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -215,11 +221,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
215
221
|
]
|
216
222
|
)
|
217
223
|
|
218
|
-
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil
|
224
|
+
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: nil,
|
225
|
+
namespace: nil)
|
219
226
|
|
220
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({}).string
|
221
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
222
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email: 'example@hotmail.com' }).string
|
227
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
|
228
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
229
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
|
223
230
|
end
|
224
231
|
|
225
232
|
def test_in_seg
|
@@ -237,7 +244,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
237
244
|
Prefab::Criterion.new(
|
238
245
|
operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
239
246
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
240
|
-
property_name: 'email'
|
247
|
+
property_name: 'user.email'
|
241
248
|
)
|
242
249
|
]
|
243
250
|
),
|
@@ -289,12 +296,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
289
296
|
)
|
290
297
|
|
291
298
|
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
|
292
|
-
base_client: nil,
|
299
|
+
base_client: nil, namespace: nil,
|
293
300
|
resolver: resolver_fake({ segment_key => segment_config }))
|
294
301
|
|
295
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
296
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
297
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@hotmail.com' }).string
|
302
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
303
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
304
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
|
298
305
|
end
|
299
306
|
|
300
307
|
def test_not_in_seg
|
@@ -312,7 +319,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
312
319
|
Prefab::Criterion.new(
|
313
320
|
operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
314
321
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
315
|
-
property_name: 'email'
|
322
|
+
property_name: 'user.email'
|
316
323
|
)
|
317
324
|
]
|
318
325
|
),
|
@@ -346,12 +353,12 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
346
353
|
)
|
347
354
|
|
348
355
|
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
|
349
|
-
base_client: nil,
|
356
|
+
base_client: nil, namespace: nil,
|
350
357
|
resolver: resolver_fake({ segment_key => segment_config }))
|
351
358
|
|
352
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({}).string
|
353
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
354
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email: 'example@hotmail.com' }).string
|
359
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).string
|
360
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
361
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).string
|
355
362
|
end
|
356
363
|
|
357
364
|
def test_multiple_conditions_in_one_value
|
@@ -369,13 +376,13 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
369
376
|
Prefab::Criterion.new(
|
370
377
|
operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
371
378
|
value_to_match: string_list(['prefab.cloud', 'gmail.com']),
|
372
|
-
property_name: 'email'
|
379
|
+
property_name: 'user.email'
|
373
380
|
),
|
374
381
|
|
375
382
|
Prefab::Criterion.new(
|
376
383
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
377
384
|
value_to_match: Prefab::ConfigValue.new(bool: true),
|
378
|
-
property_name: 'admin'
|
385
|
+
property_name: 'user.admin'
|
379
386
|
)
|
380
387
|
]
|
381
388
|
),
|
@@ -404,7 +411,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
404
411
|
Prefab::Criterion.new(
|
405
412
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
|
406
413
|
value_to_match: Prefab::ConfigValue.new(bool: true),
|
407
|
-
property_name: 'deleted'
|
414
|
+
property_name: 'user.deleted'
|
408
415
|
)
|
409
416
|
],
|
410
417
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -415,16 +422,18 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
415
422
|
)
|
416
423
|
|
417
424
|
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
|
418
|
-
base_client: nil,
|
425
|
+
base_client: nil, namespace: nil,
|
419
426
|
resolver: resolver_fake({ segment_key => segment_config }))
|
420
427
|
|
421
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
422
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
423
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud', admin: true }).string
|
424
|
-
assert_equal DEFAULT_VALUE,
|
425
|
-
|
426
|
-
assert_equal
|
427
|
-
assert_equal
|
428
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
429
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
430
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).string
|
431
|
+
assert_equal DEFAULT_VALUE,
|
432
|
+
evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).string
|
433
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).string
|
434
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).string
|
435
|
+
assert_equal DEFAULT_VALUE,
|
436
|
+
evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).string
|
428
437
|
end
|
429
438
|
|
430
439
|
def test_multiple_conditions_in_multiple_values
|
@@ -442,7 +451,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
442
451
|
Prefab::Criterion.new(
|
443
452
|
operator: Prefab::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
444
453
|
value_to_match: string_list(['prefab.cloud', 'gmail.com']),
|
445
|
-
property_name: 'email'
|
454
|
+
property_name: 'user.email'
|
446
455
|
)
|
447
456
|
]
|
448
457
|
),
|
@@ -452,7 +461,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
452
461
|
Prefab::Criterion.new(
|
453
462
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
454
463
|
value_to_match: Prefab::ConfigValue.new(bool: true),
|
455
|
-
property_name: 'admin'
|
464
|
+
property_name: 'user.admin'
|
456
465
|
)
|
457
466
|
]
|
458
467
|
),
|
@@ -481,7 +490,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
481
490
|
Prefab::Criterion.new(
|
482
491
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
|
483
492
|
value_to_match: Prefab::ConfigValue.new(bool: true),
|
484
|
-
property_name: 'deleted'
|
493
|
+
property_name: 'user.deleted'
|
485
494
|
)
|
486
495
|
],
|
487
496
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -492,17 +501,19 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
492
501
|
)
|
493
502
|
|
494
503
|
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
|
495
|
-
base_client: nil,
|
504
|
+
base_client: nil, namespace: nil,
|
496
505
|
resolver: resolver_fake({ segment_key => segment_config }))
|
497
506
|
|
498
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
499
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud' }).string
|
500
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ admin: true }).string
|
501
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@prefab.cloud', admin: true }).string
|
502
|
-
assert_equal DEFAULT_VALUE,
|
503
|
-
|
504
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ email: 'example@gmail.com'
|
505
|
-
assert_equal
|
507
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
508
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).string
|
509
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { admin: true })).string
|
510
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).string
|
511
|
+
assert_equal DEFAULT_VALUE,
|
512
|
+
evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).string
|
513
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).string
|
514
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).string
|
515
|
+
assert_equal DEFAULT_VALUE,
|
516
|
+
evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).string
|
506
517
|
end
|
507
518
|
|
508
519
|
def test_stringifying_property_values_and_names
|
@@ -518,7 +529,7 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
518
529
|
Prefab::Criterion.new(
|
519
530
|
operator: Prefab::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
520
531
|
value_to_match: string_list(%w[1 true hello]),
|
521
|
-
property_name: '
|
532
|
+
property_name: 'team.name'
|
522
533
|
)
|
523
534
|
],
|
524
535
|
value: Prefab::ConfigValue.new(string: DESIRED_VALUE)
|
@@ -529,15 +540,15 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
529
540
|
)
|
530
541
|
|
531
542
|
evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
|
532
|
-
base_client: nil)
|
543
|
+
namespace: nil, base_client: nil)
|
533
544
|
|
534
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({}).string
|
535
|
-
assert_equal DEFAULT_VALUE, evaluator.evaluate({
|
545
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).string
|
546
|
+
assert_equal DEFAULT_VALUE, evaluator.evaluate(context(team: { name: 'prefab.cloud' })).string
|
536
547
|
|
537
548
|
[1, true, :hello].each do |value|
|
538
|
-
[:
|
539
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ property_name => value }).string
|
540
|
-
assert_equal DESIRED_VALUE, evaluator.evaluate({ property_name => value.to_s }).string
|
549
|
+
[:name, 'name'].each do |property_name|
|
550
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value })).string
|
551
|
+
assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value.to_s })).string
|
541
552
|
end
|
542
553
|
end
|
543
554
|
end
|
@@ -557,14 +568,18 @@ class TestCriteriaEvaluator < Minitest::Test
|
|
557
568
|
@config[key]
|
558
569
|
end
|
559
570
|
|
560
|
-
def get(key,
|
571
|
+
def get(key, properties = {})
|
561
572
|
# This only gets called for segments, so we don't need to pass in a resolver
|
562
573
|
Prefab::CriteriaEvaluator.new(@config[key], project_env_id: nil, resolver: nil,
|
563
|
-
base_client: nil).evaluate(properties)
|
574
|
+
namespace: nil, base_client: nil).evaluate(properties)
|
564
575
|
end
|
565
576
|
end
|
566
577
|
|
567
578
|
def resolver_fake(config)
|
568
579
|
FakeResolver.new(config)
|
569
580
|
end
|
581
|
+
|
582
|
+
def context(properties)
|
583
|
+
Prefab::Context.new(properties)
|
584
|
+
end
|
570
585
|
end
|
@@ -17,38 +17,32 @@ class TestFeatureFlagClient < Minitest::Test
|
|
17
17
|
def test_feature_is_on_for
|
18
18
|
ff_client = new_client
|
19
19
|
|
20
|
-
assert_equal false, ff_client.feature_is_on_for?('something-that-does-not-exist',
|
21
|
-
assert_equal false, ff_client.feature_is_on_for?('
|
22
|
-
assert_equal
|
23
|
-
assert_equal true, ff_client.feature_is_on_for?('
|
20
|
+
assert_equal false, ff_client.feature_is_on_for?('something-that-does-not-exist', {})
|
21
|
+
assert_equal false, ff_client.feature_is_on_for?('user_key_match', {})
|
22
|
+
assert_equal false, ff_client.feature_is_on_for?('user_key_match', { user: { key: 'not-included' } })
|
23
|
+
assert_equal true, ff_client.feature_is_on_for?('user_key_match', { user: { key: 'abc123' } })
|
24
|
+
assert_equal true, ff_client.feature_is_on_for?('user_key_match', { user: { key: 'xyz987' } })
|
24
25
|
end
|
25
26
|
|
26
27
|
def test_get
|
27
28
|
ff_client = new_client
|
28
29
|
|
29
30
|
# No default
|
30
|
-
assert_equal false, ff_client.get('something-that-does-not-exist')
|
31
|
-
assert_equal false, ff_client.get('disabled_flag')
|
32
|
-
assert_equal true, ff_client.get('enabled_flag')
|
33
|
-
assert_equal 'all-features', ff_client.get('flag_with_a_value')
|
31
|
+
assert_equal false, ff_client.get('something-that-does-not-exist', {})
|
32
|
+
assert_equal false, ff_client.get('disabled_flag', {})
|
33
|
+
assert_equal true, ff_client.get('enabled_flag', {})
|
34
|
+
assert_equal 'all-features', ff_client.get('flag_with_a_value', {})
|
34
35
|
|
35
36
|
# with defaults
|
36
|
-
assert_equal DEFAULT, ff_client.get('something-that-does-not-exist', default: DEFAULT)
|
37
|
-
assert_equal false, ff_client.get('disabled_flag', default: DEFAULT)
|
38
|
-
assert_equal true, ff_client.get('enabled_flag', default: DEFAULT)
|
39
|
-
assert_equal 'all-features', ff_client.get('flag_with_a_value', default: DEFAULT)
|
37
|
+
assert_equal DEFAULT, ff_client.get('something-that-does-not-exist', {}, default: DEFAULT)
|
38
|
+
assert_equal false, ff_client.get('disabled_flag', {}, default: DEFAULT)
|
39
|
+
assert_equal true, ff_client.get('enabled_flag', {}, default: DEFAULT)
|
40
|
+
assert_equal 'all-features', ff_client.get('flag_with_a_value', {}, default: DEFAULT)
|
40
41
|
end
|
41
42
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def new_client(overrides = {})
|
45
|
-
|
46
|
-
prefab_config_override_dir: 'none',
|
47
|
-
prefab_config_classpath_dir: 'test',
|
48
|
-
prefab_envs: ['unit_tests'],
|
49
|
-
prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
|
50
|
-
}.merge(overrides))
|
51
|
-
|
52
|
-
Prefab::Client.new(options).feature_flag_client
|
46
|
+
super(overrides).feature_flag_client
|
53
47
|
end
|
54
48
|
end
|
data/test/test_helper.rb
CHANGED
data/test/test_integration.rb
CHANGED
@@ -10,24 +10,40 @@ class TestIntegration < Minitest::Test
|
|
10
10
|
tests = YAML.load(File.read(test_file))['tests']
|
11
11
|
|
12
12
|
tests.each do |test|
|
13
|
-
|
14
|
-
it = IntegrationTest.new(test)
|
13
|
+
parent_context = test['context']
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
test['cases'].each do |test_case|
|
16
|
+
define_method(:"test_#{test_case['name']}") do
|
17
|
+
it = IntegrationTest.new(test_case)
|
18
|
+
|
19
|
+
with_parent_context_maybe(parent_context) do
|
20
|
+
case it.test_type
|
21
|
+
when :raise
|
22
|
+
err = assert_raises(it.expected[:error]) do
|
23
|
+
it.test_client.send(it.func, *it.input)
|
24
|
+
end
|
25
|
+
assert_match(/#{it.expected[:message]}/, err.message)
|
26
|
+
when :nil
|
27
|
+
assert_nil it.test_client.send(it.func, *it.input)
|
28
|
+
when :feature_flag
|
29
|
+
flag, context = *it.input
|
30
|
+
assert_equal it.expected[:value], it.test_client.send(it.func, flag, context)
|
31
|
+
when :simple_equality
|
32
|
+
assert_equal it.expected[:value], it.test_client.send(it.func, *it.input)
|
33
|
+
end
|
20
34
|
end
|
21
|
-
assert_match(/#{it.expected[:message]}/, err.message)
|
22
|
-
when :nil
|
23
|
-
assert_nil it.test_client.send(it.func, *it.input)
|
24
|
-
when :feature_flag
|
25
|
-
flag, lookup_key, attributes = *it.input
|
26
|
-
assert_equal it.expected[:value], it.test_client.send(it.func, flag, lookup_key, attributes: attributes)
|
27
|
-
when :simple_equality
|
28
|
-
assert_equal it.expected[:value], it.test_client.send(it.func, *it.input)
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def with_parent_context_maybe(context, &block)
|
43
|
+
if context
|
44
|
+
Prefab::Context.with_context(context, &block)
|
45
|
+
else
|
46
|
+
yield
|
47
|
+
end
|
48
|
+
end
|
33
49
|
end
|