aspector 0.7.0 → 0.7.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.
Files changed (47) hide show
  1. data/Gemfile +2 -2
  2. data/Gemfile.lock +6 -9
  3. data/README.rdoc +5 -4
  4. data/VERSION +1 -1
  5. data/aspector.gemspec +29 -20
  6. data/examples/activerecord_hooks.rb +2 -2
  7. data/examples/around_example.rb +1 -0
  8. data/examples/aspector_apply_example.rb +4 -3
  9. data/examples/aspector_example.rb +1 -0
  10. data/examples/cache_aspect.rb +2 -2
  11. data/examples/exception_handler.rb +36 -0
  12. data/examples/logging_aspect.rb +35 -0
  13. data/examples/retry_aspect.rb +41 -0
  14. data/lib/aspector/advice.rb +3 -7
  15. data/lib/aspector/base.rb +52 -29
  16. data/lib/aspector/context.rb +2 -1
  17. data/lib/aspector/deferred_logic.rb +3 -7
  18. data/lib/aspector/method_matcher.rb +6 -9
  19. data/performance-tests/after_test.rb +25 -0
  20. data/performance-tests/around_test.rb +27 -0
  21. data/performance-tests/before_test.rb +25 -0
  22. data/performance-tests/combined_test.rb +33 -0
  23. data/performance-tests/method_invocation_test.rb +25 -0
  24. data/performance-tests/test_helper.rb +9 -0
  25. data/spec/functional/advices_on_private_methods_spec.rb +21 -0
  26. data/spec/functional/aspect_on_eigen_class_spec.rb +66 -0
  27. data/spec/functional/aspect_on_object_spec.rb +20 -0
  28. data/spec/{aspector_spec.rb → functional/aspector_spec.rb} +13 -57
  29. data/spec/functional/aspects_combined_spec.rb +42 -0
  30. data/spec/functional/execution_order_spec.rb +36 -0
  31. data/spec/spec_helper.rb +16 -1
  32. data/spec/unit/advice_spec.rb +4 -0
  33. data/spec/{aspector → unit}/after_spec.rb +42 -38
  34. data/spec/{aspector → unit}/around_spec.rb +22 -18
  35. data/spec/unit/base_class_methods_spec.rb +28 -0
  36. data/spec/unit/base_spec.rb +81 -0
  37. data/spec/{aspector → unit}/before_spec.rb +27 -18
  38. data/spec/unit/deferred_logic_spec.rb +23 -0
  39. data/spec/unit/method_matcher_spec.rb +43 -0
  40. metadata +63 -69
  41. data/spec/advices_on_private_methods_spec.rb +0 -29
  42. data/spec/aspect_on_eigen_class_spec.rb +0 -86
  43. data/spec/aspect_on_object_spec.rb +0 -32
  44. data/spec/aspector/aspect_spec.rb +0 -86
  45. data/spec/aspector/base_spec.rb +0 -35
  46. data/spec/aspects_combined_spec.rb +0 -55
  47. data/spec/execution_order_spec.rb +0 -62
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class AfterTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Klass
7
+
8
+ aspector do
9
+ after :test, :after_test
10
+ end
11
+
12
+ def test_no_aspect; end
13
+
14
+ def test; end
15
+
16
+ def after_test result; end
17
+ end
18
+
19
+ def test_after
20
+ o = Klass.new
21
+ o.test_no_aspect
22
+ o.test
23
+ end
24
+ end
25
+
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class AroundTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Klass
7
+
8
+ aspector do
9
+ around :test, :around_test
10
+ end
11
+
12
+ def test_no_aspect; end
13
+
14
+ def test; end
15
+
16
+ def around_test &block
17
+ block.call
18
+ end
19
+ end
20
+
21
+ def test_around
22
+ o = Klass.new
23
+ o.test_no_aspect
24
+ o.test
25
+ end
26
+ end
27
+
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class BeforeTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Klass
7
+
8
+ aspector do
9
+ before :test, :before_test
10
+ end
11
+
12
+ def test_no_aspect; end
13
+
14
+ def test; end
15
+
16
+ def before_test; end
17
+ end
18
+
19
+ def test_before
20
+ o = Klass.new
21
+ o.test_no_aspect
22
+ o.test
23
+ end
24
+ end
25
+
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class CombinedTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Test
7
+
8
+ aspector do
9
+ before :test, :before_test
10
+ after :test, :after_test
11
+ around :test, :around_test
12
+ end
13
+
14
+ def test_no_aspect; end
15
+
16
+ def test; end
17
+
18
+ def before_test; end
19
+
20
+ def after_test result; end
21
+
22
+ def around_test &block
23
+ block.call
24
+ end
25
+ end
26
+
27
+ def test_combined
28
+ o = Test.new
29
+ o.test_no_aspect
30
+ o.test
31
+ end
32
+ end
33
+
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class MethodInvokationTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Klass
7
+ def do_something; end
8
+
9
+ def test
10
+ do_something
11
+ end
12
+
13
+ do_something_method = instance_method(:do_something)
14
+
15
+ define_method :test_with_method_object do
16
+ do_something_method.bind(self).call
17
+ end
18
+ end
19
+
20
+ def test_method_invocation
21
+ o = Klass.new
22
+ o.test
23
+ o.test_with_method_object
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'ruby-prof/test'
6
+ require 'aspector'
7
+
8
+ RubyProf::Test::PROFILE_OPTIONS[:count ] = 10000
9
+ RubyProf::Test::PROFILE_OPTIONS[:output_dir] = File.dirname(__FILE__) + "/output"
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Advices on private methods" do
4
+ it "should work" do
5
+ klass = create_test_class do
6
+ private :test
7
+ end
8
+
9
+ aspector(klass) do
10
+ before :test do value << "do_before(public_methods_only)" end
11
+ end
12
+
13
+ aspector(klass, :private_methods => true) do
14
+ before :test do value << "do_before" end
15
+ end
16
+
17
+ obj = klass.new
18
+ obj.send :test
19
+ obj.value.should == %w"do_before test"
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspector for eigen class" do
4
+ it "should work" do
5
+ klass = Class.new do
6
+ class << self
7
+ def value
8
+ @value ||= []
9
+ end
10
+
11
+ def test
12
+ value << "test"
13
+ end
14
+ end
15
+ end
16
+
17
+ aspector(klass, :eigen_class => true) do
18
+ before :test do value << "do_before" end
19
+
20
+ after :test do value << "do_after" end
21
+
22
+ around :test do |&block|
23
+ value << "do_around_before"
24
+ result = block.call
25
+ value << "do_around_after"
26
+ result
27
+ end
28
+ end
29
+
30
+ klass.test
31
+ klass.value.should == %w"do_before do_around_before test do_around_after do_after"
32
+ end
33
+
34
+ it "new methods" do
35
+ klass = Class.new do
36
+ class << self
37
+ def value
38
+ @value ||= []
39
+ end
40
+ end
41
+ end
42
+
43
+ aspector(klass, :eigen_class => true) do
44
+ before :test do value << "do_before" end
45
+
46
+ after :test do value << "do_after" end
47
+
48
+ around :test do |&block|
49
+ value << "do_around_before"
50
+ result = block.call
51
+ value << "do_around_after"
52
+ result
53
+ end
54
+ end
55
+
56
+ klass.instance_eval do
57
+ def test
58
+ value << "test"
59
+ end
60
+ end
61
+
62
+ klass.test
63
+ klass.value.should == %w"do_before do_around_before test do_around_after do_after"
64
+ end
65
+
66
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspector for object" do
4
+ it "should work" do
5
+ klass = create_test_class
6
+
7
+ obj = klass.new
8
+
9
+ aspector(obj) do
10
+ before :test do value << "do_before" end
11
+ end
12
+
13
+ obj.test
14
+ obj.value.should == %w"do_before test"
15
+
16
+ obj2 = klass.new
17
+ obj2.test
18
+ obj2.value.should == %w"test"
19
+ end
20
+ end
@@ -1,55 +1,29 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe "Aspector" do
4
4
  it "should work" do
