flip 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -4
- data/README.md +22 -5
- data/flip.gemspec +2 -1
- data/lib/flip.rb +1 -0
- data/lib/flip/cacheable.rb +25 -0
- data/lib/flip/controller_filters.rb +4 -1
- data/lib/flip/cookie_strategy.rb +10 -5
- data/lib/flip/database_strategy.rb +5 -1
- data/lib/flip/version.rb +1 -1
- data/lib/generators/flip/migration/templates/create_features.rb +1 -0
- data/spec/cacheable_spec.rb +49 -0
- data/spec/controller_filters_spec.rb +4 -4
- data/spec/cookie_strategy_spec.rb +15 -15
- data/spec/database_strategy_spec.rb +31 -1
- data/spec/declaration_strategy_spec.rb +4 -4
- data/spec/feature_set_spec.rb +5 -5
- data/spec/flip_spec.rb +4 -4
- data/spec/spec_helper.rb +2 -1
- metadata +37 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02d991d1f3a6415ae4a80c82b7a55a10be509ce1
|
4
|
+
data.tar.gz: df57386343e6c19b21d2715d007dd2af5dc6e45b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6acd5b58a68b952db77dae428b8f66f9c451286578f677a927d75f6f3e9d54d45c87779d9de3402f2aa28979a4f8810c0bc1f7d1b024644f84ee507160785eb1
|
7
|
+
data.tar.gz: e2658c0ff8d9a5fcefd12ba116b711e7f11a4ae4ab195c5ab6b6d74ca71df2c48bd2c48fb0fd92b80e65f5cdf8240bb3e3835879e347caefe931a6ba40aaf96f
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -21,7 +21,7 @@ There is also a configurable system-wide default - !Rails.env.production?` works
|
|
21
21
|
|
22
22
|
Flip has a dashboard UI that's easy to understand and use.
|
23
23
|
|
24
|
-
![Feature Flipper Dashboard](https://
|
24
|
+
![Feature Flipper Dashboard](https://cloud.githubusercontent.com/assets/828243/4934741/a5773568-65a4-11e4-98d8-5e9a32720b2e.png)
|
25
25
|
|
26
26
|
Install
|
27
27
|
-------
|
@@ -67,7 +67,7 @@ class Feature < ActiveRecord::Base
|
|
67
67
|
# Provide a description, normally derived from the feature name.
|
68
68
|
feature :something,
|
69
69
|
default: true,
|
70
|
-
description: "Ability to purchase enrollments in courses"
|
70
|
+
description: "Ability to purchase enrollments in courses"
|
71
71
|
|
72
72
|
end
|
73
73
|
```
|
@@ -100,7 +100,7 @@ Views and controllers use the `feature?(key)` method:
|
|
100
100
|
Feature Flipping Controllers
|
101
101
|
----------------------------
|
102
102
|
|
103
|
-
The `Flip::ControllerFilters` module is mixed into the base `ApplicationController` class. The following controller will respond with 404 Page Not Found to all but the `index` action unless the
|
103
|
+
The `Flip::ControllerFilters` module is mixed into the base `ApplicationController` class. The following controller will respond with 404 Page Not Found to all but the `index` action unless the `:something` feature is enabled:
|
104
104
|
|
105
105
|
```ruby
|
106
106
|
class SampleController < ApplicationController
|
@@ -134,7 +134,7 @@ app/controllers/admin/features_controller.rb:
|
|
134
134
|
|
135
135
|
```ruby
|
136
136
|
class Admin::FeaturesController < Flip::FeaturesController
|
137
|
-
|
137
|
+
before_action :assert_authenticated_as_admin
|
138
138
|
end
|
139
139
|
```
|
140
140
|
|
@@ -142,7 +142,7 @@ app/controllers/admin/strategies_controller.rb:
|
|
142
142
|
|
143
143
|
```ruby
|
144
144
|
class Admin::StrategiesController < Flip::StrategiesController
|
145
|
-
|
145
|
+
before_action :assert_authenticated_as_admin
|
146
146
|
end
|
147
147
|
```
|
148
148
|
|
@@ -158,6 +158,23 @@ end
|
|
158
158
|
mount Flip::Engine => "/admin/features"
|
159
159
|
```
|
160
160
|
|
161
|
+
Cacheable
|
162
|
+
---------
|
163
|
+
|
164
|
+
You can optimize your feature to ensure that it doesn't make a ton of feature
|
165
|
+
calls by adding Cacheable to your model.
|
166
|
+
```ruby
|
167
|
+
extend Flip::Cacheable
|
168
|
+
```
|
169
|
+
|
170
|
+
This will ensure that your features are eager loaded with one call to the database
|
171
|
+
instead of every call to Flip#on? generating a call to the database. This is
|
172
|
+
helpful if you have a larger Rails application and more than a few features
|
173
|
+
defined.
|
174
|
+
|
175
|
+
To start or reset the cache, just call #start_feature_cache.
|
176
|
+
|
177
|
+
|
161
178
|
----
|
162
179
|
Created by Paul Annesley
|
163
180
|
Copyright © 2011-2013 Learnable Pty Ltd, [MIT Licence](http://www.opensource.org/licenses/mit-license.php).
|
data/flip.gemspec
CHANGED
@@ -18,9 +18,10 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency("activesupport", ">= 3.0", "< 5")
|
21
|
+
s.add_dependency("activesupport", ">= 3.0", "< 5.1")
|
22
22
|
s.add_dependency("i18n")
|
23
23
|
|
24
24
|
s.add_development_dependency("rspec", "~> 2.5")
|
25
|
+
s.add_development_dependency("rspec-its")
|
25
26
|
s.add_development_dependency("rake")
|
26
27
|
end
|
data/lib/flip.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Flip
|
2
|
+
module Cacheable
|
3
|
+
|
4
|
+
def use_feature_cache=(value)
|
5
|
+
@use_feature_cache = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def use_feature_cache
|
9
|
+
@use_feature_cache
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_feature_cache
|
13
|
+
@use_feature_cache = true
|
14
|
+
@features = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def feature_cache
|
18
|
+
return @features if @features
|
19
|
+
@features = {}
|
20
|
+
all.each { |f| @features[f.key] = f }
|
21
|
+
@features
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Flip
|
2
|
+
# ControllerFilters is a name that refers to the fact that Rails
|
3
|
+
# before_action and after_action used to be before_filter and
|
4
|
+
# after_filter.
|
2
5
|
module ControllerFilters
|
3
6
|
|
4
7
|
extend ActiveSupport::Concern
|
@@ -6,7 +9,7 @@ module Flip
|
|
6
9
|
module ClassMethods
|
7
10
|
|
8
11
|
def require_feature key, options = {}
|
9
|
-
|
12
|
+
before_action options do
|
10
13
|
flip_feature_disabled key unless Flip.on? key
|
11
14
|
end
|
12
15
|
end
|
data/lib/flip/cookie_strategy.rb
CHANGED
@@ -11,7 +11,9 @@ module Flip
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def on? definition
|
14
|
-
cookies[cookie_name(definition)]
|
14
|
+
cookie = cookies[cookie_name(definition)]
|
15
|
+
cookie_value = cookie.is_a?(Hash) ? cookie['value'] : cookie
|
16
|
+
cookie_value === 'true'
|
15
17
|
end
|
16
18
|
|
17
19
|
def switchable?
|
@@ -19,7 +21,10 @@ module Flip
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def switch! key, on
|
22
|
-
cookies[cookie_name(key)] =
|
24
|
+
cookies[cookie_name(key)] = {
|
25
|
+
'value' => (on ? "true" : "false"),
|
26
|
+
'domain' => :all
|
27
|
+
}
|
23
28
|
end
|
24
29
|
|
25
30
|
def delete! key
|
@@ -42,13 +47,13 @@ module Flip
|
|
42
47
|
end
|
43
48
|
|
44
49
|
# Include in ApplicationController to push cookies into CookieStrategy.
|
45
|
-
#
|
50
|
+
# Uses before_action and after_action rather than around_action to
|
46
51
|
# avoid pointlessly adding to stack depth.
|
47
52
|
module Loader
|
48
53
|
extend ActiveSupport::Concern
|
49
54
|
included do
|
50
|
-
|
51
|
-
|
55
|
+
before_action :flip_cookie_strategy_before
|
56
|
+
after_action :flip_cookie_strategy_after
|
52
57
|
end
|
53
58
|
def flip_cookie_strategy_before
|
54
59
|
CookieStrategy.cookies = cookies
|
@@ -35,7 +35,11 @@ module Flip
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def feature(definition)
|
38
|
-
@klass.
|
38
|
+
if @klass.respond_to?(:use_feature_cache) && @klass.use_feature_cache
|
39
|
+
@klass.feature_cache[definition.key.to_s]
|
40
|
+
else
|
41
|
+
@klass.where(key: definition.key.to_s).first
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
end
|
data/lib/flip/version.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Flip::Cacheable do
|
4
|
+
|
5
|
+
subject(:model_class) do
|
6
|
+
class Sample
|
7
|
+
attr_accessor :key
|
8
|
+
end
|
9
|
+
|
10
|
+
Class.new do
|
11
|
+
extend Flip::Declarable
|
12
|
+
extend Flip::Cacheable
|
13
|
+
|
14
|
+
strategy Flip::DeclarationStrategy
|
15
|
+
default false
|
16
|
+
|
17
|
+
feature :one
|
18
|
+
feature :two, description: "Second one."
|
19
|
+
feature :three, default: true
|
20
|
+
|
21
|
+
def self.all
|
22
|
+
list = []
|
23
|
+
i = 65
|
24
|
+
3.times do
|
25
|
+
list << Sample.new
|
26
|
+
list.last.key = i.chr()
|
27
|
+
i += 1
|
28
|
+
end
|
29
|
+
list
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with feature cache" do
|
35
|
+
context "initial context" do
|
36
|
+
it { should respond_to(:use_feature_cache) }
|
37
|
+
it { should respond_to(:start_feature_cache) }
|
38
|
+
it { should respond_to(:feature_cache) }
|
39
|
+
specify { model_class.use_feature_cache.should be_nil }
|
40
|
+
end
|
41
|
+
|
42
|
+
context "after a cache clear" do
|
43
|
+
before { model_class.start_feature_cache }
|
44
|
+
specify { model_class.use_feature_cache.should eq true }
|
45
|
+
specify { model_class.feature_cache.size == 3}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -8,16 +8,16 @@ describe ControllerWithFlipFilters do
|
|
8
8
|
|
9
9
|
describe ".require_feature" do
|
10
10
|
|
11
|
-
it "adds
|
11
|
+
it "adds before_action without options" do
|
12
12
|
ControllerWithFlipFilters.tap do |klass|
|
13
|
-
klass.should_receive(:
|
13
|
+
klass.should_receive(:before_action).with({})
|
14
14
|
klass.send(:require_feature, :testable)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
it "adds
|
18
|
+
it "adds before_action with options" do
|
19
19
|
ControllerWithFlipFilters.tap do |klass|
|
20
|
-
klass.should_receive(:
|
20
|
+
klass.should_receive(:before_action).with({ only: [ :show ] })
|
21
21
|
klass.send(:require_feature, :testable, only: [ :show ])
|
22
22
|
end
|
23
23
|
end
|
@@ -2,8 +2,8 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
class ControllerWithoutCookieStrategy; end
|
4
4
|
class ControllerWithCookieStrategy
|
5
|
-
def self.
|
6
|
-
def self.
|
5
|
+
def self.before_action(_); end
|
6
|
+
def self.after_action(_); end
|
7
7
|
def cookies; []; end
|
8
8
|
include Flip::CookieStrategy::Loader
|
9
9
|
end
|
@@ -26,26 +26,26 @@ describe Flip::CookieStrategy do
|
|
26
26
|
describe "cookie interrogration" do
|
27
27
|
context "enabled feature" do
|
28
28
|
specify "#knows? is true" do
|
29
|
-
strategy.knows?(:one).should
|
29
|
+
strategy.knows?(:one).should be true
|
30
30
|
end
|
31
31
|
specify "#on? is true" do
|
32
|
-
strategy.on?(:one).should
|
32
|
+
strategy.on?(:one).should be true
|
33
33
|
end
|
34
34
|
end
|
35
35
|
context "disabled feature" do
|
36
36
|
specify "#knows? is true" do
|
37
|
-
strategy.knows?(:two).should
|
37
|
+
strategy.knows?(:two).should be true
|
38
38
|
end
|
39
39
|
specify "#on? is false" do
|
40
|
-
strategy.on?(:two).should
|
40
|
+
strategy.on?(:two).should be false
|
41
41
|
end
|
42
42
|
end
|
43
43
|
context "feature with no cookie present" do
|
44
44
|
specify "#knows? is false" do
|
45
|
-
strategy.knows?(:three).should
|
45
|
+
strategy.knows?(:three).should be false
|
46
46
|
end
|
47
47
|
specify "#on? is false" do
|
48
|
-
strategy.on?(:three).should
|
48
|
+
strategy.on?(:three).should be false
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -53,20 +53,20 @@ describe Flip::CookieStrategy do
|
|
53
53
|
describe "cookie manipulation" do
|
54
54
|
it "can switch known features on" do
|
55
55
|
strategy.switch! :one, true
|
56
|
-
strategy.on?(:one).should
|
56
|
+
strategy.on?(:one).should be true
|
57
57
|
end
|
58
58
|
it "can switch unknown features on" do
|
59
59
|
strategy.switch! :three, true
|
60
|
-
strategy.on?(:three).should
|
60
|
+
strategy.on?(:three).should be true
|
61
61
|
end
|
62
62
|
it "can switch features off" do
|
63
63
|
strategy.switch! :two, false
|
64
|
-
strategy.on?(:two).should
|
64
|
+
strategy.on?(:two).should be false
|
65
65
|
end
|
66
66
|
it "can delete knowledge of a feature" do
|
67
67
|
strategy.delete! :one
|
68
|
-
strategy.on?(:one).should
|
69
|
-
strategy.knows?(:one).should
|
68
|
+
strategy.on?(:one).should be false
|
69
|
+
strategy.knows?(:one).should be false
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -76,8 +76,8 @@ describe Flip::CookieStrategy::Loader do
|
|
76
76
|
|
77
77
|
it "adds filters when included in controller" do
|
78
78
|
ControllerWithoutCookieStrategy.tap do |klass|
|
79
|
-
klass.should_receive(:
|
80
|
-
klass.should_receive(:
|
79
|
+
klass.should_receive(:before_action).with(:flip_cookie_strategy_before)
|
80
|
+
klass.should_receive(:after_action).with(:flip_cookie_strategy_after)
|
81
81
|
klass.send :include, Flip::CookieStrategy::Loader
|
82
82
|
end
|
83
83
|
end
|
@@ -5,19 +5,39 @@ describe Flip::DatabaseStrategy do
|
|
5
5
|
let(:definition) { double("definition", key: "one") }
|
6
6
|
let(:strategy) { Flip::DatabaseStrategy.new(model_klass) }
|
7
7
|
let(:model_klass) do
|
8
|
+
class Sample
|
9
|
+
attr_accessor :key
|
10
|
+
|
11
|
+
def enabled?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
Class.new do
|
17
|
+
extend Flip::Cacheable
|
9
18
|
extend Flip::Declarable
|
10
19
|
feature :one
|
11
20
|
feature :two, description: "Second one."
|
12
21
|
feature :three, default: true
|
22
|
+
|
23
|
+
def self.all
|
24
|
+
list = []
|
25
|
+
keys = ['one', 'two', 'three']
|
26
|
+
3.times do |i|
|
27
|
+
list << Sample.new
|
28
|
+
list.last.key = keys[i]
|
29
|
+
end
|
30
|
+
list
|
31
|
+
end
|
13
32
|
end
|
14
33
|
end
|
34
|
+
|
15
35
|
let(:enabled_record) { model_klass.new.tap { |m| m.stub(:enabled?) { true } } }
|
16
36
|
let(:disabled_record) { model_klass.new.tap { |m| m.stub(:enabled?) { false } } }
|
17
37
|
|
18
38
|
subject { strategy }
|
19
39
|
|
20
|
-
its(:switchable?) { should
|
40
|
+
its(:switchable?) { should be true }
|
21
41
|
its(:description) { should be_present }
|
22
42
|
|
23
43
|
let(:db_result) { [] }
|
@@ -39,6 +59,16 @@ describe Flip::DatabaseStrategy do
|
|
39
59
|
end
|
40
60
|
end
|
41
61
|
|
62
|
+
describe "#on? with feature cache" do
|
63
|
+
before { model_klass.start_feature_cache }
|
64
|
+
context "for an enabled record" do
|
65
|
+
let(:db_result) { [enabled_record] }
|
66
|
+
it "returns true" do
|
67
|
+
expect(strategy.on?(definition)).to eq(true)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
42
72
|
describe "#on?" do
|
43
73
|
context "for an enabled record" do
|
44
74
|
let(:db_result) { [enabled_record] }
|
@@ -8,16 +8,16 @@ describe Flip::DeclarationStrategy do
|
|
8
8
|
|
9
9
|
describe "#knows?" do
|
10
10
|
it "does not know definition with no default specified" do
|
11
|
-
subject.knows?(Flip::Definition.new :feature).should
|
11
|
+
subject.knows?(Flip::Definition.new :feature).should be false
|
12
12
|
end
|
13
13
|
it "does not know definition with default of nil" do
|
14
|
-
subject.knows?(definition(nil)).should
|
14
|
+
subject.knows?(definition(nil)).should be false
|
15
15
|
end
|
16
16
|
it "knows definition with default set to true" do
|
17
|
-
subject.knows?(definition(true)).should
|
17
|
+
subject.knows?(definition(true)).should be true
|
18
18
|
end
|
19
19
|
it "knows definition with default set to false" do
|
20
|
-
subject.knows?(definition(false)).should
|
20
|
+
subject.knows?(definition(false)).should be true
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/spec/feature_set_spec.rb
CHANGED
@@ -41,26 +41,26 @@ describe Flip::FeatureSet do
|
|
41
41
|
describe "#default= and #on? with null strategy" do
|
42
42
|
subject { feature_set_with_null_strategy }
|
43
43
|
it "defaults to false" do
|
44
|
-
subject.on?(:feature).should
|
44
|
+
subject.on?(:feature).should be false
|
45
45
|
end
|
46
46
|
it "can default to true" do
|
47
47
|
subject.default = true
|
48
|
-
subject.on?(:feature).should
|
48
|
+
subject.on?(:feature).should be true
|
49
49
|
end
|
50
50
|
it "accepts a proc returning true" do
|
51
51
|
subject.default = proc { true }
|
52
|
-
subject.on?(:feature).should
|
52
|
+
subject.on?(:feature).should be true
|
53
53
|
end
|
54
54
|
it "accepts a proc returning false" do
|
55
55
|
subject.default = proc { false }
|
56
|
-
subject.on?(:feature).should
|
56
|
+
subject.on?(:feature).should be false
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "feature set with null strategy then always-true strategy" do
|
61
61
|
subject { feature_set_with_null_then_true_strategies }
|
62
62
|
it "returns true due to second strategy" do
|
63
|
-
subject.on?(:feature).should
|
63
|
+
subject.on?(:feature).should be true
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
data/spec/flip_spec.rb
CHANGED
@@ -18,16 +18,16 @@ describe Flip do
|
|
18
18
|
|
19
19
|
describe ".on?" do
|
20
20
|
it "returns true for enabled features" do
|
21
|
-
Flip.on?(:one).should
|
21
|
+
Flip.on?(:one).should be true
|
22
22
|
end
|
23
23
|
it "returns false for disabled features" do
|
24
|
-
Flip.on?(:two).should
|
24
|
+
Flip.on?(:two).should be false
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "dynamic predicate methods" do
|
29
|
-
its(:one?) { should
|
30
|
-
its(:two?) { should
|
29
|
+
its(:one?) { should be true }
|
30
|
+
its(:two?) { should be false }
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require
|
1
|
+
require 'flip'
|
2
|
+
require 'rspec/its'
|
metadata
CHANGED
@@ -1,75 +1,89 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Annesley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.0'
|
20
|
-
- -
|
20
|
+
- - <
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5'
|
22
|
+
version: '5.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '3.0'
|
30
|
-
- -
|
30
|
+
- - <
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5'
|
32
|
+
version: '5.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: i18n
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - '>='
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '2.5'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - ~>
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '2.5'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec-its
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: rake
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
|
-
- -
|
79
|
+
- - '>='
|
66
80
|
- !ruby/object:Gem::Version
|
67
81
|
version: '0'
|
68
82
|
type: :development
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
|
-
- -
|
86
|
+
- - '>='
|
73
87
|
- !ruby/object:Gem::Version
|
74
88
|
version: '0'
|
75
89
|
description: Declarative API for specifying features, switchable in declaration, database
|
@@ -80,9 +94,9 @@ executables: []
|
|
80
94
|
extensions: []
|
81
95
|
extra_rdoc_files: []
|
82
96
|
files:
|
83
|
-
-
|
84
|
-
-
|
85
|
-
-
|
97
|
+
- .gitignore
|
98
|
+
- .rspec
|
99
|
+
- .travis.yml
|
86
100
|
- Gemfile
|
87
101
|
- README.md
|
88
102
|
- Rakefile
|
@@ -96,6 +110,7 @@ files:
|
|
96
110
|
- flip.gemspec
|
97
111
|
- lib/flip.rb
|
98
112
|
- lib/flip/abstract_strategy.rb
|
113
|
+
- lib/flip/cacheable.rb
|
99
114
|
- lib/flip/controller_filters.rb
|
100
115
|
- lib/flip/cookie_strategy.rb
|
101
116
|
- lib/flip/database_strategy.rb
|
@@ -117,6 +132,7 @@ files:
|
|
117
132
|
- lib/generators/flip/routes/USAGE
|
118
133
|
- lib/generators/flip/routes/routes_generator.rb
|
119
134
|
- spec/abstract_strategy_spec.rb
|
135
|
+
- spec/cacheable_spec.rb
|
120
136
|
- spec/controller_filters_spec.rb
|
121
137
|
- spec/cookie_strategy_spec.rb
|
122
138
|
- spec/database_strategy_spec.rb
|
@@ -136,22 +152,23 @@ require_paths:
|
|
136
152
|
- lib
|
137
153
|
required_ruby_version: !ruby/object:Gem::Requirement
|
138
154
|
requirements:
|
139
|
-
- -
|
155
|
+
- - '>='
|
140
156
|
- !ruby/object:Gem::Version
|
141
157
|
version: '0'
|
142
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
159
|
requirements:
|
144
|
-
- -
|
160
|
+
- - '>='
|
145
161
|
- !ruby/object:Gem::Version
|
146
162
|
version: '0'
|
147
163
|
requirements: []
|
148
164
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.
|
165
|
+
rubygems_version: 2.0.14.1
|
150
166
|
signing_key:
|
151
167
|
specification_version: 4
|
152
168
|
summary: A feature flipper for Rails web applications.
|
153
169
|
test_files:
|
154
170
|
- spec/abstract_strategy_spec.rb
|
171
|
+
- spec/cacheable_spec.rb
|
155
172
|
- spec/controller_filters_spec.rb
|
156
173
|
- spec/cookie_strategy_spec.rb
|
157
174
|
- spec/database_strategy_spec.rb
|