enabler 0.0.3 → 0.0.4
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/Gemfile.lock +1 -1
- data/lib/enabler/config.rb +30 -0
- data/lib/enabler/rule.rb +13 -9
- data/lib/enabler/version.rb +1 -1
- data/lib/enabler.rb +37 -36
- data/spec/enabler/config_spec.rb +27 -0
- data/spec/enabler/rule_spec.rb +11 -11
- data/spec/enabler/storage/redis_spec.rb +31 -31
- data/spec/enabler_spec.rb +89 -51
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96b2c11e3a376fc692ebc89c2d14cd0113093bab
|
4
|
+
data.tar.gz: be2f56970f93247b164e6298dcaa0eff9bf422b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c3a80480396a8eea950ea3d0d1cbc156f4d32e9fcdaf7866cf3aa16dd962fb4d5bde000aae0777feb9806a77025659b660565b005669f439a7929a7cecd270b
|
7
|
+
data.tar.gz: d7221069538d4e6b3be21c018827b971027773d7c2bae1d42b951bddad65ce0bfd1057daf971acbdf807e3999bdeb04d9806426c27320f1675eb904ea33bfa25
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Enabler
|
2
|
+
class Config
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def rule(feature, &block)
|
6
|
+
rules << Rule.new(feature.to_sym, block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def after_enabling(feature, &block)
|
10
|
+
after_enablings[feature.to_sym] = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def after_disabling(feature, &block)
|
14
|
+
after_disablings[feature.to_sym] = block
|
15
|
+
end
|
16
|
+
|
17
|
+
def rules
|
18
|
+
@rules ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def after_enablings
|
22
|
+
@after_enables ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_disablings
|
26
|
+
@after_enables ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/enabler/rule.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
module Enabler
|
2
|
-
|
2
|
+
class Rule
|
3
3
|
|
4
|
-
|
4
|
+
attr_reader :feature, :definition
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(feature, definition)
|
7
|
+
@feature, @definition = feature, definition
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def enabled?(model)
|
11
|
+
definition.call(model)
|
12
|
+
end
|
13
13
|
|
14
|
-
|
14
|
+
def self.find feature
|
15
|
+
::Enabler.config.rules.select { |item| item.feature == feature.to_sym }
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
15
19
|
end
|
data/lib/enabler/version.rb
CHANGED
data/lib/enabler.rb
CHANGED
@@ -1,54 +1,55 @@
|
|
1
|
+
require "singleton"
|
1
2
|
require "enabler/version"
|
3
|
+
|
4
|
+
require "enabler/config"
|
2
5
|
require "enabler/storage/redis"
|
3
6
|
require "enabler/errors/rule_already_defined_error"
|
4
7
|
require "enabler/rule"
|
5
8
|
|
6
9
|
module Enabler
|
10
|
+
class << self
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
def store=(val)
|
13
|
+
@@store = val
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
def store
|
17
|
+
@@store
|
18
|
+
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
def enable!(feature, object)
|
21
|
+
store.add!(feature, object)
|
22
|
+
config.after_enablings[feature].call(object) if config.after_enablings[feature]
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
def disable!(feature, object)
|
26
|
+
store.remove!(feature, object)
|
27
|
+
config.after_disablings[feature].call(object) if config.after_disablings[feature]
|
28
|
+
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
return false unless r
|
29
|
-
r.enabled?(object)
|
30
|
-
end
|
30
|
+
def enabled?(feature, object)
|
31
|
+
enabled_via_rule?(feature, object) || enabled_via_storage?(feature, object)
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
def config
|
35
|
+
Enabler::Config.instance
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
def configure(&block)
|
39
|
+
config.instance_eval &block
|
40
|
+
end
|
39
41
|
|
40
|
-
|
41
|
-
@@rules ||= []
|
42
|
-
end
|
42
|
+
private
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def enabled_via_storage?(feature, object)
|
45
|
+
store.enabled?(feature, object)
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
def enabled_via_rule?(feature, object)
|
49
|
+
Array(Rule.find(feature.to_sym)).map do |r|
|
50
|
+
r.enabled? object
|
51
|
+
end.include? true
|
52
|
+
end
|
53
53
|
|
54
|
+
end
|
54
55
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'enabler'
|
2
|
+
|
3
|
+
describe Enabler::Config do
|
4
|
+
let(:processor) { Proc.new { true } }
|
5
|
+
subject { Enabler::Config.instance }
|
6
|
+
|
7
|
+
describe "rule" do
|
8
|
+
it "adds the rule" do
|
9
|
+
expect {
|
10
|
+
subject.rule :dance, &processor
|
11
|
+
}.to change {
|
12
|
+
subject.rules.length
|
13
|
+
}.from(0).to 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "after_enabling" do
|
18
|
+
before { subject.after_enabling :dance, &processor }
|
19
|
+
specify { subject.after_enablings[:dance].should == processor }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "after_disabling" do
|
23
|
+
before { subject.after_enabling :dance, &processor }
|
24
|
+
specify { subject.after_disablings[:dance].should == processor }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/spec/enabler/rule_spec.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'enabler'
|
2
2
|
|
3
3
|
describe Enabler::Rule do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
let(:model) { double('Model', id:1) }
|
5
|
+
let(:pass_rule_def) { Proc.new { |model| model.id == 1 } }
|
6
|
+
let(:fail_rule_def) { Proc.new { |model| model.id != 1} }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
context "with a passing rule" do
|
9
|
+
subject { Enabler::Rule.new(:jump, pass_rule_def) }
|
10
|
+
specify { subject.enabled?(model).should be_true }
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
context "with a failing rule" do
|
14
|
+
subject { Enabler::Rule.new(:jump, fail_rule_def) }
|
15
|
+
specify { subject.enabled?(model).should be_false }
|
16
|
+
end
|
17
17
|
end
|
@@ -2,39 +2,39 @@ require 'mock_redis'
|
|
2
2
|
require 'enabler'
|
3
3
|
|
4
4
|
describe Enabler::Storage::Redis do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
let(:redis) { MockRedis.new }
|
6
|
+
let(:model) { double('Model', id:1, class:'Model') }
|
7
|
+
subject { Enabler::Storage::Redis.new(redis) }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
describe "#add!" do
|
10
|
+
it "adds the id to the correct set in redis" do
|
11
|
+
expect{
|
12
|
+
subject.add!(:dance, model)
|
13
|
+
}.to change{
|
14
|
+
redis.sismember('enabler::model::dance', 1)
|
15
|
+
}.from(false).to(true)
|
16
|
+
end
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
describe "#remove!" do
|
20
|
+
before { subject.add!(:dance, model) }
|
21
|
+
it "removes the id from the correct set in redis" do
|
22
|
+
expect{
|
23
|
+
subject.remove!(:dance, model)
|
24
|
+
}.to change{
|
25
|
+
redis.sismember('enabler::model::dance', 1)
|
26
|
+
}.from(true).to(false)
|
27
|
+
end
|
28
|
+
end
|
29
29
|
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
describe "#enabled?" do
|
32
|
+
context "when id is in set" do
|
33
|
+
before { subject.add!(:dance, model) }
|
34
|
+
specify { subject.enabled?(:dance, model).should be_true }
|
35
|
+
end
|
36
|
+
context "when id is not in set" do
|
37
|
+
specify { subject.enabled?(:dance, model).should be_false }
|
38
|
+
end
|
39
|
+
end
|
40
40
|
end
|
data/spec/enabler_spec.rb
CHANGED
@@ -1,55 +1,93 @@
|
|
1
1
|
require 'enabler'
|
2
2
|
|
3
3
|
describe Enabler do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
4
|
+
let(:store) { double('Store', add!:true, remove!:true) }
|
5
|
+
let(:model) { double('Model', id:1, class:'Model') }
|
6
|
+
|
7
|
+
after do
|
8
|
+
Enabler.config.instance_variable_set(:@rules, [])
|
9
|
+
Enabler.config.instance_variable_set(:@after_enablings, {})
|
10
|
+
Enabler.config.instance_variable_set(:@after_disablings, {})
|
11
|
+
end
|
12
|
+
|
13
|
+
before { Enabler.store = store }
|
14
|
+
|
15
|
+
describe ".enabled?" do
|
16
|
+
|
17
|
+
context "when store has feature enabled" do
|
18
|
+
before { store.stub(:enabled?) { true } }
|
19
|
+
specify { Enabler.enabled?(:dance, model).should be_true }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when store has feature disabled" do
|
23
|
+
before { store.stub(:enabled?) { false } }
|
24
|
+
specify { Enabler.enabled?(:dance, model).should be_false }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".enable!" do
|
30
|
+
it "calls set on the store" do
|
31
|
+
store.should_receive(:add!).with(:dance, model)
|
32
|
+
Enabler.enable! :dance, model
|
33
|
+
end
|
34
|
+
context "with after callbacks" do
|
35
|
+
before do
|
36
|
+
Enabler.configure do
|
37
|
+
after_enabling :dance do |object|
|
38
|
+
object.stub(:stubbed).and_return true
|
39
|
+
object.stubbed
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
it "calls the after_enabling callback" do
|
44
|
+
model.should_receive :stubbed
|
45
|
+
Enabler.enable! :dance, model
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe ".disable!" do
|
51
|
+
it "calls set on the store" do
|
52
|
+
store.should_receive(:remove!).with(:dance, model)
|
53
|
+
Enabler.disable! :dance, model
|
54
|
+
end
|
55
|
+
context "with after callbacks" do
|
56
|
+
before do
|
57
|
+
Enabler.configure do
|
58
|
+
after_disabling :dance do |object|
|
59
|
+
object.stub(:stubbed).and_return true
|
60
|
+
object.stubbed
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
it "calls the after_enabling callback" do
|
65
|
+
model.should_receive :stubbed
|
66
|
+
Enabler.disable! :dance, model
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "rules" do
|
72
|
+
context "with no rules set" do
|
73
|
+
specify { Enabler.config.rules.should be == [] }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with rules set" do
|
77
|
+
before do
|
78
|
+
Enabler.configure do
|
79
|
+
rule :boogie do
|
80
|
+
true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
after do
|
85
|
+
Enabler.class_variable_set(:@@rules, [])
|
86
|
+
end
|
87
|
+
|
88
|
+
specify { Enabler.config.rules.length.should be == 1 }
|
89
|
+
specify { Enabler::Rule.find(:boogie).first.feature.should == :boogie }
|
90
|
+
specify { Enabler::Rule.find(:boogie).first.definition.call.should be_true }
|
91
|
+
end
|
92
|
+
end
|
55
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enabler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -96,10 +96,12 @@ files:
|
|
96
96
|
- Rakefile
|
97
97
|
- enabler.gemspec
|
98
98
|
- lib/enabler.rb
|
99
|
+
- lib/enabler/config.rb
|
99
100
|
- lib/enabler/errors/rule_already_defined_error.rb
|
100
101
|
- lib/enabler/rule.rb
|
101
102
|
- lib/enabler/storage/redis.rb
|
102
103
|
- lib/enabler/version.rb
|
104
|
+
- spec/enabler/config_spec.rb
|
103
105
|
- spec/enabler/rule_spec.rb
|
104
106
|
- spec/enabler/storage/redis_spec.rb
|
105
107
|
- spec/enabler_spec.rb
|
@@ -128,6 +130,7 @@ signing_key:
|
|
128
130
|
specification_version: 4
|
129
131
|
summary: Enable features
|
130
132
|
test_files:
|
133
|
+
- spec/enabler/config_spec.rb
|
131
134
|
- spec/enabler/rule_spec.rb
|
132
135
|
- spec/enabler/storage/redis_spec.rb
|
133
136
|
- spec/enabler_spec.rb
|