flipper 1.3.2 → 1.4.1

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +9 -6
  3. data/.github/workflows/examples.yml +5 -4
  4. data/.github/workflows/release.yml +54 -0
  5. data/.superset/config.json +4 -0
  6. data/CLAUDE.md +93 -0
  7. data/Gemfile +6 -2
  8. data/README.md +4 -3
  9. data/examples/cloud/backoff_policy.rb +1 -1
  10. data/examples/cloud/poll_interval/README.md +111 -0
  11. data/examples/cloud/poll_interval/client.rb +108 -0
  12. data/examples/cloud/poll_interval/server.rb +98 -0
  13. data/examples/expressions.rb +35 -11
  14. data/lib/flipper/adapter.rb +17 -1
  15. data/lib/flipper/adapters/actor_limit.rb +27 -1
  16. data/lib/flipper/adapters/cache_base.rb +21 -3
  17. data/lib/flipper/adapters/dual_write.rb +6 -2
  18. data/lib/flipper/adapters/failover.rb +9 -3
  19. data/lib/flipper/adapters/failsafe.rb +2 -2
  20. data/lib/flipper/adapters/http/client.rb +15 -4
  21. data/lib/flipper/adapters/http/error.rb +1 -1
  22. data/lib/flipper/adapters/http.rb +39 -4
  23. data/lib/flipper/adapters/instrumented.rb +2 -2
  24. data/lib/flipper/adapters/memoizable.rb +3 -3
  25. data/lib/flipper/adapters/memory.rb +1 -1
  26. data/lib/flipper/adapters/poll.rb +15 -0
  27. data/lib/flipper/adapters/pstore.rb +1 -1
  28. data/lib/flipper/adapters/strict.rb +30 -0
  29. data/lib/flipper/adapters/sync/feature_synchronizer.rb +5 -1
  30. data/lib/flipper/adapters/sync/synchronizer.rb +13 -5
  31. data/lib/flipper/adapters/sync.rb +7 -3
  32. data/lib/flipper/cli.rb +51 -0
  33. data/lib/flipper/cloud/configuration.rb +14 -6
  34. data/lib/flipper/cloud/dsl.rb +2 -2
  35. data/lib/flipper/cloud/middleware.rb +1 -1
  36. data/lib/flipper/cloud/migrate.rb +71 -0
  37. data/lib/flipper/cloud/telemetry/backoff_policy.rb +6 -3
  38. data/lib/flipper/cloud/telemetry/submitter.rb +3 -1
  39. data/lib/flipper/cloud/telemetry.rb +3 -3
  40. data/lib/flipper/cloud.rb +1 -0
  41. data/lib/flipper/dsl.rb +1 -1
  42. data/lib/flipper/export.rb +0 -2
  43. data/lib/flipper/expressions/all.rb +0 -2
  44. data/lib/flipper/expressions/feature_enabled.rb +34 -0
  45. data/lib/flipper/expressions/time.rb +8 -1
  46. data/lib/flipper/feature.rb +8 -1
  47. data/lib/flipper/gate.rb +1 -1
  48. data/lib/flipper/gates/expression.rb +2 -2
  49. data/lib/flipper/instrumentation/log_subscriber.rb +1 -2
  50. data/lib/flipper/instrumentation/statsd.rb +4 -2
  51. data/lib/flipper/instrumentation/subscriber.rb +0 -4
  52. data/lib/flipper/metadata.rb +1 -0
  53. data/lib/flipper/poller.rb +54 -11
  54. data/lib/flipper/version.rb +1 -1
  55. data/lib/flipper.rb +17 -1
  56. data/lib/generators/flipper/setup_generator.rb +5 -0
  57. data/lib/generators/flipper/templates/initializer.rb +45 -0
  58. data/spec/flipper/adapter_spec.rb +20 -0
  59. data/spec/flipper/adapters/actor_limit_spec.rb +55 -0
  60. data/spec/flipper/adapters/dual_write_spec.rb +13 -0
  61. data/spec/flipper/adapters/failover_spec.rb +12 -0
  62. data/spec/flipper/adapters/http_spec.rb +241 -0
  63. data/spec/flipper/adapters/poll_spec.rb +41 -0
  64. data/spec/flipper/adapters/strict_spec.rb +62 -4
  65. data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +12 -0
  66. data/spec/flipper/adapters/sync/synchronizer_spec.rb +87 -0
  67. data/spec/flipper/adapters/sync_spec.rb +13 -0
  68. data/spec/flipper/cli_spec.rb +51 -0
  69. data/spec/flipper/cloud/configuration_spec.rb +6 -0
  70. data/spec/flipper/cloud/dsl_spec.rb +11 -3
  71. data/spec/flipper/cloud/middleware_spec.rb +34 -16
  72. data/spec/flipper/cloud/migrate_spec.rb +160 -0
  73. data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +3 -3
  74. data/spec/flipper/cloud/telemetry/submitter_spec.rb +4 -4
  75. data/spec/flipper/cloud/telemetry_spec.rb +6 -6
  76. data/spec/flipper/cloud_spec.rb +9 -4
  77. data/spec/flipper/dsl_spec.rb +0 -3
  78. data/spec/flipper/engine_spec.rb +3 -2
  79. data/spec/flipper/expressions/time_spec.rb +16 -0
  80. data/spec/flipper/feature_spec.rb +22 -11
  81. data/spec/flipper/gates/expression_spec.rb +82 -0
  82. data/spec/flipper/instrumentation/log_subscriber_spec.rb +1 -0
  83. data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +1 -1
  84. data/spec/flipper/middleware/memoizer_spec.rb +41 -11
  85. data/spec/flipper/model/active_record_spec.rb +11 -0
  86. data/spec/flipper/poller_spec.rb +347 -4
  87. data/spec/flipper_integration_spec.rb +133 -0
  88. data/spec/flipper_spec.rb +7 -2
  89. data/spec/spec_helper.rb +15 -5
  90. data/test_rails/generators/flipper/setup_generator_test.rb +5 -0
  91. data/test_rails/generators/flipper/update_generator_test.rb +1 -1
  92. data/test_rails/helper.rb +3 -0
  93. metadata +17 -111
  94. data/lib/flipper/expressions/duration.rb +0 -28
  95. data/spec/flipper/expressions/duration_spec.rb +0 -43
