abstract_feature_branch 1.2.2 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +15 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +74 -43
  5. data/VERSION +1 -1
  6. data/abstract_feature_branch.gemspec +31 -56
  7. data/lib/abstract_feature_branch/configuration.rb +22 -7
  8. data/lib/abstract_feature_branch/redis/connection_pool_to_redis_adapter.rb +34 -0
  9. data/lib/abstract_feature_branch.rb +75 -7
  10. data/lib/ext/feature_branch.rb +4 -3
  11. data/lib/generators/templates/config/initializers/abstract_feature_branch.rb +7 -5
  12. metadata +76 -55
  13. data/.coveralls.yml +0 -1
  14. data/.travis.yml +0 -40
  15. data/RELEASE_NOTES.md +0 -55
  16. data/config/features/admin.local.yml +0 -15
  17. data/config/features/admin.yml +0 -17
  18. data/config/features/internal/wiki.local.yml +0 -15
  19. data/config/features/internal/wiki.yml +0 -17
  20. data/config/features/public.local.yml +0 -15
  21. data/config/features/public.yml +0 -17
  22. data/ruby187.Gemfile +0 -12
  23. data/ruby187.Gemfile.lock +0 -63
  24. data/spec/abstract_feature_branch/file_beautifier_spec.rb +0 -384
  25. data/spec/ext/feature_branch__feature_branch_per_user_spec.rb +0 -113
  26. data/spec/ext/feature_branch__feature_branch_spec.rb +0 -125
  27. data/spec/ext/feature_branch__feature_enabled_spec.rb +0 -260
  28. data/spec/fixtures/application_development_config/config/features.reference.yml +0 -21
  29. data/spec/fixtures/application_no_config/no_config +0 -1
  30. data/spec/fixtures/application_rails_config/config/features.local.yml +0 -16
  31. data/spec/fixtures/application_rails_config/config/features.yml +0 -20
  32. data/spec/fixtures/application_ugly_config_reference/config/another_application_configuration.yml +0 -31
  33. data/spec/fixtures/application_ugly_config_reference/config/database.yml +0 -17
  34. data/spec/fixtures/application_ugly_config_reference/config/features/admin.local.yml +0 -44
  35. data/spec/fixtures/application_ugly_config_reference/config/features/admin.yml +0 -44
  36. data/spec/fixtures/application_ugly_config_reference/config/features/empty.local.yml +0 -0
  37. data/spec/fixtures/application_ugly_config_reference/config/features/feature_empty_config.local.yml +0 -13
  38. data/spec/fixtures/application_ugly_config_reference/config/features/including_comments.local.yml +0 -52
  39. data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.local.yml +0 -44
  40. data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.yml +0 -44
  41. data/spec/fixtures/application_ugly_config_reference/config/features/public.local.yml +0 -44
  42. data/spec/fixtures/application_ugly_config_reference/config/features/public.yml +0 -44
  43. data/spec/fixtures/application_ugly_config_reference/config/features.local.yml +0 -44
  44. data/spec/fixtures/application_ugly_config_reference/config/features.yml +0 -49
