feature_toggle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,52 @@
1
+
2
+ # FeatureToggle
3
+
4
+ FeatureToggle is a [feature toggle](http://martinfowler.com/bliki/FeatureToggle.html) library for ruby.
5
+
6
+ ## Installation
7
+
8
+ gem install feature_toggle
9
+
10
+ ## Examples
11
+
12
+ ### Rails
13
+
14
+ # File: Gemfile
15
+ gem 'feature_toggle'
16
+
17
+ # File: config/features.yml
18
+ feature1:
19
+ controller1:
20
+ - action1
21
+ - action2
22
+ controller2:
23
+ - action1
24
+ - action2
25
+ feature2:
26
+ controller3:
27
+ - action1
28
+ - action2
29
+ feature3:
30
+ controller4:
31
+ - action1
32
+ - action2
33
+
34
+ # File: config/initializers/feature_toggle.rb
35
+ FEATURES = FeatureToggle.load(File.join(RAILS_ROOT, 'config', 'features.yml'))
36
+ FEATURES.deactivate('feature1', 'feature2', 'feature3')
37
+
38
+ # File: app/controllers/application_controller.rb
39
+ before_filter :check_feature_activated?
40
+
41
+ def check_feature_activated?
42
+ FEATURES.active_action?(params[:controller], params[:action])
43
+ end
44
+
45
+ # File: app/views/example/index.html.erb
46
+ <% if FEATURES.active?('feature1') %>
47
+ <%# Feature implementation goes here %>
48
+ <% end %>
49
+ <% if FEATURES.active_action?('controller4', 'action1') %>
50
+ <%# Feature implementation goes here %>
51
+ <% end %>
52
+
File without changes
@@ -0,0 +1,11 @@
1
+ require 'yaml'
2
+ require 'feature_toggle/features'
3
+ module FeatureToggle
4
+ class UnknownFeatureError < StandardError
5
+ end
6
+
7
+ def load(config_file)
8
+ Features.new YAML.load(File.read(config_file))
9
+ end
10
+ module_function :load
11
+ end
@@ -0,0 +1,53 @@
1
+ require 'set'
2
+ module FeatureToggle
3
+ class Features
4
+ def initialize(features)
5
+ @features = features
6
+ @actions = build_actions_feature_map(features)
7
+ @deactivated_features = Set.new
8
+ end
9
+
10
+ def [](feature_name)
11
+ @features[feature_name]
12
+ end
13
+
14
+ def activate(*feature_names)
15
+ feature_names.each do |feature_name|
16
+ validate!(feature_name)
17
+ @deactivated_features.delete(feature_name)
18
+ end
19
+ end
20
+
21
+ def deactivate(*feature_names)
22
+ feature_names.each do |feature_name|
23
+ validate!(feature_name)
24
+ @deactivated_features << feature_name
25
+ end
26
+ end
27
+
28
+ def active_action?(controller, action)
29
+ feature = @actions["#{controller}:#{action}"]
30
+ active?(feature)
31
+ end
32
+
33
+ def active?(feature_name)
34
+ !@deactivated_features.include?(feature_name)
35
+ end
36
+
37
+ private
38
+ def validate!(feature_name)
39
+ raise UnknownFeatureError, "Unknown feature name: #{feature_name}" unless @features.has_key?(feature_name)
40
+ end
41
+ def build_actions_feature_map(features)
42
+ map = {}
43
+ features.each do |feature, controllers|
44
+ controllers.each do |controller_name, actions|
45
+ actions.each do |action_name|
46
+ map["#{controller_name}:#{action_name}"] = feature
47
+ end
48
+ end
49
+ end
50
+ map
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ require "test/unit"
2
+
3
+ require "feature_toggle"
4
+
5
+ class FeatureToggleTest < Test::Unit::TestCase
6
+ def test_load_features
7
+ features = load_features
8
+ assert_equal({'users' => ['update', 'show']}, features['user_profile'])
9
+ end
10
+
11
+ def test_can_deactivate_features
12
+ features = load_features
13
+ assert features.active?('user_profile')
14
+
15
+ features.deactivate("user_profile")
16
+ assert !features.active?('user_profile')
17
+
18
+ features.deactivate("wpc", "rao")
19
+ assert !features.active?('wpc')
20
+ assert !features.active?('rao')
21
+ end
22
+
23
+ def test_activate_feature_after_deactivated_feature
24
+ features = load_features
25
+ features.deactivate("user_profile")
26
+ features.activate("user_profile")
27
+ assert features.active?('user_profile')
28
+ end
29
+
30
+ def test_disabling_non_existent_features_should_raise_error
31
+ features = load_features
32
+ assert_raises FeatureToggle::UnknownFeatureError do
33
+ features.deactivate("user")
34
+ end
35
+ end
36
+
37
+ def test_activating_non_existent_features_should_raise_error
38
+ features = load_features
39
+ assert_raises FeatureToggle::UnknownFeatureError do
40
+ features.activate("user")
41
+ end
42
+ end
43
+
44
+ def test_feature_actions_should_be_active_when_feature_is_active
45
+ features = load_features
46
+ assert features.active_action?('users', 'update')
47
+ features.deactivate("user_profile")
48
+ assert !features.active_action?('users', 'update')
49
+ end
50
+
51
+ def test_feature_action_should_be_active_when_no_feature_defines_the_action
52
+ features = load_features
53
+ assert features.active_action?('users', 'destroy')
54
+ end
55
+
56
+ def load_features
57
+ config = File.join(File.dirname(__FILE__), 'features.yml')
58
+ FeatureToggle.load(config)
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ user_profile:
2
+ users:
3
+ - update
4
+ - show
5
+ wpc:
6
+ body:
7
+ - move
8
+ - jump
9
+ rao:
10
+ hand:
11
+ - wave
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: feature_toggle
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Mingle SaaS team
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-07-31 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description:
22
+ email: mingle.saas@thoughtworks.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/feature_toggle/features.rb
31
+ - lib/feature_toggle.rb
32
+ - test/feature_toggle_test.rb
33
+ - test/features.yml
34
+ - Rakefile
35
+ - README.md
36
+ - CHANGELOG.md
37
+ homepage: https://github.com/ThoughtWorksStudios/feature_toggle
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.24
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Feature Toggle library for ruby
70
+ test_files: []
71
+