aop 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab47f56fd5a02a5de555ceb2ace3ffeed0300db0
4
- data.tar.gz: 8657d57606125d660e8cbbd544054ddfb7988381
3
+ metadata.gz: a11ed9fc8c66d7dbf41febbfb8fc4d0205a3c937
4
+ data.tar.gz: 78ecf889219aeb28e044d948a40185901475b7fc
5
5
  SHA512:
6
- metadata.gz: fcfc3efd8608afcc4890a712d7b57468ef795b22e4dae6405827105ab95a8c84c1f4c62f0f2c50855a1cbd5508504b263e7d0ca203b571db1661783730e5e06e
7
- data.tar.gz: 77bef4440f0080fda36afd8399c5cdebf9502b0aebe9db42c31353e36d051cf7c1b1d7f6bbd704d1143584ea4e749483bb5dd8469fe015e251c4603d9c1e1935
6
+ metadata.gz: 264164d2abb7be0975a398ae799b0ddf59068d86a0194182476725babba90a2d1875c9d2c155ad6d775f3f54130c5aa7a9b6708fc295db77f0be9f61b9931259
7
+ data.tar.gz: 8ab954e1e2afe9dbc5b3b7c4cf7c9b2c9311615483841b2f5c0efd2c787b2c67b5d1c1d7cdf044711abe8745e139d0d05d28950c65d72b579f3390533c789c4b
@@ -9,5 +9,8 @@ rvm:
9
9
  - jruby-19mode
10
10
  - rbx
11
11
 
12
- script: bundle exec rspec
13
- bundler_args: --without development
12
+ bundler_args: --without development
13
+
14
+ script:
15
+ - bundle exec rspec
16
+ - bundle exec ruby integration/contracts.rb
data/Gemfile CHANGED
@@ -1,13 +1,14 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in aop.gemspec
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem 'rspec'
7
+ gem "rspec"
8
+ gem "contracts"
8
9
  end
9
10
 
10
11
  group :development do
11
12
  gem "method_profiler"
12
13
  gem "ruby-prof"
13
- end
14
+ end
@@ -42,8 +42,8 @@ def profile
42
42
  observers << MethodProfiler.observe(Example)
43
43
  observers << MethodProfiler.observe(Aop)
44
44
  observers << MethodProfiler.observe(Aop::Pointcut)
45
- observers << MethodProfiler.observe(Aop::Pointcut::MethodReference)
46
- observers << MethodProfiler.observe(Aop::Pointcut::MethodReference::Singleton)
45
+ observers << MethodProfiler.observe(Aop::MethodReference)
46
+ observers << MethodProfiler.observe(Aop::MethodReference::Singleton)
47
47
 
48
48
  10000.times do
49
49
  example.heavy_add(rand(1000), rand(1000))
@@ -0,0 +1,23 @@
1
+ require "aop"
2
+ require "contracts"
3
+
4
+ class BankAccount < Struct.new(:number, :amount)
5
+ include Contracts
6
+
7
+ Contract BankAccount, Num => Num
8
+ def transfer(other, amount)
9
+ self.amount -= amount
10
+ other.amount += amount
11
+ end
12
+ end
13
+
14
+ @actual = nil
15
+ @expected = "Transfered 100 from 12345 to 98765"
16
+
17
+ Aop["BankAccount#transfer:after"].advice do |account, other, amount|
18
+ @actual = "Transfered #{amount} from #{account.number} to #{other.number}"
19
+ end
20
+
21
+ BankAccount[12345, 955].transfer(BankAccount[98765, 130], 100)
22
+
23
+ fail "\nExpected: #{@expected}\nActual: #{@actual}" unless @expected == @actual
data/lib/aop.rb CHANGED
@@ -1,5 +1,14 @@
1
- require "aop/version"
2
- require "aop/pointcut"
1
+ %w[
2
+ version
3
+
4
+ errors
5
+ pointcut
6
+ joint_point
7
+ method_reference
8
+ ].each { |name| require "aop/#{name}" }
3
9
 
4
10
  module Aop
11
+ def self.[](pointcut_spec)
12
+ Pointcut.new(pointcut_spec)
13
+ end
5
14
  end
