flipper 0.26.2 → 0.28.3

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +61 -0
  3. data/Gemfile +2 -3
  4. data/benchmark/enabled_multiple_actors_ips.rb +20 -0
  5. data/examples/api/basic.ru +3 -4
  6. data/examples/api/custom_memoized.ru +3 -4
  7. data/examples/api/memoized.ru +3 -4
  8. data/examples/dsl.rb +3 -3
  9. data/examples/enabled_for_actor.rb +4 -2
  10. data/examples/mirroring.rb +59 -0
  11. data/lib/flipper/adapter.rb +23 -7
  12. data/lib/flipper/adapters/http.rb +11 -3
  13. data/lib/flipper/adapters/instrumented.rb +25 -2
  14. data/lib/flipper/adapters/memoizable.rb +19 -2
  15. data/lib/flipper/adapters/memory.rb +40 -16
  16. data/lib/flipper/adapters/operation_logger.rb +16 -3
  17. data/lib/flipper/dsl.rb +5 -9
  18. data/lib/flipper/errors.rb +3 -3
  19. data/lib/flipper/export.rb +26 -0
  20. data/lib/flipper/exporter.rb +17 -0
  21. data/lib/flipper/exporters/json/export.rb +32 -0
  22. data/lib/flipper/exporters/json/v1.rb +33 -0
  23. data/lib/flipper/feature.rb +12 -10
  24. data/lib/flipper/feature_check_context.rb +8 -4
  25. data/lib/flipper/gate.rb +12 -11
  26. data/lib/flipper/gates/actor.rb +11 -8
  27. data/lib/flipper/gates/group.rb +4 -2
  28. data/lib/flipper/gates/percentage_of_actors.rb +4 -5
  29. data/lib/flipper/identifier.rb +2 -2
  30. data/lib/flipper/instrumentation/log_subscriber.rb +24 -5
  31. data/lib/flipper/instrumentation/subscriber.rb +8 -1
  32. data/lib/flipper/poller.rb +1 -1
  33. data/lib/flipper/spec/shared_adapter_specs.rb +23 -0
  34. data/lib/flipper/test/shared_adapter_test.rb +24 -0
  35. data/lib/flipper/typecast.rb +17 -0
  36. data/lib/flipper/types/actor.rb +13 -13
  37. data/lib/flipper/types/group.rb +4 -4
  38. data/lib/flipper/version.rb +1 -1
  39. data/lib/flipper.rb +5 -4
  40. data/spec/fixtures/flipper_pstore_1679087600.json +46 -0
  41. data/spec/flipper/adapter_spec.rb +29 -2
  42. data/spec/flipper/adapters/http_spec.rb +25 -3
  43. data/spec/flipper/adapters/instrumented_spec.rb +28 -10
  44. data/spec/flipper/adapters/memoizable_spec.rb +30 -10
  45. data/spec/flipper/adapters/memory_spec.rb +11 -2
  46. data/spec/flipper/adapters/operation_logger_spec.rb +29 -10
  47. data/spec/flipper/dsl_spec.rb +25 -8
  48. data/spec/flipper/export_spec.rb +13 -0
  49. data/spec/flipper/exporter_spec.rb +16 -0
  50. data/spec/flipper/exporters/json/export_spec.rb +60 -0
  51. data/spec/flipper/exporters/json/v1_spec.rb +33 -0
  52. data/spec/flipper/feature_check_context_spec.rb +5 -5
  53. data/spec/flipper/feature_spec.rb +76 -32
  54. data/spec/flipper/gates/boolean_spec.rb +1 -1
  55. data/spec/flipper/gates/group_spec.rb +2 -3
  56. data/spec/flipper/gates/percentage_of_actors_spec.rb +61 -5
  57. data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
  58. data/spec/flipper/instrumentation/log_subscriber_spec.rb +15 -5
  59. data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +10 -0
  60. data/spec/flipper/typecast_spec.rb +79 -0
  61. data/spec/flipper/types/actor_spec.rb +45 -45
  62. data/spec/flipper/types/group_spec.rb +2 -2
  63. data/spec/flipper_integration_spec.rb +62 -50
  64. data/spec/flipper_spec.rb +7 -1
  65. data/spec/support/skippable.rb +18 -0
  66. metadata +20 -2