@@ -1,260 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'feature_branch object extensions' do
4
- before do
5
- @app_env_backup = AbstractFeatureBranch.application_environment
6
- @app_root_backup = AbstractFeatureBranch.application_root
7
- AbstractFeatureBranch.logger.warn 'Environment variable ABSTRACT_FEATURE_BRANCH_FEATURE1 already set, potentially conflicting with another test' if ENV.keys.include?('ABSTRACT_FEATURE_BRANCH_FEATURE1')
8
- AbstractFeatureBranch.logger.warn 'Environment variable Abstract_Feature_Branch_Feature2 already set, potentially conflicting with another test' if ENV.keys.include?('Abstract_Feature_Branch_Feature2')
9
- AbstractFeatureBranch.logger.warn 'Environment variable abstract_feature_branch_feature3 already set, potentially conflicting with another test' if ENV.keys.include?('abstract_feature_branch_feature3')
10
- end
11
- after do
12
- ENV.delete('ABSTRACT_FEATURE_BRANCH_FEATURE1')
13
- ENV.delete('Abstract_Feature_Branch_Feature2')
14
- ENV.delete('abstract_feature_branch_feature3')
15
- AbstractFeatureBranch.application_root = @app_root_backup
16
- AbstractFeatureBranch.application_environment = @app_env_backup
17
- AbstractFeatureBranch.unload_application_features
18
- end
19
- describe '#feature_enabled?' do
20
- it 'determines whether a feature is enabled or not in features configuration (case-insensitive string or symbol feature names)' do
21
- feature_enabled?('Feature1').should == true
22
- feature_enabled?(:FEATURE2).should == true
23
- feature_enabled?(:feature3).should == false
24
- end
25
- it 'returns nil for an invalid feature name' do
26
- feature_enabled?(:invalid_feature_that_does_not_exist).should be_nil
27
- end
28
- it 'allows environment variables (case-insensitive booleans) to override configuration file' do
29
- ENV['ABSTRACT_FEATURE_BRANCH_FEATURE1'] = 'FALSE'
30
- ENV['Abstract_Feature_Branch_Feature2'] = 'False'
31
- ENV['abstract_feature_branch_feature3'] = 'true'
32
- AbstractFeatureBranch.load_application_features
33
- feature_enabled?(:feature1).should == false
34
- feature_enabled?(:feature2).should == false
35
- feature_enabled?(:feature3).should == true
36
- feature_enabled?(:feature4a).should == true #not overridden
37
- end
38
- it 'allows local configuration file to override main configuration file in test environment' do
39
- feature_enabled?(:feature4).should == false
40
- feature_enabled?(:feature5).should == true
41
- end
42
- it 'has no local configuration for production environment' do
43
- AbstractFeatureBranch.application_environment = 'production'
44
- feature_enabled?(:feature4).should == true
45
- feature_enabled?(:feature5).should be_nil
46
- end
47
- it 'works with Rails environment' do
48
- Object.class_eval do
49
- module Rails
50
- def self.root
51
- File.expand_path(File.join(__FILE__, '..', '..', 'fixtures', 'application_rails_config'))
52
- end
53
- def self.env
54
- 'staging'
55
- end
56
- end
57
- end
58
- AbstractFeatureBranch.initialize_application_root
59
- AbstractFeatureBranch.initialize_application_environment
60
- AbstractFeatureBranch.load_application_features
61
- feature_enabled?(:feature1).should == true
62
- feature_enabled?(:feature2).should == false
63
- feature_enabled?(:feature3).should == false
64
- feature_enabled?(:feature4).should be_nil
65
- feature_enabled?(:feature4a).should be_nil
66
- feature_enabled?(:feature5).should be_nil
67
- end
68
- context 'per user' do
69
- let(:user_id) { 'email1@example.com' }
70
- let(:another_user_id) { 'another_email@example.com' }
71
- before do
72
- AbstractFeatureBranch.user_features_storage.del("#{AbstractFeatureBranch::ENV_FEATURE_PREFIX}feature6")
73
- end
74
- after do
75
- AbstractFeatureBranch.user_features_storage.del("#{AbstractFeatureBranch::ENV_FEATURE_PREFIX}feature6")
76
- end
77
- it 'behaves as expected if member list is empty, regardless of the user provided' do
78
- feature_enabled?('feature6').should == false
79
- feature_enabled?('feature6', nil).should == false
80
- feature_enabled?('feature6', user_id).should == false
81
- end
82
- it 'behaves as expected if member list is not empty, and user provided is in member list' do
83
- AbstractFeatureBranch.toggle_features_for_user(user_id, :feature6 => true)
84
- feature_enabled?('feature6').should == false
85
- feature_enabled?('feature6', user_id).should == true
86
- end
87
- it 'behaves as expected if member list is not empty, and user provided is not in member list' do
88
- AbstractFeatureBranch.toggle_features_for_user(another_user_id, :feature6 => true)
89
- feature_enabled?('feature6', user_id).should == false
90
- end
91
- end
92
- context 'cacheability' do
93
- before do
94
- @development_application_root = File.expand_path(File.join(__FILE__, '..', '..', 'fixtures', 'application_development_config'))
95
- @feature_file_reference_path = File.join(@development_application_root, 'config', 'features.reference.yml')
96
- @feature_file_path = File.join(@development_application_root, 'config', 'features.yml')
97
- FileUtils.cp(@feature_file_reference_path, @feature_file_path)
98
- AbstractFeatureBranch.application_root = @development_application_root
99
- end
100
- after do
101
- FileUtils.rm(@feature_file_path)
102
- end
103
- it 'refreshes features at runtime in development (without forcing load of application features again)' do
104
- AbstractFeatureBranch.application_environment = 'development'
105
- feature_enabled?(:feature1).should == false
106
- feature_enabled?(:feature2).should == true
107
- File.open(@feature_file_path, 'w+') do |file|
108
- file << <<-CONTENT
109
- defaults: &defaults
110
-
111
- development:
112
- <<: *defaults
113
- FEATURE1: true
114
- Feature2: false
115
-
116
- test:
117
- <<: *defaults
118
- FEATURE1: true
119
- Feature2: false
120
-
121
- staging:
122
- <<: *defaults
123
- FEATURE1: true
124
- Feature2: false
125
-
126
- production:
127
- <<: *defaults
128
- FEATURE1: true
129
- Feature2: false
130
- CONTENT
131
- end
132
- feature_enabled?(:feature1).should == true
133
- feature_enabled?(:feature2).should == false
134
- end
135
-
136
- %w(test staging production).each do |environment|
137
- it "does not refresh features at runtime in #{environment} (without forcing load of application features again)" do
138
- AbstractFeatureBranch.application_environment = environment
139
- AbstractFeatureBranch.load_application_features
140
- feature_enabled?(:feature1).should == false
141
- feature_enabled?(:feature2).should == true
142
- File.open(@feature_file_path, 'w+') do |file|
143
- file << <<-CONTENT
144
- defaults: &defaults
145
-
146
- development:
147
- <<: *defaults
148
- FEATURE1: true
149
- Feature2: false
150
-
151
- test:
152
- <<: *defaults
153
- FEATURE1: true
154
- Feature2: false
155
-
156
- staging:
157
- <<: *defaults
158
- FEATURE1: true
159
- Feature2: false
160
-
161
- production:
162
- <<: *defaults
163
- FEATURE1: true
164
- Feature2: false
165
- CONTENT
166
- end
167
- feature_enabled?(:feature1).should == false
168
- feature_enabled?(:feature2).should == true
169
- end
170
- end
171
-
172
- it 'does not refresh features at runtime in development when overridden' do
173
- AbstractFeatureBranch.application_environment = 'development'
174
- AbstractFeatureBranch.cacheable = {:development => true}
175
- AbstractFeatureBranch.load_application_features
176
- feature_enabled?(:feature1).should == false
177
- feature_enabled?(:feature2).should == true
178
- File.open(@feature_file_path, 'w+') do |file|
179
- file << <<-CONTENT
180
- defaults: &defaults
181
-
182
- development:
183
- <<: *defaults
184
- FEATURE1: true
185
- Feature2: false
186
-
187
- test:
188
- <<: *defaults
189
- FEATURE1: true
190
- Feature2: false
191
-
192
- staging:
193
- <<: *defaults
194
- FEATURE1: true
195
- Feature2: false
196
-
197
- production:
198
- <<: *defaults
199
- FEATURE1: true
200
- Feature2: false
201
- CONTENT
202
- end
203
- feature_enabled?(:feature1).should == false
204
- feature_enabled?(:feature2).should == true
205
- end
206
-
207
- %w(test staging production).each do |environment|
208
- it "does refresh features at runtime in #{environment} (without forcing load of application features again)" do
209
- AbstractFeatureBranch.application_environment = environment
210
- AbstractFeatureBranch.cacheable = {:test => false, :staging => false, :production => false}
211
- feature_enabled?(:feature1).should == false
212
- feature_enabled?(:feature2).should == true
213
- File.open(@feature_file_path, 'w+') do |file|
214
- file << <<-CONTENT
215
- defaults: &defaults
216
-
217
- development:
218
- <<: *defaults
219
- FEATURE1: true
220
- Feature2: false
221
-
222
- test:
223
- <<: *defaults
224
- FEATURE1: true
225
- Feature2: false
226
-
227
- staging:
228
- <<: *defaults
229
- FEATURE1: true
230
- Feature2: false
231
-
232
- production:
233
- <<: *defaults
234
- FEATURE1: true
235
- Feature2: false
236
- CONTENT
237
- end
238
- feature_enabled?(:feature1).should == true
239
- feature_enabled?(:feature2).should == false
240
- end
241
- end
242
- end
243
- end
244
- describe 'self#feature_enabled?' do
245
- after do
246
- Object.send(:remove_const, :TestObject)
247
- end
248
- # No need to retest all instance test cases, just a spot check due to implementation reuse
249
- it 'determines whether a feature is enabled or not in features configuration' do
250
- class TestObject
251
- def self.hit_me
252
- feature_enabled?(:feature1).should == true
253
- feature_enabled?(:feature2).should == true
254
- feature_enabled?(:feature3).should == false
255
- end
256
- end
257
- TestObject.hit_me
258
- end
259
- end
260
- end
@@ -1,21 +0,0 @@
1
- defaults: &defaults
2
-
3
- development:
4
- <<: *defaults
5
- FEATURE1: false
6
- Feature2: true
7
-
8
- test:
9
- <<: *defaults
10
- FEATURE1: false
11
- Feature2: true
12
-
13
- staging:
14
- <<: *defaults
15
- FEATURE1: false
16
- Feature2: true
17
-
18
- production:
19
- <<: *defaults
20
- FEATURE1: false
21
- Feature2: true
@@ -1 +0,0 @@
1
- # just a stub to allow directory to be committed to git
@@ -1,16 +0,0 @@
1
- defaults: &defaults
2
-
3
-
4
- development:
5
- <<: *defaults
6
-
7
- test:
8
- <<: *defaults
9
-
10
- staging:
11
- <<: *defaults
12
- feature3: false
13
-
14
- production:
15
- <<: *defaults
16
-
@@ -1,20 +0,0 @@
1
- defaults: &defaults
2
- FEATURE1: true
3
- Feature2: true
4
- feature3: true
5
-
6
- development:
7
- <<: *defaults
8
-
9
- test:
10
- <<: *defaults
11
-
12
- staging:
13
- <<: *defaults
14
- FEATURE1: true
15
- Feature2: false
16
- feature3: true
17
-
18
- production:
19
- <<: *defaults
20
-
@@ -1,31 +0,0 @@
1
- common: &default_settings
2
- license_key: <%= ENV["LICENSE_KEY"] %>
3
- app_name: <%= ENV["APP_NAME"] %>
4
- monitor_mode: true
5
- developer_mode: false
6
- log_level: info
7
-
8
- browser_monitoring:
9
- auto_instrument: true
10
-
11
- audit_log:
12
- enabled: false
13
-
14
-
15
- development:
16
- <<: *default_settings
17
- monitor_mode: false
18
- developer_mode: true
19
-
20
- test:
21
- <<: *default_settings
22
- monitor_mode: false
23
-
24
- production:
25
- <<: *default_settings
26
- monitor_mode: true
27
-
28
- staging:
29
- <<: *default_settings
30
- monitor_mode: true
31
- app_name: <%= ENV["APP_NAME"] %> (Staging)
@@ -1,17 +0,0 @@
1
- development:
2
- adapter: sqlite3
3
- database: db/development.sqlite3
4
- pool: 5
5
- timeout: 5000
6
-
7
- test:
8
- adapter: sqlite3
9
- database: db/test.sqlite3
10
- pool: 5
11
- timeout: 5000
12
-
13
- production:
14
- adapter: sqlite3
15
- database: db/production.sqlite3
16
- pool: 5
17
- timeout: 5000
@@ -1,44 +0,0 @@
1
- defaults: &defaults
2
-
3
- feature4a: true
4
- FEATURE1: true
5
- feature4: true
6
- feature3: false
7
- Feature2: true
8
-
9
- development:
10
- <<: *defaults
11
- FEATURE1: true
12
-
13
- feature4a: true
14
- feature4: true
15
- feature3: false
16
- Feature2: true
17
-
18
- test:
19
- <<: *defaults
20
- FEATURE1: true
21
- feature4: true
22
-
23
- feature4a: true
24
- feature3: false
25
- Feature2: true
26
-
27
- staging:
28
- <<: *defaults
29
- FEATURE1: true
30
- feature4: true
31
- feature3: false
32
-
33
- feature4a: true
34
- Feature2: true
35
-
36
- production:
37
- <<: *defaults
38
- FEATURE1: true
39
- feature4: true
40
- feature3: false
41
- Feature2: true
42
-
43
- feature4a: true
44
-
@@ -1,44 +0,0 @@
1
- defaults: &defaults
2
-
3
- feature4a: true
4
- FEATURE1: true
5
- feature4: true
6
- feature3: false
7
- Feature2: true
8
-
9
- development:
10
- <<: *defaults
11
- FEATURE1: true
12
-
13
- feature4a: true
14
- feature4: true
15
- feature3: false
16
- Feature2: true
17
-
18
- test:
19
- <<: *defaults
20
- FEATURE1: true
21
- feature4: true
22
-
23
- feature4a: true
24
- feature3: false
25
- Feature2: true
26
-
27
- staging:
28
- <<: *defaults
29
- FEATURE1: true
30
- feature4: true
31
- feature3: false
32
-
33
- feature4a: true
34
- Feature2: true
35
-
36
- production:
37
- <<: *defaults
38
- FEATURE1: true
39
- feature4: true
40
- feature3: false
41
- Feature2: true
42
-
43
- feature4a: true
44
-
@@ -1,13 +0,0 @@
1
- defaults: &defaults
2
-
3
- development:
4
- <<: *defaults
5
-
6
- test:
7
- <<: *defaults
8
-
9
- staging:
10
- <<: *defaults
11
-
12
- production:
13
- <<: *defaults
@@ -1,52 +0,0 @@
1
- # This file allows you to override any feature configuration locally without it being committed to git
2
- # It is recommended to use this file only for temporary overrides. Once done, make final change in main .yml
3
-
4
- defaults: &defaults
5
-
6
- feature4a: true
7
- FEATURE1: true
8
- feature4: true
9
- # Some comment in between features (will get deleted by beautifier)
10
- feature3: false
11
-
12
- # another comment in between features (will get deleted by beautifier)
13
- Feature2: true
14
-
15
- development:
16
- # yet another comment in between features (will get deleted by beautifier)
17
- <<: *defaults
18
- FEATURE1: true
19
-
20
- feature4a: true
21
- feature4: true
22
- feature3: false
23
- Feature2: true
24
-
25
- test:
26
- <<: *defaults
27
- FEATURE1: true
28
- feature4: true
29
-
30
- feature4a: true
31
- feature3: false
32
- Feature2: true
33
-
34
- staging:
35
- <<: *defaults
36
- FEATURE1: true
37
- feature4: true
38
- feature3: false
39
-
40
- feature4a: true
41
- Feature2: true
42
-
43
- production:
44
- <<: *defaults
45
- FEATURE1: true
46
- feature4: true
47
- feature3: false
48
- Feature2: true
49
-
50
- feature4a: true
51
-
52
- # absolutely deleted by beautifier
@@ -1,44 +0,0 @@
1
- defaults: &defaults
2
-
3
- feature4a: true
4
- FEATURE1: true
5
- feature4: true
6
- feature3: false
7
- Feature2: true
8
-
9
- development:
10
- <<: *defaults
11
- FEATURE1: true
12
-
13
- feature4a: true
14
- feature4: true
15
- feature3: false
16
- Feature2: true
17
-
18
- test:
19
- <<: *defaults
20
- FEATURE1: true
21
- feature4: true
22
-
23
- feature4a: true
24
- feature3: false
25
- Feature2: true
26
-
27
- staging:
28
- <<: *defaults
29
- FEATURE1: true
30
- feature4: true
31
- feature3: false
32
-
33
- feature4a: true
34
- Feature2: true
35
-
36
- production:
37
- <<: *defaults
38
- FEATURE1: true
39
- feature4: true
40
- feature3: false
41
- Feature2: true
42
-
43
- feature4a: true
44
-
@@ -1,44 +0,0 @@
1
- defaults: &defaults
2
-
3
- feature4a: true
4
- FEATURE1: true
5
- feature4: true
6
- feature3: false
7
- Feature2: true
8
-
9
- development:
10
- <<: *defaults
11
- FEATURE1: true
12
-
13
- feature4a: true
14
- feature4: true
15
- feature3: false
16
- Feature2: true
17
-
18
- test:
19
- <<: *defaults
20
- FEATURE1: true
21
- feature4: true
22
-
23
- feature4a: true
24
- feature3: false
25
- Feature2: true
26
-
27
- staging:
28
- <<: *defaults
29
- FEATURE1: true
30
- feature4: true
31
- feature3: false
32
-
33
- feature4a: true
34
- Feature2: true
35
-
36
- production:
37
- <<: *defaults
38
- FEATURE1: true
39
- feature4: true
40
- feature3: false
41
- Feature2: true
42
-
43
- feature4a: true
44
-
@@ -1,44 +0,0 @@
1
- defaults: &defaults
2
-
3
- feature4a: true
4
- FEATURE1: true
5
- feature4: true
6
- feature3: false
7
- Feature2: true
8
-
9
- development:
10
- <<: *defaults
11
- FEATURE1: true
12
-
13
- feature4a: true
14
- feature4: true
15
- feature3: false
16
- Feature2: true
17
-
18
- test:
19
- <<: *defaults
20
- FEATURE1: true
21
- feature4: true
22
-
23
- feature4a: true
24
- feature3: false
25
- Feature2: true
26
-
27
- staging:
28
- <<: *defaults
29
- FEATURE1: true
30
- feature4: true
31
- feature3: false
32
-
33
- feature4a: true
34
- Feature2: true
35
-
36
- production:
37
- <<: *defaults
38
- FEATURE1: true
39
- feature4: true
40
- feature3: false
41
- Feature2: true
42
-
43
- feature4a: true
44
-