5
- klass = Class.new do
6
- def value
7
- @value ||= []
8
- end
9
-
10
- def test
11
- value << "test"
12
- end
5
+ klass = create_test_class
13
6
 
14
- def do_before
15
- value << "do_before"
16
- end
7
+ aspector(klass) do
8
+ before :test do value << "do_before" end
17
9
 
18
- def do_after result
19
- value << "do_after"
20
- result
21
- end
10
+ after :test do value << "do_after" end
22
11
 
23
- def do_around &block
24
- value << "do_around_before"
25
- result = block.call
26
- value << "do_around_after"
12
+ around :test do |&block|
13
+ value << "do_around_before"
14
+ result = block.call
15
+ value << "do_around_after"
27
16
  result
28
17
  end
29
18
  end
30
19
 
31
- aspector(klass) do
32
- before :test, :do_before
33
- after :test, :do_after
34
- around :test, :do_around
35
- end
36
-
37
20
  obj = klass.new
38
21
  obj.test
39
22
  obj.value.should == %w"do_before do_around_before test do_around_after do_after"
40
23
  end
41
24
 
42
25
  it "multiple aspects should work together" do
43
- klass = Class.new do
44
- def value
45
- @value ||= []
46
- end
47
-
48
- def test
49
- value << "test"
50
- end
51
- end
52
-
26
+ klass = create_test_class
53
27
  aspector(klass) do
