aspector 0.13.1 → 0.14.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 +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +26 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -11
- data/Changelog.md +59 -0
- data/Gemfile +9 -14
- data/Gemfile.lock +84 -50
- data/README.md +118 -0
- data/Rakefile +6 -22
- data/aspector.gemspec +15 -127
- data/benchmarks/after_benchmark.rb +28 -0
- data/benchmarks/around_advice_benchmark.rb +35 -0
- data/benchmarks/around_benchmark.rb +32 -0
- data/benchmarks/before_benchmark.rb +28 -0
- data/benchmarks/benchmark_helper.rb +17 -0
- data/benchmarks/combined_benchmark.rb +36 -0
- data/benchmarks/method_invocation_benchmark.rb +30 -0
- data/benchmarks/raw_benchmark.rb +39 -0
- data/examples/activerecord_hooks.rb +10 -15
- data/examples/around_example.rb +20 -31
- data/examples/aspector_apply_example.rb +10 -17
- data/examples/aspector_example.rb +7 -16
- data/examples/cache_aspect.rb +20 -30
- data/examples/design_by_contract.rb +20 -44
- data/examples/exception_handler.rb +12 -20
- data/examples/exception_handler2.rb +16 -24
- data/examples/implicit_method_option_test.rb +8 -16
- data/examples/interception_options_example.rb +71 -0
- data/examples/logging_aspect.rb +16 -24
- data/examples/process_aspector.rb +13 -0
- data/examples/retry_aspect.rb +20 -20
- data/lib/aspector.rb +17 -15
- data/lib/aspector/advice.rb +44 -57
- data/lib/aspector/advice_metadata.rb +10 -11
- data/lib/aspector/aspect_instances.rb +2 -3
- data/lib/aspector/base.rb +6 -368
- data/lib/aspector/base_class_methods.rb +24 -55
- data/lib/aspector/deferred_logic.rb +3 -4
- data/lib/aspector/deferred_option.rb +5 -10
- data/lib/aspector/interception.rb +356 -0
- data/lib/aspector/logger.rb +18 -45
- data/lib/aspector/logging.rb +10 -29
- data/lib/aspector/method_matcher.rb +5 -6
- data/lib/aspector/object_extension.rb +4 -12
- data/lib/aspector/version.rb +3 -0
- data/spec/examples_spec.rb +59 -0
- data/spec/functionals/aspect_for_multiple_targets_spec.rb +54 -0
- data/spec/functionals/aspect_interception_options_accessing_spec.rb +112 -0
- data/spec/functionals/aspect_on_a_class_spec.rb +159 -0
- data/spec/functionals/aspect_on_an_instance_spec.rb +66 -0
- data/spec/functionals/aspector_spec.rb +138 -0
- data/spec/functionals/aspects_combined_spec.rb +37 -0
- data/spec/functionals/aspects_execution_order_spec.rb +61 -0
- data/spec/functionals/aspects_on_private_methods_spec.rb +82 -0
- data/spec/spec_helper.rb +20 -21
- data/spec/support/class_builder.rb +44 -0
- data/spec/units/advice_spec.rb +49 -0
- data/spec/units/advices/after_spec.rb +328 -0
- data/spec/units/advices/around_spec.rb +336 -0
- data/spec/units/advices/before_filter_spec.rb +287 -0
- data/spec/units/advices/before_spec.rb +237 -0
- data/spec/units/advices/raw_spec.rb +67 -0
- data/spec/units/base_class_methods_spec.rb +262 -0
- data/spec/units/base_spec.rb +133 -0
- data/spec/units/deferred_logic_spec.rb +35 -0
- data/spec/units/logger_spec.rb +20 -0
- data/spec/units/logging_spec.rb +85 -0
- data/spec/units/method_matcher_spec.rb +95 -0
- data/spec/units/object_extension_spec.rb +11 -0
- data/spec/units/special_chars_spec.rb +128 -0
- metadata +98 -246
- data/.document +0 -5
- data/.rvmrc +0 -8
- data/README.rdoc +0 -80
- data/VERSION +0 -1
- data/performance-tests/after_test.rb +0 -25
- data/performance-tests/around_advice_benchmark.rb +0 -66
- data/performance-tests/around_test.rb +0 -27
- data/performance-tests/before_test.rb +0 -25
- data/performance-tests/combined_test.rb +0 -33
- data/performance-tests/method_invocation_test.rb +0 -25
- data/performance-tests/raw_test.rb +0 -37
- data/performance-tests/test_helper.rb +0 -9
- data/run_all_examples.sh +0 -12
- data/spec/functional/advices_on_private_methods_spec.rb +0 -21
- data/spec/functional/aspect_on_eigen_class_spec.rb +0 -72
- data/spec/functional/aspect_on_object_spec.rb +0 -20
- data/spec/functional/aspector_spec.rb +0 -140
- data/spec/functional/aspects_combined_spec.rb +0 -48
- data/spec/functional/execution_order_spec.rb +0 -42
- data/spec/unit/advice_spec.rb +0 -4
- data/spec/unit/after_spec.rb +0 -88
- data/spec/unit/around_spec.rb +0 -76
- data/spec/unit/base_class_methods_spec.rb +0 -28
- data/spec/unit/base_spec.rb +0 -112
- data/spec/unit/before_spec.rb +0 -125
- data/spec/unit/deferred_logic_spec.rb +0 -23
- data/spec/unit/method_matcher_spec.rb +0 -43
- data/spec/unit/raw_spec.rb +0 -53
- data/spec/unit/special_chars_spec.rb +0 -122
data/lib/aspector/logger.rb
CHANGED
@@ -1,63 +1,36 @@
|
|
1
1
|
module Aspector
|
2
|
-
|
3
|
-
|
2
|
+
# Default logger for Aspector
|
3
|
+
# @note It uses ::Logger features - providing basic logging
|
4
|
+
class Logger < ::Logger
|
4
5
|
attr_reader :context
|
5
|
-
attr_accessor :level
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize(context)
|
8
|
+
super(STDOUT)
|
8
9
|
@context = context
|
9
|
-
|
10
|
-
if (level_string = ENV['ASPECTOR_LOG_LEVEL'])
|
11
|
-
@level = string_to_level(level_string)
|
12
|
-
else
|
13
|
-
@level = Logging::DEFAULT_VISIBLE_LEVEL
|
14
|
-
end
|
10
|
+
@level = (ENV['ASPECTOR_LOG_LEVEL'] || ::Logger::ERROR).to_i
|
15
11
|
end
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def visible? level
|
24
|
-
self.level <= level
|
13
|
+
%i( debug info warn error fatal ).each do |level|
|
14
|
+
define_method level do |*args|
|
15
|
+
super(nil) { postfix(*args) }
|
16
|
+
end
|
25
17
|
end
|
26
18
|
|
27
19
|
private
|
28
20
|
|
29
|
-
def
|
30
|
-
|
21
|
+
def postfix(*args)
|
22
|
+
msg = []
|
23
|
+
|
31
24
|
if context.is_a? Aspector::Base
|
32
|
-
|
25
|
+
msg << context.class.to_s
|
26
|
+
msg << context.target.to_s
|
33
27
|
else
|
34
|
-
|
28
|
+
msg << context.to_s
|
35
29
|
end
|
36
|
-
end
|
37
30
|
|
38
|
-
|
39
|
-
case level
|
40
|
-
when Logging::ERROR then "ERROR"
|
41
|
-
when Logging::WARN then "WARN "
|
42
|
-
when Logging::INFO then "INFO "
|
43
|
-
when Logging::DEBUG then "DEBUG"
|
44
|
-
when Logging::TRACE then "TRACE"
|
45
|
-
else level.to_s
|
46
|
-
end
|
47
|
-
end
|
31
|
+
msg += args
|
48
32
|
|
49
|
-
|
50
|
-
return Logging::DEFAULT_VISIBLE_LEVEL if level_string.nil? or level_string.strip == ''
|
51
|
-
|
52
|
-
case level_string.downcase
|
53
|
-
when 'error' then Logging::ERROR
|
54
|
-
when 'warn' then Logging::WARN
|
55
|
-
when 'info' then Logging::INFO
|
56
|
-
when 'debug' then Logging::DEBUG
|
57
|
-
when 'trace' then Logging::TRACE
|
58
|
-
when 'none' then Logging::NONE
|
59
|
-
end
|
33
|
+
msg.join(' | ')
|
60
34
|
end
|
61
35
|
end
|
62
36
|
end
|
63
|
-
|
data/lib/aspector/logging.rb
CHANGED
@@ -1,38 +1,19 @@
|
|
1
1
|
module Aspector
|
2
|
+
# Class used as a wrapper to get logging instances
|
2
3
|
module Logging
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
WARN = 40
|
7
|
-
INFO = 30
|
8
|
-
DEBUG = 20
|
9
|
-
TRACE = 10
|
10
|
-
|
11
|
-
DEFAULT_VISIBLE_LEVEL = INFO
|
12
|
-
|
13
|
-
def self.get_logger context
|
14
|
-
if logger_class_name = ENV["ASPECTOR_LOGGER"]
|
15
|
-
begin
|
16
|
-
logger_class = constanize(logger_class_name)
|
17
|
-
logger_class.new(context)
|
18
|
-
rescue => e
|
19
|
-
$stderr.puts e.message
|
20
|
-
|
21
|
-
Logger.new(context)
|
22
|
-
end
|
23
|
-
else
|
24
|
-
Logger.new(context)
|
4
|
+
class << self
|
5
|
+
def get_logger(context)
|
6
|
+
(deconstantize(ENV['ASPECTOR_LOGGER'] || 'Aspector::Logger')).new(context)
|
25
7
|
end
|
26
|
-
end
|
27
8
|
|
28
|
-
|
9
|
+
private
|
29
10
|
|
30
|
-
|
31
|
-
|
32
|
-
|
11
|
+
def deconstantize(klass_name)
|
12
|
+
Object.const_get(klass_name.to_s)
|
13
|
+
rescue NameError
|
14
|
+
$stderr.puts "#{klass_name} is not a valid constant name!"
|
15
|
+
Aspector::Logger
|
33
16
|
end
|
34
|
-
|
35
|
-
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
36
17
|
end
|
37
18
|
end
|
38
19
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Aspector
|
2
2
|
class MethodMatcher
|
3
|
-
def initialize
|
3
|
+
def initialize(*match_data)
|
4
4
|
@match_data = match_data
|
5
5
|
@match_data.flatten!
|
6
6
|
end
|
7
7
|
|
8
|
-
def match?
|
8
|
+
def match?(method, aspect = nil)
|
9
9
|
@match_data.detect do |item|
|
10
10
|
case item
|
11
11
|
when String
|
@@ -29,16 +29,15 @@ module Aspector
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
33
|
-
def use_deferred_logic?
|
32
|
+
|
33
|
+
def use_deferred_logic?(logic)
|
34
34
|
@match_data.detect do |item|
|
35
35
|
logic == item
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def to_s
|
40
|
-
@match_data.map
|
40
|
+
@match_data.map(&:inspect).join(', ')
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
@@ -1,33 +1,25 @@
|
|
1
1
|
module Aspector
|
2
2
|
module ObjectExtension
|
3
|
-
|
4
3
|
private
|
5
4
|
|
6
|
-
def aspector
|
5
|
+
def aspector(*args, &block)
|
7
6
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
8
7
|
|
9
8
|
aspect = Aspector(options, &block)
|
10
9
|
|
11
10
|
aspect.apply(self) if self.is_a? Module
|
12
|
-
args.each {|target| aspect.apply(target) }
|
11
|
+
args.each { |target| aspect.apply(target) }
|
13
12
|
|
14
13
|
aspect
|
15
14
|
end
|
16
15
|
|
17
|
-
def Aspector
|
16
|
+
def Aspector(options = {}, &block)
|
18
17
|
klass = Class.new(Aspector::Base)
|
19
18
|
klass.class_eval { default options }
|
20
|
-
klass.class_eval
|
19
|
+
klass.class_eval(&block) if block_given?
|
21
20
|
klass
|
22
21
|
end
|
23
|
-
|
24
|
-
def returns value = nil
|
25
|
-
throw :returns, value
|
26
|
-
end
|
27
|
-
alias :returns :returns
|
28
|
-
|
29
22
|
end
|
30
23
|
end
|
31
24
|
|
32
25
|
Object.send(:include, Aspector::ObjectExtension)
|
33
|
-
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# This spec will execute all the examples to check if they are working
|
2
|
+
# By default all of them should work just fine
|
3
|
+
# Note that it won't check if the aspector works in examples as it should
|
4
|
+
# This is covered in unit and functional specs - here we check that all examples run
|
5
|
+
# without problems
|
6
|
+
|
7
|
+
require 'spec_helper'
|
8
|
+
require 'stringio'
|
9
|
+
|
10
|
+
# Kernel
|
11
|
+
module Kernel
|
12
|
+
# Method used to catch the STDIO from all the examples
|
13
|
+
# Examples by default print some stuff to the output - we don't want that
|
14
|
+
# in our specs, thats why we catch it
|
15
|
+
# We're only interested if all examples work as they should (without any errors)
|
16
|
+
def capture_stdout
|
17
|
+
out = StringIO.new
|
18
|
+
$stdout = out
|
19
|
+
yield
|
20
|
+
out
|
21
|
+
ensure
|
22
|
+
$stdout = STDOUT
|
23
|
+
end
|
24
|
+
|
25
|
+
# Same as capture_stdout but to silence stderr
|
26
|
+
def capture_stderr
|
27
|
+
out = StringIO.new
|
28
|
+
$stderr = out
|
29
|
+
yield
|
30
|
+
out
|
31
|
+
ensure
|
32
|
+
$stderr = STDOUT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec.describe 'Aspector examples' do
|
37
|
+
Dir.glob(
|
38
|
+
File.join(
|
39
|
+
File.dirname(__FILE__),
|
40
|
+
'..',
|
41
|
+
'examples/*.rb'
|
42
|
+
)
|
43
|
+
).each do |example_file|
|
44
|
+
context "examples file: #{example_file}" do
|
45
|
+
it 'should run without any errors' do
|
46
|
+
capture_stdout do
|
47
|
+
capture_stderr do
|
48
|
+
Process.fork do
|
49
|
+
require example_file
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
_pid, status = Process.wait2
|
55
|
+
expect(status.exitstatus).to eq 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Aspector do
|
4
|
+
let(:klass1) do
|
5
|
+
ClassBuilder.build do
|
6
|
+
def exec1
|
7
|
+
values << 'exec1'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:klass2) do
|
13
|
+
ClassBuilder.build do
|
14
|
+
def exec2
|
15
|
+
values << 'exec2'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:instance1) { klass1.new }
|
21
|
+
let(:instance2) { klass2.new }
|
22
|
+
|
23
|
+
let(:aspect_klass) do
|
24
|
+
ClassBuilder.inherit(Aspector::Base) do
|
25
|
+
attr_accessor :call_count
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@call_count = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
before interception_arg: true do |interception|
|
32
|
+
interception.aspect.call_count += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:aspect) { aspect_klass.new }
|
38
|
+
|
39
|
+
context 'binding single aspect to multiple different targets' do
|
40
|
+
before do
|
41
|
+
aspect.apply klass1, method: :exec1
|
42
|
+
aspect.apply klass2, methods: %w( exec2 )
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should work' do
|
46
|
+
instance1.exec1
|
47
|
+
instance2.exec2
|
48
|
+
|
49
|
+
expect(aspect.call_count).to eq 2
|
50
|
+
expect(instance1.values).to eq %w( exec1 )
|
51
|
+
expect(instance2.values).to eq %w( exec2 )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'Aspector options access' do
|
4
|
+
subject { klass.new }
|
5
|
+
let(:interception_options) { { rand => rand } }
|
6
|
+
|
7
|
+
context 'accessing interception options' do
|
8
|
+
let(:klass) do
|
9
|
+
ClassBuilder.build do
|
10
|
+
attr_accessor :interception_options
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
aspect.apply klass, interception_options.merge(method: :exec)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'before aspect' do
|
19
|
+
let(:aspect) do
|
20
|
+
ClassBuilder.inherit(Aspector::Base) do
|
21
|
+
default aspect_field: 60
|
22
|
+
|
23
|
+
before interception_arg: true do |interception|
|
24
|
+
self.interception_options = interception.options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should be able to reach interception options that were merged with aspect options' do
|
30
|
+
subject.exec
|
31
|
+
expected = interception_options.merge(method: :exec).merge(aspect_field: 60)
|
32
|
+
expect(subject.interception_options).to eq expected
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'still should exec original method' do
|
36
|
+
subject.exec
|
37
|
+
expect(subject.values).to eq %w( exec-result )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'before_filter aspect' do
|
42
|
+
let(:aspect) do
|
43
|
+
ClassBuilder.inherit(Aspector::Base) do
|
44
|
+
default aspect_field: 60
|
45
|
+
|
46
|
+
before_filter interception_arg: true do |interception|
|
47
|
+
self.interception_options = interception.options
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should be able to reach interception options that were merged with aspect options' do
|
53
|
+
subject.exec
|
54
|
+
expected = interception_options.merge(method: :exec).merge(aspect_field: 60)
|
55
|
+
expect(subject.interception_options).to eq expected
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'still should exec original method' do
|
59
|
+
subject.exec
|
60
|
+
expect(subject.values).to eq %w( exec-result )
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'around aspect' do
|
65
|
+
let(:aspect) do
|
66
|
+
ClassBuilder.inherit(Aspector::Base) do
|
67
|
+
default aspect_field: 60
|
68
|
+
|
69
|
+
around interception_arg: true do |interception, proxy, &block|
|
70
|
+
self.interception_options = interception.options
|
71
|
+
proxy.call(&block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should be able to reach interception options that were merged with aspect options' do
|
77
|
+
subject.exec
|
78
|
+
expected = interception_options.merge(method: :exec).merge(aspect_field: 60)
|
79
|
+
expect(subject.interception_options).to eq expected
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'still should exec original method' do
|
83
|
+
subject.exec
|
84
|
+
expect(subject.values).to eq %w( exec-result )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'after aspect' do
|
89
|
+
let(:aspect) do
|
90
|
+
ClassBuilder.inherit(Aspector::Base) do
|
91
|
+
default aspect_field: 60
|
92
|
+
|
93
|
+
after interception_arg: true do |interception, result|
|
94
|
+
self.interception_options = interception.options
|
95
|
+
result
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should be able to reach interception options that were merged with aspect options' do
|
101
|
+
subject.exec
|
102
|
+
expected = interception_options.merge(method: :exec).merge(aspect_field: 60)
|
103
|
+
expect(subject.interception_options).to eq expected
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'still should exec original method' do
|
107
|
+
subject.exec
|
108
|
+
expect(subject.values).to eq %w( exec-result )
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'Aspector for a class' do
|
4
|
+
context 'public class methods' do
|
5
|
+
subject do
|
6
|
+
ClassBuilder.build do
|
7
|
+
class << self
|
8
|
+
def values
|
9
|
+
@values ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def exec
|
13
|
+
values << 'class-exec-result'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'before aspect' do
|
20
|
+
before do
|
21
|
+
aspector(subject, class_methods: true) do
|
22
|
+
before :exec do
|
23
|
+
values << 'class-exec-before'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should work' do
|
29
|
+
subject.exec
|
30
|
+
expect(subject.values).to eq %w( class-exec-before class-exec-result )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'around aspect' do
|
35
|
+
before do
|
36
|
+
aspector(subject, class_methods: true) do
|
37
|
+
around :exec do |proxy, &block|
|
38
|
+
values << 'class-exec-around-before'
|
39
|
+
result = proxy.call(&block)
|
40
|
+
values << 'class-exec-around-after'
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should work' do
|
47
|
+
expected = %w( class-exec-around-before class-exec-result class-exec-around-after )
|
48
|
+
subject.exec
|
49
|
+
expect(subject.values).to eq expected
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'after aspect' do
|
54
|
+
before do
|
55
|
+
aspector(subject, class_methods: true) do
|
56
|
+
after :exec do |result|
|
57
|
+
values << 'class-exec-after'
|
58
|
+
result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should work' do
|
64
|
+
subject.exec
|
65
|
+
expect(subject.values).to eq %w( class-exec-result class-exec-after )
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'private class methods' do
|
71
|
+
subject do
|
72
|
+
ClassBuilder.build do
|
73
|
+
class << self
|
74
|
+
def values
|
75
|
+
@values ||= []
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def exec
|
81
|
+
values << 'class-exec-result'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'before aspect' do
|
88
|
+
before do
|
89
|
+
aspector(subject, class_methods: true) do
|
90
|
+
before :exec do
|
91
|
+
values << 'class-exec-before(public_methods_only)'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
aspector(subject, class_methods: true, private_methods: true) do
|
96
|
+
before :exec do
|
97
|
+
values << 'class-exec-before'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should work' do
|
103
|
+
subject.send(:exec)
|
104
|
+
expect(subject.values).to eq %w( class-exec-before class-exec-result )
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'around aspect' do
|
109
|
+
before do
|
110
|
+
aspector(subject, class_methods: true) do
|
111
|
+
around :exec do |proxy, &block|
|
112
|
+
values << 'class-exec-around-before(public_methods_only)'
|
113
|
+
result = proxy.call(&block)
|
114
|
+
values << 'class-exec-around-after(public_methods_only)'
|
115
|
+
result
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
aspector(subject, class_methods: true, private_methods: true) do
|
120
|
+
around :exec do |proxy, &block|
|
121
|
+
values << 'class-exec-around-before'
|
122
|
+
result = proxy.call(&block)
|
123
|
+
values << 'class-exec-around-after'
|
124
|
+
result
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should work' do
|
130
|
+
expected = %w( class-exec-around-before class-exec-result class-exec-around-after )
|
131
|
+
subject.send(:exec)
|
132
|
+
expect(subject.values).to eq expected
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'after aspect' do
|
137
|
+
before do
|
138
|
+
aspector(subject, class_methods: true) do
|
139
|
+
after :exec do |result|
|
140
|
+
values << 'class-exec-after(public_methods_only)'
|
141
|
+
result
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
aspector(subject, class_methods: true, private_methods: true) do
|
146
|
+
after :exec do |result|
|
147
|
+
values << 'class-exec-after'
|
148
|
+
result
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should work' do
|
154
|
+
subject.send(:exec)
|
155
|
+
expect(subject.values).to eq %w( class-exec-result class-exec-after )
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|