method_decorators 0.9.1 → 0.9.2
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/README.md +1 -1
- data/lib/method_decorators.rb +1 -1
- data/lib/method_decorators/decorators/memoize.rb +6 -6
- data/lib/method_decorators/decorators/precondition.rb +2 -2
- data/lib/method_decorators/decorators/retry.rb +1 -1
- data/lib/method_decorators/version.rb +1 -1
- data/spec/decorators/memoize_spec.rb +23 -11
- data/spec/decorators/precondition_spec.rb +24 -6
- data/spec/decorators/retry_spec.rb +2 -2
- data/spec/support/add_n.rb +1 -1
- data/spec/support/reverse.rb +1 -1
- data/spec/support/stringify.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -50,7 +50,7 @@ Include these with `require 'method_decorators/decorators/name_of_decorator'`, o
|
|
50
50
|
|
51
51
|
```ruby
|
52
52
|
class Transactional < MethodDecorator
|
53
|
-
def call(wrapped, *args, &blk)
|
53
|
+
def call(wrapped, this, *args, &blk)
|
54
54
|
ActiveRecord::Base.transaction do
|
55
55
|
wrapped.call(*args, &blk)
|
56
56
|
end
|
data/lib/method_decorators.rb
CHANGED
@@ -39,7 +39,7 @@ module MethodDecorators
|
|
39
39
|
|
40
40
|
def self.decorate_callable(orig, decorators)
|
41
41
|
decorators.reduce(orig) do |callable, decorator|
|
42
|
-
lambda{ |*a, &b| decorator.call(callable, *a, &b) }
|
42
|
+
lambda{ |*a, &b| decorator.call(callable, orig.receiver, *a, &b) }
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class Memoize < MethodDecorator
|
2
|
-
def
|
3
|
-
|
4
|
-
|
2
|
+
def call(orig, this, *args, &blk)
|
3
|
+
return cache(this)[args] if cache(this).has_key?(args)
|
4
|
+
cache(this)[args] = orig.call(*args, &blk)
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
@
|
7
|
+
private
|
8
|
+
def cache(this)
|
9
|
+
this.instance_variable_get("@_memoize_cache") || this.instance_variable_set("@_memoize_cache", {})
|
10
10
|
end
|
11
11
|
end
|
@@ -3,8 +3,8 @@ class Precondition < MethodDecorator
|
|
3
3
|
@block = blk
|
4
4
|
end
|
5
5
|
|
6
|
-
def call(orig, *args, &blk)
|
7
|
-
unless passes?(
|
6
|
+
def call(orig, this, *args, &blk)
|
7
|
+
unless passes?(this, *args)
|
8
8
|
raise ArgumentError, "failed precondition"
|
9
9
|
end
|
10
10
|
orig.call(*args, &blk)
|
@@ -4,32 +4,33 @@ require 'method_decorators/decorators/memoize'
|
|
4
4
|
describe Memoize do
|
5
5
|
describe "#call" do
|
6
6
|
let(:method) { double(:method, :call => :calculation) }
|
7
|
+
let(:this) { Object.new }
|
7
8
|
subject { Memoize.new }
|
8
9
|
|
9
10
|
it "calculates the value the first time the arguments are supplied" do
|
10
11
|
method.should_receive(:call)
|
11
|
-
subject.call(method, 10)
|
12
|
+
subject.call(method, this, 10)
|
12
13
|
end
|
13
14
|
|
14
15
|
it "stores the value of the method call" do
|
15
16
|
method.stub(:call).and_return(:foo, :bar)
|
16
|
-
subject.call(method, 10).should == :foo
|
17
|
-
subject.call(method, 10).should == :foo
|
17
|
+
subject.call(method, this, 10).should == :foo
|
18
|
+
subject.call(method, this, 10).should == :foo
|
18
19
|
end
|
19
20
|
|
20
21
|
it "memoizes the return value and skips the call the second time" do
|
21
|
-
subject.call(method, 10)
|
22
|
+
subject.call(method, this, 10)
|
22
23
|
method.should_not_receive(:call)
|
23
|
-
subject.call(method, 10)
|
24
|
+
subject.call(method, this, 10)
|
24
25
|
end
|
25
26
|
|
26
27
|
it "memoizes different values for different arguments" do
|
27
28
|
method.stub(:call).with(10).and_return(:foo, :bar)
|
28
29
|
method.stub(:call).with(20).and_return(:bar, :foo)
|
29
|
-
subject.call(method, 10).should == :foo
|
30
|
-
subject.call(method, 10).should == :foo
|
31
|
-
subject.call(method, 20).should == :bar
|
32
|
-
subject.call(method, 20).should == :bar
|
30
|
+
subject.call(method, this, 10).should == :foo
|
31
|
+
subject.call(method, this, 10).should == :foo
|
32
|
+
subject.call(method, this, 20).should == :bar
|
33
|
+
subject.call(method, this, 20).should == :bar
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -40,14 +41,25 @@ describe Memoize do
|
|
40
41
|
def count
|
41
42
|
@count ||= 0
|
42
43
|
@count += 1
|
44
|
+
rand
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
46
48
|
subject { klass.new }
|
47
49
|
|
48
50
|
it "memoizes calls to the method" do
|
49
|
-
subject.count
|
50
|
-
subject.count.should ==
|
51
|
+
x = subject.count
|
52
|
+
subject.count.should == x
|
53
|
+
#subject.count.should == 1
|
54
|
+
#subject.count.should == 1
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with two instances of the decorated class" do
|
58
|
+
let(:o1) { subject }
|
59
|
+
let(:o2) { klass.new }
|
60
|
+
it "cache does not interact with that of other instances" do
|
61
|
+
o1.count.should_not == o2.count
|
62
|
+
end
|
51
63
|
end
|
52
64
|
end
|
53
65
|
end
|
@@ -10,12 +10,12 @@ describe Precondition do
|
|
10
10
|
describe "#call" do
|
11
11
|
it "raises when the precondition fails" do
|
12
12
|
subject.stub(:passes?){ false }
|
13
|
-
expect{ subject.call(method) }.to raise_error(ArgumentError)
|
13
|
+
expect{ subject.call(method, nil) }.to raise_error(ArgumentError)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "executes the method when authorization succeeds" do
|
17
17
|
subject.stub(:passes?){ true }
|
18
|
-
subject.call(method).should == :secret
|
18
|
+
subject.call(method, nil).should == :secret
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -30,16 +30,34 @@ describe Precondition do
|
|
30
30
|
def multiply(a)
|
31
31
|
a * @x
|
32
32
|
end
|
33
|
+
|
34
|
+
+Precondition.new{ |a| a + @x == 10 }
|
35
|
+
+Precondition.new{ |a| a * @x == 21 }
|
36
|
+
def concat(a)
|
37
|
+
"#{@x}#{a}"
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
35
41
|
subject { klass.new(3) }
|
36
42
|
|
37
|
-
|
38
|
-
|
43
|
+
context "with one precondition" do
|
44
|
+
it "calls the method if the precondition passes" do
|
45
|
+
subject.multiply(2).should == 6
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises if the precondition fails" do
|
49
|
+
expect{ subject.multiply(8) }.to raise_error(ArgumentError)
|
50
|
+
end
|
39
51
|
end
|
40
52
|
|
41
|
-
|
42
|
-
|
53
|
+
context "with multiple preconditions" do
|
54
|
+
it "calls the method if the precondition passes" do
|
55
|
+
subject.concat(7).should == "37"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises if the precondition fails" do
|
59
|
+
expect{ subject.concat(8) }.to raise_error(ArgumentError)
|
60
|
+
end
|
43
61
|
end
|
44
62
|
end
|
45
63
|
end
|
@@ -10,12 +10,12 @@ describe Retry do
|
|
10
10
|
method.stub(:call){ raise }
|
11
11
|
|
12
12
|
method.should_receive(:call).exactly(3).times
|
13
|
-
expect{ subject.call(method) }.to raise_error
|
13
|
+
expect{ subject.call(method, nil) }.to raise_error
|
14
14
|
end
|
15
15
|
|
16
16
|
it "does not retry the method if it succeeds" do
|
17
17
|
method.should_receive(:call).once.and_return(3)
|
18
|
-
subject.call(method).should == 3
|
18
|
+
subject.call(method, nil).should == 3
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
data/spec/support/add_n.rb
CHANGED
data/spec/support/reverse.rb
CHANGED
data/spec/support/stringify.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: method_decorators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.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: 2012-
|
12
|
+
date: 2012-07-15 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Python's function decorators for Ruby
|
15
15
|
email:
|