54
28
  before(:test) { value << 'first_aspect' }
55
29
  end
@@ -64,20 +38,11 @@ describe "Aspector" do
64
38
  end
65
39
 
66
40
  it "treating Aspect as regular class should work" do
67
- klass = Class.new do
68
- def value
69
- @value ||= []
70
- end
71
-
72
- def test
73
- value << "test"
74
- end
75
- end
76
-
77
41
  class TestAspect < Aspector::Base
78
42
  before(:test) { value << 'before_test' }
79
43
  end
80
44
 
45
+ klass = create_test_class
81
46
  TestAspect.apply(klass)
82
47
 
83
48
  obj = klass.new
@@ -85,21 +50,12 @@ describe "Aspector" do
85
50
  obj.value.should == %w"before_test test"
86
51
  end
87
52
 
88
- it "applied multiple times" do
89
- klass = Class.new do
90
- def value
91
- @value ||= []
92
- end
93
-
94
- def test
95
- value << "test"
96
- end
97
- end
98
-
53
+ it "can be applied multiple times" do
99
54
  aspect = Aspector do
100
55
  before(:test) { value << 'before_test' }
101
56
  end
102
57
 
58
+ klass = create_test_class
103
59
  aspect.apply(klass)
104
60
  aspect.apply(klass)
105
61
 
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspects combined" do
4
+ it "should work" do
5
+ klass = create_test_class
6
+
7
+ aspector(klass) do
8
+ before :test do value << "do_before" end
9
+
10
+ after :test do value << "do_after" end
11
+
12
+ around :test do |&block|
13
+ value << "do_around_before"
14
+ result = block.call
15
+ value << "do_around_after"
16
+ result
17
+ end
18
+ end
19
+
20
+ aspector(klass) do
21
+ before :test do value << "do_before2" end
22
+
23
+ after :test do value << "do_after2" end
24
+
25
+ around :test do |&block|
26
+ value << "do_around_before2"
27
+ result = block.call
28
+ value << "do_around_after2"
29
+ result
30
+ end
31
+ end
32
+
33
+ obj = klass.new
34
+ obj.test
35
+ obj.value.should == %w"
36
+ do_before2 do_around_before2
37
+ do_before do_around_before
38
+ test
39
+ do_around_after do_after
40
+ do_around_after2 do_after2"
41
+ end
42
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspect execution order" do
4
+ it "should work" do
5
+ klass = create_test_class
6
+
7
+ aspector(klass) do
8
+ before :test do value << "do_before" end
9
+
10
+ after :test do value << "do_after" end
11
+
12
+ around :test do |&block|
13
+ value << "do_around_before"
14
+ result = block.call
15
+ value << "do_around_after"
16
+ result
17
+ end
18
+
19
+ before :test do value << "do_before2" end
20
+
21
+ after :test do value << "do_after2" end
22
+
23
+ around :test do |&block|
24
+ value << "do_around_before2"
25
+ result = block.call
26
+ value << "do_around_after2"
27
+ result
28
+ end
29
+ end
30
+
31
+ obj = klass.new
32
+ obj.test
33
+ obj.value.should == %w"do_before do_before2 do_around_before do_around_before2 test
34
+ do_around_after2 do_around_after do_after do_after2"
35
+ end
36
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,5 +8,20 @@ require 'aspector'
8
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
9
 
10
10
  RSpec.configure do |config|
11
- config.mock_with :mocha
12
11
  end
12
+
13
+ def create_test_class &block
14
+ klass = Class.new do
15
+ def value
16
+ @value ||= []
17
+ end
18
+
19
+ def test
20
+ value << "test"
21
+ end
22
+ end
23
+
24
+ klass.class_eval &block if block_given?
25
+ klass
26
+ end
27
+
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspector::Advice" do
4
+ end
@@ -2,15 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe "After advices" do
4
4
  it "should work" do
5
- klass = Class.new do
6
- def value
7
- @value ||= []
8
- end
9
-
10
- def test
11
- value << "test"
12
- end
13
-
5
+ klass = create_test_class do
14
6
  def do_this result
15
7
  value << "do_this"
16
8
  result
@@ -27,65 +19,76 @@ describe "After advices" do
27
19
  end
28
20
 
29
21
  it "context_arg" do
30
- klass = Class.new do
31
- def value
32
- @value ||= []
22
+ klass = create_test_class do
23
+ def do_this context, result
24
+ value << "do_this(#{context.method_name})"
25
+ result
33
26
  end
27
+ end
34
28
 
35
- def test
36
- value << "test"
37
- end
29
+ aspector(klass) do
30
+ after :test, :do_this, :context_arg => true
31
+ end
38
32
 
