feature 0.6.0 → 0.7.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.
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -0
- data/README.md +25 -1
- data/lib/feature.rb +2 -0
- data/lib/feature/generators/install_generator.rb +19 -0
- data/lib/feature/generators/templates/create_feature_toggles.rb +10 -0
- data/lib/feature/generators/templates/feature.rb +5 -0
- data/lib/feature/generators/templates/feature_toggle.rb +6 -0
- data/lib/feature/repository.rb +1 -0
- data/lib/feature/repository/active_record_repository.rb +61 -0
- data/spec/feature/active_record_repository_spec.rb +40 -0
- data/spec/feature/yaml_repository_spec.rb +1 -1
- metadata +23 -38
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -73,7 +73,7 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
73
73
|
### Rails using YamlRepository
|
74
74
|
|
75
75
|
# File: Gemfile
|
76
|
-
gem 'feature' # Or with version specifier, e.g. '~> 0.
|
76
|
+
gem 'feature' # Or with version specifier, e.g. '~> 0.7.0'
|
77
77
|
|
78
78
|
# File: config/feature.yml
|
79
79
|
features:
|
@@ -88,3 +88,27 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
88
88
|
<% if Feature.active?(:an_active_feature) %>
|
89
89
|
<%# Feature implementation goes here %>
|
90
90
|
<% end %>
|
91
|
+
|
92
|
+
|
93
|
+
### Rails using ActiveRecordRepository
|
94
|
+
|
95
|
+
# File: Gemfile
|
96
|
+
gem 'feature' # Or with version specifier, e.g. '~> 0.7.0'
|
97
|
+
|
98
|
+
# Run generator and migrations
|
99
|
+
$ rails g feature:install
|
100
|
+
$ rake db:migrate
|
101
|
+
|
102
|
+
# Add Features to table FeaturesToggle for example in
|
103
|
+
# File: db/schema.rb
|
104
|
+
FeatureToggle.new(name: "ActiveFeature", active: true)
|
105
|
+
FeatureToggle.new(name: "InActiveFeature", active: false)
|
106
|
+
|
107
|
+
# or in initializer
|
108
|
+
# File: config/initializers/feature.rb
|
109
|
+
repo.add_active_feature(:active_feature)
|
110
|
+
|
111
|
+
# File: app/views/example/index.html.erb
|
112
|
+
<% if Feature.active?(:an_active_feature) %>
|
113
|
+
<%# Feature implementation goes here %>
|
114
|
+
<% end %>
|
data/lib/feature.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
require 'rails/generators/active_record'
|
4
|
+
|
5
|
+
module Feature
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
extend ActiveRecord::Generators::Migration
|
9
|
+
|
10
|
+
desc 'This generator creates a migration and a model for FeatureToggles.'
|
11
|
+
source_root File.expand_path('../templates', __FILE__)
|
12
|
+
|
13
|
+
def create_model_file
|
14
|
+
template 'feature.rb', 'config/initializers/feature.rb'
|
15
|
+
template 'feature_toggle.rb', 'app/models/feature_toggle.rb'
|
16
|
+
migration_template 'create_feature_toggles.rb', 'db/migrate/create_feature_toggles.rb'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/feature/repository.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
module Feature
|
2
|
+
module Repository
|
3
|
+
# AcitveRecordRepository for active feature list
|
4
|
+
# Right now we assume you have at least name:string and active:boolean
|
5
|
+
# defined in your table.
|
6
|
+
#
|
7
|
+
# Example usage:
|
8
|
+
# repository = ActiveRecordRepository.new(FeatureToggle)
|
9
|
+
# repository.add_active_feature(:feature_name)
|
10
|
+
# # use repository with Feature
|
11
|
+
#
|
12
|
+
class ActiveRecordRepository
|
13
|
+
# Constructor
|
14
|
+
#
|
15
|
+
def initialize(model)
|
16
|
+
@model = model
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns list of active features
|
20
|
+
#
|
21
|
+
# @return [Array<Symbol>] list of active features
|
22
|
+
#
|
23
|
+
def active_features
|
24
|
+
@model.where(:active => true).map { |f| f.name.to_sym }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add an active feature to repository
|
28
|
+
#
|
29
|
+
# @param [Symbol] feature the feature to be added
|
30
|
+
#
|
31
|
+
def add_active_feature(feature)
|
32
|
+
check_feature_is_not_symbol(feature)
|
33
|
+
check_feature_already_in_list(feature)
|
34
|
+
@model.new(:name => feature.to_s, :active => true).save
|
35
|
+
end
|
36
|
+
|
37
|
+
# Checks if the given feature is a not symbol and raises an exception if so
|
38
|
+
#
|
39
|
+
# @param [Sybmol] feature the feature to be checked
|
40
|
+
#
|
41
|
+
def check_feature_is_not_symbol(feature)
|
42
|
+
if !feature.is_a?(Symbol)
|
43
|
+
raise ArgumentError, "given feature #{feature} is not a symbol"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
private :check_feature_is_not_symbol
|
47
|
+
|
48
|
+
# Checks if given feature is already added to list of active features
|
49
|
+
# and raises an exception if so
|
50
|
+
#
|
51
|
+
# @param [Symbol] feature the feature to be checked
|
52
|
+
#
|
53
|
+
def check_feature_already_in_list(feature)
|
54
|
+
if @model.exists?(feature.to_s)
|
55
|
+
raise ArgumentError, "feature :#{feature} already added to list of active features"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
private :check_feature_already_in_list
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include Feature::Repository
|
4
|
+
|
5
|
+
describe Feature::Repository::ActiveRecordRepository do
|
6
|
+
before(:each) do
|
7
|
+
# Mock the model
|
8
|
+
@features = double("FeatureToggle")
|
9
|
+
@repository = ActiveRecordRepository.new(@features)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have no active features after initialization" do
|
13
|
+
@features.stub(:where) { Hash.new }
|
14
|
+
|
15
|
+
@repository.active_features.should == []
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should add an active feature" do
|
19
|
+
@features.should_receive(:exists?).with("feature_a").and_return(false)
|
20
|
+
@features.should_receive(:new).with(:name => "feature_a",:active => true).and_return(stub(:save => true))
|
21
|
+
|
22
|
+
@repository.add_active_feature :feature_a
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise an exception when adding not a symbol as active feature" do
|
26
|
+
expect {
|
27
|
+
@repository.add_active_feature 'feature_a'
|
28
|
+
}.to raise_error(ArgumentError, "given feature feature_a is not a symbol")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise an exception when adding a active feature already added as active" do
|
32
|
+
@features.should_receive(:new).with(:name => "feature_a",:active => true).and_return(stub(:save => true))
|
33
|
+
@features.stub(:exists?).and_return(false,true)
|
34
|
+
|
35
|
+
@repository.add_active_feature :feature_a
|
36
|
+
expect {
|
37
|
+
@repository.add_active_feature :feature_a
|
38
|
+
}.to raise_error(ArgumentError, "feature :feature_a already added to list of active features")
|
39
|
+
end
|
40
|
+
end
|
@@ -87,7 +87,7 @@ EOF
|
|
87
87
|
repo = YamlRepository.new("/this/file/should/not/exist")
|
88
88
|
lambda do
|
89
89
|
repo.active_features
|
90
|
-
end.should raise_error(Errno::ENOENT, /No such file or directory
|
90
|
+
end.should raise_error(Errno::ENOENT, /No such file or directory/)
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should raise exception on invalid yaml" do
|
metadata
CHANGED
@@ -1,37 +1,33 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: feature
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 6
|
9
|
-
- 0
|
10
|
-
version: 0.6.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Markus Gerdes
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2013-03-24 00:00:00 Z
|
12
|
+
date: 2013-12-07 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
14
|
description:
|
22
15
|
email: github@mgsnova.de
|
23
16
|
executables: []
|
24
|
-
|
25
17
|
extensions: []
|
26
|
-
|
27
18
|
extra_rdoc_files: []
|
28
|
-
|
29
|
-
files:
|
19
|
+
files:
|
30
20
|
- lib/feature.rb
|
21
|
+
- lib/feature/generators/install_generator.rb
|
22
|
+
- lib/feature/generators/templates/create_feature_toggles.rb
|
23
|
+
- lib/feature/generators/templates/feature.rb
|
24
|
+
- lib/feature/generators/templates/feature_toggle.rb
|
31
25
|
- lib/feature/repository.rb
|
26
|
+
- lib/feature/repository/active_record_repository.rb
|
32
27
|
- lib/feature/repository/simple_repository.rb
|
33
28
|
- lib/feature/repository/yaml_repository.rb
|
34
29
|
- lib/feature/testing.rb
|
30
|
+
- spec/feature/active_record_repository_spec.rb
|
35
31
|
- spec/feature/feature_spec.rb
|
36
32
|
- spec/feature/simple_repository_spec.rb
|
37
33
|
- spec/feature/testing_spec.rb
|
@@ -43,37 +39,26 @@ files:
|
|
43
39
|
- CHANGELOG.md
|
44
40
|
homepage: http://github.com/mgsnova/feature
|
45
41
|
licenses: []
|
46
|
-
|
47
42
|
post_install_message:
|
48
43
|
rdoc_options: []
|
49
|
-
|
50
|
-
require_paths:
|
44
|
+
require_paths:
|
51
45
|
- lib
|
52
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
47
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
|
58
|
-
|
59
|
-
- 0
|
60
|
-
version: "0"
|
61
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
53
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
|
67
|
-
segments:
|
68
|
-
- 0
|
69
|
-
version: "0"
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
70
58
|
requirements: []
|
71
|
-
|
72
59
|
rubyforge_project:
|
73
60
|
rubygems_version: 1.8.24
|
74
61
|
signing_key:
|
75
62
|
specification_version: 3
|
76
63
|
summary: Feature Toggle library for ruby
|
77
64
|
test_files: []
|
78
|
-
|
79
|
-
has_rdoc:
|