@@ -7,17 +7,17 @@ RSpec.describe Flipper do
7
7
  let(:admin_group) { flipper.group(:admins) }
8
8
  let(:dev_group) { flipper.group(:devs) }
9
9
 
10
- let(:admin_thing) do
10
+ let(:admin_actor) do
11
11
  double 'Non Flipper Thing', flipper_id: 1, admin?: true, dev?: false
12
12
  end
13
- let(:dev_thing) do
13
+ let(:dev_actor) do
14
14
  double 'Non Flipper Thing', flipper_id: 10, admin?: false, dev?: true
15
15
  end
16
16
 
17
- let(:admin_truthy_thing) do
17
+ let(:admin_truthy_actor) do
18
18
  double 'Non Flipper Thing', flipper_id: 1, admin?: 'true-ish', dev?: false
19
19
  end
20
- let(:admin_falsey_thing) do
20
+ let(:admin_falsey_actor) do
21
21
  double 'Non Flipper Thing', flipper_id: 1, admin?: nil, dev?: false
22
22
  end
23
23
 
@@ -60,20 +60,20 @@ RSpec.describe Flipper do
60
60
  expect(@result).to eq(true)
61
61
  end
62
62
 
63
- it 'enables feature for non flipper thing in group' do
64
- expect(feature.enabled?(admin_thing)).to eq(true)
63
+ it 'enables feature for non flipper actor in group' do
64
+ expect(feature.enabled?(admin_actor)).to eq(true)
65
65
  end
66
66
 
67
- it 'does not enable feature for non flipper thing in other group' do
68
- expect(feature.enabled?(dev_thing)).to eq(false)
67
+ it 'does not enable feature for non flipper actor in other group' do
68
+ expect(feature.enabled?(dev_actor)).to eq(false)
69
69
  end
70
70
 
71
71
  it 'enables feature for flipper actor in group' do
72
- expect(feature.enabled?(flipper.actor(admin_thing))).to eq(true)
72
+ expect(feature.enabled?(flipper.actor(admin_actor))).to eq(true)
73
73
  end
74
74
 
75
75
  it 'does not enable for flipper actor not in group' do
76
- expect(feature.enabled?(flipper.actor(dev_thing))).to eq(false)
76
+ expect(feature.enabled?(flipper.actor(dev_actor))).to eq(false)
77
77
  end
78
78
 
79
79
  it 'does not enable feature for all' do
@@ -118,8 +118,8 @@ RSpec.describe Flipper do
118
118
 
119
119
  it 'enables feature for actor within percentage' do
120
120
  enabled = (1..100).select do |i|
121
- thing = Flipper::Actor.new(i)
122
- feature.enabled?(thing)
121
+ actor = Flipper::Actor.new(i)
122
+ feature.enabled?(actor)
123
123
  end.size
124
124
 
125
125
  expect(enabled).to be_within(2).of(5)
@@ -141,8 +141,8 @@ RSpec.describe Flipper do
141
141
 
142
142
  it 'enables feature for actor within percentage' do
143
143
  enabled = (1..100).select do |i|
144
- thing = Flipper::Actor.new(i)
145
- feature.enabled?(thing)
144
+ actor = Flipper::Actor.new(i)
145
+ feature.enabled?(actor)
146
146
  end.size
147
147
 
148
148
  expect(enabled).to be_within(2).of(5)
@@ -180,10 +180,10 @@ RSpec.describe Flipper do
180
180
 
181
181
  context 'with argument that has no gate' do
182
182
  it 'raises error' do
183
- thing = Object.new
183
+ actor = Object.new
184
184
  expect do
185
- feature.enable(thing)
186
- end.to raise_error(Flipper::GateNotFound, "Could not find gate for #{thing.inspect}")
185
+ feature.enable(actor)
186
+ end.to raise_error(Flipper::GateNotFound, "Could not find gate for #{actor.inspect}")
187
187
  end
