method_decorators 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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 initialize
3
- @cache ||= {}
4
- super
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
- def call(orig, *args, &blk)
8
- return @cache[args] if @cache.has_key?(args)
9
- @cache[args] = orig.call(*args, &blk)
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?(orig.receiver, *args)
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)
@@ -3,7 +3,7 @@ class Retry < MethodDecorator
3
3
  @max = max
4
4
  end
5
5
 
6
- def call(orig, *args, &blk)
6
+ def call(orig, this, *args, &blk)
7
7
  attempts = 0
8
8
  begin
9
9
  attempts += 1
@@ -1,3 +1,3 @@
1
1
  module MethodDecorators
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.2"
3
3
  end
@@ -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.should == 1
50
- subject.count.should == 1
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
- it "calls the method if the precondition passes" do
38
- subject.multiply(2).should == 6
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
- it "raises if the precondition passes" do
42
- expect{ subject.multiply(8) }.to raise_error(ArgumentError)
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
 
@@ -3,7 +3,7 @@ class AddN < MethodDecorator
3
3
  @n = n
4
4
  end
5
5
 
6
- def call(orig, *args, &blk)
6
+ def call(orig, this, *args, &blk)
7
7
  orig.call(*args, &blk) + @n
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
1
  class Reverse < MethodDecorator
2
- def call(orig, *args, &blk)
2
+ def call(orig, this, *args, &blk)
3
3
  orig.call(*args.reverse, &blk)
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  class Stringify < MethodDecorator
2
- def call(orig, *args, &blk)
2
+ def call(orig, this, *args, &blk)
3
3
  orig.call(*args, &blk).to_s
4
4
  end
5
5
  end
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.1
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-05-01 00:00:00.000000000 Z
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: