flipflop 2.4.0 → 2.5.0
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/.travis.yml +6 -6
- data/CHANGES.md +5 -0
- data/Gemfile +7 -1
- data/LICENSE +1 -1
- data/README.md +12 -6
- data/app/controllers/flipflop/features_controller.rb +6 -1
- data/lib/flipflop.rb +1 -0
- data/lib/flipflop/facade.rb +2 -0
- data/lib/flipflop/strategies/active_record_strategy.rb +8 -1
- data/lib/flipflop/strategies/sequel_strategy.rb +57 -0
- data/lib/flipflop/version.rb +1 -1
- data/lib/generators/flipflop/features/templates/features.rb +3 -1
- data/test/test_helper.rb +19 -0
- data/test/unit/strategies/active_record_strategy_test.rb +16 -16
- data/test/unit/strategies/sequel_strategy_test.rb +165 -0
- metadata +5 -5
- data/app/models/flipflop/feature.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2285d1f81e213c214eba67b891e72bd671b2dea7096759ba142bd8457197c671
|
4
|
+
data.tar.gz: d560e6dc20e028641bea194e4626b2103e0e4999e40308b3f3d9009574090c64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31b1406c3ab135e4bf628040914ea4057ab37bef82909e180da668d60365abf480081819720d4d044baabea59940167f3353d2478ba3433a1867e035dce981e9
|
7
|
+
data.tar.gz: 2f78138c8de1ae3b96bdf511effbad20cf0e08b66764ce82b159f024c32868c78f9ced8c6918bc52ce316b7599a4301f03583006d58de441f72835a694aa4a09
|
data/.travis.yml
CHANGED
@@ -2,7 +2,7 @@ language: ruby
|
|
2
2
|
cache: bundler
|
3
3
|
rvm:
|
4
4
|
- 2.5.0
|
5
|
-
- 2.4.
|
5
|
+
- 2.4.4
|
6
6
|
- 2.3.5
|
7
7
|
- jruby-9.1.13.0
|
8
8
|
- ruby-head
|
@@ -18,16 +18,12 @@ env:
|
|
18
18
|
- RAILS_VERSION=5.0 RAILS_API_ONLY=1
|
19
19
|
matrix:
|
20
20
|
include:
|
21
|
-
- rvm: 2.3.5
|
22
|
-
env: RAILS_VERSION=4.2
|
23
21
|
- rvm: 2.2.8
|
24
22
|
env: RAILS_VERSION=4.2
|
25
23
|
- rvm: 2.1.10
|
26
24
|
env: RAILS_VERSION=4.2
|
27
25
|
- rvm: 2.0.0
|
28
26
|
env: RAILS_VERSION=4.2
|
29
|
-
- rvm: 2.3.5
|
30
|
-
env: RAILS_VERSION=4.1
|
31
27
|
- rvm: 2.2.8
|
32
28
|
env: RAILS_VERSION=4.1
|
33
29
|
- rvm: 2.1.10
|
@@ -35,6 +31,10 @@ matrix:
|
|
35
31
|
- rvm: 2.0.0
|
36
32
|
env: RAILS_VERSION=4.1
|
37
33
|
exclude:
|
34
|
+
- rvm: 2.4.4
|
35
|
+
env: RAILS_VERSION=master
|
36
|
+
- rvm: 2.4.4
|
37
|
+
env: RAILS_VERSION=master RAILS_API_ONLY=1
|
38
38
|
- rvm: 2.3.5
|
39
39
|
env: RAILS_VERSION=master
|
40
40
|
- rvm: 2.3.5
|
@@ -52,4 +52,4 @@ deploy:
|
|
52
52
|
on:
|
53
53
|
tags: true
|
54
54
|
repo: voormedia/flipflop
|
55
|
-
ruby: 2.
|
55
|
+
ruby: 2.5.0
|
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
@@ -13,7 +13,13 @@ group :test do
|
|
13
13
|
gem "bootstrap", "= 4.0.0.alpha6", require: false
|
14
14
|
|
15
15
|
gem "fakeredis", require: false
|
16
|
-
|
16
|
+
|
17
|
+
if version == "master" || version >= "6"
|
18
|
+
gem "sqlite3", "~> 1.4.0", platform: :ruby
|
19
|
+
else
|
20
|
+
gem "sqlite3", "~> 1.3.6", platform: :ruby
|
21
|
+
end
|
22
|
+
|
17
23
|
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby,
|
18
24
|
github: "jruby/activerecord-jdbc-adapter"
|
19
25
|
|
data/LICENSE
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
3
|
Copyright (c) 2011-2013 Learnable Pty Ltd
|
4
|
-
Copyright (c) 2016-
|
4
|
+
Copyright (c) 2016-2019 Voormedia
|
5
5
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -4,11 +4,13 @@
|
|
4
4
|
|
5
5
|
**Flipflop** provides a declarative, layered way of enabling and disabling
|
6
6
|
application functionality at run-time. It is originally based on
|
7
|
-
[Flip](https://github.com/pda/flip).
|
7
|
+
[Flip](https://github.com/pda/flip). **Flipflop** has the following features:
|
8
|
+
* simple configuration
|
9
|
+
* ease of use for developers
|
8
10
|
* an improved dashboard
|
9
11
|
* thread safety
|
10
12
|
* better database performance due to per-request caching, enabled by default
|
11
|
-
* more strategies (Redis, query strings, sessions, custom code)
|
13
|
+
* more strategies (Sequel, Redis, query strings, sessions, custom code)
|
12
14
|
* more strategy options (cookie options, strategy names and descriptions, custom database models)
|
13
15
|
* the ability to use the same strategy twice, with different options
|
14
16
|
* configuration in a fixed location (`config/features.rb`) that is usable even if you don't use the database strategy
|
@@ -21,7 +23,7 @@ application functionality at run-time. It is originally based on
|
|
21
23
|
You can configure strategy layers that will evaluate if a feature is currently
|
22
24
|
enabled or disabled. Available strategies are:
|
23
25
|
* a per-feature default setting
|
24
|
-
* database (with Active Record or Redis), to flipflop features site-wide for all users
|
26
|
+
* database (with Active Record, Sequel, or Redis), to flipflop features site-wide for all users
|
25
27
|
* cookie or session, to flipflop features for single users
|
26
28
|
* query string parameters, to flipflop features occasionally (in development mode for example)
|
27
29
|
* custom strategy code
|
@@ -30,6 +32,10 @@ Flipflop has a dashboard interface that's easy to understand and use.
|
|
30
32
|
|
31
33
|
[<img src="https://raw.githubusercontent.com/voormedia/flipflop/screenshots/dashboard.png" alt="Dashboard">](https://raw.githubusercontent.com/voormedia/flipflop/screenshots/dashboard.png)
|
32
34
|
|
35
|
+
## Rails requirements
|
36
|
+
|
37
|
+
This gem requires Rails 4, 5 or 6. Using an ORM layer is entirely optional.
|
38
|
+
|
33
39
|
## Installation
|
34
40
|
|
35
41
|
Add the gem to your `Gemfile`:
|
@@ -58,7 +64,7 @@ Features and strategies are declared in `config/features.rb`:
|
|
58
64
|
Flipflop.configure do
|
59
65
|
# Strategies will be used in the order listed here.
|
60
66
|
strategy :cookie
|
61
|
-
strategy :active_record
|
67
|
+
strategy :active_record # or :sequel, :redis
|
62
68
|
strategy :default
|
63
69
|
|
64
70
|
# Basic feature declaration:
|
@@ -86,8 +92,8 @@ Feature definitions support these options:
|
|
86
92
|
## Strategies
|
87
93
|
|
88
94
|
The following strategies are provided:
|
89
|
-
* `:active_record` – Save feature settings in the database.
|
90
|
-
* `:class` – Provide the feature model. `Flipflop::Feature` by default (which uses the table `flipflop_features`).
|
95
|
+
* `:active_record`/`:sequel` – Save feature settings in the database.
|
96
|
+
* `:class` – Provide the feature model. `Flipflop::Feature` by default (which is defined automatically and uses the table `flipflop_features`). The `ActiveRecord` version honors `default_scope` when features are resolved or switched on/off.
|
91
97
|
* `:cookie` – Save feature settings in browser cookies for the current user.
|
92
98
|
* `:prefix` – String prefix for all cookie names. Defaults to no prefix.
|
93
99
|
* `:path` – The path for which the cookies apply. Defaults to the root of the application.
|
@@ -25,7 +25,12 @@ module Flipflop
|
|
25
25
|
@strategies = @feature_set.strategies.reject(&:hidden?)
|
26
26
|
@grouped_features = @feature_set.features.group_by(&:group)
|
27
27
|
|
28
|
-
|
28
|
+
app_class = Rails.application.class
|
29
|
+
application_name = app_class.respond_to?(:module_parent_name) ?
|
30
|
+
app_class.module_parent_name :
|
31
|
+
app_class.parent_name
|
32
|
+
|
33
|
+
@application_name = application_name.underscore.titleize
|
29
34
|
end
|
30
35
|
|
31
36
|
def grouped?
|
data/lib/flipflop.rb
CHANGED
@@ -22,6 +22,7 @@ require "flipflop/strategies/lambda_strategy"
|
|
22
22
|
require "flipflop/strategies/query_string_strategy"
|
23
23
|
require "flipflop/strategies/redis_strategy"
|
24
24
|
require "flipflop/strategies/session_strategy"
|
25
|
+
require "flipflop/strategies/sequel_strategy"
|
25
26
|
require "flipflop/strategies/test_strategy"
|
26
27
|
|
27
28
|
require "flipflop/engine" if defined?(Rails)
|
data/lib/flipflop/facade.rb
CHANGED
@@ -5,10 +5,17 @@ module Flipflop
|
|
5
5
|
def default_description
|
6
6
|
"Stores features in database. Applies to all users."
|
7
7
|
end
|
8
|
+
|
9
|
+
def define_feature_class
|
10
|
+
return Flipflop::Feature if defined?(Flipflop::Feature)
|
11
|
+
|
12
|
+
model = Class.new(ActiveRecord::Base)
|
13
|
+
Flipflop.const_set(:Feature, model)
|
14
|
+
end
|
8
15
|
end
|
9
16
|
|
10
17
|
def initialize(**options)
|
11
|
-
@class = options.delete(:class) ||
|
18
|
+
@class = options.delete(:class) || self.class.define_feature_class
|
12
19
|
if !@class.kind_of?(Class)
|
13
20
|
@class = ActiveSupport::Inflector.constantize(@class.to_s)
|
14
21
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Flipflop
|
2
|
+
module Strategies
|
3
|
+
class SequelStrategy < AbstractStrategy
|
4
|
+
class << self
|
5
|
+
def default_description
|
6
|
+
"Stores features in database. Applies to all users."
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_feature_class
|
10
|
+
return Flipflop::Feature if defined?(Flipflop::Feature)
|
11
|
+
|
12
|
+
model = Class.new(Sequel::Model(:flipflop_features))
|
13
|
+
model.plugin(:timestamps, force: true, update_on_create: true)
|
14
|
+
model.raise_on_save_failure = true
|
15
|
+
|
16
|
+
Flipflop.const_set(:Feature, model)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(**options)
|
21
|
+
@class = options.delete(:class) || self.class.define_feature_class
|
22
|
+
if !@class.kind_of?(Class)
|
23
|
+
@class = ActiveSupport::Inflector.constantize(@class.to_s)
|
24
|
+
end
|
25
|
+
super(**options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def switchable?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled?(feature)
|
33
|
+
find(feature).try(:enabled?)
|
34
|
+
end
|
35
|
+
|
36
|
+
def switch!(feature, enabled)
|
37
|
+
record = find_or_new(feature)
|
38
|
+
record.enabled = enabled
|
39
|
+
record.save
|
40
|
+
end
|
41
|
+
|
42
|
+
def clear!(feature)
|
43
|
+
find(feature).try(:destroy)
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def find_or_new(feature)
|
49
|
+
find(feature) || @class.new(key: feature.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
def find(feature)
|
53
|
+
@class.where(key: feature.to_s).first
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/flipflop/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -100,7 +100,11 @@ class TestApp
|
|
100
100
|
quiet: true,
|
101
101
|
api: ENV["RAILS_API_ONLY"].to_i.nonzero?,
|
102
102
|
skip_active_job: true,
|
103
|
+
skip_active_storage: true,
|
104
|
+
skip_action_cable: true,
|
105
|
+
skip_bootsnap: true,
|
103
106
|
skip_bundle: true,
|
107
|
+
skip_puma: true,
|
104
108
|
skip_gemfile: true,
|
105
109
|
skip_git: true,
|
106
110
|
skip_javascript: true,
|
@@ -128,11 +132,26 @@ class TestApp
|
|
128
132
|
require "rails"
|
129
133
|
require "flipflop/engine"
|
130
134
|
|
135
|
+
ActiveSupport::Dependencies.autoloaded_constants.clear
|
131
136
|
load File.expand_path("../../#{path}/config/application.rb", __FILE__)
|
132
137
|
load File.expand_path("../../#{path}/config/environments/test.rb", __FILE__)
|
133
138
|
Rails.application.config.cache_classes = false
|
134
139
|
Rails.application.config.action_view.raise_on_missing_translations = true
|
135
140
|
Rails.application.config.i18n.enforce_available_locales = false
|
141
|
+
Rails.application.config.autoloader = :classic # Disable Zeitwerk in Rails 6+
|
142
|
+
|
143
|
+
# Avoid Rails 6+ deprecation warning
|
144
|
+
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter) &&
|
145
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.respond_to?(:represent_boolean_as_integer=) &&
|
146
|
+
Rails.application.config.active_record.sqlite3.nil?
|
147
|
+
Rails.application.config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
|
148
|
+
end
|
149
|
+
|
150
|
+
# Avoid Rails 6+ deprecation warning
|
151
|
+
if defined?(ActionView::Railtie::NULL_OPTION)
|
152
|
+
Rails.application.config.action_view.finalize_compiled_template_methods = ActionView::Railtie::NULL_OPTION
|
153
|
+
end
|
154
|
+
|
136
155
|
Rails.application.initialize!
|
137
156
|
|
138
157
|
I18n.locale = :en
|
@@ -6,7 +6,7 @@ class ResultSet
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def first_or_initialize
|
9
|
-
@results.first or
|
9
|
+
@results.first or MyAr::Feature.new(@key, false)
|
10
10
|
end
|
11
11
|
|
12
12
|
def first
|
@@ -14,7 +14,7 @@ class ResultSet
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
module
|
17
|
+
module MyAr
|
18
18
|
class Feature < Struct.new(:key, :enabled)
|
19
19
|
class << self
|
20
20
|
attr_accessor :results
|
@@ -27,11 +27,11 @@ module My
|
|
27
27
|
alias_method :enabled?, :enabled
|
28
28
|
|
29
29
|
def destroy
|
30
|
-
|
30
|
+
MyAr::Feature.results[key] = ResultSet.new(key)
|
31
31
|
end
|
32
32
|
|
33
33
|
def save!
|
34
|
-
|
34
|
+
MyAr::Feature.results[key] = ResultSet.new(key, [self])
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -39,7 +39,7 @@ end
|
|
39
39
|
describe Flipflop::Strategies::ActiveRecordStrategy do
|
40
40
|
describe "with defaults" do
|
41
41
|
subject do
|
42
|
-
Flipflop::Strategies::ActiveRecordStrategy.new(class:
|
42
|
+
Flipflop::Strategies::ActiveRecordStrategy.new(class: MyAr::Feature).freeze
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should have default name" do
|
@@ -65,8 +65,8 @@ describe Flipflop::Strategies::ActiveRecordStrategy do
|
|
65
65
|
|
66
66
|
describe "with enabled feature" do
|
67
67
|
before do
|
68
|
-
|
69
|
-
one: ResultSet.new(:one, [
|
68
|
+
MyAr::Feature.results = {
|
69
|
+
one: ResultSet.new(:one, [MyAr::Feature.new(:one, true)]),
|
70
70
|
}
|
71
71
|
end
|
72
72
|
|
@@ -87,8 +87,8 @@ describe Flipflop::Strategies::ActiveRecordStrategy do
|
|
87
87
|
|
88
88
|
describe "with disabled feature" do
|
89
89
|
before do
|
90
|
-
|
91
|
-
two: ResultSet.new(:two, [
|
90
|
+
MyAr::Feature.results = {
|
91
|
+
two: ResultSet.new(:two, [MyAr::Feature.new(:two, false)]),
|
92
92
|
}
|
93
93
|
end
|
94
94
|
|
@@ -109,7 +109,7 @@ describe Flipflop::Strategies::ActiveRecordStrategy do
|
|
109
109
|
|
110
110
|
describe "with unsaved feature" do
|
111
111
|
before do
|
112
|
-
|
112
|
+
MyAr::Feature.results = {
|
113
113
|
three: ResultSet.new(:three),
|
114
114
|
}
|
115
115
|
end
|
@@ -127,12 +127,12 @@ describe Flipflop::Strategies::ActiveRecordStrategy do
|
|
127
127
|
|
128
128
|
describe "with string class name" do
|
129
129
|
subject do
|
130
|
-
Flipflop::Strategies::ActiveRecordStrategy.new(class: "
|
130
|
+
Flipflop::Strategies::ActiveRecordStrategy.new(class: "MyAr::Feature").freeze
|
131
131
|
end
|
132
132
|
|
133
133
|
before do
|
134
|
-
|
135
|
-
one: ResultSet.new(:one, [
|
134
|
+
MyAr::Feature.results = {
|
135
|
+
one: ResultSet.new(:one, [MyAr::Feature.new(:one, true)]),
|
136
136
|
}
|
137
137
|
end
|
138
138
|
|
@@ -144,12 +144,12 @@ describe Flipflop::Strategies::ActiveRecordStrategy do
|
|
144
144
|
|
145
145
|
describe "with symbol class name" do
|
146
146
|
subject do
|
147
|
-
Flipflop::Strategies::ActiveRecordStrategy.new(class: :"
|
147
|
+
Flipflop::Strategies::ActiveRecordStrategy.new(class: :"MyAr::Feature").freeze
|
148
148
|
end
|
149
149
|
|
150
150
|
before do
|
151
|
-
|
152
|
-
one: ResultSet.new(:one, [
|
151
|
+
MyAr::Feature.results = {
|
152
|
+
one: ResultSet.new(:one, [MyAr::Feature.new(:one, true)]),
|
153
153
|
}
|
154
154
|
end
|
155
155
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require File.expand_path("../../../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class ResultSet
|
4
|
+
def initialize(key, results = [])
|
5
|
+
@key, @results = key, results
|
6
|
+
end
|
7
|
+
|
8
|
+
def first
|
9
|
+
@results.first
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module MySq
|
14
|
+
class Feature < Struct.new(:key, :enabled)
|
15
|
+
class << self
|
16
|
+
attr_accessor :results
|
17
|
+
|
18
|
+
def where(conditions)
|
19
|
+
results[conditions[:key].to_sym]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :enabled?, :enabled
|
24
|
+
|
25
|
+
def initialize(key, value = false)
|
26
|
+
if key.kind_of?(Hash)
|
27
|
+
key.each { |k, v| self[k] = v.to_sym }
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
MySq::Feature.results[key] = ResultSet.new(key)
|
35
|
+
end
|
36
|
+
|
37
|
+
def save
|
38
|
+
MySq::Feature.results[key] = ResultSet.new(key, [self])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Flipflop::Strategies::SequelStrategy do
|
44
|
+
describe "with defaults" do
|
45
|
+
subject do
|
46
|
+
Flipflop::Strategies::SequelStrategy.new(class: MySq::Feature).freeze
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have default name" do
|
50
|
+
assert_equal "sequel", subject.name
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have title derived from name" do
|
54
|
+
assert_equal "Sequel", subject.title
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have default description" do
|
58
|
+
assert_equal "Stores features in database. Applies to all users.",
|
59
|
+
subject.description
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should be switchable" do
|
63
|
+
assert_equal true, subject.switchable?
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have unique key" do
|
67
|
+
assert_match /^\w+$/, subject.key
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "with enabled feature" do
|
71
|
+
before do
|
72
|
+
MySq::Feature.results = {
|
73
|
+
one: ResultSet.new(:one, [MySq::Feature.new(:one, true)]),
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have feature enabled" do
|
78
|
+
assert_equal true, subject.enabled?(:one)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be able to switch feature off" do
|
82
|
+
subject.switch!(:one, false)
|
83
|
+
assert_equal false, subject.enabled?(:one)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be able to clear feature" do
|
87
|
+
subject.clear!(:one)
|
88
|
+
assert_nil subject.enabled?(:one)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "with disabled feature" do
|
93
|
+
before do
|
94
|
+
MySq::Feature.results = {
|
95
|
+
two: ResultSet.new(:two, [MySq::Feature.new(:two, false)]),
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should not have feature enabled" do
|
100
|
+
assert_equal false, subject.enabled?(:two)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be able to switch feature on" do
|
104
|
+
subject.switch!(:two, true)
|
105
|
+
assert_equal true, subject.enabled?(:two)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should be able to clear feature" do
|
109
|
+
subject.clear!(:two)
|
110
|
+
assert_nil subject.enabled?(:two)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "with unsaved feature" do
|
115
|
+
before do
|
116
|
+
MySq::Feature.results = {
|
117
|
+
three: ResultSet.new(:three),
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should not know feature" do
|
122
|
+
assert_nil subject.enabled?(:three)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should be able to switch feature on" do
|
126
|
+
subject.switch!(:three, true)
|
127
|
+
assert_equal true, subject.enabled?(:three)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "with string class name" do
|
133
|
+
subject do
|
134
|
+
Flipflop::Strategies::SequelStrategy.new(class: "MySq::Feature").freeze
|
135
|
+
end
|
136
|
+
|
137
|
+
before do
|
138
|
+
MySq::Feature.results = {
|
139
|
+
one: ResultSet.new(:one, [MySq::Feature.new(:one, true)]),
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should be able to switch feature off" do
|
144
|
+
subject.switch!(:one, false)
|
145
|
+
assert_equal false, subject.enabled?(:one)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "with symbol class name" do
|
150
|
+
subject do
|
151
|
+
Flipflop::Strategies::SequelStrategy.new(class: :"MySq::Feature").freeze
|
152
|
+
end
|
153
|
+
|
154
|
+
before do
|
155
|
+
MySq::Feature.results = {
|
156
|
+
one: ResultSet.new(:one, [MySq::Feature.new(:one, true)]),
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should be able to switch feature off" do
|
161
|
+
subject.switch!(:one, false)
|
162
|
+
assert_equal false, subject.enabled?(:one)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipflop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Annesley
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2019-04-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -45,7 +45,6 @@ files:
|
|
45
45
|
- Rakefile
|
46
46
|
- app/controllers/flipflop/features_controller.rb
|
47
47
|
- app/controllers/flipflop/strategies_controller.rb
|
48
|
-
- app/models/flipflop/feature.rb
|
49
48
|
- app/views/flipflop/features/index.html.erb
|
50
49
|
- app/views/flipflop/stylesheets/_flipflop.css
|
51
50
|
- app/views/layouts/flipflop.html.erb
|
@@ -70,6 +69,7 @@ files:
|
|
70
69
|
- lib/flipflop/strategies/options_hasher.rb
|
71
70
|
- lib/flipflop/strategies/query_string_strategy.rb
|
72
71
|
- lib/flipflop/strategies/redis_strategy.rb
|
72
|
+
- lib/flipflop/strategies/sequel_strategy.rb
|
73
73
|
- lib/flipflop/strategies/session_strategy.rb
|
74
74
|
- lib/flipflop/strategies/test_strategy.rb
|
75
75
|
- lib/flipflop/version.rb
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- test/unit/strategies/options_hasher_test.rb
|
106
106
|
- test/unit/strategies/query_string_strategy_test.rb
|
107
107
|
- test/unit/strategies/redis_strategy_test.rb
|
108
|
+
- test/unit/strategies/sequel_strategy_test.rb
|
108
109
|
- test/unit/strategies/session_strategy_test.rb
|
109
110
|
- test/unit/strategies/test_strategy_test.rb
|
110
111
|
- test/unit/strategies_controller_test.rb
|
@@ -127,8 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
128
|
- !ruby/object:Gem::Version
|
128
129
|
version: '0'
|
129
130
|
requirements: []
|
130
|
-
|
131
|
-
rubygems_version: 2.7.6
|
131
|
+
rubygems_version: 3.0.3
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
134
|
summary: A feature flipflopper for Rails web applications.
|