188
188
  end
189
189
  end
@@ -215,13 +215,13 @@ RSpec.describe Flipper do
215
215
  end
216
216
 
217
217
  it 'disables actor in group' do
218
- expect(feature.enabled?(admin_thing)).to eq(false)
218
+ expect(feature.enabled?(admin_actor)).to eq(false)
219
219
  end
220
220
 
221
221
  it 'disables actor in percentage of actors' do
222
222
  enabled = (1..100).select do |i|
223
- thing = Flipper::Actor.new(i)
224
- feature.enabled?(thing)
223
+ actor = Flipper::Actor.new(i)
224
+ feature.enabled?(actor)
225
225
  end.size
226
226
 
227
227
  expect(enabled).to be(0)
@@ -247,20 +247,20 @@ RSpec.describe Flipper do
247
247
  expect(@result).to eq(true)
248
248
  end
249
249
 
250
- it 'disables the feature for non flipper thing in the group' do
251
- expect(feature.enabled?(admin_thing)).to eq(false)
250
+ it 'disables the feature for non flipper actor in the group' do
251
+ expect(feature.enabled?(admin_actor)).to eq(false)
252
252
  end
253
253
 
254
- it 'does not disable feature for non flipper thing in other groups' do
255
- expect(feature.enabled?(dev_thing)).to eq(true)
254
+ it 'does not disable feature for non flipper actor in other groups' do
255
+ expect(feature.enabled?(dev_actor)).to eq(true)
256
256
  end
257
257
 
258
258
  it 'disables feature for flipper actor in group' do
259
- expect(feature.enabled?(flipper.actor(admin_thing))).to eq(false)
259
+ expect(feature.enabled?(flipper.actor(admin_actor))).to eq(false)
260
260
  end
261
261
 
262
262
  it 'does not disable feature for flipper actor in other groups' do
263
- expect(feature.enabled?(flipper.actor(dev_thing))).to eq(true)
263
+ expect(feature.enabled?(flipper.actor(dev_actor))).to eq(true)
264
264
  end
265
265
 
266
266
  it 'adds feature to set of features' do
@@ -303,8 +303,8 @@ RSpec.describe Flipper do
303
303
 
304
304
  it 'disables feature' do
305
305
  enabled = (1..100).select do |i|
306
- thing = Flipper::Actor.new(i)
307
- feature.enabled?(thing)
306
+ actor = Flipper::Actor.new(i)
307
+ feature.enabled?(actor)
308
308
  end.size
309
309
 
310
310
  expect(enabled).to be(0)
@@ -342,10 +342,10 @@ RSpec.describe Flipper do
342
342
 
343
343
  context 'with argument that has no gate' do
344
344
  it 'raises error' do
345
- thing = Object.new
345
+ actor = Object.new
346
346
  expect do
347
- feature.disable(thing)
348
- end.to raise_error(Flipper::GateNotFound, "Could not find gate for #{thing.inspect}")
347
+ feature.disable(actor)
348
+ end.to raise_error(Flipper::GateNotFound, "Could not find gate for #{actor.inspect}")
349
349
  end
350
350
  end
351
351
  end
@@ -373,23 +373,27 @@ RSpec.describe Flipper do
373
373
  end
374
374
 
375
375
  it 'returns true' do
376
- expect(feature.enabled?(flipper.actor(admin_thing))).to eq(true)
377
- expect(feature.enabled?(admin_thing)).to eq(true)
376
+ expect(feature.enabled?(flipper.actor(admin_actor))).to eq(true)
377
+ expect(feature.enabled?(admin_actor)).to eq(true)
378
378
  end
379
379
 
380
380
  it 'returns true for truthy block values' do
381
- expect(feature.enabled?(flipper.actor(admin_truthy_thing))).to eq(true)
381
+ expect(feature.enabled?(flipper.actor(admin_truthy_actor))).to eq(true)
382
+ end
383
+
384
+ it 'returns true if any actor is in enabled group' do
385
+ expect(feature.enabled?(dev_actor, admin_actor)).to be(true)
382
386
  end