@@ -600,6 +600,139 @@ RSpec.describe Flipper do
600
600
  end
601
601
  end
602
602
 
603
+ context "for FeatureEnabled" do
604
+ before do
605
+ @original_instance = Flipper.instance
606
+ Flipper.instance = flipper
607
+ end
608
+
609
+ after do
610
+ Flipper.instance = @original_instance
611
+ Thread.current[:flipper_evaluating_features] = nil
612
+ end
613
+
614
+ it "returns true when referenced feature is enabled" do
615
+ flipper.enable(:search_beta)
616
+ feature.enable Flipper.feature_enabled(:search_beta)
617
+
618
+ expect(feature.enabled?).to be(true)
619
+ end
620
+
621
+ it "returns false when referenced feature is disabled" do
622
+ feature.enable Flipper.feature_enabled(:search_beta)
623
+
624
+ expect(feature.enabled?).to be(false)
625
+ end
626
+
627
+ it "passes actor through to referenced feature" do
628
+ flipper.enable_actor(:search_beta, pitt)
629
+ feature.enable Flipper.feature_enabled(:search_beta)
630
+
631
+ expect(feature.enabled?(pitt)).to be(true)
632
+ expect(feature.enabled?(clooney)).to be(false)
633
+ end
634
+
635
+ it "returns false on circular dependency" do
636
+ feature.enable Flipper.feature_enabled(:other)
637
+ flipper[:other].enable Flipper.feature_enabled(:search)
638
+
639
+ expect(feature.enabled?).to be(false)
640
+ end
641
+
642
+ it "returns false on self-reference" do
643
+ feature.enable Flipper.feature_enabled(:search)
644
+
645
+ expect(feature.enabled?).to be(false)
646
+ end
647
+
648
+ it "cleans up thread-local state after evaluation" do
649
+ flipper.enable(:search_beta)
650
+ feature.enable Flipper.feature_enabled(:search_beta)
651
+
652
+ feature.enabled?
653
+ evaluating = Thread.current[:flipper_evaluating_features]
654
+ expect(evaluating.nil? || evaluating.empty?).to be(true)
655
+ end
656
+
657
+ it "cleans up thread-local state after self-reference" do
658
+ feature.enable Flipper.feature_enabled(:search)
659
+
660
+ feature.enabled?
661
+ evaluating = Thread.current[:flipper_evaluating_features]
662
+ expect(evaluating.nil? || evaluating.empty?).to be(true)
663
+ end
664
+
665
+ it "cleans up thread-local state after circular dependency" do
666
+ feature.enable Flipper.feature_enabled(:other)
667
+ flipper[:other].enable Flipper.feature_enabled(:search)
668
+
669
+ feature.enabled?
670
+ evaluating = Thread.current[:flipper_evaluating_features]
671
+ expect(evaluating.nil? || evaluating.empty?).to be(true)
672
+ end
673
+ end
674
+
675
+ context "for FeatureDisabled" do
676
+ before do
677
+ @original_instance = Flipper.instance
678
+ Flipper.instance = flipper
679
+ end
680
+
681
+ after do
682
+ Flipper.instance = @original_instance
683
+ Thread.current[:flipper_evaluating_features] = nil
684
+ end
685
+
686
+ it "returns true when referenced feature is disabled" do
687
+ feature.enable Flipper.feature_disabled(:old_checkout)
688
+
689
+ expect(feature.enabled?).to be(true)
690
+ end
691
+
692
+ it "returns false when referenced feature is enabled" do
693
+ flipper.enable(:old_checkout)
694
+ feature.enable Flipper.feature_disabled(:old_checkout)
695
+
696
+ expect(feature.enabled?).to be(false)
697
+ end
698
+ end
699
+
700
+ context "for FeatureEnabled composed with other expressions" do
701
+ before do
702
+ @original_instance = Flipper.instance
703
+ Flipper.instance = flipper
704
+ end
705
+
706
+ after do
707
+ Flipper.instance = @original_instance
708
+ Thread.current[:flipper_evaluating_features] = nil
709
+ end
710
+
711
+ it "works with Any" do
712
+ feature.enable Flipper.any(
713
+ Flipper.feature_enabled(:beta_program),
714
+ Flipper.property(:plan).eq("basic")
715
+ )
716
+
717
+ expect(feature.enabled?(basic_plan_actor)).to be(true)
718
+ expect(feature.enabled?(premium_plan_actor)).to be(false)
719
+
720
+ flipper.enable(:beta_program)
721
+ expect(feature.enabled?(premium_plan_actor)).to be(true)
722
+ end
723
+
724
+ it "works with All" do
725
+ flipper.enable(:basic_search)
726
+ feature.enable Flipper.all(
727
+ Flipper.feature_enabled(:basic_search),
728
+ Flipper.property(:plan).eq("basic")
729
+ )
730
+
731
+ expect(feature.enabled?(basic_plan_actor)).to be(true)
732
+ expect(feature.enabled?(premium_plan_actor)).to be(false)
733
+ end
734
+ end
735
+
603
736
  context "for All" do