@@ -0,0 +1,14 @@
1
+ module Aop
2
+ class PointcutNotFound < StandardError
3
+ attr_reader :original_error
4
+
5
+ def initialize(pointcut_spec, original_error)
6
+ super("Unable to find pointcut #{pointcut_spec}")
7
+ @original_error = original_error
8
+ end
9
+
10
+ def to_s
11
+ "#{super}\n\tReason: #{original_error.inspect}"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Aop
2
+ class JointPoint
3
+ def initialize(method_name, action)
4
+ @method_name = method_name
5
+ @action = action
6
+ end
7
+
8
+ def call(*args)
9
+ @action.call(*args)
10
+ end
11
+
12
+ attr_reader :method_name
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ module Aop
2
+ class MethodReference
3
+ def self.from(m)
4
+ return new(m) if m[0...1] == "#"
5
+ Singleton.new(m)
6
+ end
7
+
8
+ def initialize(m)
9
+ @name = m[1..-1]
10
+ end
11
+
12
+ def decorate(target, &with)
13
+ name = @name
14
+ new_name = alias_name
15
+ alias_target(target).class_eval do
16
+ alias_method(new_name, name)
17
+ define_method(name, &with)
18
+ end
19
+ rescue NameError => err
20
+ raise PointcutNotFound.new(method_spec(target), err)
21
+ end
22
+
23
+ def call(target, *args, &blk)
24
+ target.send(alias_name, *args, &blk)
25
+ end
26
+
27
+ def method_name
28
+ "#{method_notation}#{@name}"
29
+ end
30
+
31
+ private
32
+
33
+ def method_spec(target)
34
+ "#{target_name(target)}#{method_name}"
35
+ end
36
+
37
+ def method_notation
38
+ "#"
39
+ end
40
+
41
+ def alias_target(target)
42
+ target
43
+ end
44
+
45
+ def target_name(target)
46
+ target.name || target.inspect
47
+ end
48
+
49
+ def alias_name
50
+ @_alias_name ||= :"__aop_#{SecureRandom.hex(10)}"
51
+ end
52
+
53
+ class Singleton < self
54
+ def method_notation
55
+ "."
56
+ end
57
+
58
+ def alias_target(target)
59
+ class << target; self; end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,23 +1,6 @@
1
1
  require "securerandom"
2
2
 
3
3
  module Aop
4
- def self.[](pointcut_spec)
5
- Pointcut.new(pointcut_spec)
6
- end
7
-
8
- class PointcutNotFound < StandardError
9
- attr_reader :original_error
10
-
11
- def initialize(pointcut_spec, original_error)
12
- super("Unable to find pointcut #{pointcut_spec}")
13
- @original_error = original_error
14
- end
15
-
16
- def to_s
17
- "#{super}\n\tReason: #{original_error.inspect}"
18
- end
19
- end
20
-
21
4
  class Pointcut
22
5
  def initialize(spec)
23
6
  @spec = spec
@@ -87,69 +70,14 @@ module Aop
87
70
  generic_advice(advised) do |method_ref|
88
71
  lambda do |*args, &blk|
89
72
  result = nil
90
- joint_point = lambda { result = method_ref.call(self, *args, &blk) }
73
+ joint_point = JointPoint.new(
74
+ method_ref.method_name,
75
+ lambda { result = method_ref.call(self, *args, &blk) }
76
+ )
91
77
  advised.call(joint_point, self, *args, &blk)
92
78
  result
93
79
  end
94
80
  end
95
81
  end
96
-
97
- class MethodReference
98
- def self.from(m)
99
- return new(m) if m[0...1] == "#"
100
- Singleton.new(m)
101
- end
102
-
103
- def initialize(m)
104
- @name = m[1..-1]
105
- end
106
-
107
- def decorate(target, &with)
108
- name = @name
109
- new_name = alias_name
110
- alias_target(target).class_eval do
111
- alias_method(new_name, name)
112
- define_method(name, &with)
113
- end
114
- rescue NameError => err
115
- raise PointcutNotFound.new(method_spec(target), err)
116
- end
117
-
118
- def call(target, *args, &blk)
119
- target.send(alias_name, *args, &blk)
120
- end
121
-
122
- private
123
-
124
- def method_spec(target)
125
- "#{target_name(target)}#{method_notation}#{@name}"
126
- end
127
-
128
- def method_notation
129
- "#"
130
- end
131
-
132
- def alias_target(target)
133
- target
134
- end
135
-
136
- def target_name(target)
137
- target.name || target.inspect
138
- end
139
-
140
- def alias_name
141
- @_alias_name ||= :"__aop_#{SecureRandom.hex(10)}"
142
- end
143
-
144
- class Singleton < self
145
- def method_notation
146
- "."
147
- end
148
-
149
- def alias_target(target)
150
- class << target; self; end
151
- end
152
- end
153
- end
154
82
  end
155
83
  end
@@ -1,3 +1,3 @@
1
1
  module Aop
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -8,6 +8,7 @@ RSpec.describe "Around advice" do
8
8
 
9
9
  Aop["BankAccount#transfer:around"].advice do |joint_point, account, *args, &blk|
10
10
  spy.before(account, *args, &blk)
11
+ spy.method_is(joint_point.method_name)
11
12
  joint_point.call
12
13
  spy.after(account, *args, &blk)
13
14
  end
@@ -19,6 +20,7 @@ RSpec.describe "Around advice" do
19
20
  amount = 55
20
21
 
21
22
  expect(spy).to receive(:before).with(account, other, amount).ordered.once
23
+ expect(spy).to receive(:method_is).with("#transfer").ordered.once
22
24
  expect(spy).to receive(:inside).with(other, amount).ordered.once
23
25
  expect(spy).to receive(:after).with(account, other, amount).ordered.once
24
26
 
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: 1.0.0
4
+ version: 1.0.1
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 00:00:00.000000000 Z
11
+ date: 2015-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -54,7 +54,11 @@ files:
54
54
  - Rakefile
55
55
  - aop.gemspec
56
56
  - benchmarks/before.rb
57
+ - integration/contracts.rb
57
58
  - lib/aop.rb
59
+ - lib/aop/errors.rb
60
+ - lib/aop/joint_point.rb
61
+ - lib/aop/method_reference.rb
58
62
  - lib/aop/pointcut.rb
59
63
  - lib/aop/version.rb
60
64
  - spec/aop/advanced_spec.rb