383
387
  end
384
388
 
385
389
  context 'for actor in disabled group' do
386
390
  it 'returns false' do
387
- expect(feature.enabled?(flipper.actor(dev_thing))).to eq(false)
388
- expect(feature.enabled?(dev_thing)).to eq(false)
391
+ expect(feature.enabled?(flipper.actor(dev_actor))).to eq(false)
392
+ expect(feature.enabled?(dev_actor)).to eq(false)
389
393
  end
390
394
 
391
395
  it 'returns false for falsey block values' do
392
- expect(feature.enabled?(flipper.actor(admin_falsey_thing))).to eq(false)
396
+ expect(feature.enabled?(flipper.actor(admin_falsey_actor))).to eq(false)
393
397
  end
394
398
  end
395
399
 
@@ -408,6 +412,10 @@ RSpec.describe Flipper do
408
412
  expect(feature.enabled?(clooney)).to eq(false)
409
413
  end
410
414
 
415
+ it 'returns false if all actors are disabled' do
416
+ expect(feature.enabled?(clooney, pitt)).to be(false)
417
+ end
418
+
411
419
  it 'returns true if boolean enabled' do
412
420
  feature.enable
413
421
  expect(feature.enabled?(clooney)).to eq(true)
@@ -428,7 +436,7 @@ RSpec.describe Flipper do
428
436
  expect(feature.enabled?).to eq(true)
429
437
  expect(feature.enabled?(nil)).to eq(true)
430
438
  expect(feature.enabled?(pitt)).to eq(true)
431
- expect(feature.enabled?(admin_thing)).to eq(true)
439
+ expect(feature.enabled?(admin_actor)).to eq(true)
432
440
  end
433
441
  end
434
442
 
@@ -446,7 +454,7 @@ RSpec.describe Flipper do
446
454
  expect(feature.enabled?).to eq(true)
447
455
  expect(feature.enabled?(nil)).to eq(true)
448
456
  expect(feature.enabled?(pitt)).to eq(true)
449
- expect(feature.enabled?(admin_thing)).to eq(true)
457
+ expect(feature.enabled?(admin_actor)).to eq(true)
450
458
  end
451
459
  end
452
460
 
@@ -463,7 +471,7 @@ RSpec.describe Flipper do
463
471
  expect(feature.enabled?).to eq(false)
464
472
  expect(feature.enabled?(nil)).to eq(false)
465
473
  expect(feature.enabled?(pitt)).to eq(false)
466
- expect(feature.enabled?(admin_thing)).to eq(false)
474
+ expect(feature.enabled?(admin_actor)).to eq(false)
467
475
  end
468
476
 
469
477
  it 'returns true if boolean enabled' do
@@ -471,7 +479,7 @@ RSpec.describe Flipper do
471
479
  expect(feature.enabled?).to eq(true)
472
480
  expect(feature.enabled?(nil)).to eq(true)
473
481
  expect(feature.enabled?(pitt)).to eq(true)
474
- expect(feature.enabled?(admin_thing)).to eq(true)
482
+ expect(feature.enabled?(admin_actor)).to eq(true)
475
483
  end
476
484
  end
477
485
 
@@ -488,7 +496,7 @@ RSpec.describe Flipper do
488
496
  expect(feature.enabled?).to eq(false)
489
497
  expect(feature.enabled?(nil)).to eq(false)
490
498
  expect(feature.enabled?(pitt)).to eq(false)
491
- expect(feature.enabled?(admin_thing)).to eq(false)
499
+ expect(feature.enabled?(admin_actor)).to eq(false)
492
500
  end
493
501
 
494
502
  it 'returns true if boolean enabled' do
@@ -496,27 +504,31 @@ RSpec.describe Flipper do
496
504
  expect(feature.enabled?).to eq(true)
497
505
  expect(feature.enabled?(nil)).to eq(true)
498
506
  expect(feature.enabled?(pitt)).to eq(true)
