feature_release 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.5"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "mock_redis"
24
25
  end
@@ -1,15 +1,17 @@
1
1
  require "feature_release/version"
2
2
  require "feature_release/feature"
3
+ require "feature_release/storage"
3
4
 
4
5
  class FeatureRelease
5
6
 
6
7
  attr_reader :groups, :features
7
8
 
8
- def initialize
9
+ def initialize(storage=nil)
9
10
  @groups = {:all => lambda{|obj| true}}
10
11
  @features = Hash.new do |hash, missing_key|
11
12
  hash[missing_key] = Feature.new(missing_key)
12
13
  end
14
+ set_storage(storage) if storage
13
15
  end
14
16
 
15
17
  def define_group(name, &block)
@@ -29,4 +31,21 @@ class FeatureRelease
29
31
  @features[feature.to_sym].groups.all? {|group| groups[group].call(user)}
30
32
  end
31
33
 
34
+ def persisted?(feature)
35
+ !(@storage.get(@features[feature.to_sym].name).nil?)
36
+ end
37
+
38
+ def save
39
+ @features.each{|key, value| @storage.save(value.name, value.to_string)}
40
+ end
41
+
42
+ private
43
+
44
+ def set_storage(storage)
45
+ @storage = storage
46
+ @storage.get_all.each do |feature_name|
47
+ @features[feature_name.to_sym] = Feature.new(feature_name, @storage.get(feature_name))
48
+ end
49
+ end
50
+
32
51
  end
@@ -3,10 +3,12 @@ class FeatureRelease
3
3
  class Feature
4
4
 
5
5
  attr_accessor :groups
6
+ attr_reader :name
6
7
 
7
- def initialize(name)
8
+ def initialize(name, groups_string=nil)
8
9
  @name = name
9
10
  @groups = []
11
+ parse_groups(groups_string)
10
12
  end
11
13
 
12
14
  def add_group(group)
@@ -17,6 +19,16 @@ class FeatureRelease
17
19
  @groups.delete(group.to_sym)
18
20
  end
19
21
 
22
+ def to_string
23
+ @groups.join(",")
24
+ end
25
+
26
+ private
27
+ def parse_groups(string)
28
+ return unless string
29
+ @groups = string.split(",").map(&:to_sym)
30
+ end
31
+
20
32
  end
21
33
 
22
34
  end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ class FeatureRelease
3
+ class Storage
4
+
5
+ def initialize(options={})
6
+ @store = options.fetch(:store)
7
+ end
8
+
9
+ def save(feature, data)
10
+ persist(feature, data)
11
+ end
12
+
13
+ def get(feature)
14
+ retrieve(feature_key(feature))
15
+ end
16
+
17
+ def get_all
18
+ (retrieve(global_key) || "").split(",").map(&:to_sym)
19
+ end
20
+
21
+
22
+ private
23
+
24
+ def feature_key(feature)
25
+ "feature:#{feature}"
26
+ end
27
+
28
+ def global_key
29
+ "features:all"
30
+ end
31
+
32
+ def persist(feature, data)
33
+ @store.set(feature_key(feature), data)
34
+ @store.set(global_key, (get_all | [feature]).join(","))
35
+ end
36
+
37
+ def retrieve(key)
38
+ @store.get(key)
39
+ end
40
+
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  class FeatureRelease
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -57,4 +57,38 @@ describe FeatureRelease do
57
57
 
58
58
  end
59
59
 
60
+ context "persistence" do
61
+ let(:tester) {double("user", :new? => true, :admin? => false)}
62
+ let(:admin) {double("user", :admin? => true, :new? => false)}
63
+
64
+ before(:each) do
65
+ @redis = MockRedis.new
66
+ @storage = FeatureRelease::Storage.new(store:@redis)
67
+ @fr = FeatureRelease.new(@storage)
68
+ @fr.define_group(:testers) do |user|
69
+ user.new?
70
+ end
71
+ @fr.activate_feature(:test_feature, :testers)
72
+ @fr.define_group(:admins) do |user|
73
+ user.admin?
74
+ end
75
+ @fr.activate_feature(:new_feature, :admins)
76
+ end
77
+
78
+ it "commands its storage object to save the features" do
79
+ @fr.save
80
+ @fr.persisted?(:test_feature).should be_true
81
+ end
82
+
83
+ it "can build itself from persisted date" do
84
+ @fr.save
85
+ @new_fr = FeatureRelease.new(@storage)
86
+ @new_fr.define_group(:admins) do |user|
87
+ user.admin?
88
+ end
89
+ @new_fr.active?(:new_feature, admin).should be_true
90
+ end
91
+
92
+
93
+ end
60
94
  end
