abstract_feature_branch 1.2.2 → 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 (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
-