499
- expect(feature.enabled?(admin_thing)).to eq(true)
507
+ expect(feature.enabled?(admin_actor)).to eq(true)
500
508
  end
501
509
  end
502
510
 
503
- context 'for a non flipper thing' do
511
+ context 'for a non flipper actor' do
504
512
  before do
505
513
  feature.enable admin_group
506
514
  end
507
515
 
508
516
  it 'returns true if in enabled group' do
509
- expect(feature.enabled?(admin_thing)).to eq(true)
517
+ expect(feature.enabled?(admin_actor)).to eq(true)
510
518
  end
511
519
 
512
520
  it 'returns false if not in enabled group' do
513
- expect(feature.enabled?(dev_thing)).to eq(false)
521
+ expect(feature.enabled?(dev_actor)).to eq(false)
522
+ end
523
+
524
+ it 'retruns true if any actor is true' do
525
+ expect(feature.enabled?(admin_actor, dev_actor)).to eq(true)
514
526
  end
515
527
 
516
528
  it 'returns true if boolean enabled' do
517
529
  feature.enable
518
- expect(feature.enabled?(admin_thing)).to eq(true)
519
- expect(feature.enabled?(dev_thing)).to eq(true)
530
+ expect(feature.enabled?(admin_actor)).to eq(true)
531
+ expect(feature.enabled?(dev_actor)).to eq(true)
520
532
  end
521
533
  end
522
534
  end
@@ -530,11 +542,11 @@ RSpec.describe Flipper do
530
542
  end
531
543
 
532
544
  it 'enables feature for object in enabled group' do
533
- expect(feature.enabled?(admin_thing)).to eq(true)
545
+ expect(feature.enabled?(admin_actor)).to eq(true)
534
546
  end
535
547
 
536
548
  it 'does not enable feature for object in not enabled group' do
537
- expect(feature.enabled?(dev_thing)).to eq(false)
549
+ expect(feature.enabled?(dev_actor)).to eq(false)
538
550
  end
539
551
  end
540
552
  end
data/spec/flipper_spec.rb CHANGED
@@ -202,6 +202,12 @@ RSpec.describe Flipper do
202
202
  expect(described_class.enabled?(:search)).to be(true)
203
203
  end
204
204
 
205
+ it 'delegates export to instance' do
206
+ described_class.enable(:search)
207
+ expect(described_class.export).to eq(described_class.adapter.export)
208
+ expect(described_class.export(format: :json)).to eq(described_class.adapter.export(format: :json))
209
+ end
210
+
205
211
  it 'delegates adapter to instance' do
206
212
  expect(described_class.adapter).to eq(described_class.instance.adapter)
207
213
  end
@@ -222,7 +228,7 @@ RSpec.describe Flipper do
222
228
  end
223
229
 
224
230
  it 'delegates sync stuff to instance for Flipper::Cloud' do