604
737
  it "works" do
605
738
  true_actor = Flipper::Actor.new("User;1", {
data/spec/flipper_spec.rb CHANGED
@@ -218,6 +218,11 @@ RSpec.describe Flipper do
218
218
  expect(described_class.adapter).to eq(described_class.instance.adapter)
219
219
  end
220
220
 
221
+ it 'delegates adapter_stack to instance' do
222
+ expect(described_class.adapter_stack).to eq(described_class.instance.adapter_stack)
223
+ expect(described_class.adapter_stack).to eq("memoizable -> memory")
224
+ end
225
+
221
226
  it 'delegates memoize= to instance' do
222
227
  expect(described_class.adapter.memoizing?).to be(false)
223
228
  described_class.memoize = true
@@ -254,7 +259,7 @@ RSpec.describe Flipper do
254
259
  end
255
260
  described_class.sync
256
261
  expect(described_class.sync_secret).to eq("tasty")
257
- expect(stub).to have_been_requested
262
+ expect(stub).to have_been_made.at_least_once
258
263
  end
259
264
  end
260
265
 
@@ -313,7 +318,7 @@ RSpec.describe Flipper do
313
318
 
314
319
  describe '.group_exists' do
315
320
  it 'returns true if the group is already created' do
316
- group = described_class.register('admins', &:admin?)
321
+ described_class.register('admins', &:admin?)
317
322
  expect(described_class.group_exists?(:admins)).to eq(true)
318
323
  end
319
324
 
data/spec/spec_helper.rb CHANGED
@@ -2,12 +2,14 @@ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
2
 
3
3
  require 'pp'
4
4
  require 'pathname'
5
- FlipperRoot = Pathname(__FILE__).dirname.join('..').expand_path
6
-
7
- require 'rubygems'
8
- require 'bundler'
5
+ require 'bundler/setup'
9
6
 
10
- Bundler.setup(:default)
7
+ require 'warning'
8
+ Warning.ignore(/lib\/statsd/)
9
+ Warning.ignore(/lib\/debug\//)
10
+ Warning.ignore(/lib\/ice_age\//)
11
+ Warning.ignore(/lib\/moneta\//)
12
+ Warning.ignore(/lib\/mongo\//)
11
13
 
12
14
  require 'debug'
13
15
  require 'statsd'
@@ -20,6 +22,7 @@ require 'flipper/spec/shared_adapter_specs'
20
22
  require 'flipper/ui'
21
23
  require 'flipper/test_help'
22
24
 
25
+ FlipperRoot = Pathname(__FILE__).dirname.join('..').expand_path
23
26
  Dir[FlipperRoot.join('spec/support/**/*.rb')].sort.each { |f| require f }
24
27
 
25
28
  # Disable telemetry logging in specs.
@@ -36,6 +39,13 @@ RSpec.configure do |config|
36
39
  Flipper.configuration = nil
37
40
  end
38
41
 
42
+ config.after(:example) do
43
+ # Stop any pollers started during the test BEFORE WebMock clears stubs
44
+ # in its own after hook (RSpec runs after hooks in reverse registration
45
+ # order, so ours runs first since webmock/rspec was required before this).
46
+ Flipper::Poller.reset if defined?(Flipper::Poller)
47
+ end
48
+
39
49
  config.disable_monkey_patching!
40
50
 
41
51
  config.filter_run focus: true
@@ -17,6 +17,11 @@ class SetupGeneratorTest < Rails::Generators::TestCase
17
17
  end
18
18
  end
19
19
 
20
+ test "generates an initializer" do
21
+ run_generator
22
+ assert_file 'config/initializers/flipper.rb', /Flipper\.configure/
23
+ end
24
+
20
25
  test "does not invoke flipper:active_record generator if ActiveRecord adapter not defined" do
21
26
  # Ensure adapter not defined
22
27
  Flipper::Adapters.send(:remove_const, :ActiveRecord) rescue nil
@@ -65,7 +65,7 @@ class UpdateGeneratorTest < Rails::Generators::TestCase
65
65
 
66
66
  assert_migration "db/migrate/create_flipper_tables.rb" do |migration|
67
67
  assert_method :up, migration do |up|
68
- assert_match /text :value/, up
68
+ assert_match(/text :value/, up)
69
69
  end
70
70
  end
71
71
 
data/test_rails/helper.rb CHANGED
@@ -4,6 +4,9 @@ require 'minitest/autorun'
4
4
  require 'rails'
5
5
  require 'rails/test_help'
6
6
 
7
+ require 'warning'
8
+ Warning.ignore(/lib\/capybara\//)
9
+
7
10
  begin
8
11
  ActiveSupport::TestCase.test_order = :random
9
12
  rescue NoMethodError
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: 1.3.2
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-19 00:00:00.000000000 Z
11
+ date: 2026-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -36,7 +36,10 @@ files:
36
36
  - ".github/dependabot.yml"
37
37
  - ".github/workflows/ci.yml"
38
38
  - ".github/workflows/examples.yml"
39
+ - ".github/workflows/release.yml"
39
40
  - ".rspec"
41
+ - ".superset/config.json"
42
+ - CLAUDE.md
40
43
  - CODE_OF_CONDUCT.md
41
44
  - Changelog.md
42
45
  - Dockerfile
@@ -64,6 +67,9 @@ files:
64
67
  - examples/cloud/cloud_setup.rb
65
68
  - examples/cloud/forked.rb
66
69
  - examples/cloud/import.rb
70
+ - examples/cloud/poll_interval/README.md
71
+ - examples/cloud/poll_interval/client.rb
72
+ - examples/cloud/poll_interval/server.rb
67
73
  - examples/cloud/threaded.rb
68
74
  - examples/configuring_default.rb
69
75
  - examples/dsl.rb
@@ -118,6 +124,7 @@ files:
118
124
  - lib/flipper/cloud/dsl.rb
119
125
  - lib/flipper/cloud/message_verifier.rb
120
126
  - lib/flipper/cloud/middleware.rb
127
+ - lib/flipper/cloud/migrate.rb
121
128
  - lib/flipper/cloud/routes.rb
122
129
  - lib/flipper/cloud/telemetry.rb
123
130
  - lib/flipper/cloud/telemetry/backoff_policy.rb
@@ -140,8 +147,8 @@ files:
140
147
  - lib/flipper/expressions/any.rb
141
148
  - lib/flipper/expressions/boolean.rb
142
149
  - lib/flipper/expressions/comparable.rb
143
- - lib/flipper/expressions/duration.rb
144
150
  - lib/flipper/expressions/equal.rb
151
+ - lib/flipper/expressions/feature_enabled.rb
145
152
  - lib/flipper/expressions/greater_than.rb
146
153
  - lib/flipper/expressions/greater_than_or_equal_to.rb
147
154
  - lib/flipper/expressions/less_than.rb
@@ -193,6 +200,7 @@ files:
193
200
  - lib/flipper/types/percentage_of_time.rb
194
201
  - lib/flipper/version.rb
195
202
  - lib/generators/flipper/setup_generator.rb
203
+ - lib/generators/flipper/templates/initializer.rb
196
204
  - lib/generators/flipper/templates/update/migrations/01_create_flipper_tables.rb.erb
197
205
  - lib/generators/flipper/templates/update/migrations/02_change_flipper_gates_value_to_text.rb.erb
198
206
  - lib/generators/flipper/update_generator.rb
@@ -214,6 +222,7 @@ files:
214
222
  - spec/flipper/adapters/memoizable_spec.rb
215
223
  - spec/flipper/adapters/memory_spec.rb
216
224
  - spec/flipper/adapters/operation_logger_spec.rb
225
+ - spec/flipper/adapters/poll_spec.rb
217
226
  - spec/flipper/adapters/pstore_spec.rb
218
227
  - spec/flipper/adapters/read_only_spec.rb
219
228
  - spec/flipper/adapters/strict_spec.rb
@@ -226,6 +235,7 @@ files:
226
235
  - spec/flipper/cloud/dsl_spec.rb
227
236
  - spec/flipper/cloud/message_verifier_spec.rb
228
237
  - spec/flipper/cloud/middleware_spec.rb
238
+ - spec/flipper/cloud/migrate_spec.rb
229
239
  - spec/flipper/cloud/telemetry/backoff_policy_spec.rb
230
240
  - spec/flipper/cloud/telemetry/metric_spec.rb
231
241
  - spec/flipper/cloud/telemetry/metric_storage_spec.rb
@@ -244,7 +254,6 @@ files:
244
254
  - spec/flipper/expressions/all_spec.rb
245
255
  - spec/flipper/expressions/any_spec.rb
246
256
  - spec/flipper/expressions/boolean_spec.rb
247
- - spec/flipper/expressions/duration_spec.rb
248
257
  - spec/flipper/expressions/equal_spec.rb
249
258
  - spec/flipper/expressions/greater_than_or_equal_to_spec.rb
250
259
  - spec/flipper/expressions/greater_than_spec.rb
@@ -314,7 +323,8 @@ metadata:
314
323
  homepage_uri: https://www.flippercloud.io
315
324
  source_code_uri: https://github.com/flippercloud/flipper
316
325
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
317
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.2
326
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.4.1
327
+ funding_uri: https://github.com/sponsors/flippercloud
318
328
  post_install_message:
319
329
  rdoc_options: []
320
330
  require_paths:
@@ -330,112 +340,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
330
340
  - !ruby/object:Gem::Version
331
341
  version: '0'
332
342
  requirements: []
333
- rubygems_version: 3.5.23
343
+ rubygems_version: 3.5.22
334
344
  signing_key:
335
345
  specification_version: 4
336
346
  summary: Beautiful, performant feature flags for Ruby and Rails.
337
- test_files:
338
- - spec/fixtures/environment.rb
339
- - spec/fixtures/feature.json
340
- - spec/fixtures/flipper_pstore_1679087600.json
341
- - spec/flipper/actor_spec.rb
342
- - spec/flipper/adapter_builder_spec.rb
343
- - spec/flipper/adapter_spec.rb
344
- - spec/flipper/adapters/actor_limit_spec.rb
345
- - spec/flipper/adapters/dual_write_spec.rb
346
- - spec/flipper/adapters/failover_spec.rb
347
- - spec/flipper/adapters/failsafe_spec.rb
348
- - spec/flipper/adapters/http/client_spec.rb
349
- - spec/flipper/adapters/http_spec.rb
350
- - spec/flipper/adapters/instrumented_spec.rb
351
- - spec/flipper/adapters/memoizable_spec.rb
352
- - spec/flipper/adapters/memory_spec.rb
353
- - spec/flipper/adapters/operation_logger_spec.rb
354
- - spec/flipper/adapters/pstore_spec.rb
355
- - spec/flipper/adapters/read_only_spec.rb
356
- - spec/flipper/adapters/strict_spec.rb
357
- - spec/flipper/adapters/sync/feature_synchronizer_spec.rb
358
- - spec/flipper/adapters/sync/interval_synchronizer_spec.rb
359
- - spec/flipper/adapters/sync/synchronizer_spec.rb
360
- - spec/flipper/adapters/sync_spec.rb
361
- - spec/flipper/cli_spec.rb
362
- - spec/flipper/cloud/configuration_spec.rb
363
- - spec/flipper/cloud/dsl_spec.rb
364
- - spec/flipper/cloud/message_verifier_spec.rb
365
- - spec/flipper/cloud/middleware_spec.rb
366
- - spec/flipper/cloud/telemetry/backoff_policy_spec.rb
367
- - spec/flipper/cloud/telemetry/metric_spec.rb
368
- - spec/flipper/cloud/telemetry/metric_storage_spec.rb
369
- - spec/flipper/cloud/telemetry/submitter_spec.rb
370
- - spec/flipper/cloud/telemetry_spec.rb
371
- - spec/flipper/cloud_spec.rb
372
- - spec/flipper/configuration_spec.rb
373
- - spec/flipper/dsl_spec.rb
374
- - spec/flipper/engine_spec.rb
375
- - spec/flipper/export_spec.rb
376
- - spec/flipper/exporter_spec.rb
377
- - spec/flipper/exporters/json/export_spec.rb
378
- - spec/flipper/exporters/json/v1_spec.rb
379
- - spec/flipper/expression/builder_spec.rb
380
- - spec/flipper/expression_spec.rb
381
- - spec/flipper/expressions/all_spec.rb
382
- - spec/flipper/expressions/any_spec.rb
383
- - spec/flipper/expressions/boolean_spec.rb
384
- - spec/flipper/expressions/duration_spec.rb
385
- - spec/flipper/expressions/equal_spec.rb
386
- - spec/flipper/expressions/greater_than_or_equal_to_spec.rb
387
- - spec/flipper/expressions/greater_than_spec.rb
388
- - spec/flipper/expressions/less_than_or_equal_to_spec.rb
389
- - spec/flipper/expressions/less_than_spec.rb
390
- - spec/flipper/expressions/not_equal_spec.rb
391
- - spec/flipper/expressions/now_spec.rb
392
- - spec/flipper/expressions/number_spec.rb
393
- - spec/flipper/expressions/percentage_of_actors_spec.rb
394
- - spec/flipper/expressions/percentage_spec.rb
395
- - spec/flipper/expressions/property_spec.rb
396
- - spec/flipper/expressions/random_spec.rb
397
- - spec/flipper/expressions/string_spec.rb
398
- - spec/flipper/expressions/time_spec.rb
399
- - spec/flipper/feature_check_context_spec.rb
400
- - spec/flipper/feature_spec.rb
401
- - spec/flipper/gate_spec.rb
402
- - spec/flipper/gate_values_spec.rb
403
- - spec/flipper/gates/actor_spec.rb
404
- - spec/flipper/gates/boolean_spec.rb
405
- - spec/flipper/gates/expression_spec.rb
406
- - spec/flipper/gates/group_spec.rb
407
- - spec/flipper/gates/percentage_of_actors_spec.rb
408
- - spec/flipper/gates/percentage_of_time_spec.rb
409
- - spec/flipper/identifier_spec.rb
410
- - spec/flipper/instrumentation/log_subscriber_spec.rb
411
- - spec/flipper/instrumentation/statsd_subscriber_spec.rb
412
- - spec/flipper/instrumenters/memory_spec.rb
413
- - spec/flipper/instrumenters/noop_spec.rb
414
- - spec/flipper/middleware/memoizer_spec.rb
415
- - spec/flipper/middleware/setup_env_spec.rb
416
- - spec/flipper/model/active_record_spec.rb
417
- - spec/flipper/poller_spec.rb
418
- - spec/flipper/registry_spec.rb
419
- - spec/flipper/serializers/gzip_spec.rb
420
- - spec/flipper/serializers/json_spec.rb
421
- - spec/flipper/typecast_spec.rb
422
- - spec/flipper/types/actor_spec.rb
423
- - spec/flipper/types/boolean_spec.rb
424
- - spec/flipper/types/group_spec.rb
425
- - spec/flipper/types/percentage_of_actors_spec.rb
426
- - spec/flipper/types/percentage_of_time_spec.rb
427
- - spec/flipper/types/percentage_spec.rb
428
- - spec/flipper_integration_spec.rb
429
- - spec/flipper_spec.rb
430
- - spec/spec_helper.rb
431
- - spec/support/actor_names.yml
432
- - spec/support/descriptions.yml
433
- - spec/support/fail_on_output.rb
434
- - spec/support/fake_backoff_policy.rb
435
- - spec/support/fake_udp_socket.rb
436
- - spec/support/skippable.rb
437
- - spec/support/spec_helpers.rb
438
- - test/adapters/actor_limit_test.rb
439
- - test/adapters/memory_test.rb
440
- - test/adapters/pstore_test.rb
441
- - test/test_helper.rb
347
+ test_files: []
@@ -1,28 +0,0 @@
1
- module Flipper
2
- module Expressions
3
- class Duration
4
- SECONDS_PER = {
5
- "second" => 1,
6
- "minute" => 60,
7
- "hour" => 3600,
8
- "day" => 86400,
9
- "week" => 604_800,
10
- "month" => 2_629_746, # 1/12 of a gregorian year
11
- "year" => 31_556_952 # length of a gregorian year (365.2425 days)
12
- }.freeze
13
-
14
- def self.call(scalar, unit = 'second')
15
- unit = unit.to_s.downcase.chomp("s")
16
-
17
- unless scalar.is_a?(Numeric)
18
- raise ArgumentError.new("Duration value must be a number but was #{scalar.inspect}")
19
- end
20
- unless SECONDS_PER[unit]
21
- raise ArgumentError.new("Duration unit #{unit.inspect} must be one of: #{SECONDS_PER.keys.join(', ')}")
22
- end
23
-
24
- scalar * SECONDS_PER[unit]
25
- end
26
- end
27
- end
28
- end
@@ -1,43 +0,0 @@
1
- RSpec.describe Flipper::Expressions::Duration do
2
- describe "#call" do
3
- it "raises error with invalid value" do
4
- expect { described_class.call(false, 'minute') }.to raise_error(ArgumentError)
5
- end
6
-
7
- it "raises error with invalid unit" do
8
- expect { described_class.call(4, 'score') }.to raise_error(ArgumentError)
9
- end
10
-
11
- it 'defaults unit to seconds' do
12
- expect(described_class.call(10)).to eq(10)
13
- end
14
-
15
- it "evaluates seconds" do
16
- expect(described_class.call(10, 'seconds')).to eq(10)
17
- end
18
-
19
- it "evaluates minutes" do
20
- expect(described_class.call(2, 'minutes')).to eq(120)
21
- end
22
-
23
- it "evaluates hours" do
24
- expect(described_class.call(2, 'hours')).to eq(7200)
25
- end
26
-
27
- it "evaluates days" do
28
- expect(described_class.call(2, 'days')).to eq(172_800)
29
- end
30
-
31
- it "evaluates weeks" do
32
- expect(described_class.call(2, 'weeks')).to eq(1_209_600)
33
- end
34
-
35
- it "evaluates months" do
36
- expect(described_class.call(2, 'months')).to eq(5_259_492)
37
- end
38
-
39
- it "evaluates years" do
40
- expect(described_class.call(2, 'years')).to eq(63_113_904)
41
- end
42
- end
43
- end