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