39
- def do_this context, result
40
- value << "do_this"
33
+ obj = klass.new
34
+ obj.test
35
+ obj.value.should == %w"test do_this(test)"
36
+ end
37
+
38
+ it "method_name_arg" do
39
+ klass = create_test_class do
40
+ def do_this method, result
41
+ value << "do_this(#{method})"
41
42
  result
42
43
  end
43
44
  end
44
45
 
45
46
  aspector(klass) do
46
- after :test, :do_this, :context_arg => true
47
+ after :test, :do_this, :method_name_arg => true
47
48
  end
48
49
 
49
50
  obj = klass.new
50
51
  obj.test
51
- obj.value.should == %w"test do_this"
52
+ obj.value.should == %w"test do_this(test)"
52
53
  end
53
54
 
54
- it "result_arg set to false" do
55
- klass = Class.new do
56
- def value
57
- @value ||= []
55
+ it "new result will be returned by default" do
56
+ klass = create_test_class
57
+
58
+ aspector(klass) do
59
+ after :test do |result|
60
+ value << "do_after"
61
+ 'do_after'
58
62
  end
63
+ end
59
64
 
65
+ obj = klass.new
66
+ obj.test.should == 'do_after'
67
+ obj.value.should == %w"test do_after"
68
+ end
69
+
70
+ it "result_arg set to false" do
71
+ klass = create_test_class do
60
72
  def test
61
73
  value << "test"
62
74
  'test'
63
75
  end
64
-
65
- def do_this
66
- value << "do_this"
67
- end
68
76
  end
69
77
 
70
78
  aspector(klass) do
71
- after :test, :do_this, :result_arg => false
79
+ after :test, :result_arg => false do
80
+ value << "do_after"
81
+ 'do_after'
82
+ end
72
83
  end
73
84
 
74
85
  obj = klass.new
75
86
  obj.test.should == 'test'
76
- obj.value.should == %w"test do_this"
87
+ obj.value.should == %w"test do_after"
77
88
  end
78
89
 
79
90
  it "logic in block" do
80
- klass = Class.new do
81
- def value
82
- @value ||= []
83
- end
84
-
85
- def test
86
- value << "test"
87
- end
88
- end
91
+ klass = create_test_class
89
92
 
90
93
  aspector(klass) do
91
94
  after(:test) do |result|
@@ -99,3 +102,4 @@ describe "After advices" do
99
102
  obj.value.should == %w"test do_block"
100
103
  end
101
104
  end
105
+
@@ -2,15 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe "Around advices" do
4
4
  it "should work" do
5
- klass = Class.new do
6
- def value
7
- @value ||= []
8
- end
9
-
10
- def test
11
- value << "test"
12
- end
13
-
5
+ klass = create_test_class do
14
6
  def do_this &block
15
7
  value << "before"
16
8
  result = block.call
@@ -29,15 +21,7 @@ describe "Around advices" do
29
21
  end
30
22
 
31
23
  it "logic in block" do
32
- klass = Class.new do
33
- def value
34
- @value ||= []
35
- end
36
-
37
- def test
38
- value << "test"
39
- end
40
- end
24
+ klass = create_test_class
41
25
 
42
26
  aspector(klass) do
43
27
  around :test do |&block|
@@ -52,4 +36,24 @@ describe "Around advices" do
52
36
  obj.test
53
37
  obj.value.should == %w"before test after"
54
38
  end
39
+
40
+ it "method_name_arg" do
41
+ klass = create_test_class do
42
+ def do_this method, &block
43
+ value << "before(#{method})"
44
+ result = block.call
45
+ value << "after(#{method})"
46
+ result
47
+ end
48
+ end
49
+
50
+ aspector(klass) do
51
+ around :test, :do_this, :method_name_arg => true
52
+ end
53
+
54
+ obj = klass.new
55
+ obj.test
56
+ obj.value.should == %w"before(test) test after(test)"
57
+ end
55
58
  end
59
+
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Aspector::Base class methods" do
4
+ it "before" do
5
+ klass = Class.new(Aspector::Base) do
6
+ before :test, :do_before
7
+ end
8
+
9
+ klass.advices.size.should == 1
10
+ advice = klass.advices.first
11
+ advice.before?.should be_true
12
+ advice.options[:skip_if_false].should_not be_true
13
+ advice.with_method.should == 'do_before'
14
+ end
15
+
16
+ it "before_filter" do
17
+ klass = Class.new(Aspector::Base) do
18
+ before_filter :test, :do_before
19
+ end
20
+
21
+ klass.advices.size.should == 1
22
+ advice = klass.advices.first
23
+ advice.before?.should be_true
24
+ advice.options[:skip_if_false].should be_true
25
+ advice.with_method.should == 'do_before'
26
+ end
27
+
28
+ end