@@ -23,5 +23,21 @@ describe FeatureRelease::Feature do
23
23
  f.remove_group(:testers)
24
24
  f.groups.should_not include(:testers)
25
25
  end
26
+
27
+ it "can be to_string into a string" do
28
+ f = FeatureRelease::Feature.new(:test_feature)
29
+ f.add_group(:testers)
30
+ f.add_group(:admins)
31
+ f.to_string.should eq("testers,admins")
32
+ end
33
+
34
+ it "can be built from a string" do
35
+ f = FeatureRelease::Feature.new(:test_feature)
36
+ f.add_group(:testers)
37
+ f.add_group(:admins)
38
+ string = f.to_string
39
+ from_s = FeatureRelease::Feature.new(:test_feature, string)
40
+ from_s.groups.should eq([:testers, :admins])
41
+ end
26
42
 
27
43
  end
@@ -1,6 +1,7 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'feature_release.rb'
4
+ require 'mock_redis'
4
5
 
5
6
  RSpec.configure do |config|
6
7
  config.treat_symbols_as_metadata_keys_with_true_values = true
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe FeatureRelease::Storage do
4
+
5
+ before(:each) do
6
+ @redis = MockRedis.new
7
+ end
8
+
9
+ it "should initialize with a store" do
10
+ expect{FeatureRelease::Storage.new()}.to raise_error
11
+ expect{FeatureRelease::Storage.new(store: @redis)}.to_not raise_error
12
+ end
13
+
14
+ context 'saving features' do
15
+
16
+ before(:each) do
17
+ @storage = FeatureRelease::Storage.new(store: @redis)
18
+ @feature = double 'Feature', name: :test_feature, to_string: "test_users, new_users, admin_users"
19
+ end
20
+
21
+ it "should save a feature to the store" do
22
+ @storage.save(@feature.name, @feature.to_string)
23
+ @storage.get(@feature.name).should eq(@feature.to_string)
24
+ end
25
+
26
+ it "should add a feature to the collection of features" do
27
+ @storage = FeatureRelease::Storage.new(store: @redis)
28
+ @storage.save(@feature.name, @feature.to_string)
29
+ @storage.get_all.should eq([:test_feature])
30
+ end
31
+
32
+ end
33
+
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feature_release
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-07 00:00:00.000000000 Z
12
+ date: 2014-05-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mock_redis
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  description: Allows you to restrict access of portions of an app to certain users
63
79
  email:
64
80
  - kavinderd@gmail.com
@@ -75,10 +91,12 @@ files:
75
91
  - feature_release.gemspec
76
92
  - lib/feature_release.rb
77
93
  - lib/feature_release/feature.rb
94
+ - lib/feature_release/storage.rb
78
95
  - lib/feature_release/version.rb
79
96
  - spec/feature_release_spec.rb
80
97
  - spec/feature_spec.rb
81
98
  - spec/spec_helper.rb
99
+ - spec/storage_spec.rb
82
100
  homepage: ''
83
101
  licenses:
84
102
  - MIT
@@ -94,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
112
  version: '0'
95
113
  segments:
96
114
  - 0
97
- hash: 4375904973404869369
115
+ hash: -1008631629134333472
98
116
  required_rubygems_version: !ruby/object:Gem::Requirement
99
117
  none: false
100
118
  requirements:
@@ -103,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
121
  version: '0'
104
122
  segments:
105
123
  - 0
106
- hash: 4375904973404869369
124
+ hash: -1008631629134333472
107
125
  requirements: []
108
126
  rubyforge_project:
109
127
  rubygems_version: 1.8.25
@@ -114,3 +132,4 @@ test_files:
114
132
  - spec/feature_release_spec.rb
115
133
  - spec/feature_spec.rb
116
134
  - spec/spec_helper.rb
135
+ - spec/storage_spec.rb