quonfig 0.0.2

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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/rules/constitution.md +81 -0
  3. data/.claude/rules/git-safety.md +11 -0
  4. data/.claude/rules/issue-tracking.md +13 -0
  5. data/.claude/rules/testing-workflow.md +28 -0
  6. data/.envrc.sample +3 -0
  7. data/.github/CODEOWNERS +2 -0
  8. data/.github/pull_request_template.md +8 -0
  9. data/.github/workflows/push_gem.yml +49 -0
  10. data/.github/workflows/ruby.yml +60 -0
  11. data/.github/workflows/test.yaml +40 -0
  12. data/.rubocop.yml +13 -0
  13. data/.tool-versions +1 -0
  14. data/CHANGELOG.md +301 -0
  15. data/CLAUDE.md +29 -0
  16. data/CODEOWNERS +1 -0
  17. data/Gemfile +26 -0
  18. data/Gemfile.lock +177 -0
  19. data/LICENSE.txt +20 -0
  20. data/README.md +213 -0
  21. data/Rakefile +64 -0
  22. data/VERSION +1 -0
  23. data/dev/allocation_stats +60 -0
  24. data/dev/benchmark +40 -0
  25. data/dev/console +12 -0
  26. data/dev/script_setup.rb +18 -0
  27. data/lib/quonfig/bound_client.rb +71 -0
  28. data/lib/quonfig/caching_http_connection.rb +95 -0
  29. data/lib/quonfig/client.rb +221 -0
  30. data/lib/quonfig/config_envelope.rb +5 -0
  31. data/lib/quonfig/config_loader.rb +103 -0
  32. data/lib/quonfig/config_store.rb +42 -0
  33. data/lib/quonfig/context.rb +101 -0
  34. data/lib/quonfig/datadir.rb +101 -0
  35. data/lib/quonfig/duration.rb +58 -0
  36. data/lib/quonfig/encryption.rb +74 -0
  37. data/lib/quonfig/error.rb +6 -0
  38. data/lib/quonfig/errors/env_var_parse_error.rb +11 -0
  39. data/lib/quonfig/errors/initialization_timeout_error.rb +12 -0
  40. data/lib/quonfig/errors/invalid_sdk_key_error.rb +19 -0
  41. data/lib/quonfig/errors/missing_default_error.rb +13 -0
  42. data/lib/quonfig/errors/missing_env_var_error.rb +11 -0
  43. data/lib/quonfig/errors/type_mismatch_error.rb +11 -0
  44. data/lib/quonfig/errors/uninitialized_error.rb +13 -0
  45. data/lib/quonfig/evaluation.rb +64 -0
  46. data/lib/quonfig/evaluator.rb +464 -0
  47. data/lib/quonfig/exponential_backoff.rb +21 -0
  48. data/lib/quonfig/fixed_size_hash.rb +14 -0
  49. data/lib/quonfig/http_connection.rb +46 -0
  50. data/lib/quonfig/internal_logger.rb +173 -0
  51. data/lib/quonfig/murmer3.rb +50 -0
  52. data/lib/quonfig/options.rb +194 -0
  53. data/lib/quonfig/periodic_sync.rb +74 -0
  54. data/lib/quonfig/quonfig.rb +58 -0
  55. data/lib/quonfig/rate_limit_cache.rb +41 -0
  56. data/lib/quonfig/reason.rb +39 -0
  57. data/lib/quonfig/resolver.rb +42 -0
  58. data/lib/quonfig/semantic_logger_filter.rb +90 -0
  59. data/lib/quonfig/semver.rb +132 -0
  60. data/lib/quonfig/sse_config_client.rb +135 -0
  61. data/lib/quonfig/time_helpers.rb +7 -0
  62. data/lib/quonfig/types.rb +56 -0
  63. data/lib/quonfig/weighted_value_resolver.rb +49 -0
  64. data/lib/quonfig.rb +57 -0
  65. data/quonfig.gemspec +149 -0
  66. data/scripts/generate_integration_tests.rb +362 -0
  67. data/test/fixtures/datafile.json +87 -0
  68. data/test/integration/test_context_precedence.rb +194 -0
  69. data/test/integration/test_datadir_environment.rb +76 -0
  70. data/test/integration/test_enabled.rb +784 -0
  71. data/test/integration/test_enabled_with_contexts.rb +94 -0
  72. data/test/integration/test_get.rb +224 -0
  73. data/test/integration/test_get_feature_flag.rb +34 -0
  74. data/test/integration/test_get_or_raise.rb +86 -0
  75. data/test/integration/test_get_weighted_values.rb +29 -0
  76. data/test/integration/test_helpers.rb +139 -0
  77. data/test/integration/test_helpers_test.rb +73 -0
  78. data/test/integration/test_post.rb +34 -0
  79. data/test/integration/test_telemetry.rb +114 -0
  80. data/test/support/common_helpers.rb +106 -0
  81. data/test/support/mock_base_client.rb +27 -0
  82. data/test/support/mock_config_loader.rb +1 -0
  83. data/test/test_bound_client.rb +109 -0
  84. data/test/test_caching_http_connection.rb +218 -0
  85. data/test/test_client.rb +255 -0
  86. data/test/test_config_loader.rb +70 -0
  87. data/test/test_context.rb +136 -0
  88. data/test/test_datadir.rb +199 -0
  89. data/test/test_duration.rb +37 -0
  90. data/test/test_encryption.rb +16 -0
  91. data/test/test_evaluator.rb +285 -0
  92. data/test/test_exponential_backoff.rb +44 -0
  93. data/test/test_fixed_size_hash.rb +119 -0
  94. data/test/test_helper.rb +17 -0
  95. data/test/test_http_connection.rb +79 -0
  96. data/test/test_internal_logger.rb +34 -0
  97. data/test/test_options.rb +167 -0
  98. data/test/test_rate_limit_cache.rb +44 -0
  99. data/test/test_reason.rb +79 -0
  100. data/test/test_rename.rb +65 -0
  101. data/test/test_resolver.rb +144 -0
  102. data/test/test_semantic_logger_filter.rb +123 -0
  103. data/test/test_semver.rb +108 -0
  104. data/test/test_sse_config_client.rb +297 -0
  105. data/test/test_typed_getters.rb +131 -0
  106. data/test/test_types.rb +141 -0
  107. data/test/test_weighted_value_resolver.rb +84 -0
  108. metadata +311 -0