225
- stub = stub_request(:get, "https://www.flippercloud.io/adapter/features").
231
+ stub = stub_request(:get, "https://www.flippercloud.io/adapter/features?exclude_gate_names=true").
226
232
  with({
227
233
  headers: {
228
234
  'Flipper-Cloud-Token'=>'asdf',
@@ -0,0 +1,18 @@
1
+ RSpec.configure do |config|
2
+ config.before(:all) do
3
+ $skip = false
4
+ end
5
+
6
+ def skip_on_error(error, message, &block)
7
+ # Premptively skip if we've already skipped
8
+ skip(message) if $skip
9
+ block.call
10
+ rescue error
11
+ if ENV["CI"]
12
+ raise
13
+ else
14
+ $skip = true
15
+ skip(message)
16
+ end
17
+ end
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.2
4
+ version: 0.28.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-15 00:00:00.000000000 Z
11
+ date: 2023-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -45,6 +45,7 @@ files:
45
45
  - README.md
46
46
  - Rakefile
47
47
  - benchmark/enabled_ips.rb
48
+ - benchmark/enabled_multiple_actors_ips.rb
48
49
  - benchmark/enabled_profile.rb
49
50
  - benchmark/instrumentation_ips.rb
50
51
  - benchmark/typecast_ips.rb
@@ -67,6 +68,7 @@ files:
67
68
  - examples/instrumentation.rb
68
69
  - examples/instrumentation_last_accessed_at.rb
69
70
  - examples/memoizing.rb
71
+ - examples/mirroring.rb
70
72
  - examples/percentage_of_actors.rb
71
73
  - examples/percentage_of_actors_enabled_check.rb
72
74
  - examples/percentage_of_actors_group.rb
@@ -96,6 +98,10 @@ files:
96
98
  - lib/flipper/configuration.rb
97
99
  - lib/flipper/dsl.rb
98
100
  - lib/flipper/errors.rb
101
+ - lib/flipper/export.rb
102
+ - lib/flipper/exporter.rb
103
+ - lib/flipper/exporters/json/export.rb
104
+ - lib/flipper/exporters/json/v1.rb
99
105
  - lib/flipper/feature.rb
100
106
  - lib/flipper/feature_check_context.rb
101
107
  - lib/flipper/gate.rb
@@ -130,6 +136,7 @@ files:
130
136
  - lib/flipper/types/percentage_of_time.rb
131
137
  - lib/flipper/version.rb
132
138
  - spec/fixtures/feature.json
139
+ - spec/fixtures/flipper_pstore_1679087600.json
133
140
  - spec/flipper/actor_spec.rb
134
141
  - spec/flipper/adapter_spec.rb
135
142
  - spec/flipper/adapters/dual_write_spec.rb
@@ -148,6 +155,10 @@ files:
148
155
  - spec/flipper/adapters/sync_spec.rb
149
156
  - spec/flipper/configuration_spec.rb
150
157
  - spec/flipper/dsl_spec.rb
158
+ - spec/flipper/export_spec.rb
159
+ - spec/flipper/exporter_spec.rb
160
+ - spec/flipper/exporters/json/export_spec.rb
161
+ - spec/flipper/exporters/json/v1_spec.rb
151
162
  - spec/flipper/feature_check_context_spec.rb
152
163
  - spec/flipper/feature_spec.rb
153
164
  - spec/flipper/gate_spec.rb
@@ -179,6 +190,7 @@ files:
179
190
  - spec/spec_helper.rb
180
191
  - spec/support/descriptions.yml
181
192
  - spec/support/fake_udp_socket.rb
193
+ - spec/support/skippable.rb
182
194
  - spec/support/spec_helpers.rb
183
195
  - test/adapters/memory_test.rb
184
196
  - test/adapters/pstore_test.rb
@@ -210,6 +222,7 @@ specification_version: 4
210
222
  summary: Feature flipper for ANYTHING
211
223
  test_files:
212
224
  - spec/fixtures/feature.json
225
+ - spec/fixtures/flipper_pstore_1679087600.json
213
226
  - spec/flipper/actor_spec.rb
214
227
  - spec/flipper/adapter_spec.rb
215
228
  - spec/flipper/adapters/dual_write_spec.rb
@@ -228,6 +241,10 @@ test_files:
228
241
  - spec/flipper/adapters/sync_spec.rb
229
242
  - spec/flipper/configuration_spec.rb
230
243
  - spec/flipper/dsl_spec.rb
244
+ - spec/flipper/export_spec.rb
245
+ - spec/flipper/exporter_spec.rb
246
+ - spec/flipper/exporters/json/export_spec.rb
247
+ - spec/flipper/exporters/json/v1_spec.rb
231
248
  - spec/flipper/feature_check_context_spec.rb
232
249
  - spec/flipper/feature_spec.rb
233
250
  - spec/flipper/gate_spec.rb
@@ -259,6 +276,7 @@ test_files:
259
276
  - spec/spec_helper.rb
260
277
  - spec/support/descriptions.yml
261
278
  - spec/support/fake_udp_socket.rb
279
+ - spec/support/skippable.rb
262
280
  - spec/support/spec_helpers.rb
263
281
  - test/adapters/memory_test.rb
264
282
  - test/adapters/pstore_test.rb