active_record_rollout 0.0.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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +261 -0
- data/Rakefile +1 -0
- data/active_record_rollout.gemspec +32 -0
- data/lib/active_record/rollout.rb +35 -0
- data/lib/active_record/rollout/acts_as_flaggable.rb +36 -0
- data/lib/active_record/rollout/feature.rb +260 -0
- data/lib/active_record/rollout/flag.rb +13 -0
- data/lib/active_record/rollout/flaggable.rb +66 -0
- data/lib/active_record/rollout/flaggable_flag.rb +9 -0
- data/lib/active_record/rollout/group_flag.rb +7 -0
- data/lib/active_record/rollout/opt_out_flag.rb +9 -0
- data/lib/active_record/rollout/percentage_flag.rb +11 -0
- data/lib/active_record/rollout/version.rb +5 -0
- data/lib/generators/active_record_rollout_generator.rb +20 -0
- data/lib/generators/templates/active_record_rollout.rb +5 -0
- data/lib/generators/templates/migration.rb +24 -0
- data/lib/tasks/rollout.rake +119 -0
- data/spec/integration/flag_rollout_spec.rb +27 -0
- data/spec/integration/group_rollout_spec.rb +20 -0
- data/spec/integration/percentage_rollout_spec.rb +13 -0
- data/spec/lib/active_record/rollout/acts_as_flaggable_spec.rb +31 -0
- data/spec/lib/active_record/rollout/feature_spec.rb +235 -0
- data/spec/lib/active_record/rollout/flag_spec.rb +8 -0
- data/spec/lib/active_record/rollout/flaggable_flag_spec.rb +8 -0
- data/spec/lib/active_record/rollout/flaggable_spec.rb +149 -0
- data/spec/lib/active_record/rollout/group_flag_spec.rb +7 -0
- data/spec/lib/active_record/rollout/opt_out_flag_spec.rb +8 -0
- data/spec/lib/active_record/rollout/percentage_flag_spec.rb +10 -0
- data/spec/lib/tasks/rollout_rake_spec.rb +162 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/schema.rb +13 -0
- data/spec/support/shared_contexts/rake.rb +20 -0
- metadata +222 -0
@@ -0,0 +1,8 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveRecord::Rollout::FlaggableFlag do
|
4
|
+
it { should be_a ActiveRecord::Rollout::Flag }
|
5
|
+
it { should belong_to :flaggable }
|
6
|
+
it { should validate_presence_of :flaggable_id }
|
7
|
+
it { should allow_mass_assignment_of :flaggable }
|
8
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveRecord::Rollout::Flaggable do
|
4
|
+
subject { User.new }
|
5
|
+
|
6
|
+
describe "#flaggable_find!" do
|
7
|
+
context "when a non-default find_by is not specified" do
|
8
|
+
it "finds by id" do
|
9
|
+
User.should_receive(:find_by_id!).with(1)
|
10
|
+
User.flaggable_find!(1)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when a non-default find_by is not specified" do
|
15
|
+
class Foo < ActiveRecord::Base
|
16
|
+
acts_as_flaggable find_by: :email
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds by id" do
|
20
|
+
Foo.should_receive(:find_by_email!).with("user@example.com")
|
21
|
+
Foo.flaggable_find!("user@example.com")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#has_feature?" do
|
27
|
+
let(:user) { User.create(name: "foo") }
|
28
|
+
let(:feature) { ActiveRecord::Rollout::Feature.create(name: "bar") }
|
29
|
+
|
30
|
+
it "memoizes found features" do
|
31
|
+
ActiveRecord::Rollout::Feature.stub(:find_by_name) { feature }
|
32
|
+
feature.flaggable_flags.create(flaggable: user)
|
33
|
+
|
34
|
+
feature.should_receive(:match?).with(user).and_return(true)
|
35
|
+
user.has_feature?(:bar)
|
36
|
+
|
37
|
+
feature.should_not_receive(:match?).with(user)
|
38
|
+
user.has_feature?(:bar)
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when given a block" do
|
42
|
+
context "and the user is flagged in" do
|
43
|
+
before do
|
44
|
+
feature.flaggable_flags.create(flaggable: user)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "calls the block" do
|
48
|
+
foo = "foo"
|
49
|
+
user.has_feature?(:bar) { foo = "bar" }
|
50
|
+
foo.should eq "bar"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the match" do
|
54
|
+
foo = "foo"
|
55
|
+
|
56
|
+
if user.has_feature? :not_feature do
|
57
|
+
end; else
|
58
|
+
foo = "bar"
|
59
|
+
end
|
60
|
+
|
61
|
+
foo.should eq "bar"
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when the block raises an exception" do
|
65
|
+
it "increments the failure_count of the feature" do
|
66
|
+
begin
|
67
|
+
user.has_feature? :bar do
|
68
|
+
raise "This is an exception"
|
69
|
+
end
|
70
|
+
rescue
|
71
|
+
feature.reload.failure_count.should eq 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "raises the exception" do
|
76
|
+
expect do
|
77
|
+
user.has_feature? :bar do
|
78
|
+
raise "This is an exception"
|
79
|
+
end
|
80
|
+
end.to raise_error "This is an exception"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "and the user is not flagged in" do
|
86
|
+
it "does not call the block" do
|
87
|
+
foo = "foo"
|
88
|
+
user.has_feature?(:bar) { foo = "bar" }
|
89
|
+
foo.should eq "foo"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when the user is not flagged in" do
|
95
|
+
it "returns false" do
|
96
|
+
user.has_feature?(:bar).should be_false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when the user is flagged in" do
|
101
|
+
context "and the user is opted out" do
|
102
|
+
before do
|
103
|
+
feature.flaggable_flags.create(flaggable: user)
|
104
|
+
feature.opt_out_flags.create(flaggable: user)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "returns false" do
|
108
|
+
user.has_feature?(:bar).should be_false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "and the user is not opted out" do
|
113
|
+
context "and the user is flagged in individually" do
|
114
|
+
before do
|
115
|
+
feature.flaggable_flags.create(flaggable: user)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns true" do
|
119
|
+
user.has_feature?(:bar).should be_true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "and the user is flagged in as a percentage" do
|
124
|
+
before do
|
125
|
+
feature.percentage_flags.create(flaggable_type: "User", percentage: 100)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "returns true" do
|
129
|
+
user.has_feature?(:bar).should be_true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "and the user is flagged in via a group" do
|
134
|
+
before do
|
135
|
+
ActiveRecord::Rollout::Feature.define_user_group "name_foo" do |user|
|
136
|
+
user.name == "foo"
|
137
|
+
end
|
138
|
+
|
139
|
+
feature.group_flags.create(flaggable_type: "User", group_name: "name_foo")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "returns true" do
|
143
|
+
user.has_feature?(:bar).should be_true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveRecord::Rollout::PercentageFlag do
|
4
|
+
subject { ActiveRecord::Rollout::PercentageFlag.new(feature_id: 1, flaggable_type: "User") }
|
5
|
+
|
6
|
+
it { should be_a ActiveRecord::Rollout::Flag }
|
7
|
+
it { should validate_numericality_of(:percentage).is_greater_than(0).is_less_than_or_equal_to(100) }
|
8
|
+
it { should allow_mass_assignment_of :percentage }
|
9
|
+
it { should validate_uniqueness_of :feature_id }
|
10
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "rollout:create" do
|
4
|
+
include_context "rake"
|
5
|
+
|
6
|
+
it "creates the given feature" do
|
7
|
+
ActiveRecord::Rollout::Feature.should_receive(:find_or_create_by_name!).with("foo")
|
8
|
+
subject.invoke("foo")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "rollout:destroy" do
|
13
|
+
include_context "rake"
|
14
|
+
|
15
|
+
let(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
16
|
+
|
17
|
+
it "destroys the given feature" do
|
18
|
+
ActiveRecord::Rollout::Feature.should_receive(:find_by_name!).with(feature.name).and_return(feature)
|
19
|
+
feature.should_receive(:destroy)
|
20
|
+
subject.invoke("foo")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "rollout:activate" do
|
25
|
+
include_context "rake"
|
26
|
+
|
27
|
+
let(:user) { User.create(name: "foo") }
|
28
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
29
|
+
|
30
|
+
it "activates the feature for the record" do
|
31
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_record_to_feature).with(user, "foo")
|
32
|
+
subject.invoke("foo", "User", user.id.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "does not require a class if defined_flaggable_class is set" do
|
36
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_record_to_feature).with(user, "foo")
|
37
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
38
|
+
expect { subject.invoke("foo", user.id.to_s) }.to_not raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "rollout:deactivate" do
|
43
|
+
include_context "rake"
|
44
|
+
|
45
|
+
let(:user) { User.create(name: "foo") }
|
46
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
47
|
+
|
48
|
+
it "deactivates the feature for the record" do
|
49
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_record_from_feature).with(user, "foo")
|
50
|
+
subject.invoke("foo", "User", user.id.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "does not require a class if defined_flaggable_class is set" do
|
54
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_record_from_feature).with(user, "foo")
|
55
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
56
|
+
expect { subject.invoke("foo", user.id.to_s) }.to_not raise_error
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "rollout:opt_out" do
|
61
|
+
include_context "rake"
|
62
|
+
|
63
|
+
let(:user) { User.create(name: "foo") }
|
64
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
65
|
+
|
66
|
+
it "deactivates the feature for the record" do
|
67
|
+
ActiveRecord::Rollout::Feature.should_receive(:opt_record_out_of_feature).with(user, "foo")
|
68
|
+
subject.invoke("foo", "User", user.id.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "does not require a class if defined_flaggable_class is set" do
|
72
|
+
ActiveRecord::Rollout::Feature.should_receive(:opt_record_out_of_feature).with(user, "foo")
|
73
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
74
|
+
expect { subject.invoke("foo", user.id.to_s) }.to_not raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "rollout:un_opt_out" do
|
79
|
+
include_context "rake"
|
80
|
+
|
81
|
+
let(:user) { User.create(name: "foo") }
|
82
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
83
|
+
|
84
|
+
it "deactivates the feature for the record" do
|
85
|
+
ActiveRecord::Rollout::Feature.should_receive(:un_opt_record_out_of_feature).with(user, "foo")
|
86
|
+
subject.invoke("foo", "User", user.id.to_s)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "does not require a class if defined_flaggable_class is set" do
|
90
|
+
ActiveRecord::Rollout::Feature.should_receive(:un_opt_record_out_of_feature).with(user, "foo")
|
91
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
92
|
+
expect { subject.invoke("foo", user.id.to_s) }.to_not raise_error
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "rollout:activate_group" do
|
97
|
+
include_context "rake"
|
98
|
+
|
99
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
100
|
+
|
101
|
+
it "activates the feature for the group" do
|
102
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_group_to_feature).with("User", "admins", "foo")
|
103
|
+
subject.invoke("foo", "User", "admins")
|
104
|
+
end
|
105
|
+
|
106
|
+
it "does not require a class if defined_flaggable_class is set" do
|
107
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_group_to_feature).with("User", "admins", "foo")
|
108
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
109
|
+
expect { subject.invoke("foo", "admins") }.to_not raise_error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "rollout:deactivate_group" do
|
114
|
+
include_context "rake"
|
115
|
+
|
116
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
117
|
+
|
118
|
+
it "deactivates the feature for the group" do
|
119
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_group_from_feature).with("User", "admins", "foo")
|
120
|
+
subject.invoke("foo", "User", "admins")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "does not require a class if defined_flaggable_class is set" do
|
124
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_group_from_feature).with("User", "admins", "foo")
|
125
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
126
|
+
expect { subject.invoke("foo", "admins") }.to_not raise_error
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "rollout:activate_percentage" do
|
131
|
+
include_context "rake"
|
132
|
+
|
133
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
134
|
+
|
135
|
+
it "activates the feature for the percentage" do
|
136
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_percentage_to_feature).with("User", 50, "foo")
|
137
|
+
subject.invoke("foo", "User", "50")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not require a class if defined_flaggable_class is set" do
|
141
|
+
ActiveRecord::Rollout::Feature.should_receive(:add_percentage_to_feature).with("User", 50, "foo")
|
142
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
143
|
+
expect { subject.invoke("foo", "50") }.to_not raise_error
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "rollout:deactivate_percentage" do
|
148
|
+
include_context "rake"
|
149
|
+
|
150
|
+
let!(:feature) { ActiveRecord::Rollout::Feature.create(name: "foo") }
|
151
|
+
|
152
|
+
it "deactivates the feature for the percentage" do
|
153
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_percentage_from_feature).with("User", "foo")
|
154
|
+
subject.invoke("foo", "User")
|
155
|
+
end
|
156
|
+
|
157
|
+
it "does not require a class if defined_flaggable_class is set" do
|
158
|
+
ActiveRecord::Rollout::Feature.should_receive(:remove_percentage_from_feature).with("User", "foo")
|
159
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", "User"
|
160
|
+
expect { subject.invoke("foo") }.to_not raise_error
|
161
|
+
end
|
162
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "rails"
|
2
|
+
require "active_record"
|
3
|
+
require "active_record/rollout"
|
4
|
+
require "shoulda-matchers"
|
5
|
+
require "generators/templates/migration"
|
6
|
+
require "support/shared_contexts/rake"
|
7
|
+
require "pry"
|
8
|
+
|
9
|
+
class User < ActiveRecord::Base
|
10
|
+
acts_as_flaggable
|
11
|
+
end
|
12
|
+
|
13
|
+
class Organization < ActiveRecord::Base
|
14
|
+
acts_as_flaggable
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.before :suite do
|
19
|
+
ActiveRecord::Base.establish_connection \
|
20
|
+
adapter: "sqlite3",
|
21
|
+
database: File.dirname(__FILE__) + "/spec.sqlite3"
|
22
|
+
|
23
|
+
require File.dirname(__FILE__) + "/support/schema.rb"
|
24
|
+
end
|
25
|
+
|
26
|
+
config.before :each do
|
27
|
+
SetupActiveRecordRollout.migrate :up
|
28
|
+
ActiveRecord::Schema.migrate :up
|
29
|
+
end
|
30
|
+
|
31
|
+
config.after :each do
|
32
|
+
SetupActiveRecordRollout.migrate :down
|
33
|
+
ActiveRecord::Schema.migrate :down
|
34
|
+
end
|
35
|
+
|
36
|
+
config.after :each do
|
37
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@defined_groups", {}
|
38
|
+
ActiveRecord::Rollout::Feature.instance_variable_set "@default_flaggable_class_name", nil
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
# Hat tip: http://robots.thoughtbot.com/test-rake-tasks-like-a-boss
|
4
|
+
shared_context "rake" do
|
5
|
+
let(:rake) { Rake::Application.new }
|
6
|
+
let(:task_name) { self.class.top_level_description }
|
7
|
+
let(:task_path) { File.join(File.dirname(__FILE__), "../../../lib/tasks/#{task_name.split(":").first}") }
|
8
|
+
subject { rake[task_name] }
|
9
|
+
|
10
|
+
def loaded_files_excluding_current_rake_file
|
11
|
+
$".reject { |file| file == "#{task_path}.rake" }
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
Rake.application = rake
|
16
|
+
Rake.application.rake_require(task_path, [Rails.root.to_s], loaded_files_excluding_current_rake_file)
|
17
|
+
|
18
|
+
Rake::Task.define_task(:environment)
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record_rollout
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Clem
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: shoulda-matchers
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sqlite3-ruby
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-debugger
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: yard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Rollouts (feature flags) for ActiveRecord models.
|
140
|
+
email:
|
141
|
+
- jonathan@heroku.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- .gitignore
|
147
|
+
- .travis.yml
|
148
|
+
- Gemfile
|
149
|
+
- LICENSE.txt
|
150
|
+
- README.md
|
151
|
+
- Rakefile
|
152
|
+
- active_record_rollout.gemspec
|
153
|
+
- lib/active_record/rollout.rb
|
154
|
+
- lib/active_record/rollout/acts_as_flaggable.rb
|
155
|
+
- lib/active_record/rollout/feature.rb
|
156
|
+
- lib/active_record/rollout/flag.rb
|
157
|
+
- lib/active_record/rollout/flaggable.rb
|
158
|
+
- lib/active_record/rollout/flaggable_flag.rb
|
159
|
+
- lib/active_record/rollout/group_flag.rb
|
160
|
+
- lib/active_record/rollout/opt_out_flag.rb
|
161
|
+
- lib/active_record/rollout/percentage_flag.rb
|
162
|
+
- lib/active_record/rollout/version.rb
|
163
|
+
- lib/generators/active_record_rollout_generator.rb
|
164
|
+
- lib/generators/templates/active_record_rollout.rb
|
165
|
+
- lib/generators/templates/migration.rb
|
166
|
+
- lib/tasks/rollout.rake
|
167
|
+
- spec/integration/flag_rollout_spec.rb
|
168
|
+
- spec/integration/group_rollout_spec.rb
|
169
|
+
- spec/integration/percentage_rollout_spec.rb
|
170
|
+
- spec/lib/active_record/rollout/acts_as_flaggable_spec.rb
|
171
|
+
- spec/lib/active_record/rollout/feature_spec.rb
|
172
|
+
- spec/lib/active_record/rollout/flag_spec.rb
|
173
|
+
- spec/lib/active_record/rollout/flaggable_flag_spec.rb
|
174
|
+
- spec/lib/active_record/rollout/flaggable_spec.rb
|
175
|
+
- spec/lib/active_record/rollout/group_flag_spec.rb
|
176
|
+
- spec/lib/active_record/rollout/opt_out_flag_spec.rb
|
177
|
+
- spec/lib/active_record/rollout/percentage_flag_spec.rb
|
178
|
+
- spec/lib/tasks/rollout_rake_spec.rb
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/support/schema.rb
|
181
|
+
- spec/support/shared_contexts/rake.rb
|
182
|
+
homepage: https://github.com/jclem/active_record_rollout
|
183
|
+
licenses:
|
184
|
+
- MIT
|
185
|
+
metadata: {}
|
186
|
+
post_install_message:
|
187
|
+
rdoc_options: []
|
188
|
+
require_paths:
|
189
|
+
- lib
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - '>='
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 1.9.3
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - '>='
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
requirements: []
|
201
|
+
rubyforge_project:
|
202
|
+
rubygems_version: 2.0.14
|
203
|
+
signing_key:
|
204
|
+
specification_version: 4
|
205
|
+
summary: Rollouts (feature flags) for ActiveRecord models.
|
206
|
+
test_files:
|
207
|
+
- spec/integration/flag_rollout_spec.rb
|
208
|
+
- spec/integration/group_rollout_spec.rb
|
209
|
+
- spec/integration/percentage_rollout_spec.rb
|
210
|
+
- spec/lib/active_record/rollout/acts_as_flaggable_spec.rb
|
211
|
+
- spec/lib/active_record/rollout/feature_spec.rb
|
212
|
+
- spec/lib/active_record/rollout/flag_spec.rb
|
213
|
+
- spec/lib/active_record/rollout/flaggable_flag_spec.rb
|
214
|
+
- spec/lib/active_record/rollout/flaggable_spec.rb
|
215
|
+
- spec/lib/active_record/rollout/group_flag_spec.rb
|
216
|
+
- spec/lib/active_record/rollout/opt_out_flag_spec.rb
|
217
|
+
- spec/lib/active_record/rollout/percentage_flag_spec.rb
|
218
|
+
- spec/lib/tasks/rollout_rake_spec.rb
|
219
|
+
- spec/spec_helper.rb
|
220
|
+
- spec/support/schema.rb
|
221
|
+
- spec/support/shared_contexts/rake.rb
|
222
|
+
has_rdoc:
|