@@ -0,0 +1,784 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # AUTO-GENERATED from integration-test-data/tests/eval/enabled.yaml.
4
+ # Regenerate with `bundle exec ruby scripts/generate_integration_tests.rb`.
5
+ # Do NOT edit by hand — changes will be overwritten.
6
+
7
+ require 'test_helper'
8
+ require 'integration/test_helpers'
9
+
10
+ class TestEnabled < Minitest::Test
11
+ def setup
12
+ @store = IntegrationTestHelpers.build_store("enabled")
13
+ end
14
+
15
+ # returns the correct value for a simple flag
16
+ def test_returns_the_correct_value_for_a_simple_flag
17
+ begin
18
+ resolver = IntegrationTestHelpers.build_resolver(@store)
19
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.simple", {}, true)
20
+ rescue Exception => e
21
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
22
+ end
23
+ end
24
+
25
+ # always returns false for a non-boolean flag
26
+ def test_always_returns_false_for_a_non_boolean_flag
27
+ begin
28
+ resolver = IntegrationTestHelpers.build_resolver(@store)
29
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.integer", {}, false)
30
+ rescue Exception => e
31
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
32
+ end
33
+ end
34
+
35
+ # returns true for a PROP_IS_ONE_OF rule when any prop matches
36
+ def test_returns_true_for_a_prop_is_one_of_rule_when_any_prop_matches
37
+ begin
38
+ resolver = IntegrationTestHelpers.build_resolver(@store)
39
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.properties.positive", {"" => {"name" => "michael", "domain" => "something.com"}}, true)
40
+ rescue Exception => e
41
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
42
+ end
43
+ end
44
+
45
+ # returns false for a PROP_IS_ONE_OF rule when no prop matches
46
+ def test_returns_false_for_a_prop_is_one_of_rule_when_no_prop_matches
47
+ begin
48
+ resolver = IntegrationTestHelpers.build_resolver(@store)
49
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.properties.positive", {"" => {"name" => "lauren", "domain" => "something.com"}}, false)
50
+ rescue Exception => e
51
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
52
+ end
53
+ end
54
+
55
+ # returns true for a PROP_IS_NOT_ONE_OF rule when any prop doesn't match
56
+ def test_returns_true_for_a_prop_is_not_one_of_rule_when_any_prop_doesn_t_match
57
+ begin
58
+ resolver = IntegrationTestHelpers.build_resolver(@store)
59
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.properties.negative", {"" => {"name" => "lauren", "domain" => "prefab.cloud"}}, true)
60
+ rescue Exception => e
61
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
62
+ end
63
+ end
64
+
65
+ # returns false for a PROP_IS_NOT_ONE_OF rule when all props match
66
+ def test_returns_false_for_a_prop_is_not_one_of_rule_when_all_props_match
67
+ begin
68
+ resolver = IntegrationTestHelpers.build_resolver(@store)
69
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.properties.negative", {"" => {"name" => "michael", "domain" => "prefab.cloud"}}, false)
70
+ rescue Exception => e
71
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
72
+ end
73
+ end
74
+
75
+ # returns true for PROP_ENDS_WITH_ONE_OF rule when the given prop has a matching suffix
76
+ def test_returns_true_for_prop_ends_with_one_of_rule_when_the_given_prop_has_a_matching_suffix
77
+ begin
78
+ resolver = IntegrationTestHelpers.build_resolver(@store)
79
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.ends-with-one-of.positive", {"" => {"email" => "jeff@prefab.cloud"}}, true)
80
+ rescue Exception => e
81
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
82
+ end
83
+ end
84
+
85
+ # returns false for PROP_ENDS_WITH_ONE_OF rule when the given prop doesn't have a matching suffix
86
+ def test_returns_false_for_prop_ends_with_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_suffix
87
+ begin
88
+ resolver = IntegrationTestHelpers.build_resolver(@store)
89
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.ends-with-one-of.positive", {"" => {"email" => "jeff@test.com"}}, false)
90
+ rescue Exception => e
91
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
92
+ end
93
+ end
94
+
95
+ # returns true for PROP_DOES_NOT_END_WITH_ONE_OF rule when the given prop doesn't have a matching suffix
96
+ def test_returns_true_for_prop_does_not_end_with_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_suffix
97
+ begin
98
+ resolver = IntegrationTestHelpers.build_resolver(@store)
99
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.ends-with-one-of.negative", {"" => {"email" => "michael@test.com"}}, true)
100
+ rescue Exception => e
101
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
102
+ end
103
+ end
104
+
105
+ # returns false for PROP_DOES_NOT_END_WITH_ONE_OF rule when the given prop has a matching suffix
106
+ def test_returns_false_for_prop_does_not_end_with_one_of_rule_when_the_given_prop_has_a_matching_suffix
107
+ begin
108
+ resolver = IntegrationTestHelpers.build_resolver(@store)
109
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.ends-with-one-of.negative", {"" => {"email" => "michael@prefab.cloud"}}, false)
110
+ rescue Exception => e
111
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
112
+ end
113
+ end
114
+
115
+ # returns true for PROP_STARTS_WITH_ONE_OF rule when the given prop has a matching prefix
116
+ def test_returns_true_for_prop_starts_with_one_of_rule_when_the_given_prop_has_a_matching_prefix
117
+ begin
118
+ resolver = IntegrationTestHelpers.build_resolver(@store)
119
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.starts-with-one-of.positive", {"user" => {"email" => "foo@prefab.cloud"}}, true)
120
+ rescue Exception => e
121
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
122
+ end
123
+ end
124
+
125
+ # returns false for PROP_STARTS_WITH_ONE_OF rule when the given prop doesn't have a matching prefix
126
+ def test_returns_false_for_prop_starts_with_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_prefix
127
+ begin
128
+ resolver = IntegrationTestHelpers.build_resolver(@store)
129
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.starts-with-one-of.positive", {"user" => {"email" => "notfoo@prefab.cloud"}}, false)
130
+ rescue Exception => e
131
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
132
+ end
133
+ end
134
+
135
+ # returns true for PROP_DOES_NOT_START_WITH_ONE_OF rule when the given prop doesn't have a matching prefix
136
+ def test_returns_true_for_prop_does_not_start_with_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_prefix
137
+ begin
138
+ resolver = IntegrationTestHelpers.build_resolver(@store)
139
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.starts-with-one-of.negative", {"user" => {"email" => "notfoo@prefab.cloud"}}, true)
140
+ rescue Exception => e
141
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
142
+ end
143
+ end
144
+
145
+ # returns false for PROP_DOES_NOT_START_WITH_ONE_OF rule when the given prop has a matching prefix
146
+ def test_returns_false_for_prop_does_not_start_with_one_of_rule_when_the_given_prop_has_a_matching_prefix
147
+ begin
148
+ resolver = IntegrationTestHelpers.build_resolver(@store)
149
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.starts-with-one-of.negative", {"user" => {"email" => "foo@prefab.cloud"}}, false)
150
+ rescue Exception => e
151
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
152
+ end
153
+ end
154
+
155
+ # returns true for PROP_CONTAINS_ONE_OF rule when the given prop has a matching substring
156
+ def test_returns_true_for_prop_contains_one_of_rule_when_the_given_prop_has_a_matching_substring
157
+ begin
158
+ resolver = IntegrationTestHelpers.build_resolver(@store)
159
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.contains-one-of.positive", {"user" => {"email" => "somefoo@prefab.cloud"}}, true)
160
+ rescue Exception => e
161
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
162
+ end
163
+ end
164
+
165
+ # returns false for PROP_CONTAINS_ONE_OF rule when the given prop doesn't have a matching substring
166
+ def test_returns_false_for_prop_contains_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_substring
167
+ begin
168
+ resolver = IntegrationTestHelpers.build_resolver(@store)
169
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.contains-one-of.positive", {"user" => {"email" => "info@prefab.cloud"}}, false)
170
+ rescue Exception => e
171
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
172
+ end
173
+ end
174
+
175
+ # returns true for PROP_DOES_NOT_CONTAIN_ONE_OF rule when the given prop doesn't have a matching substring
176
+ def test_returns_true_for_prop_does_not_contain_one_of_rule_when_the_given_prop_doesn_t_have_a_matching_substring
177
+ begin
178
+ resolver = IntegrationTestHelpers.build_resolver(@store)
179
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.contains-one-of.negative", {"user" => {"email" => "info@prefab.cloud"}}, true)
180
+ rescue Exception => e
181
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
182
+ end
183
+ end
184
+
185
+ # returns false for PROP_DOES_NOT_CONTAIN_ONE_OF rule when the given prop has a matching substring
186
+ def test_returns_false_for_prop_does_not_contain_one_of_rule_when_the_given_prop_has_a_matching_substring
187
+ begin
188
+ resolver = IntegrationTestHelpers.build_resolver(@store)
189
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.contains-one-of.negative", {"user" => {"email" => "notfoo@prefab.cloud"}}, false)
190
+ rescue Exception => e
191
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
192
+ end
193
+ end
194
+
195
+ # returns true for IN_SEG when the segment rule matches
196
+ def test_returns_true_for_in_seg_when_the_segment_rule_matches
197
+ begin
198
+ resolver = IntegrationTestHelpers.build_resolver(@store)
199
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.positive", {"user" => {"key" => "lauren"}}, true)
200
+ rescue Exception => e
201
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
202
+ end
203
+ end
204
+
205
+ # returns false for IN_SEG when the segment rule doesn't match
206
+ def test_returns_false_for_in_seg_when_the_segment_rule_doesn_t_match
207
+ begin
208
+ resolver = IntegrationTestHelpers.build_resolver(@store)
209
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.positive", {"user" => {"key" => "josh"}}, false)
210
+ rescue Exception => e
211
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
212
+ end
213
+ end
214
+
215
+ # returns false for IN_SEG if any segment rule fails to match
216
+ def test_returns_false_for_in_seg_if_any_segment_rule_fails_to_match
217
+ begin
218
+ resolver = IntegrationTestHelpers.build_resolver(@store)
219
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-seg.segment-and", {"user" => {"key" => "josh"}, "" => {"domain" => "prefab.cloud"}}, false)
220
+ rescue Exception => e
221
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
222
+ end
223
+ end
224
+
225
+ # returns true for IN_SEG (segment-and) if all rules matches
226
+ def test_returns_true_for_in_seg_segment_and_if_all_rules_matches
227
+ begin
228
+ resolver = IntegrationTestHelpers.build_resolver(@store)
229
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-seg.segment-and", {"user" => {"key" => "michael"}, "" => {"domain" => "prefab.cloud"}}, true)
230
+ rescue Exception => e
231
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
232
+ end
233
+ end
234
+
235
+ # returns true for IN_SEG (segment-or) if any segment rule matches (lookup)
236
+ def test_returns_true_for_in_seg_segment_or_if_any_segment_rule_matches_lookup
237
+ begin
238
+ resolver = IntegrationTestHelpers.build_resolver(@store)
239
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-seg.segment-or", {"user" => {"key" => "michael"}, "" => {"domain" => "example.com"}}, true)
240
+ rescue Exception => e
241
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
242
+ end
243
+ end
244
+
245
+ # returns true for IN_SEG (segment-or) if any segment rule matches (prop)
246
+ def test_returns_true_for_in_seg_segment_or_if_any_segment_rule_matches_prop
247
+ begin
248
+ resolver = IntegrationTestHelpers.build_resolver(@store)
249
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-seg.segment-or", {"user" => {"key" => "nobody"}, "" => {"domain" => "gmail.com"}}, true)
250
+ rescue Exception => e
251
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
252
+ end
253
+ end
254
+
255
+ # returns true for NOT_IN_SEG when the segment rule doesn't match
256
+ def test_returns_true_for_not_in_seg_when_the_segment_rule_doesn_t_match
257
+ begin
258
+ resolver = IntegrationTestHelpers.build_resolver(@store)
259
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.negative", {"user" => {"key" => "josh"}}, true)
260
+ rescue Exception => e
261
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
262
+ end
263
+ end
264
+
265
+ # returns false for NOT_IN_SEG when the segment rule matches
266
+ def test_returns_false_for_not_in_seg_when_the_segment_rule_matches
267
+ begin
268
+ resolver = IntegrationTestHelpers.build_resolver(@store)
269
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.negative", {"user" => {"key" => "michael"}}, false)
270
+ rescue Exception => e
271
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
272
+ end
273
+ end
274
+
275
+ # returns false for NOT_IN_SEG if any segment rule matches
276
+ def test_returns_false_for_not_in_seg_if_any_segment_rule_matches
277
+ begin
278
+ resolver = IntegrationTestHelpers.build_resolver(@store)
279
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.multiple-criteria.negative", {"user" => {"key" => "josh"}, "" => {"domain" => "prefab.cloud"}}, true)
280
+ rescue Exception => e
281
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
282
+ end
283
+ end
284
+
285
+ # returns true for NOT_IN_SEG if no segment rule matches
286
+ def test_returns_true_for_not_in_seg_if_no_segment_rule_matches
287
+ begin
288
+ resolver = IntegrationTestHelpers.build_resolver(@store)
289
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-segment.multiple-criteria.negative", {"user" => {"key" => "josh"}, "" => {"domain" => "something.com"}}, true)
290
+ rescue Exception => e
291
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
292
+ end
293
+ end
294
+
295
+ # returns true for NOT_IN_SEG (segment-and) if not segment rule fails to match
296
+ def test_returns_true_for_not_in_seg_segment_and_if_not_segment_rule_fails_to_match
297
+ begin
298
+ resolver = IntegrationTestHelpers.build_resolver(@store)
299
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.not-in-seg.segment-and", {"user" => {"key" => "josh"}, "" => {"domain" => "prefab.cloud"}}, true)
300
+ rescue Exception => e
301
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
302
+ end
303
+ end
304
+
305
+ # returns true for IN_SEG (segment-and) if not segment rule fails to match
306
+ def test_returns_true_for_in_seg_segment_and_if_not_segment_rule_fails_to_match
307
+ begin
308
+ resolver = IntegrationTestHelpers.build_resolver(@store)
309
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.in-seg.segment-and", {"user" => {"key" => "josh"}, "" => {"domain" => "prefab.cloud"}}, false)
310
+ rescue Exception => e
311
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
312
+ end
313
+ end
314
+
315
+ # returns false for NOT_IN_SEG (segment-and) if segment rules matches
316
+ def test_returns_false_for_not_in_seg_segment_and_if_segment_rules_matches
317
+ begin
318
+ resolver = IntegrationTestHelpers.build_resolver(@store)
319
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.not-in-seg.segment-and", {"user" => {"key" => "michael"}, "" => {"domain" => "prefab.cloud"}}, false)
320
+ rescue Exception => e
321
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
322
+ end
323
+ end
324
+
325
+ # returns true for NOT_IN_SEG (segment-or) if no segment rule matches
326
+ def test_returns_true_for_not_in_seg_segment_or_if_no_segment_rule_matches
327
+ begin
328
+ resolver = IntegrationTestHelpers.build_resolver(@store)
329
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.not-in-seg.segment-or", {"user" => {"key" => "nobody"}, "" => {"domain" => "example.com"}}, true)
330
+ rescue Exception => e
331
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
332
+ end
333
+ end
334
+
335
+ # returns false for NOT_IN_SEG (segment-or) if one segment rule matches (prop)
336
+ def test_returns_false_for_not_in_seg_segment_or_if_one_segment_rule_matches_prop
337
+ begin
338
+ resolver = IntegrationTestHelpers.build_resolver(@store)
339
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.not-in-seg.segment-or", {"user" => {"key" => "nobody"}, "" => {"domain" => "gmail.com"}}, false)
340
+ rescue Exception => e
341
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
342
+ end
343
+ end
344
+
345
+ # returns false for NOT_IN_SEG (segment-or) if one segment rule matches (lookup)
346
+ def test_returns_false_for_not_in_seg_segment_or_if_one_segment_rule_matches_lookup
347
+ begin
348
+ resolver = IntegrationTestHelpers.build_resolver(@store)
349
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.not-in-seg.segment-or", {"user" => {"key" => "michael"}, "" => {"domain" => "example.com"}}, false)
350
+ rescue Exception => e
351
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
352
+ end
353
+ end
354
+
355
+ # returns true for PROP_BEFORE rule when the given prop represents a date (string) before the rule's time
356
+ def test_returns_true_for_prop_before_rule_when_the_given_prop_represents_a_date_string_before_the_rule_s_time
357
+ begin
358
+ resolver = IntegrationTestHelpers.build_resolver(@store)
359
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before", {"user" => {"creation_date" => "2024-11-01T00:00:00Z"}}, true)
360
+ rescue Exception => e
361
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
362
+ end
363
+ end
364
+
365
+ # returns true for PROP_BEFORE rule when the given prop represents a date (number) before the rule's time
366
+ def test_returns_true_for_prop_before_rule_when_the_given_prop_represents_a_date_number_before_the_rule_s_time
367
+ begin
368
+ resolver = IntegrationTestHelpers.build_resolver(@store)
369
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before", {"user" => {"creation_date" => 1730419200000}}, true)
370
+ rescue Exception => e
371
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
372
+ end
373
+ end
374
+
375
+ # returns false for PROP_BEFORE rule when the given prop represents a date (number) exactly matching rule's time
376
+ def test_returns_false_for_prop_before_rule_when_the_given_prop_represents_a_date_number_exactly_matching_rule_s_time
377
+ begin
378
+ resolver = IntegrationTestHelpers.build_resolver(@store)
379
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before", {"user" => {"creation_date" => 1733011200000}}, false)
380
+ rescue Exception => e
381
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
382
+ end
383
+ end
384
+
385
+ # returns false for PROP_BEFORE rule when the given prop represents a date (number) AFTER the rule's time
386
+ def test_returns_false_for_prop_before_rule_when_the_given_prop_represents_a_date_number_after_the_rule_s_time
387
+ begin
388
+ resolver = IntegrationTestHelpers.build_resolver(@store)
389
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before", {"user" => {"creation_date" => "2025-01-01T00:00:00Z"}}, false)
390
+ rescue Exception => e
391
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
392
+ end
393
+ end
394
+
395
+ # returns false for PROP_BEFORE rule when the given prop won't parse as a date
396
+ def test_returns_false_for_prop_before_rule_when_the_given_prop_won_t_parse_as_a_date
397
+ begin
398
+ resolver = IntegrationTestHelpers.build_resolver(@store)
399
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before", {"user" => {"creation_date" => "not a date"}}, false)
400
+ rescue Exception => e
401
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
402
+ end
403
+ end
404
+
405
+ # returns false for PROP_BEFORE rule using current-time relative to 2050-01-01
406
+ def test_returns_false_for_prop_before_rule_using_current_time_relative_to_2050_01_01
407
+ begin
408
+ resolver = IntegrationTestHelpers.build_resolver(@store)
409
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.before.current-time", {}, true)
410
+ rescue Exception => e
411
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
412
+ end
413
+ end
414
+
415
+ # returns true for PROP_AFTER rule when the given prop represents a date (string) after the rule's time
416
+ def test_returns_true_for_prop_after_rule_when_the_given_prop_represents_a_date_string_after_the_rule_s_time
417
+ begin
418
+ resolver = IntegrationTestHelpers.build_resolver(@store)
419
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after", {"user" => {"creation_date" => "2025-01-01T00:00:00Z"}}, true)
420
+ rescue Exception => e
421
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
422
+ end
423
+ end
424
+
425
+ # returns true for PROP_AFTER rule when the given prop represents a date (number) after the rule's time
426
+ def test_returns_true_for_prop_after_rule_when_the_given_prop_represents_a_date_number_after_the_rule_s_time
427
+ begin
428
+ resolver = IntegrationTestHelpers.build_resolver(@store)
429
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after", {"user" => {"creation_date" => 1735689600000}}, true)
430
+ rescue Exception => e
431
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
432
+ end
433
+ end
434
+
435
+ # returns false for PROP_AFTER rule when the given prop represents a date (number) exactly matching rule's time
436
+ def test_returns_false_for_prop_after_rule_when_the_given_prop_represents_a_date_number_exactly_matching_rule_s_time
437
+ begin
438
+ resolver = IntegrationTestHelpers.build_resolver(@store)
439
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after", {"user" => {"creation_date" => 1733011200000}}, false)
440
+ rescue Exception => e
441
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
442
+ end
443
+ end
444
+
445
+ # returns false for PROP_BEFORE rule when the given prop represents a date (number) BEFORE the rule's time
446
+ def test_returns_false_for_prop_before_rule_when_the_given_prop_represents_a_date_number_before_the_rule_s_time
447
+ begin
448
+ resolver = IntegrationTestHelpers.build_resolver(@store)
449
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after", {"user" => {"creation_date" => "2024-01-01T00:00:00Z"}}, false)
450
+ rescue Exception => e
451
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
452
+ end
453
+ end
454
+
455
+ # returns false for PROP_AFTER rule when the given prop won't parse as a date
456
+ def test_returns_false_for_prop_after_rule_when_the_given_prop_won_t_parse_as_a_date
457
+ begin
458
+ resolver = IntegrationTestHelpers.build_resolver(@store)
459
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after", {"user" => {"creation_date" => "not a date"}}, false)
460
+ rescue Exception => e
461
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
462
+ end
463
+ end
464
+
465
+ # returns false for PROP_AFTER rule using current-time relative to 2025-01-01
466
+ def test_returns_false_for_prop_after_rule_using_current_time_relative_to_2025_01_01
467
+ begin
468
+ resolver = IntegrationTestHelpers.build_resolver(@store)
469
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.after.current-time", {}, true)
470
+ rescue Exception => e
471
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
472
+ end
473
+ end
474
+
475
+ # returns true for PROP_LESS_THAN rule when the given prop is less than the rule's value
476
+ def test_returns_true_for_prop_less_than_rule_when_the_given_prop_is_less_than_the_rule_s_value
477
+ begin
478
+ resolver = IntegrationTestHelpers.build_resolver(@store)
479
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than", {"user" => {"age" => 20}}, true)
480
+ rescue Exception => e
481
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
482
+ end
483
+ end
484
+
485
+ # returns true for PROP_LESS_THAN rule when the given prop is less than the rule's value (float)
486
+ def test_returns_true_for_prop_less_than_rule_when_the_given_prop_is_less_than_the_rule_s_value_float
487
+ begin
488
+ resolver = IntegrationTestHelpers.build_resolver(@store)
489
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than", {"user" => {"age" => 20.5}}, true)
490
+ rescue Exception => e
491
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
492
+ end
493
+ end
494
+
495
+ # returns false for PROP_LESS_THAN rule when the given prop is equal to rule's value
496
+ def test_returns_false_for_prop_less_than_rule_when_the_given_prop_is_equal_to_rule_s_value
497
+ begin
498
+ resolver = IntegrationTestHelpers.build_resolver(@store)
499
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than", {"user" => {"age" => 30}}, false)
500
+ rescue Exception => e
501
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
502
+ end
503
+ end
504
+
505
+ # returns false for PROP_LESS_THAN rule when the given prop a string
506
+ def test_returns_false_for_prop_less_than_rule_when_the_given_prop_a_string
507
+ begin
508
+ resolver = IntegrationTestHelpers.build_resolver(@store)
509
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than", {"user" => {"age" => "20"}}, false)
510
+ rescue Exception => e
511
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
512
+ end
513
+ end
514
+
515
+ # returns true for PROP_LESS_THAN_OR_EQUAL rule when the given prop is less than the rule's value
516
+ def test_returns_true_for_prop_less_than_or_equal_rule_when_the_given_prop_is_less_than_the_rule_s_value
517
+ begin
518
+ resolver = IntegrationTestHelpers.build_resolver(@store)
519
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than-or-equal", {"user" => {"age" => 20}}, true)
520
+ rescue Exception => e
521
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
522
+ end
523
+ end
524
+
525
+ # returns true for PROP_LESS_THAN_OR_EQUAL rule when the given prop is less than the rule's value (float)
526
+ def test_returns_true_for_prop_less_than_or_equal_rule_when_the_given_prop_is_less_than_the_rule_s_value_float
527
+ begin
528
+ resolver = IntegrationTestHelpers.build_resolver(@store)
529
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than-or-equal", {"user" => {"age" => 20.5}}, true)
530
+ rescue Exception => e
531
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
532
+ end
533
+ end
534
+
535
+ # returns false for PROP_LESS_THAN_OR_EQUAL rule when the given prop is equal to rule's value
536
+ def test_returns_false_for_prop_less_than_or_equal_rule_when_the_given_prop_is_equal_to_rule_s_value
537
+ begin
538
+ resolver = IntegrationTestHelpers.build_resolver(@store)
539
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than-or-equal", {"user" => {"age" => 30}}, true)
540
+ rescue Exception => e
541
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
542
+ end
543
+ end
544
+
545
+ # returns false for PROP_LESS_THAN_OR_EQUAL rule when the given prop a string
546
+ def test_returns_false_for_prop_less_than_or_equal_rule_when_the_given_prop_a_string
547
+ begin
548
+ resolver = IntegrationTestHelpers.build_resolver(@store)
549
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.less-than-or-equal", {"user" => {"age" => "20"}}, false)
550
+ rescue Exception => e
551
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
552
+ end
553
+ end
554
+
555
+ # returns true for PROP_GREATER_THAN rule when the given prop is greater than the rule's value
556
+ def test_returns_true_for_prop_greater_than_rule_when_the_given_prop_is_greater_than_the_rule_s_value
557
+ begin
558
+ resolver = IntegrationTestHelpers.build_resolver(@store)
559
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than", {"user" => {"age" => 100}}, true)
560
+ rescue Exception => e
561
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
562
+ end
563
+ end
564
+
565
+ # returns true for PROP_GREATER_THAN rule when the given prop is greater than the rule's value (float)
566
+ def test_returns_true_for_prop_greater_than_rule_when_the_given_prop_is_greater_than_the_rule_s_value_float
567
+ begin
568
+ resolver = IntegrationTestHelpers.build_resolver(@store)
569
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than", {"user" => {"age" => 30.5}}, true)
570
+ rescue Exception => e
571
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
572
+ end
573
+ end
574
+
575
+ # returns true for PROP_GREATER_THAN rule when the given prop is greater than the rule's float value (float)
576
+ def test_returns_true_for_prop_greater_than_rule_when_the_given_prop_is_greater_than_the_rule_s_float_value_float
577
+ begin
578
+ resolver = IntegrationTestHelpers.build_resolver(@store)
579
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than.double", {"user" => {"age" => 32.7}}, true)
580
+ rescue Exception => e
581
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
582
+ end
583
+ end
584
+
585
+ # returns true for PROP_GREATER_THAN rule when the given prop is greater than the rule's float value (integer)
586
+ def test_returns_true_for_prop_greater_than_rule_when_the_given_prop_is_greater_than_the_rule_s_float_value_integer
587
+ begin
588
+ resolver = IntegrationTestHelpers.build_resolver(@store)
589
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than.double", {"user" => {"age" => 32}}, true)
590
+ rescue Exception => e
591
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
592
+ end
593
+ end
594
+
595
+ # returns false for PROP_GREATER_THAN rule when the given prop is equal to rule's value
596
+ def test_returns_false_for_prop_greater_than_rule_when_the_given_prop_is_equal_to_rule_s_value
597
+ begin
598
+ resolver = IntegrationTestHelpers.build_resolver(@store)
599
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than", {"user" => {"age" => 30}}, false)
600
+ rescue Exception => e
601
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
602
+ end
603
+ end
604
+
605
+ # returns false for PROP_GREATER_THAN rule when the given prop a string
606
+ def test_returns_false_for_prop_greater_than_rule_when_the_given_prop_a_string
607
+ begin
608
+ resolver = IntegrationTestHelpers.build_resolver(@store)
609
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than", {"user" => {"age" => "100"}}, false)
610
+ rescue Exception => e
611
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
612
+ end
613
+ end
614
+
615
+ # returns true for PROP_GREATER_THAN_OR_EQUAL rule when the given prop is greater than the rule's value
616
+ def test_returns_true_for_prop_greater_than_or_equal_rule_when_the_given_prop_is_greater_than_the_rule_s_value
617
+ begin
618
+ resolver = IntegrationTestHelpers.build_resolver(@store)
619
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than-or-equal", {"user" => {"age" => 30}}, true)
620
+ rescue Exception => e
621
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
622
+ end
623
+ end
624
+
625
+ # returns true for PROP_GREATER_THAN_OR_EQUAL rule when the given prop is greater than the rule's value (float)
626
+ def test_returns_true_for_prop_greater_than_or_equal_rule_when_the_given_prop_is_greater_than_the_rule_s_value_float
627
+ begin
628
+ resolver = IntegrationTestHelpers.build_resolver(@store)
629
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than-or-equal", {"user" => {"age" => 30.5}}, true)
630
+ rescue Exception => e
631
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
632
+ end
633
+ end
634
+
635
+ # returns true for PROP_GREATER_THAN_OR_EQUAL rule when the given prop is equal to rule's value
636
+ def test_returns_true_for_prop_greater_than_or_equal_rule_when_the_given_prop_is_equal_to_rule_s_value
637
+ begin
638
+ resolver = IntegrationTestHelpers.build_resolver(@store)
639
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than-or-equal", {"user" => {"age" => 30}}, true)
640
+ rescue Exception => e
641
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
642
+ end
643
+ end
644
+
645
+ # returns false for PROP_GREATER_THAN_OR_EQUAL rule when the given prop a string
646
+ def test_returns_false_for_prop_greater_than_or_equal_rule_when_the_given_prop_a_string
647
+ begin
648
+ resolver = IntegrationTestHelpers.build_resolver(@store)
649
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.greater-than-or-equal", {"user" => {"age" => "100"}}, false)
650
+ rescue Exception => e
651
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
652
+ end
653
+ end
654
+
655
+ # returns true for PROP_MATCHES rule when the given prop matches the regex
656
+ def test_returns_true_for_prop_matches_rule_when_the_given_prop_matches_the_regex
657
+ begin
658
+ resolver = IntegrationTestHelpers.build_resolver(@store)
659
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.matches", {"user" => {"code" => "aaaaaab"}}, true)
660
+ rescue Exception => e
661
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
662
+ end
663
+ end
664
+
665
+ # returns false for PROP_MATCHES rule when the given prop does not match the regex
666
+ def test_returns_false_for_prop_matches_rule_when_the_given_prop_does_not_match_the_regex
667
+ begin
668
+ resolver = IntegrationTestHelpers.build_resolver(@store)
669
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.matches", {"user" => {"code" => "aa"}}, false)
670
+ rescue Exception => e
671
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
672
+ end
673
+ end
674
+
675
+ # returns true for PROP_DOES_NOT_MATCH rule when the given prop does not match the regex
676
+ def test_returns_true_for_prop_does_not_match_rule_when_the_given_prop_does_not_match_the_regex
677
+ begin
678
+ resolver = IntegrationTestHelpers.build_resolver(@store)
679
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.does-not-match", {"user" => {"code" => "b"}}, true)
680
+ rescue Exception => e
681
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
682
+ end
683
+ end
684
+
685
+ # returns false for PROP_DOES_NOT_MATCH rule when the given prop matches the regex
686
+ def test_returns_false_for_prop_does_not_match_rule_when_the_given_prop_matches_the_regex
687
+ begin
688
+ resolver = IntegrationTestHelpers.build_resolver(@store)
689
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.does-not-match", {"user" => {"code" => "aabb"}}, false)
690
+ rescue Exception => e
691
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
692
+ end
693
+ end
694
+
695
+ # returns true for PROP_SEMVER_EQUAL rule when the given prop equals the version
696
+ def test_returns_true_for_prop_semver_equal_rule_when_the_given_prop_equals_the_version
697
+ begin
698
+ resolver = IntegrationTestHelpers.build_resolver(@store)
699
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-equal", {"app" => {"version" => "2.0.0"}}, true)
700
+ rescue Exception => e
701
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
702
+ end
703
+ end
704
+
705
+ # returns false for PROP_SEMVER_EQUAL rule when the given prop does not equal the version
706
+ def test_returns_false_for_prop_semver_equal_rule_when_the_given_prop_does_not_equal_the_version
707
+ begin
708
+ resolver = IntegrationTestHelpers.build_resolver(@store)
709
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-equal", {"app" => {"version" => "2.0.1"}}, false)
710
+ rescue Exception => e
711
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
712
+ end
713
+ end
714
+
715
+ # returns false for PROP_SEMVER_EQUAL rule when the given prop is not a valid semver
716
+ def test_returns_false_for_prop_semver_equal_rule_when_the_given_prop_is_not_a_valid_semver
717
+ begin
718
+ resolver = IntegrationTestHelpers.build_resolver(@store)
719
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-equal", {"app" => {"version" => "2.0"}}, false)
720
+ rescue Exception => e
721
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
722
+ end
723
+ end
724
+
725
+ # returns true for PROP_SEMVER_LESS_THAN rule when the given prop is less than 2.0.0
726
+ def test_returns_true_for_prop_semver_less_than_rule_when_the_given_prop_is_less_than_2_0_0
727
+ begin
728
+ resolver = IntegrationTestHelpers.build_resolver(@store)
729
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-less-than", {"app" => {"version" => "1.5.1"}}, true)
730
+ rescue Exception => e
731
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
732
+ end
733
+ end
734
+
735
+ # returns false for PROP_SEMVER_LESS_THAN rule when the given prop equals the version
736
+ def test_returns_false_for_prop_semver_less_than_rule_when_the_given_prop_equals_the_version
737
+ begin
738
+ resolver = IntegrationTestHelpers.build_resolver(@store)
739
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-less-than", {"app" => {"version" => "2.0.0"}}, false)
740
+ rescue Exception => e
741
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
742
+ end
743
+ end
744
+
745
+ # returns false for PROP_SEMVER_LESS_THAN rule when the given prop is greater than the version
746
+ def test_returns_false_for_prop_semver_less_than_rule_when_the_given_prop_is_greater_than_the_version
747
+ begin
748
+ resolver = IntegrationTestHelpers.build_resolver(@store)
749
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-less-than", {"app" => {"version" => "2.2.1"}}, false)
750
+ rescue Exception => e
751
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
752
+ end
753
+ end
754
+
755
+ # returns true for PROP_SEMVER_GREATER_THAN rule when the given prop is greater than 2.0.0
756
+ def test_returns_true_for_prop_semver_greater_than_rule_when_the_given_prop_is_greater_than_2_0_0
757
+ begin
758
+ resolver = IntegrationTestHelpers.build_resolver(@store)
759
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-greater-than", {"app" => {"version" => "2.5.1"}}, true)
760
+ rescue Exception => e
761
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
762
+ end
763
+ end
764
+
765
+ # returns false for PROP_SEMVER_GREATER_THAN rule when the given prop equals the version
766
+ def test_returns_false_for_prop_semver_greater_than_rule_when_the_given_prop_equals_the_version
767
+ begin
768
+ resolver = IntegrationTestHelpers.build_resolver(@store)
769
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-greater-than", {"app" => {"version" => "2.0.0"}}, false)
770
+ rescue Exception => e
771
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
772
+ end
773
+ end
774
+
775
+ # returns false for PROP_SEMVER_EQUAL rule when the given prop is less than the version
776
+ def test_returns_false_for_prop_semver_equal_rule_when_the_given_prop_is_less_than_the_version
777
+ begin
778
+ resolver = IntegrationTestHelpers.build_resolver(@store)
779
+ IntegrationTestHelpers.assert_resolved(resolver, "feature-flag.semver-greater-than", {"app" => {"version" => "0.0.5"}}, false)
780
+ rescue Exception => e
781
+ skip("resolver not yet ported for this case: #{e.class}: #{e.message}")
782
+ end
783
+ end
784
+ end