feature_gate 0.0.7 → 0.0.8
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/.gitignore +1 -0
- data/Gemfile.lock +111 -69
- data/README.md +49 -1
- data/app/models/feature_gate/gated_feature.rb +19 -0
- data/app/models/feature_gate/manager.rb +35 -0
- data/feature_gate.gemspec +3 -1
- data/lib/feature_gate/version.rb +1 -1
- data/lib/feature_gate.rb +0 -24
- data/spec/factories.rb +10 -0
- data/spec/fake_app.rb +17 -0
- data/spec/models/feature_gate/manager_spec.rb +94 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/database.yml +3 -0
- metadata +37 -3
- data/app/models/gated_feature.rb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e187e63d24ae3b5361f106b9bec9447d2b0d18ac
|
|
4
|
+
data.tar.gz: 4a194e22810c9e87b39a16b9a725f6743dfac712
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c32a616311c119c7e68d69192c5207ce82b14ecc0a373168a13f42b73f85d63fb81a67e7bfd4728047885b2b98129ff941bfdd1dee992b4182d0207edd009cb
|
|
7
|
+
data.tar.gz: 771f991a6fc664aff138a9ad627b27f45a4b994e3668fd3acfdfbf4b1d81530f0c84588dc209edf990b537781e24ffbc069cbf5c7900e1926a81461a92e967e1
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,93 +1,135 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
feature_gate (0.0.
|
|
5
|
-
rails (~>
|
|
4
|
+
feature_gate (0.0.7)
|
|
5
|
+
rails (~> 4.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
actionmailer (
|
|
11
|
-
actionpack (=
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
actionmailer (4.2.6)
|
|
11
|
+
actionpack (= 4.2.6)
|
|
12
|
+
actionview (= 4.2.6)
|
|
13
|
+
activejob (= 4.2.6)
|
|
14
|
+
mail (~> 2.5, >= 2.5.4)
|
|
15
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
16
|
+
actionpack (4.2.6)
|
|
17
|
+
actionview (= 4.2.6)
|
|
18
|
+
activesupport (= 4.2.6)
|
|
19
|
+
rack (~> 1.6)
|
|
20
|
+
rack-test (~> 0.6.2)
|
|
21
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
22
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
23
|
+
actionview (4.2.6)
|
|
24
|
+
activesupport (= 4.2.6)
|
|
25
|
+
builder (~> 3.1)
|
|
17
26
|
erubis (~> 2.7.0)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
activemodel (
|
|
24
|
-
activesupport (=
|
|
25
|
-
builder (~> 3.
|
|
26
|
-
activerecord (
|
|
27
|
-
activemodel (=
|
|
28
|
-
activesupport (=
|
|
29
|
-
arel (~>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
29
|
+
activejob (4.2.6)
|
|
30
|
+
activesupport (= 4.2.6)
|
|
31
|
+
globalid (>= 0.3.0)
|
|
32
|
+
activemodel (4.2.6)
|
|
33
|
+
activesupport (= 4.2.6)
|
|
34
|
+
builder (~> 3.1)
|
|
35
|
+
activerecord (4.2.6)
|
|
36
|
+
activemodel (= 4.2.6)
|
|
37
|
+
activesupport (= 4.2.6)
|
|
38
|
+
arel (~> 6.0)
|
|
39
|
+
activesupport (4.2.6)
|
|
40
|
+
i18n (~> 0.7)
|
|
41
|
+
json (~> 1.7, >= 1.7.7)
|
|
42
|
+
minitest (~> 5.1)
|
|
43
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
44
|
+
tzinfo (~> 1.1)
|
|
45
|
+
arel (6.0.3)
|
|
46
|
+
builder (3.2.2)
|
|
47
|
+
concurrent-ruby (1.0.2)
|
|
48
|
+
diff-lcs (1.2.5)
|
|
39
49
|
erubis (2.7.0)
|
|
40
|
-
|
|
50
|
+
factory_girl (4.7.0)
|
|
51
|
+
activesupport (>= 3.0.0)
|
|
52
|
+
factory_girl_rails (4.7.0)
|
|
53
|
+
factory_girl (~> 4.7.0)
|
|
54
|
+
railties (>= 3.0.0)
|
|
55
|
+
globalid (0.3.6)
|
|
56
|
+
activesupport (>= 4.1.0)
|
|
41
57
|
i18n (0.7.0)
|
|
42
|
-
journey (1.0.4)
|
|
43
58
|
json (1.8.3)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
loofah (2.0.3)
|
|
60
|
+
nokogiri (>= 1.5.9)
|
|
61
|
+
mail (2.6.4)
|
|
62
|
+
mime-types (>= 1.16, < 4)
|
|
63
|
+
mime-types (3.0)
|
|
64
|
+
mime-types-data (~> 3.2015)
|
|
65
|
+
mime-types-data (3.2016.0221)
|
|
66
|
+
mini_portile2 (2.0.0)
|
|
67
|
+
minitest (5.8.4)
|
|
68
|
+
nokogiri (1.6.7.2)
|
|
69
|
+
mini_portile2 (~> 2.0.0.rc2)
|
|
70
|
+
rack (1.6.4)
|
|
55
71
|
rack-test (0.6.3)
|
|
56
72
|
rack (>= 1.0)
|
|
57
|
-
rails (
|
|
58
|
-
actionmailer (=
|
|
59
|
-
actionpack (=
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
rails (4.2.6)
|
|
74
|
+
actionmailer (= 4.2.6)
|
|
75
|
+
actionpack (= 4.2.6)
|
|
76
|
+
actionview (= 4.2.6)
|
|
77
|
+
activejob (= 4.2.6)
|
|
78
|
+
activemodel (= 4.2.6)
|
|
79
|
+
activerecord (= 4.2.6)
|
|
80
|
+
activesupport (= 4.2.6)
|
|
81
|
+
bundler (>= 1.3.0, < 2.0)
|
|
82
|
+
railties (= 4.2.6)
|
|
83
|
+
sprockets-rails
|
|
84
|
+
rails-deprecated_sanitizer (1.0.3)
|
|
85
|
+
activesupport (>= 4.2.0.alpha)
|
|
86
|
+
rails-dom-testing (1.0.7)
|
|
87
|
+
activesupport (>= 4.2.0.beta, < 5.0)
|
|
88
|
+
nokogiri (~> 1.6.0)
|
|
89
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
|
90
|
+
rails-html-sanitizer (1.0.3)
|
|
91
|
+
loofah (~> 2.0)
|
|
92
|
+
railties (4.2.6)
|
|
93
|
+
actionpack (= 4.2.6)
|
|
94
|
+
activesupport (= 4.2.6)
|
|
69
95
|
rake (>= 0.8.7)
|
|
70
|
-
|
|
71
|
-
thor (>= 0.14.6, < 2.0)
|
|
96
|
+
thor (>= 0.18.1, < 2.0)
|
|
72
97
|
rake (11.1.2)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
rspec-core (3.4.4)
|
|
99
|
+
rspec-support (~> 3.4.0)
|
|
100
|
+
rspec-expectations (3.4.0)
|
|
101
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
102
|
+
rspec-support (~> 3.4.0)
|
|
103
|
+
rspec-mocks (3.4.1)
|
|
104
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
105
|
+
rspec-support (~> 3.4.0)
|
|
106
|
+
rspec-rails (3.4.2)
|
|
107
|
+
actionpack (>= 3.0, < 4.3)
|
|
108
|
+
activesupport (>= 3.0, < 4.3)
|
|
109
|
+
railties (>= 3.0, < 4.3)
|
|
110
|
+
rspec-core (~> 3.4.0)
|
|
111
|
+
rspec-expectations (~> 3.4.0)
|
|
112
|
+
rspec-mocks (~> 3.4.0)
|
|
113
|
+
rspec-support (~> 3.4.0)
|
|
114
|
+
rspec-support (3.4.1)
|
|
115
|
+
sprockets (3.6.0)
|
|
116
|
+
concurrent-ruby (~> 1.0)
|
|
117
|
+
rack (> 1, < 3)
|
|
118
|
+
sprockets-rails (3.0.4)
|
|
119
|
+
actionpack (>= 4.0)
|
|
120
|
+
activesupport (>= 4.0)
|
|
121
|
+
sprockets (>= 3.0.0)
|
|
80
122
|
sqlite3 (1.3.11)
|
|
81
123
|
thor (0.19.1)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
polyglot (>= 0.3.1)
|
|
86
|
-
tzinfo (0.3.49)
|
|
124
|
+
thread_safe (0.3.5)
|
|
125
|
+
tzinfo (1.2.2)
|
|
126
|
+
thread_safe (~> 0.1)
|
|
87
127
|
|
|
88
128
|
PLATFORMS
|
|
89
129
|
ruby
|
|
90
130
|
|
|
91
131
|
DEPENDENCIES
|
|
132
|
+
factory_girl_rails (~> 4.5)
|
|
92
133
|
feature_gate!
|
|
134
|
+
rspec-rails (~> 3.1)
|
|
93
135
|
sqlite3 (~> 1.3)
|
data/README.md
CHANGED
|
@@ -1,2 +1,50 @@
|
|
|
1
1
|
# feature_gate
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
A gem to help toggle features on and off in Rails applications without having to re-deploy.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Include gem in Gemfile:
|
|
8
|
+
|
|
9
|
+
gem 'feature_gate'
|
|
10
|
+
|
|
11
|
+
Run generator to create the migration needed
|
|
12
|
+
|
|
13
|
+
rails generate feature_gate
|
|
14
|
+
|
|
15
|
+
Migrate to create the table in your DB:
|
|
16
|
+
|
|
17
|
+
rake db:migrate
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
All gates are closed by default, meaning the features you gate will be hidden until you toggle the gates open.
|
|
22
|
+
|
|
23
|
+
In view files:
|
|
24
|
+
|
|
25
|
+
<% FeatureGate::Manager.gate('gate-name') do %>
|
|
26
|
+
<h1>This is my gated content</h1>
|
|
27
|
+
<p>I am not seen if the gate is on</p>
|
|
28
|
+
<% end %>
|
|
29
|
+
|
|
30
|
+
In controller actions:
|
|
31
|
+
|
|
32
|
+
def index
|
|
33
|
+
FeatureGate::Manager.gate_page('gate-name') # 404s if gate is closed
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
To deploy your feature:
|
|
37
|
+
|
|
38
|
+
FeatureGate::Manager.open!('gate-name')
|
|
39
|
+
|
|
40
|
+
To gate your feature:
|
|
41
|
+
|
|
42
|
+
FeatureGate::Manager.close!('gate-name')
|
|
43
|
+
|
|
44
|
+
To see the names of all opened gates:
|
|
45
|
+
|
|
46
|
+
FeatureGate::Manager.opened_gates
|
|
47
|
+
|
|
48
|
+
To see the names of all closed gates:
|
|
49
|
+
|
|
50
|
+
FeatureGate::Manager.closed_gates
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module FeatureGate
|
|
2
|
+
class GatedFeature < ActiveRecord::Base
|
|
3
|
+
validates :name, presence: true
|
|
4
|
+
validates :gated, inclusion: { in: [true, false] }
|
|
5
|
+
|
|
6
|
+
scope :opened, -> { where(gated: false) }
|
|
7
|
+
scope :closed, -> { where(gated: true) }
|
|
8
|
+
|
|
9
|
+
def deploy_feature!
|
|
10
|
+
self.gated = false
|
|
11
|
+
save!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def gate_feature!
|
|
15
|
+
self.gated = true
|
|
16
|
+
save!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module FeatureGate
|
|
2
|
+
class Manager
|
|
3
|
+
def self.gate_page(name)
|
|
4
|
+
gated_feature = GatedFeature.where(name: name).first_or_create
|
|
5
|
+
if gated_feature.gated?
|
|
6
|
+
raise ActionController::RoutingError.new('Not Found')
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.gate(name)
|
|
11
|
+
gated_feature = GatedFeature.where(name: name).first_or_create
|
|
12
|
+
if !gated_feature.gated?
|
|
13
|
+
yield
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.opened_gates
|
|
18
|
+
GatedFeature.opened.pluck(:name)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.closed_gates
|
|
22
|
+
GatedFeature.closed.pluck(:name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.open!(name)
|
|
26
|
+
gated_feature = GatedFeature.find_by_name!(name)
|
|
27
|
+
gated_feature.deploy_feature!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.close!(name)
|
|
31
|
+
gated_feature = GatedFeature.find_by_name!(name)
|
|
32
|
+
gated_feature.gate_feature!
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/feature_gate.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
|
8
8
|
s.summary = 'A gem to toggle feature gates on and off'
|
|
9
9
|
s.description = 'A gem to toggle feature gates on and off'
|
|
10
10
|
s.authors = ['Tiffany Huang']
|
|
11
|
-
s.email = 'little.huang@gmail.'
|
|
11
|
+
s.email = 'little.huang@gmail.com'
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
|
13
13
|
s.homepage = 'https://github.com/tiffling/feature_gate'
|
|
14
14
|
s.license = 'MIT'
|
|
@@ -16,4 +16,6 @@ Gem::Specification.new do |s|
|
|
|
16
16
|
|
|
17
17
|
s.add_dependency 'rails', '~> 4.0'
|
|
18
18
|
s.add_development_dependency('sqlite3', '~> 1.3')
|
|
19
|
+
s.add_development_dependency('rspec-rails', '~> 3.1')
|
|
20
|
+
s.add_development_dependency('factory_girl_rails', '~> 4.5')
|
|
19
21
|
end
|
data/lib/feature_gate/version.rb
CHANGED
data/lib/feature_gate.rb
CHANGED
|
@@ -9,30 +9,6 @@ module FeatureGate
|
|
|
9
9
|
def self.setup
|
|
10
10
|
yield self
|
|
11
11
|
end
|
|
12
|
-
|
|
13
|
-
def self.gate_page(name)
|
|
14
|
-
gated_feature = GatedFeature.where(name: name).first_or_create
|
|
15
|
-
if gated_feature.gated?
|
|
16
|
-
raise ActiveRecord::RecordNotFound
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.gate(name)
|
|
21
|
-
gated_feature = GatedFeature.where(name: name).first_or_create
|
|
22
|
-
if !gated_feature.gated?
|
|
23
|
-
yield
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def self.open!(name)
|
|
28
|
-
gated_feature = GatedFeature.find_by_name!(name)
|
|
29
|
-
gated_feature.deploy_feature!
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def self.close!(name)
|
|
33
|
-
gated_feature = GatedFeature.find_by_name!(name)
|
|
34
|
-
gated_feature.gate_feature!
|
|
35
|
-
end
|
|
36
12
|
end
|
|
37
13
|
|
|
38
14
|
require 'feature_gate/engine'
|
data/spec/factories.rb
ADDED
data/spec/fake_app.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Classes required for the tests
|
|
2
|
+
# class User; end
|
|
3
|
+
# module ApplicationHelper; def current_user; raise; end; end
|
|
4
|
+
|
|
5
|
+
# Create a rails app
|
|
6
|
+
module FeatureGate
|
|
7
|
+
class Application < Rails::Application
|
|
8
|
+
config.secret_key_base = 'test'
|
|
9
|
+
config.paths['config/database'] = ['spec/support/database.yml']
|
|
10
|
+
config.eager_load = false
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
FeatureGate::Application.initialize!
|
|
14
|
+
|
|
15
|
+
# Run migrations
|
|
16
|
+
require_relative '../lib/generators/feature_gate/templates/migration'
|
|
17
|
+
CreateGatedFeatures.suppress_messages { CreateGatedFeatures.new.change }
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe FeatureGate::Manager do
|
|
4
|
+
describe '.gate' do
|
|
5
|
+
it 'if the gate for the given name does not exist, create the gate and return nil' do
|
|
6
|
+
expect do
|
|
7
|
+
result = FeatureGate::Manager.gate('new_gate') do
|
|
8
|
+
'foobar'
|
|
9
|
+
end
|
|
10
|
+
expect(result).to eq nil
|
|
11
|
+
end.to change{ FeatureGate::GatedFeature.count }.by(1)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'if the gate does exist and it is closed, return nil' do
|
|
15
|
+
create(:gated_feature, name: 'new_gate')
|
|
16
|
+
|
|
17
|
+
expect do
|
|
18
|
+
result = FeatureGate::Manager.gate('new_gate') do
|
|
19
|
+
'foobar'
|
|
20
|
+
end
|
|
21
|
+
expect(result).to eq nil
|
|
22
|
+
end.not_to change{ FeatureGate::GatedFeature.count }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'if the gate does exist and it is opened, yield' do
|
|
26
|
+
create(:gated_feature, :open, name: 'new_gate')
|
|
27
|
+
|
|
28
|
+
expect do
|
|
29
|
+
result = FeatureGate::Manager.gate('new_gate') do
|
|
30
|
+
'foobar'
|
|
31
|
+
end
|
|
32
|
+
expect(result).to eq 'foobar'
|
|
33
|
+
end.not_to change{ FeatureGate::GatedFeature.count }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '.gate_page' do
|
|
38
|
+
it 'if the gate for the given name does not exist, create the gate and raise not found' do
|
|
39
|
+
expect do
|
|
40
|
+
FeatureGate::Manager.gate_page('new_gate')
|
|
41
|
+
end.to raise_error(ActionController::RoutingError)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'if the gate does exist and it is closed, raise not found' do
|
|
45
|
+
create(:gated_feature, name: 'new_gate')
|
|
46
|
+
|
|
47
|
+
expect do
|
|
48
|
+
FeatureGate::Manager.gate_page('new_gate')
|
|
49
|
+
end.to raise_error(ActionController::RoutingError)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'if the gate does exist and it is opened do not raise' do
|
|
53
|
+
create(:gated_feature, :open, name: 'new_gate')
|
|
54
|
+
|
|
55
|
+
expect do
|
|
56
|
+
FeatureGate::Manager.gate_page('new_gate')
|
|
57
|
+
end.not_to raise_error(ActionController::RoutingError)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe '.opened_gates' do
|
|
62
|
+
it 'returns names of all opened gates' do
|
|
63
|
+
opened_gates = create_list(:gated_feature, 2, :open)
|
|
64
|
+
create_list(:gated_feature, 2)
|
|
65
|
+
|
|
66
|
+
expect(FeatureGate::Manager.opened_gates).to match_array(opened_gates.map(&:name))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '.closed_gates' do
|
|
71
|
+
it 'returns names of all closed gates' do
|
|
72
|
+
create_list(:gated_feature, 2, :open)
|
|
73
|
+
closed_gates = create_list(:gated_feature, 2)
|
|
74
|
+
|
|
75
|
+
expect(FeatureGate::Manager.closed_gates).to match_array(closed_gates.map(&:name))
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe '.open!' do
|
|
80
|
+
it 'marks a given gate as open' do
|
|
81
|
+
gate = create(:gated_feature)
|
|
82
|
+
FeatureGate::Manager.open!(gate.name)
|
|
83
|
+
expect(gate.reload).not_to be_gated
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe '.close!' do
|
|
88
|
+
it 'marks a given gate as closed' do
|
|
89
|
+
gate = create(:gated_feature, :open)
|
|
90
|
+
FeatureGate::Manager.close!(gate.name)
|
|
91
|
+
expect(gate.reload).to be_gated
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
|
2
|
+
|
|
3
|
+
require 'rails/all'
|
|
4
|
+
require 'rspec/rails'
|
|
5
|
+
require 'fake_app'
|
|
6
|
+
|
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
8
|
+
|
|
9
|
+
require 'factory_girl'
|
|
10
|
+
require 'factories'
|
|
11
|
+
|
|
12
|
+
RSpec.configure do |config|
|
|
13
|
+
config.include FactoryGirl::Syntax::Methods
|
|
14
|
+
config.include Rails.application.routes.url_helpers
|
|
15
|
+
config.infer_spec_type_from_file_location!
|
|
16
|
+
config.default_formatter = 'doc'
|
|
17
|
+
config.before(:each) do
|
|
18
|
+
FeatureGate::GatedFeature.delete_all
|
|
19
|
+
end
|
|
20
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: feature_gate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tiffany Huang
|
|
@@ -38,8 +38,36 @@ dependencies:
|
|
|
38
38
|
- - ~>
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '1.3'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec-rails
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.1'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.1'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: factory_girl_rails
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '4.5'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ~>
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '4.5'
|
|
41
69
|
description: A gem to toggle feature gates on and off
|
|
42
|
-
email: little.huang@gmail.
|
|
70
|
+
email: little.huang@gmail.com
|
|
43
71
|
executables: []
|
|
44
72
|
extensions: []
|
|
45
73
|
extra_rdoc_files: []
|
|
@@ -49,13 +77,19 @@ files:
|
|
|
49
77
|
- Gemfile.lock
|
|
50
78
|
- LICENSE
|
|
51
79
|
- README.md
|
|
52
|
-
- app/models/gated_feature.rb
|
|
80
|
+
- app/models/feature_gate/gated_feature.rb
|
|
81
|
+
- app/models/feature_gate/manager.rb
|
|
53
82
|
- feature_gate.gemspec
|
|
54
83
|
- lib/feature_gate.rb
|
|
55
84
|
- lib/feature_gate/engine.rb
|
|
56
85
|
- lib/feature_gate/version.rb
|
|
57
86
|
- lib/generators/feature_gate/feature_gate_generator.rb
|
|
58
87
|
- lib/generators/feature_gate/templates/migration.rb
|
|
88
|
+
- spec/factories.rb
|
|
89
|
+
- spec/fake_app.rb
|
|
90
|
+
- spec/models/feature_gate/manager_spec.rb
|
|
91
|
+
- spec/spec_helper.rb
|
|
92
|
+
- spec/support/database.yml
|
|
59
93
|
homepage: https://github.com/tiffling/feature_gate
|
|
60
94
|
licenses:
|
|
61
95
|
- MIT
|
data/app/models/gated_feature.rb
DELETED