aop 1.0.0 → 1.0.1

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 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