flipper 0.26.0 → 1.3.6
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/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +61 -16
- data/.github/workflows/examples.yml +55 -18
- data/CLAUDE.md +74 -0
- data/Changelog.md +1 -486
- data/Gemfile +23 -11
- data/README.md +31 -27
- data/Rakefile +2 -2
- data/benchmark/enabled_ips.rb +10 -0
- data/benchmark/enabled_multiple_actors_ips.rb +20 -0
- data/benchmark/enabled_profile.rb +20 -0
- data/benchmark/instrumentation_ips.rb +21 -0
- data/benchmark/typecast_ips.rb +27 -0
- data/docs/images/banner.jpg +0 -0
- data/docs/images/flipper_cloud.png +0 -0
- data/examples/api/basic.ru +3 -4
- data/examples/api/custom_memoized.ru +3 -4
- data/examples/api/memoized.ru +3 -4
- data/examples/cloud/app.ru +12 -0
- data/examples/cloud/backoff_policy.rb +13 -0
- data/examples/cloud/basic.rb +22 -0
- data/examples/cloud/cloud_setup.rb +20 -0
- data/examples/cloud/forked.rb +36 -0
- data/examples/cloud/import.rb +17 -0
- data/examples/cloud/threaded.rb +33 -0
- data/examples/dsl.rb +1 -15
- data/examples/enabled_for_actor.rb +4 -2
- data/examples/expressions.rb +213 -0
- data/examples/mirroring.rb +59 -0
- data/examples/strict.rb +18 -0
- data/exe/flipper +5 -0
- data/flipper-cloud.gemspec +19 -0
- data/flipper.gemspec +8 -6
- data/lib/flipper/actor.rb +6 -3
- data/lib/flipper/adapter.rb +33 -7
- data/lib/flipper/adapter_builder.rb +44 -0
- data/lib/flipper/adapters/actor_limit.rb +28 -0
- data/lib/flipper/adapters/cache_base.rb +143 -0
- data/lib/flipper/adapters/dual_write.rb +1 -3
- data/lib/flipper/adapters/failover.rb +0 -4
- data/lib/flipper/adapters/failsafe.rb +0 -4
- data/lib/flipper/adapters/http/client.rb +40 -12
- data/lib/flipper/adapters/http/error.rb +2 -2
- data/lib/flipper/adapters/http.rb +30 -17
- data/lib/flipper/adapters/instrumented.rb +25 -6
- data/lib/flipper/adapters/memoizable.rb +33 -21
- data/lib/flipper/adapters/memory.rb +81 -46
- data/lib/flipper/adapters/operation_logger.rb +17 -78
- data/lib/flipper/adapters/poll/poller.rb +2 -125
- data/lib/flipper/adapters/poll.rb +20 -3
- data/lib/flipper/adapters/pstore.rb +17 -11
- data/lib/flipper/adapters/read_only.rb +8 -41
- data/lib/flipper/adapters/strict.rb +45 -0
- data/lib/flipper/adapters/sync/feature_synchronizer.rb +10 -1
- data/lib/flipper/adapters/sync.rb +0 -4
- data/lib/flipper/adapters/wrapper.rb +54 -0
- data/lib/flipper/cli.rb +263 -0
- data/lib/flipper/cloud/configuration.rb +266 -0
- data/lib/flipper/cloud/dsl.rb +27 -0
- data/lib/flipper/cloud/message_verifier.rb +95 -0
- data/lib/flipper/cloud/middleware.rb +63 -0
- data/lib/flipper/cloud/routes.rb +14 -0
- data/lib/flipper/cloud/telemetry/backoff_policy.rb +96 -0
- data/lib/flipper/cloud/telemetry/instrumenter.rb +22 -0
- data/lib/flipper/cloud/telemetry/metric.rb +39 -0
- data/lib/flipper/cloud/telemetry/metric_storage.rb +30 -0
- data/lib/flipper/cloud/telemetry/submitter.rb +100 -0
- data/lib/flipper/cloud/telemetry.rb +191 -0
- data/lib/flipper/cloud.rb +53 -0
- data/lib/flipper/configuration.rb +25 -4
- data/lib/flipper/dsl.rb +46 -45
- data/lib/flipper/engine.rb +102 -0
- data/lib/flipper/errors.rb +3 -3
- data/lib/flipper/export.rb +24 -0
- data/lib/flipper/exporter.rb +17 -0
- data/lib/flipper/exporters/json/export.rb +32 -0
- data/lib/flipper/exporters/json/v1.rb +33 -0
- data/lib/flipper/expression/builder.rb +73 -0
- data/lib/flipper/expression/constant.rb +25 -0
- data/lib/flipper/expression.rb +71 -0
- data/lib/flipper/expressions/all.rb +9 -0
- data/lib/flipper/expressions/any.rb +9 -0
- data/lib/flipper/expressions/boolean.rb +9 -0
- data/lib/flipper/expressions/comparable.rb +13 -0
- data/lib/flipper/expressions/duration.rb +28 -0
- data/lib/flipper/expressions/equal.rb +9 -0
- data/lib/flipper/expressions/greater_than.rb +9 -0
- data/lib/flipper/expressions/greater_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/less_than.rb +9 -0
- data/lib/flipper/expressions/less_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/not_equal.rb +9 -0
- data/lib/flipper/expressions/now.rb +9 -0
- data/lib/flipper/expressions/number.rb +9 -0
- data/lib/flipper/expressions/percentage.rb +9 -0
- data/lib/flipper/expressions/percentage_of_actors.rb +12 -0
- data/lib/flipper/expressions/property.rb +9 -0
- data/lib/flipper/expressions/random.rb +9 -0
- data/lib/flipper/expressions/string.rb +9 -0
- data/lib/flipper/expressions/time.rb +9 -0
- data/lib/flipper/feature.rb +94 -26
- data/lib/flipper/feature_check_context.rb +10 -6
- data/lib/flipper/gate.rb +13 -11
- data/lib/flipper/gate_values.rb +5 -18
- data/lib/flipper/gates/actor.rb +10 -17
- data/lib/flipper/gates/boolean.rb +1 -1
- data/lib/flipper/gates/expression.rb +75 -0
- data/lib/flipper/gates/group.rb +5 -7
- data/lib/flipper/gates/percentage_of_actors.rb +10 -13
- data/lib/flipper/gates/percentage_of_time.rb +1 -2
- data/lib/flipper/identifier.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +35 -8
- data/lib/flipper/instrumentation/statsd.rb +4 -2
- data/lib/flipper/instrumentation/statsd_subscriber.rb +2 -4
- data/lib/flipper/instrumentation/subscriber.rb +8 -5
- data/lib/flipper/metadata.rb +8 -1
- data/lib/flipper/middleware/memoizer.rb +30 -14
- data/lib/flipper/model/active_record.rb +23 -0
- data/lib/flipper/poller.rb +118 -0
- data/lib/flipper/serializers/gzip.rb +22 -0
- data/lib/flipper/serializers/json.rb +17 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +105 -63
- data/lib/flipper/test/shared_adapter_test.rb +101 -58
- data/lib/flipper/test_help.rb +43 -0
- data/lib/flipper/typecast.rb +59 -18
- data/lib/flipper/types/actor.rb +13 -13
- data/lib/flipper/types/group.rb +4 -4
- data/lib/flipper/types/percentage.rb +1 -1
- data/lib/flipper/version.rb +11 -1
- data/lib/flipper.rb +50 -11
- data/lib/generators/flipper/setup_generator.rb +68 -0
- data/lib/generators/flipper/templates/initializer.rb +45 -0
- data/lib/generators/flipper/templates/update/migrations/01_create_flipper_tables.rb.erb +22 -0
- data/lib/generators/flipper/templates/update/migrations/02_change_flipper_gates_value_to_text.rb.erb +18 -0
- data/lib/generators/flipper/update_generator.rb +35 -0
- data/package-lock.json +41 -0
- data/package.json +10 -0
- data/spec/fixtures/environment.rb +1 -0
- data/spec/fixtures/flipper_pstore_1679087600.json +46 -0
- data/spec/flipper/adapter_builder_spec.rb +72 -0
- data/spec/flipper/adapter_spec.rb +30 -2
- data/spec/flipper/adapters/actor_limit_spec.rb +20 -0
- data/spec/flipper/adapters/dual_write_spec.rb +2 -2
- data/spec/flipper/adapters/http/client_spec.rb +61 -0
- data/spec/flipper/adapters/http_spec.rb +138 -55
- data/spec/flipper/adapters/instrumented_spec.rb +29 -11
- data/spec/flipper/adapters/memoizable_spec.rb +51 -31
- data/spec/flipper/adapters/memory_spec.rb +14 -3
- data/spec/flipper/adapters/operation_logger_spec.rb +31 -12
- data/spec/flipper/adapters/poll_spec.rb +41 -0
- data/spec/flipper/adapters/read_only_spec.rb +32 -17
- data/spec/flipper/adapters/strict_spec.rb +64 -0
- data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +27 -0
- data/spec/flipper/cli_spec.rb +166 -0
- data/spec/flipper/cloud/configuration_spec.rb +251 -0
- data/spec/flipper/cloud/dsl_spec.rb +82 -0
- data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
- data/spec/flipper/cloud/middleware_spec.rb +289 -0
- data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +107 -0
- data/spec/flipper/cloud/telemetry/metric_spec.rb +87 -0
- data/spec/flipper/cloud/telemetry/metric_storage_spec.rb +58 -0
- data/spec/flipper/cloud/telemetry/submitter_spec.rb +145 -0
- data/spec/flipper/cloud/telemetry_spec.rb +208 -0
- data/spec/flipper/cloud_spec.rb +186 -0
- data/spec/flipper/configuration_spec.rb +17 -0
- data/spec/flipper/dsl_spec.rb +54 -76
- data/spec/flipper/engine_spec.rb +374 -0
- data/spec/flipper/export_spec.rb +13 -0
- data/spec/flipper/exporter_spec.rb +16 -0
- data/spec/flipper/exporters/json/export_spec.rb +60 -0
- data/spec/flipper/exporters/json/v1_spec.rb +33 -0
- data/spec/flipper/expression/builder_spec.rb +248 -0
- data/spec/flipper/expression_spec.rb +188 -0
- data/spec/flipper/expressions/all_spec.rb +15 -0
- data/spec/flipper/expressions/any_spec.rb +15 -0
- data/spec/flipper/expressions/boolean_spec.rb +15 -0
- data/spec/flipper/expressions/duration_spec.rb +43 -0
- data/spec/flipper/expressions/equal_spec.rb +24 -0
- data/spec/flipper/expressions/greater_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/greater_than_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_spec.rb +32 -0
- data/spec/flipper/expressions/not_equal_spec.rb +15 -0
- data/spec/flipper/expressions/now_spec.rb +11 -0
- data/spec/flipper/expressions/number_spec.rb +21 -0
- data/spec/flipper/expressions/percentage_of_actors_spec.rb +20 -0
- data/spec/flipper/expressions/percentage_spec.rb +15 -0
- data/spec/flipper/expressions/property_spec.rb +13 -0
- data/spec/flipper/expressions/random_spec.rb +9 -0
- data/spec/flipper/expressions/string_spec.rb +11 -0
- data/spec/flipper/expressions/time_spec.rb +13 -0
- data/spec/flipper/feature_check_context_spec.rb +17 -17
- data/spec/flipper/feature_spec.rb +453 -39
- data/spec/flipper/gate_values_spec.rb +2 -33
- data/spec/flipper/gates/boolean_spec.rb +1 -1
- data/spec/flipper/gates/expression_spec.rb +108 -0
- data/spec/flipper/gates/group_spec.rb +2 -3
- data/spec/flipper/gates/percentage_of_actors_spec.rb +61 -5
- data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
- data/spec/flipper/identifier_spec.rb +4 -5
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +24 -6
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +26 -2
- data/spec/flipper/middleware/memoizer_spec.rb +79 -10
- data/spec/flipper/model/active_record_spec.rb +72 -0
- data/spec/flipper/poller_spec.rb +47 -0
- data/spec/flipper/serializers/gzip_spec.rb +13 -0
- data/spec/flipper/serializers/json_spec.rb +13 -0
- data/spec/flipper/typecast_spec.rb +121 -6
- data/spec/flipper/types/actor_spec.rb +63 -46
- data/spec/flipper/types/group_spec.rb +2 -2
- data/spec/flipper_integration_spec.rb +168 -58
- data/spec/flipper_spec.rb +94 -30
- data/spec/spec_helper.rb +18 -18
- data/spec/support/actor_names.yml +1 -0
- data/spec/support/fail_on_output.rb +8 -0
- data/spec/support/fake_backoff_policy.rb +15 -0
- data/spec/support/skippable.rb +18 -0
- data/spec/support/spec_helpers.rb +34 -8
- data/test/adapters/actor_limit_test.rb +20 -0
- data/test_rails/generators/flipper/setup_generator_test.rb +69 -0
- data/test_rails/generators/flipper/update_generator_test.rb +96 -0
- data/test_rails/helper.rb +22 -2
- data/test_rails/system/test_help_test.rb +52 -0
- metadata +203 -20
- data/.github/workflows/release.yml +0 -44
- data/.tool-versions +0 -1
- data/lib/flipper/railtie.rb +0 -47
- data/spec/flipper/railtie_spec.rb +0 -109
@@ -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
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'ice_age'
|
2
2
|
require 'json'
|
3
3
|
require 'rack/test'
|
4
|
+
require 'rack/session'
|
4
5
|
|
5
6
|
module SpecHelpers
|
7
|
+
extend self
|
8
|
+
|
6
9
|
def self.included(base)
|
7
10
|
base.let(:flipper) { build_flipper }
|
8
11
|
base.let(:app) { build_app(flipper) }
|
@@ -10,7 +13,7 @@ module SpecHelpers
|
|
10
13
|
|
11
14
|
def build_app(flipper, options = {})
|
12
15
|
Flipper::UI.app(flipper, options) do |builder|
|
13
|
-
builder.use Rack::Session::Cookie, secret: 'test'
|
16
|
+
builder.use Rack::Session::Cookie, secret: 'test' * 16 # Rack 3+ wants a 64-character secret
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
@@ -27,7 +30,11 @@ module SpecHelpers
|
|
27
30
|
end
|
28
31
|
|
29
32
|
def json_response
|
30
|
-
|
33
|
+
body = last_response.body
|
34
|
+
if last_response["content-encoding"] == 'gzip'
|
35
|
+
body = Flipper::Typecast.from_gzip(body)
|
36
|
+
end
|
37
|
+
JSON.parse(body)
|
31
38
|
end
|
32
39
|
|
33
40
|
def api_error_code_reference_url
|
@@ -42,6 +49,14 @@ module SpecHelpers
|
|
42
49
|
}
|
43
50
|
end
|
44
51
|
|
52
|
+
def api_positive_percentage_error_response
|
53
|
+
{
|
54
|
+
'code' => 3,
|
55
|
+
'message' => 'Percentage must be a positive number less than or equal to 100.',
|
56
|
+
'more_info' => api_error_code_reference_url,
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
45
60
|
def api_flipper_id_is_missing_response
|
46
61
|
{
|
47
62
|
'code' => 4,
|
@@ -50,10 +65,10 @@ module SpecHelpers
|
|
50
65
|
}
|
51
66
|
end
|
52
67
|
|
53
|
-
def
|
68
|
+
def api_expression_invalid_response
|
54
69
|
{
|
55
|
-
'code' =>
|
56
|
-
'message' => '
|
70
|
+
'code' => 7,
|
71
|
+
'message' => 'The provided expression was not valid.',
|
57
72
|
'more_info' => api_error_code_reference_url,
|
58
73
|
}
|
59
74
|
end
|
@@ -64,15 +79,26 @@ module SpecHelpers
|
|
64
79
|
original_stdout = $stdout
|
65
80
|
|
66
81
|
# Redirect stderr and stdout
|
67
|
-
|
82
|
+
$stderr = $stdout = StringIO.new
|
68
83
|
|
69
84
|
yield
|
70
|
-
|
85
|
+
ensure
|
71
86
|
$stderr = original_stderr
|
72
87
|
$stdout = original_stdout
|
88
|
+
end
|
89
|
+
|
90
|
+
def capture_output
|
91
|
+
original_stderr = $stderr
|
92
|
+
original_stdout = $stdout
|
93
|
+
|
94
|
+
output = $stdout = $stderr = StringIO.new
|
95
|
+
|
96
|
+
yield
|
73
97
|
|
74
|
-
# Return output
|
75
98
|
output.string
|
99
|
+
ensure
|
100
|
+
$stderr = original_stderr
|
101
|
+
$stdout = original_stdout
|
76
102
|
end
|
77
103
|
end
|
78
104
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "flipper/test/shared_adapter_test"
|
3
|
+
require "flipper/adapters/actor_limit"
|
4
|
+
|
5
|
+
class Flipper::Adapters::ActorLimitTest < MiniTest::Test
|
6
|
+
prepend Flipper::Test::SharedAdapterTests
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@memory = Flipper::Adapters::Memory.new
|
10
|
+
@adapter = Flipper::Adapters::ActorLimit.new(@memory, 5)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_enable_fails_when_limit_exceeded
|
14
|
+
5.times { |i| @feature.enable Flipper::Actor.new("User;#{i}") }
|
15
|
+
|
16
|
+
assert_raises Flipper::Adapters::ActorLimit::LimitExceeded do
|
17
|
+
@feature.enable Flipper::Actor.new("User;6")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "generators/flipper/setup_generator"
|
3
|
+
|
4
|
+
class SetupGeneratorTest < Rails::Generators::TestCase
|
5
|
+
tests Flipper::Generators::SetupGenerator
|
6
|
+
ROOT = File.expand_path("../../../tmp/generators", __dir__)
|
7
|
+
destination ROOT
|
8
|
+
setup :prepare_destination
|
9
|
+
|
10
|
+
test "invokes flipper:active_record generator if ActiveRecord adapter defined" do
|
11
|
+
begin
|
12
|
+
load 'flipper/adapters/active_record.rb'
|
13
|
+
run_generator
|
14
|
+
assert_migration "db/migrate/create_flipper_tables.rb"
|
15
|
+
ensure
|
16
|
+
Flipper::Adapters.send(:remove_const, :ActiveRecord)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
test "generates an initializer" do
|
21
|
+
run_generator
|
22
|
+
assert_file 'config/initializers/flipper.rb', /Flipper\.configure/
|
23
|
+
end
|
24
|
+
|
25
|
+
test "does not invoke flipper:active_record generator if ActiveRecord adapter not defined" do
|
26
|
+
# Ensure adapter not defined
|
27
|
+
Flipper::Adapters.send(:remove_const, :ActiveRecord) rescue nil
|
28
|
+
|
29
|
+
run_generator
|
30
|
+
assert_no_migration "db/migrate/create_flipper_tables.rb"
|
31
|
+
end
|
32
|
+
|
33
|
+
%w(.env.development .env.local .env).each do |file|
|
34
|
+
test "configures Flipper Cloud token in #{file} if it exists" do
|
35
|
+
File.write("#{ROOT}/#{file}", "")
|
36
|
+
run_generator %w(--token abc123)
|
37
|
+
assert_file file, /^FLIPPER_CLOUD_TOKEN=abc123$/m
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test "configures Flipper Cloud token in .env.development before .env" do
|
42
|
+
File.write("#{ROOT}/.env.development", "")
|
43
|
+
File.write("#{ROOT}/.env", "")
|
44
|
+
|
45
|
+
run_generator %w(--token abc123)
|
46
|
+
assert_file ".env.development", /^FLIPPER_CLOUD_TOKEN=abc123$/m
|
47
|
+
assert_file ".env", ""
|
48
|
+
end
|
49
|
+
|
50
|
+
test "does not write to .env if no token provided" do
|
51
|
+
File.write("#{ROOT}/.env", "")
|
52
|
+
run_generator
|
53
|
+
assert_file ".env", ""
|
54
|
+
end
|
55
|
+
|
56
|
+
test "configures Flipper Cloud token in config/credentials.yml.enc if credentials.yml.enc exist" do
|
57
|
+
Dir.chdir(ROOT) do
|
58
|
+
FileUtils.mkdir_p("config")
|
59
|
+
ENV["RAILS_MASTER_KEY"] = "a" * 32
|
60
|
+
Rails.application = Class.new(Rails::Application)
|
61
|
+
Rails.application.credentials.write("")
|
62
|
+
|
63
|
+
run_generator %w(--token abc123)
|
64
|
+
assert_file "config/credentials.yml.enc"
|
65
|
+
expected_config = { flipper: { cloud_token: "abc123" } }
|
66
|
+
assert_equal expected_config, Rails.application.credentials.config
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "generators/flipper/update_generator"
|
3
|
+
|
4
|
+
class UpdateGeneratorTest < Rails::Generators::TestCase
|
5
|
+
tests Flipper::Generators::UpdateGenerator
|
6
|
+
ROOT = File.expand_path("../../../../tmp/generators", __FILE__)
|
7
|
+
destination ROOT
|
8
|
+
setup :prepare_destination
|
9
|
+
|
10
|
+
setup do
|
11
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
ActiveRecord::Base.connection.close
|
16
|
+
end
|
17
|
+
|
18
|
+
test "generates migrations" do
|
19
|
+
run_generator
|
20
|
+
|
21
|
+
assert_migration "db/migrate/create_flipper_tables.rb" do |migration|
|
22
|
+
assert_method :up, migration do |up|
|
23
|
+
assert_match(/create_table :flipper_features/, up)
|
24
|
+
assert_match(/create_table :flipper_gates/, up)
|
25
|
+
end
|
26
|
+
|
27
|
+
assert_method :down, migration do |down|
|
28
|
+
assert_match(/drop_table :flipper_features/, down)
|
29
|
+
assert_match(/drop_table :flipper_gates/, down)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
assert_migration "db/migrate/change_flipper_gates_value_to_text.rb" do |migration|
|
34
|
+
[:up, :down].each do |dir|
|
35
|
+
assert_method :up, migration do |method|
|
36
|
+
assert_match(/change_column/, method)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
require_migrations
|
42
|
+
|
43
|
+
silence { CreateFlipperTables.migrate(:up) }
|
44
|
+
assert ActiveRecord::Base.connection.table_exists?(:flipper_features)
|
45
|
+
assert ActiveRecord::Base.connection.table_exists?(:flipper_gates)
|
46
|
+
|
47
|
+
assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :string)
|
48
|
+
silence { ChangeFlipperGatesValueToText.migrate(:up) }
|
49
|
+
assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
|
50
|
+
|
51
|
+
silence { ChangeFlipperGatesValueToText.migrate(:down) }
|
52
|
+
assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :string)
|
53
|
+
|
54
|
+
silence { CreateFlipperTables.migrate(:down) }
|
55
|
+
refute ActiveRecord::Base.connection.table_exists?(:flipper_features)
|
56
|
+
refute ActiveRecord::Base.connection.table_exists?(:flipper_gates)
|
57
|
+
end
|
58
|
+
|
59
|
+
test "ChangeFlipperGatesValueToText is a noop if value is already text" do
|
60
|
+
self.class.generator_class = Flipper::Generators::ActiveRecordGenerator
|
61
|
+
run_generator
|
62
|
+
|
63
|
+
self.class.generator_class = Flipper::Generators::UpdateGenerator
|
64
|
+
run_generator
|
65
|
+
|
66
|
+
assert_migration "db/migrate/create_flipper_tables.rb" do |migration|
|
67
|
+
assert_method :up, migration do |up|
|
68
|
+
assert_match(/text :value/, up)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
assert_migration "db/migrate/change_flipper_gates_value_to_text.rb"
|
73
|
+
|
74
|
+
require_migrations
|
75
|
+
|
76
|
+
silence { CreateFlipperTables.migrate(:up) }
|
77
|
+
assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
|
78
|
+
|
79
|
+
assert_nothing_raised do
|
80
|
+
silence { ChangeFlipperGatesValueToText.migrate(:up) }
|
81
|
+
end
|
82
|
+
assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
|
83
|
+
end
|
84
|
+
|
85
|
+
def require_migrations
|
86
|
+
# If these are not reloaded, then test order can cause failures
|
87
|
+
Object.send(:remove_const, :CreateFlipperTables) if defined?(::CreateFlipperTables)
|
88
|
+
Object.send(:remove_const, :ChangeFlipperGatesValueToText) if defined?(::ChangeFlipperGatesValueToText)
|
89
|
+
|
90
|
+
Dir.glob("#{ROOT}/db/migrate/*.rb").each do |file|
|
91
|
+
assert_nothing_raised do
|
92
|
+
load file
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/test_rails/helper.rb
CHANGED
@@ -1,11 +1,31 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
|
2
|
+
require 'bundler/setup'
|
3
|
+
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
|
10
13
|
# no biggie, means we are on older version of AS that doesn't have this option
|
11
14
|
end
|
15
|
+
|
16
|
+
def silence
|
17
|
+
# Store the original stderr and stdout in order to restore them later
|
18
|
+
original_stderr = $stderr
|
19
|
+
original_stdout = $stdout
|
20
|
+
|
21
|
+
# Redirect stderr and stdout
|
22
|
+
output = $stderr = $stdout = StringIO.new
|
23
|
+
|
24
|
+
yield
|
25
|
+
|
26
|
+
$stderr = original_stderr
|
27
|
+
$stdout = original_stdout
|
28
|
+
|
29
|
+
# Return output
|
30
|
+
output.string
|
31
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative "../helper"
|
2
|
+
|
3
|
+
# Not worth trying to test on old Rails versions
|
4
|
+
return unless Rails::VERSION::MAJOR >= 7
|
5
|
+
|
6
|
+
require "capybara/cuprite"
|
7
|
+
require "flipper"
|
8
|
+
require "flipper/test_help"
|
9
|
+
require "action_controller/railtie"
|
10
|
+
|
11
|
+
require 'action_dispatch/system_testing/server'
|
12
|
+
ActionDispatch::SystemTesting::Server.silence_puma = true
|
13
|
+
|
14
|
+
class TestApp < Rails::Application
|
15
|
+
config.load_defaults "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}"
|
16
|
+
config.eager_load = false
|
17
|
+
config.logger = ActiveSupport::Logger.new(StringIO.new)
|
18
|
+
routes.append do
|
19
|
+
root to: "features#index"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
TestApp.initialize!
|
24
|
+
|
25
|
+
class FeaturesController < ActionController::Base
|
26
|
+
def index
|
27
|
+
render json: Flipper.enabled?(:test) ? "Enabled" : "Disabled"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestHelpTest < ActionDispatch::SystemTestCase
|
32
|
+
# Any driver that runs the app in a separate thread will test what we want here.
|
33
|
+
driven_by :cuprite, options: { process_timeout: 60 }
|
34
|
+
|
35
|
+
setup do
|
36
|
+
# Reconfigure Flipper since other tests change the adapter.
|
37
|
+
flipper_configure
|
38
|
+
|
39
|
+
# Ensure this test uses this app instance
|
40
|
+
Rails.application = TestApp.instance
|
41
|
+
end
|
42
|
+
|
43
|
+
test "configures a shared adapter between tests and app" do
|
44
|
+
Flipper.disable(:test)
|
45
|
+
visit "/"
|
46
|
+
assert_selector "*", text: "Disabled"
|
47
|
+
|
48
|
+
Flipper.enable(:test)
|
49
|
+
visit "/"
|
50
|
+
assert_selector "*", text: "Enabled"
|
51
|
+
end
|
52
|
+
end
|