aop 0.0.2 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +24 -4
- data/lib/aop/pointcut.rb +18 -6
- data/lib/aop/version.rb +1 -1
- data/spec/aop/advanced_spec.rb +110 -0
- data/spec/aop/around_spec.rb +27 -0
- data/spec/fixtures/bank_account.rb +10 -0
- data/spec/fixtures/cash_account.rb +16 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 265bbfbbde5fedca853374f381977f960186c174
|
4
|
+
data.tar.gz: 5ba07e066d01dfb9647f8294f29b1508604fe2ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e762bcad98bbbf72d5f867d22bb20e1add43d02a66e0f63f1da21c1804b335b539bee2eea2c2956c0a7900153931285052a4ee21413bc78e620575c0caefb79
|
7
|
+
data.tar.gz: aa177e07c23669b04a02ac5de5e4ca9bedb2dacc7e92dd8124419b63fd5d5924fa0d236fee9dc01471ec32c8a3454e20cb19f59eb1c9e3b8c77cf1cb969092df
|
data/README.md
CHANGED
@@ -50,8 +50,6 @@ end
|
|
50
50
|
|
51
51
|
### Around advice
|
52
52
|
|
53
|
-
*Not implemented*
|
54
|
-
|
55
53
|
```ruby
|
56
54
|
module Transactional
|
57
55
|
Aop["BankAccount#transfer:around"].advice do |joint_point, account, *args, &blk|
|
@@ -62,9 +60,31 @@ module Transactional
|
|
62
60
|
end
|
63
61
|
```
|
64
62
|
|
65
|
-
|
63
|
+
### Class methods
|
64
|
+
|
65
|
+
Use `.method` notation:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
module Transactional
|
69
|
+
Aop["BankAccount.transfer:around"].advice do |joint_point, klass, *args, &blk|
|
70
|
+
start_transaction
|
71
|
+
joint_point.call
|
72
|
+
finish_transaction
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### Multiple classes, methods and advices
|
66
78
|
|
67
|
-
|
79
|
+
Use `,` to use multiple classes, methods and advices:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
module Analytics
|
83
|
+
Aop["User,Admin#sign_in,.sign_up,#sign_out:before,:after"].advice do |target, *args, &blk|
|
84
|
+
report("auth_action", user.id)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
68
88
|
|
69
89
|
## Contributing
|
70
90
|
|
data/lib/aop/pointcut.rb
CHANGED
@@ -13,16 +13,16 @@ module Aop
|
|
13
13
|
@class_names = @class_spec.split(",")
|
14
14
|
@classes = @class_names.map { |name| Object.const_get(name) }
|
15
15
|
|
16
|
-
@method_spec = spec.scan(/[#\.][
|
16
|
+
@method_spec = spec.scan(/[#\.][^,#\.:]+/)
|
17
17
|
@methods = @method_spec.map { |m| MethodReference.from(m) }
|
18
18
|
|
19
|
-
@advices = spec.scan(/[^:]:([
|
19
|
+
@advices = spec.scan(/[^:]:([^:,]+)/).flatten
|
20
20
|
end
|
21
21
|
|
22
22
|
def advice(&advised)
|
23
|
-
advices
|
24
|
-
advices.each do |advice|
|
25
|
-
|
23
|
+
return _advice(@advices.first, advised) if @advices.count == 1
|
24
|
+
@advices.each do |advice|
|
25
|
+
Aop["#{@class_names.join(",")}#{@method_spec.join(",")}:#{advice}"].advice(&advised)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -30,6 +30,7 @@ module Aop
|
|
30
30
|
|
31
31
|
def _advice(advice, advised)
|
32
32
|
return before_advice(advised) if advice == "before"
|
33
|
+
return around_advice(advised) if advice == "around"
|
33
34
|
after_advice(advised)
|
34
35
|
end
|
35
36
|
|
@@ -63,6 +64,17 @@ module Aop
|
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
67
|
+
def around_advice(advised)
|
68
|
+
generic_advice(advised) do |method_ref|
|
69
|
+
lambda do |*args, &blk|
|
70
|
+
result = nil
|
71
|
+
joint_point = lambda { result = method_ref.call(self, *args, &blk) }
|
72
|
+
advised.call(joint_point, self, *args, &blk)
|
73
|
+
result
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
66
78
|
class MethodReference
|
67
79
|
def self.from(m)
|
68
80
|
return new(m) if m[0...1] == "#"
|
@@ -83,7 +95,7 @@ module Aop
|
|
83
95
|
end
|
84
96
|
|
85
97
|
def call(target, *args, &blk)
|
86
|
-
|
98
|
+
target.send(alias_name, *args, &blk)
|
87
99
|
end
|
88
100
|
|
89
101
|
private
|
data/lib/aop/version.rb
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
RSpec.describe "Advanced advices" do
|
2
|
+
include FixtureLoader
|
3
|
+
|
4
|
+
let(:spy) { double("Spy") }
|
5
|
+
|
6
|
+
before do
|
7
|
+
load_fixture("BankAccount", "bank_account")
|
8
|
+
load_fixture("CashAccount", "cash_account")
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "class methods" do
|
12
|
+
before do
|
13
|
+
Aop["BankAccount.transfer:around"].advice do |joint_point, klass, *args, &blk|
|
14
|
+
spy.before(klass, *args, &blk)
|
15
|
+
joint_point.call
|
16
|
+
spy.after(klass, *args, &blk)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fires around #transfer" do
|
21
|
+
account = BankAccount.new(spy)
|
22
|
+
other = BankAccount.new(spy)
|
23
|
+
amount = 55
|
24
|
+
|
25
|
+
expect(spy).to receive(:before).with(BankAccount, spy, account, other, amount).ordered.once
|
26
|
+
expect(spy).to receive(:inside).with(spy, account, other, amount).ordered.once
|
27
|
+
expect(spy).to receive(:after).with(BankAccount, spy, account, other, amount).ordered.once
|
28
|
+
|
29
|
+
expect(BankAccount.transfer(spy, account, other, amount)).to eq(:a_result)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "multiple classes, methods and advices" do
|
34
|
+
before do
|
35
|
+
Aop["BankAccount,CashAccount#transfer,#withdraw,.transfer:before,:after"].advice do |*args, &blk|
|
36
|
+
spy.report(*args, &blk)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "works for BankAccount#transfer" do
|
41
|
+
account = BankAccount.new(spy)
|
42
|
+
other = BankAccount.new(spy)
|
43
|
+
amount = 55
|
44
|
+
|
45
|
+
expect(spy).to receive(:report).with(account, other, amount).ordered.once
|
46
|
+
expect(spy).to receive(:inside).with(other, amount).ordered.once
|
47
|
+
expect(spy).to receive(:report).with(account, other, amount).ordered.once
|
48
|
+
|
49
|
+
expect(account.transfer(other, amount)).to eq(:a_result)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "works for CashAccount#transfer" do
|
53
|
+
account = CashAccount.new(spy)
|
54
|
+
other = CashAccount.new(spy)
|
55
|
+
amount = 55
|
56
|
+
|
57
|
+
expect(spy).to receive(:report).with(account, other, amount).ordered.once
|
58
|
+
expect(spy).to receive(:inside).with(:cash_account, other, amount).ordered.once
|
59
|
+
expect(spy).to receive(:report).with(account, other, amount).ordered.once
|
60
|
+
|
61
|
+
expect(account.transfer(other, amount)).to eq(:a_result)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "works for BankAccount#withdraw" do
|
65
|
+
account = BankAccount.new(spy)
|
66
|
+
amount = 55
|
67
|
+
|
68
|
+
expect(spy).to receive(:report).with(account, amount).ordered.once
|
69
|
+
expect(spy).to receive(:withdraw).with(account, amount).ordered.once
|
70
|
+
expect(spy).to receive(:report).with(account, amount).ordered.once
|
71
|
+
|
72
|
+
expect(account.withdraw(amount)).to eq(:a_result)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "works for CashAccount#withdraw" do
|
76
|
+
account = CashAccount.new(spy)
|
77
|
+
amount = 55
|
78
|
+
|
79
|
+
expect(spy).to receive(:report).with(account, amount).ordered.once
|
80
|
+
expect(spy).to receive(:withdraw).with(:cash_account, account, amount).ordered.once
|
81
|
+
expect(spy).to receive(:report).with(account, amount).ordered.once
|
82
|
+
|
83
|
+
expect(account.withdraw(amount)).to eq(:a_result)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "works for BankAccount.transfer" do
|
87
|
+
account = BankAccount.new(spy)
|
88
|
+
other = BankAccount.new(spy)
|
89
|
+
amount = 55
|
90
|
+
|
91
|
+
expect(spy).to receive(:report).with(BankAccount, spy, account, other, amount).ordered.once
|
92
|
+
expect(spy).to receive(:inside).with(spy, account, other, amount).ordered.once
|
93
|
+
expect(spy).to receive(:report).with(BankAccount, spy, account, other, amount).ordered.once
|
94
|
+
|
95
|
+
expect(BankAccount.transfer(spy, account, other, amount)).to eq(:a_result)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "works for CashAccount.transfer" do
|
99
|
+
account = CashAccount.new(spy)
|
100
|
+
other = CashAccount.new(spy)
|
101
|
+
amount = 55
|
102
|
+
|
103
|
+
expect(spy).to receive(:report).with(CashAccount, spy, account, other, amount).ordered.once
|
104
|
+
expect(spy).to receive(:inside).with(:cash_account, spy, account, other, amount).ordered.once
|
105
|
+
expect(spy).to receive(:report).with(CashAccount, spy, account, other, amount).ordered.once
|
106
|
+
|
107
|
+
expect(CashAccount.transfer(spy, account, other, amount)).to eq(:a_result)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
RSpec.describe "Around advice" do
|
2
|
+
include FixtureLoader
|
3
|
+
|
4
|
+
let(:spy) { double("Spy") }
|
5
|
+
|
6
|
+
before do
|
7
|
+
load_fixture("BankAccount", "bank_account")
|
8
|
+
|
9
|
+
Aop["BankAccount#transfer:around"].advice do |joint_point, account, *args, &blk|
|
10
|
+
spy.before(account, *args, &blk)
|
11
|
+
joint_point.call
|
12
|
+
spy.after(account, *args, &blk)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fires around #transfer" do
|
17
|
+
account = BankAccount.new(spy)
|
18
|
+
other = BankAccount.new(spy)
|
19
|
+
amount = 55
|
20
|
+
|
21
|
+
expect(spy).to receive(:before).with(account, other, amount).ordered.once
|
22
|
+
expect(spy).to receive(:inside).with(other, amount).ordered.once
|
23
|
+
expect(spy).to receive(:after).with(account, other, amount).ordered.once
|
24
|
+
|
25
|
+
expect(account.transfer(other, amount)).to eq(:a_result)
|
26
|
+
end
|
27
|
+
end
|
@@ -3,4 +3,14 @@ class BankAccount < Struct.new(:spy)
|
|
3
3
|
spy.inside(to, amount)
|
4
4
|
:a_result
|
5
5
|
end
|
6
|
+
|
7
|
+
def withdraw(amount)
|
8
|
+
spy.withdraw(self, amount)
|
9
|
+
:a_result
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.transfer(spy, from, to, amount)
|
13
|
+
spy.inside(spy, from, to, amount)
|
14
|
+
:a_result
|
15
|
+
end
|
6
16
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CashAccount < Struct.new(:spy)
|
2
|
+
def transfer(to, amount)
|
3
|
+
spy.inside(:cash_account, to, amount)
|
4
|
+
:a_result
|
5
|
+
end
|
6
|
+
|
7
|
+
def withdraw(amount)
|
8
|
+
spy.withdraw(:cash_account, self, amount)
|
9
|
+
:a_result
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.transfer(spy, from, to, amount)
|
13
|
+
spy.inside(:cash_account, spy, from, to, amount)
|
14
|
+
:a_result
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Fedorov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,9 +56,12 @@ files:
|
|
56
56
|
- lib/aop.rb
|
57
57
|
- lib/aop/pointcut.rb
|
58
58
|
- lib/aop/version.rb
|
59
|
+
- spec/aop/advanced_spec.rb
|
59
60
|
- spec/aop/after_spec.rb
|
61
|
+
- spec/aop/around_spec.rb
|
60
62
|
- spec/aop/before_spec.rb
|
61
63
|
- spec/fixtures/bank_account.rb
|
64
|
+
- spec/fixtures/cash_account.rb
|
62
65
|
- spec/spec_helper.rb
|
63
66
|
- spec/support/loader.rb
|
64
67
|
homepage: https://github.com/waterlink/aop
|
@@ -86,8 +89,11 @@ signing_key:
|
|
86
89
|
specification_version: 4
|
87
90
|
summary: Very thin AOP gem for Ruby
|
88
91
|
test_files:
|
92
|
+
- spec/aop/advanced_spec.rb
|
89
93
|
- spec/aop/after_spec.rb
|
94
|
+
- spec/aop/around_spec.rb
|
90
95
|
- spec/aop/before_spec.rb
|
91
96
|
- spec/fixtures/bank_account.rb
|
97
|
+
- spec/fixtures/cash_account.rb
|
92
98
|
- spec/spec_helper.rb
|
93
99
|
- spec/support/loader.rb
|