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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +9 -6
- data/.github/workflows/examples.yml +5 -4
- data/.github/workflows/release.yml +54 -0
- data/.superset/config.json +4 -0
- data/CLAUDE.md +93 -0
- data/Gemfile +6 -2
- data/README.md +4 -3
- data/examples/cloud/backoff_policy.rb +1 -1
- data/examples/cloud/poll_interval/README.md +111 -0
- data/examples/cloud/poll_interval/client.rb +108 -0
- data/examples/cloud/poll_interval/server.rb +98 -0
- data/examples/expressions.rb +35 -11
- data/lib/flipper/adapter.rb +17 -1
- data/lib/flipper/adapters/actor_limit.rb +27 -1
- data/lib/flipper/adapters/cache_base.rb +21 -3
- data/lib/flipper/adapters/dual_write.rb +6 -2
- data/lib/flipper/adapters/failover.rb +9 -3
- data/lib/flipper/adapters/failsafe.rb +2 -2
- data/lib/flipper/adapters/http/client.rb +15 -4
- data/lib/flipper/adapters/http/error.rb +1 -1
- data/lib/flipper/adapters/http.rb +39 -4
- data/lib/flipper/adapters/instrumented.rb +2 -2
- data/lib/flipper/adapters/memoizable.rb +3 -3
- data/lib/flipper/adapters/memory.rb +1 -1
- data/lib/flipper/adapters/poll.rb +15 -0
- data/lib/flipper/adapters/pstore.rb +1 -1
- data/lib/flipper/adapters/strict.rb +30 -0
- data/lib/flipper/adapters/sync/feature_synchronizer.rb +5 -1
- data/lib/flipper/adapters/sync/synchronizer.rb +13 -5
- data/lib/flipper/adapters/sync.rb +7 -3
- data/lib/flipper/cli.rb +51 -0
- data/lib/flipper/cloud/configuration.rb +14 -6
- data/lib/flipper/cloud/dsl.rb +2 -2
- data/lib/flipper/cloud/middleware.rb +1 -1
- data/lib/flipper/cloud/migrate.rb +71 -0
- data/lib/flipper/cloud/telemetry/backoff_policy.rb +6 -3
- data/lib/flipper/cloud/telemetry/submitter.rb +3 -1
- data/lib/flipper/cloud/telemetry.rb +3 -3
- data/lib/flipper/cloud.rb +1 -0
- data/lib/flipper/dsl.rb +1 -1
- data/lib/flipper/export.rb +0 -2
- data/lib/flipper/expressions/all.rb +0 -2
- data/lib/flipper/expressions/feature_enabled.rb +34 -0
- data/lib/flipper/expressions/time.rb +8 -1
- data/lib/flipper/feature.rb +8 -1
- data/lib/flipper/gate.rb +1 -1
- data/lib/flipper/gates/expression.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +1 -2
- data/lib/flipper/instrumentation/statsd.rb +4 -2
- data/lib/flipper/instrumentation/subscriber.rb +0 -4
- data/lib/flipper/metadata.rb +1 -0
- data/lib/flipper/poller.rb +54 -11
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +17 -1
- data/lib/generators/flipper/setup_generator.rb +5 -0
- data/lib/generators/flipper/templates/initializer.rb +45 -0
- data/spec/flipper/adapter_spec.rb +20 -0
- data/spec/flipper/adapters/actor_limit_spec.rb +55 -0
- data/spec/flipper/adapters/dual_write_spec.rb +13 -0
- data/spec/flipper/adapters/failover_spec.rb +12 -0
- data/spec/flipper/adapters/http_spec.rb +241 -0
- data/spec/flipper/adapters/poll_spec.rb +41 -0
- data/spec/flipper/adapters/strict_spec.rb +62 -4
- data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +12 -0
- data/spec/flipper/adapters/sync/synchronizer_spec.rb +87 -0
- data/spec/flipper/adapters/sync_spec.rb +13 -0
- data/spec/flipper/cli_spec.rb +51 -0
- data/spec/flipper/cloud/configuration_spec.rb +6 -0
- data/spec/flipper/cloud/dsl_spec.rb +11 -3
- data/spec/flipper/cloud/middleware_spec.rb +34 -16
- data/spec/flipper/cloud/migrate_spec.rb +160 -0
- data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +3 -3
- data/spec/flipper/cloud/telemetry/submitter_spec.rb +4 -4
- data/spec/flipper/cloud/telemetry_spec.rb +6 -6
- data/spec/flipper/cloud_spec.rb +9 -4
- data/spec/flipper/dsl_spec.rb +0 -3
- data/spec/flipper/engine_spec.rb +3 -2
- data/spec/flipper/expressions/time_spec.rb +16 -0
- data/spec/flipper/feature_spec.rb +22 -11
- data/spec/flipper/gates/expression_spec.rb +82 -0
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +1 -0
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +1 -1
- data/spec/flipper/middleware/memoizer_spec.rb +41 -11
- data/spec/flipper/model/active_record_spec.rb +11 -0
- data/spec/flipper/poller_spec.rb +347 -4
- data/spec/flipper_integration_spec.rb +133 -0
- data/spec/flipper_spec.rb +7 -2
- data/spec/spec_helper.rb +15 -5
- data/test_rails/generators/flipper/setup_generator_test.rb +5 -0
- data/test_rails/generators/flipper/update_generator_test.rb +1 -1
- data/test_rails/helper.rb +3 -0
- metadata +17 -111
- data/lib/flipper/expressions/duration.rb +0 -28
- 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
|
|
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
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
require 'rubygems'
|
|
8
|
-
require 'bundler'
|
|
5
|
+
require 'bundler/setup'
|
|
9
6
|
|
|
10
|
-
|
|
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
|
data/test_rails/helper.rb
CHANGED
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.
|
|
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:
|
|
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.
|
|
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.
|
|
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
|