abstract_feature_branch 0.7.1 → 0.8.0
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/README.md +138 -37
- data/VERSION +1 -1
- data/abstract_feature_branch.gemspec +26 -11
- data/config/features/admin.local.yml +2 -1
- data/config/features/admin.yml +2 -1
- data/config/features/internal/wiki.local.yml +2 -1
- data/config/features/internal/wiki.yml +2 -1
- data/config/features/public.local.yml +2 -1
- data/config/features/public.yml +2 -1
- data/lib/abstract_feature_branch.rb +14 -3
- data/lib/abstract_feature_branch/file_beautifier.rb +63 -0
- data/lib/generators/abstract_feature_branch/install_generator.rb +1 -0
- data/lib/generators/templates/config/features.local.yml +1 -0
- data/lib/generators/templates/config/initializers/abstract_feature_branch.rb +3 -0
- data/lib/generators/templates/lib/tasks/abstract_feature_branch.rake +9 -0
- data/spec/abstract_feature_branch/file_beautifier_spec.rb +384 -0
- data/spec/ext/feature_branch__feature_branch_spec.rb +145 -0
- data/spec/ext/feature_branch__feature_enabled_spec.rb +84 -0
- data/spec/{application_no_config → fixtures/application_no_config}/no_config +0 -0
- data/spec/{application_rails_config → fixtures/application_rails_config}/config/features.local.yml +1 -0
- data/spec/{application_rails_config → fixtures/application_rails_config}/config/features.yml +0 -0
- data/spec/fixtures/application_ugly_config_reference/config/another_application_configuration.yml +31 -0
- data/spec/fixtures/application_ugly_config_reference/config/database.yml +17 -0
- data/spec/fixtures/application_ugly_config_reference/config/features.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features.yml +49 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/admin.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/admin.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/empty.local.yml +0 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/feature_empty_config.local.yml +13 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/including_comments.local.yml +52 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/public.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/public.yml +44 -0
- metadata +46 -32
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'feature_branch object extensions' do
|
4
|
+
before do
|
5
|
+
@app_env_backup = AbstractFeatureBranch.application_environment
|
6
|
+
AbstractFeatureBranch.logger.warn 'Environment variable ABSTRACT_FEATURE_BRANCH_FEATURE1 already set, potentially conflicting with another test' if ENV.keys.include?('ABSTRACT_FEATURE_BRANCH_FEATURE1')
|
7
|
+
AbstractFeatureBranch.logger.warn 'Environment variable Abstract_Feature_Branch_Feature2 already set, potentially conflicting with another test' if ENV.keys.include?('Abstract_Feature_Branch_Feature2')
|
8
|
+
AbstractFeatureBranch.logger.warn 'Environment variable abstract_feature_branch_feature3 already set, potentially conflicting with another test' if ENV.keys.include?('abstract_feature_branch_feature3')
|
9
|
+
end
|
10
|
+
after do
|
11
|
+
ENV.delete('ABSTRACT_FEATURE_BRANCH_FEATURE1')
|
12
|
+
ENV.delete('Abstract_Feature_Branch_Feature2')
|
13
|
+
ENV.delete('abstract_feature_branch_feature3')
|
14
|
+
AbstractFeatureBranch.initialize_application_root
|
15
|
+
AbstractFeatureBranch.load_application_features
|
16
|
+
AbstractFeatureBranch.application_environment = @app_env_backup
|
17
|
+
end
|
18
|
+
describe '#feature_enabled?' do
|
19
|
+
it 'determines whether a feature is enabled or not in features configuration (case-insensitive string or symbol feature names)' do
|
20
|
+
feature_enabled?('Feature1').should == true
|
21
|
+
feature_enabled?(:FEATURE2).should == true
|
22
|
+
feature_enabled?(:feature3).should == false
|
23
|
+
end
|
24
|
+
it 'returns nil for an invalid feature name' do
|
25
|
+
feature_enabled?(:invalid_feature_that_does_not_exist).should be_nil
|
26
|
+
end
|
27
|
+
it 'allows environment variables (case-insensitive booleans) to override configuration file' do
|
28
|
+
ENV['ABSTRACT_FEATURE_BRANCH_FEATURE1'] = 'FALSE'
|
29
|
+
ENV['Abstract_Feature_Branch_Feature2'] = 'False'
|
30
|
+
ENV['abstract_feature_branch_feature3'] = 'true'
|
31
|
+
AbstractFeatureBranch.load_application_features
|
32
|
+
feature_enabled?(:feature1).should == false
|
33
|
+
feature_enabled?(:feature2).should == false
|
34
|
+
feature_enabled?(:feature3).should == true
|
35
|
+
feature_enabled?(:feature4a).should == true #not overridden
|
36
|
+
end
|
37
|
+
it 'allows local configuration file to override main configuration file in test environment' do
|
38
|
+
feature_enabled?(:feature4).should == false
|
39
|
+
feature_enabled?(:feature5).should == true
|
40
|
+
end
|
41
|
+
it 'no local configuration in production environment' do
|
42
|
+
AbstractFeatureBranch.application_environment = 'production'
|
43
|
+
feature_enabled?(:feature4).should == true
|
44
|
+
feature_enabled?(:feature5).should be_nil
|
45
|
+
end
|
46
|
+
it 'works with Rails environment' do
|
47
|
+
Object.class_eval do
|
48
|
+
module Rails
|
49
|
+
def self.root
|
50
|
+
File.expand_path(File.join(__FILE__, '..', '..', 'fixtures', 'application_rails_config'))
|
51
|
+
end
|
52
|
+
def self.env
|
53
|
+
'staging'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
AbstractFeatureBranch.initialize_application_root
|
58
|
+
AbstractFeatureBranch.initialize_application_environment
|
59
|
+
AbstractFeatureBranch.load_application_features
|
60
|
+
feature_enabled?(:feature1).should == true
|
61
|
+
feature_enabled?(:feature2).should == false
|
62
|
+
feature_enabled?(:feature3).should == false
|
63
|
+
feature_enabled?(:feature4).should be_nil
|
64
|
+
feature_enabled?(:feature4a).should be_nil
|
65
|
+
feature_enabled?(:feature5).should be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
describe 'self#feature_enabled?' do
|
69
|
+
after do
|
70
|
+
Object.send(:remove_const, :TestObject)
|
71
|
+
end
|
72
|
+
# No need to retest all instance test cases, just a spot check due to implementation reuse
|
73
|
+
it 'determines whether a feature is enabled or not in features configuration' do
|
74
|
+
class TestObject
|
75
|
+
def self.hit_me
|
76
|
+
feature_enabled?(:feature1).should == true
|
77
|
+
feature_enabled?(:feature2).should == true
|
78
|
+
feature_enabled?(:feature3).should == false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
TestObject.hit_me
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
File without changes
|
data/spec/{application_rails_config → fixtures/application_rails_config}/config/features.yml
RENAMED
File without changes
|
data/spec/fixtures/application_ugly_config_reference/config/another_application_configuration.yml
ADDED
@@ -0,0 +1,31 @@
|
|
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)
|
@@ -0,0 +1,17 @@
|
|
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
|
@@ -0,0 +1,44 @@
|
|
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
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
|
3
|
+
|
4
|
+
FEATURE1: true
|
5
|
+
Feature2: true
|
6
|
+
feature3: false
|
7
|
+
feature4: true
|
8
|
+
feature4a: true
|
9
|
+
|
10
|
+
development:
|
11
|
+
<<: *defaults
|
12
|
+
FEATURE1: true
|
13
|
+
|
14
|
+
Feature2: true
|
15
|
+
feature3: false
|
16
|
+
feature4: true
|
17
|
+
feature4a: true
|
18
|
+
|
19
|
+
test:
|
20
|
+
<<: *defaults
|
21
|
+
FEATURE1: true
|
22
|
+
Feature2: true
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
feature3: false
|
27
|
+
feature4: true
|
28
|
+
feature4a: true
|
29
|
+
|
30
|
+
staging:
|
31
|
+
<<: *defaults
|
32
|
+
FEATURE1: true
|
33
|
+
Feature2: true
|
34
|
+
|
35
|
+
feature3: false
|
36
|
+
|
37
|
+
feature4: true
|
38
|
+
feature4a: true
|
39
|
+
|
40
|
+
production:
|
41
|
+
<<: *defaults
|
42
|
+
FEATURE1: true
|
43
|
+
|
44
|
+
Feature2: true
|
45
|
+
|
46
|
+
feature3: false
|
47
|
+
feature4: true
|
48
|
+
|
49
|
+
feature4a: true
|
@@ -0,0 +1,44 @@
|
|
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
|
+
|
@@ -0,0 +1,44 @@
|
|
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
|
+
|
File without changes
|
data/spec/fixtures/application_ugly_config_reference/config/features/including_comments.local.yml
ADDED
@@ -0,0 +1,52 @@
|
|
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
|
@@ -0,0 +1,44 @@
|
|
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
|
+
|