feature 0.5.0 → 0.6.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 CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.6.0 (2013-03-24)
2
+
3
+ * add capability for easier testing of activated or deactivated features
4
+
1
5
  ## 0.5.0 (2012-09-29)
2
6
 
3
7
  * added erb support for yaml feature config (dscataglini)
data/Gemfile CHANGED
@@ -1,4 +1,8 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem "rake"
4
4
  gem "rspec"
5
+
6
+ group :test do
7
+ gem 'coveralls', :require => false
8
+ end
data/README.md CHANGED
@@ -1,23 +1,60 @@
1
1
  # Feature
2
2
 
3
- Feature is a [feature toggle](http://martinfowler.com/bliki/FeatureToggle.html) library for ruby.
3
+ Feature is a battle-tested [feature toggle](http://martinfowler.com/bliki/FeatureToggle.html) library for ruby.
4
4
 
5
- The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active and inctive features.
5
+ The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active features (symbols!). Unknown features are assumed deactive.
6
6
  With this approach Feature is higly configurable and not bound to a specific kind of configuration.
7
7
 
8
8
  ## CI status
9
9
 
10
- [![Travis-CI Build Status](https://secure.travis-ci.org/mgsnova/feature.png)](https://secure.travis-ci.org/mgsnova/feature)
11
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/mgsnova/feature)
10
+ [![Gem Version](https://badge.fury.io/rb/feature.png)](https://rubygems.org/gems/feature)
11
+ [![Travis-CI Build Status](https://travis-ci.org/mgsnova/feature.png)](https://travis-ci.org/mgsnova/feature)
12
+ [![Code Climate](https://codeclimate.com/github/mgsnova/feature.png)](https://codeclimate.com/github/mgsnova/feature)
13
+ [![Coverage Status](https://coveralls.io/repos/mgsnova/feature/badge.png)](https://coveralls.io/r/mgsnova/feature)
12
14
 
13
15
  ## Installation
14
16
 
15
17
  gem install feature
16
18
 
19
+ ## How to use
20
+
21
+ * Setup Feature
22
+ * Create a repository (see examples below)
23
+ * set repository to Feature
24
+
25
+ Feature.set_repository(your_repository)
26
+
27
+ * Use Feature in your production code
28
+
29
+ Feature.active(:feature_name) # => true/false
30
+
31
+ Feature.deactive?(:feature_name) # => true/false
32
+
33
+ Feature.with(:feature_name) do
34
+ # code
35
+ end
36
+
37
+ Feature.without(:feature_name) do
38
+ # code
39
+ end
40
+
41
+ * Use Feature in your test code (for reliable testing of feature depending code)
42
+
43
+ require 'feature/testing'
44
+
45
+ Feature.run_with_activated(:feature_name) do
46
+ # your test code
47
+ end
48
+
49
+ Feature.run_with_deactivated(:feature_name) do
50
+ # your test code
51
+ end
52
+
17
53
  ## Examples
18
54
 
19
- ### Vanilla Ruby
55
+ ### Vanilla Ruby using SimpleRepository
20
56
 
57
+ # setup code
21
58
  require 'feature'
22
59
 
23
60
  repo = Feature::Repository::SimpleRepository.new
@@ -25,6 +62,7 @@ With this approach Feature is higly configurable and not bound to a specific kin
25
62
 
26
63
  Feature.set_repository repo
27
64
 
65
+ # production code
28
66
  Feature.active?(:be_nice)
29
67
  # => true
30
68
 
@@ -32,10 +70,10 @@ With this approach Feature is higly configurable and not bound to a specific kin
32
70
  puts "you can read this"
33
71
  end
34
72
 
35
- ### Rails
73
+ ### Rails using YamlRepository
36
74
 
37
75
  # File: Gemfile
38
- gem 'feature' # Or with version specifier, e.g. '~> 0.4.0'
76
+ gem 'feature' # Or with version specifier, e.g. '~> 0.6.0'
39
77
 
40
78
  # File: config/feature.yml
41
79
  features:
data/lib/feature.rb CHANGED
@@ -5,6 +5,20 @@
5
5
  # - to refresh the feature lists (request them from repository)
6
6
  #
7
7
  # @note all features not active will be handled has inactive
8
+ #
9
+ # Example usage:
10
+ # repository = SimpleRepository.new
11
+ # repository.add_active_feature(:feature_name)
12
+ #
13
+ # Feature.set_repository(repository)
14
+ # Feature.active?(:feature_name)
15
+ # # => true
16
+ # Feature.inactive?(:inactive_feature)
17
+ # # => false
18
+ #
19
+ # Feature.with(:feature_name) do
20
+ # # code will be executed
21
+ # end
8
22
  #
9
23
  module Feature
10
24
  require 'feature/repository'
@@ -26,7 +40,7 @@ module Feature
26
40
  refresh!
27
41
  end
28
42
 
29
- # Obtains list of active features from repository
43
+ # Obtains list of active features from repository (for the case they change e.g. when using db-backed repository)
30
44
  #
31
45
  def self.refresh!
32
46
  @active_features = @repository.active_features
@@ -3,6 +3,11 @@ module Feature
3
3
  # SimpleRepository for active feature list
4
4
  # Simply add features to that should be active, no config or data sources required
5
5
  #
6
+ # Example usage:
7
+ # repository = SimpleRepository.new
8
+ # repository.add_active_feature(:feature_name)
9
+ # # use repository with Feature
10
+ #
6
11
  class SimpleRepository
7
12
  # Constructor
8
13
  #
@@ -7,6 +7,10 @@ module Feature
7
7
  # an_active_feature: true
8
8
  # an_inactive_feature: false
9
9
  #
10
+ # Example usage:
11
+ # repository = YamlRepository.new('/path/to/yaml/file')
12
+ # # use repository with Feature
13
+ #
10
14
  class YamlRepository
11
15
  require 'erb'
12
16
  require 'yaml'
@@ -0,0 +1,37 @@
1
+ require 'feature'
2
+
3
+ # This file provides functionality for testing your code with features
4
+ # activated or deactivated.
5
+ # This file should only be required in test/spec code!
6
+ #
7
+ # To enable Feature testing capabilities do:
8
+ # require 'feature/testing'
9
+ module Feature
10
+ # Execute the code block with the given feature active
11
+ #
12
+ # Example usage:
13
+ # Feature.run_with_activated(:feature) do
14
+ # # your test code here
15
+ # end
16
+ def self.run_with_activated(feature)
17
+ old_features = @active_features.dup
18
+ @active_features.push(feature).uniq!
19
+ yield
20
+ ensure
21
+ @active_features = old_features
22
+ end
23
+
24
+ # Execute the code block with the given feature deactive
25
+ #
26
+ # Example usage:
27
+ # Feature.run_with_deactivated(:feature) do
28
+ # # your test code here
29
+ # end
30
+ def self.run_with_deactivated(feature)
31
+ old_features = @active_features.dup
32
+ @active_features.delete(feature)
33
+ yield
34
+ ensure
35
+ @active_features = old_features
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'feature/testing'
3
+
4
+ describe "Feature testing support" do
5
+ before(:each) do
6
+ repository = SimpleRepository.new
7
+ repository.add_active_feature(:active_feature)
8
+ Feature.set_repository(repository)
9
+ end
10
+
11
+ it "should execute code block with an deactivated feature" do
12
+ Feature.active?(:another_feature).should be_false
13
+
14
+ Feature.run_with_activated(:another_feature) do
15
+ Feature.active?(:another_feature).should be_true
16
+ end
17
+
18
+ Feature.active?(:another_feature).should be_false
19
+ end
20
+
21
+ it "should execute code block with an deactivated feature" do
22
+ Feature.active?(:active_feature).should be_true
23
+
24
+ Feature.run_with_deactivated(:active_feature) do
25
+ Feature.active?(:active_feature).should be_false
26
+ end
27
+
28
+ Feature.active?(:active_feature).should be_true
29
+ end
30
+ 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 - /this/file/should/not/exist")
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
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "pathname"
2
2
  require 'pp'
3
+ require 'coveralls'
4
+ Coveralls.wear!
3
5
 
4
6
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
metadata CHANGED
@@ -1,28 +1,40 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: feature
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Markus Gerdes
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-09-29 00:00:00.000000000 Z
17
+
18
+ date: 2013-03-24 00:00:00 Z
13
19
  dependencies: []
20
+
14
21
  description:
15
22
  email: github@mgsnova.de
16
23
  executables: []
24
+
17
25
  extensions: []
26
+
18
27
  extra_rdoc_files: []
19
- files:
28
+
29
+ files:
30
+ - lib/feature.rb
31
+ - lib/feature/repository.rb
20
32
  - lib/feature/repository/simple_repository.rb
21
33
  - lib/feature/repository/yaml_repository.rb
22
- - lib/feature/repository.rb
23
- - lib/feature.rb
34
+ - lib/feature/testing.rb
24
35
  - spec/feature/feature_spec.rb
25
36
  - spec/feature/simple_repository_spec.rb
37
+ - spec/feature/testing_spec.rb
26
38
  - spec/feature/yaml_repository_spec.rb
27
39
  - spec/spec_helper.rb
28
40
  - Rakefile
@@ -31,26 +43,37 @@ files:
31
43
  - CHANGELOG.md
32
44
  homepage: http://github.com/mgsnova/feature
33
45
  licenses: []
46
+
34
47
  post_install_message:
35
48
  rdoc_options: []
36
- require_paths:
49
+
50
+ require_paths:
37
51
  - lib
38
- required_ruby_version: !ruby/object:Gem::Requirement
52
+ required_ruby_version: !ruby/object:Gem::Requirement
39
53
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
62
  none: false
46
- requirements:
47
- - - ! '>='
48
- - !ruby/object:Gem::Version
49
- version: '0'
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
50
70
  requirements: []
71
+
51
72
  rubyforge_project:
52
73
  rubygems_version: 1.8.24
53
74
  signing_key:
54
75
  specification_version: 3
55
76
  summary: Feature Toggle library for ruby
56
77
  test_files: []
78
+
79
+ has_rdoc: