rcapture 1.0.4
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.
- data/License +26 -0
- data/README +46 -0
- data/Rakefile +38 -0
- data/example/class_methods.rb +14 -0
- data/example/filter_method_calls.rb +24 -0
- data/example/hello_world.rb +35 -0
- data/example/inheritance.rb +36 -0
- data/example/modify_arguments.rb +39 -0
- data/example/multithreaded.rb +32 -0
- data/example/new_with_block.rb +30 -0
- data/example/no_endless_recursion.rb +16 -0
- data/rcapture.rb +19 -0
- data/rcapture/capture.rb +60 -0
- data/rcapture/capture_18x.rb +78 -0
- data/rcapture/capture_19x.rb +65 -0
- data/rcapture/capture_status.rb +53 -0
- data/rcapture/captured_info.rb +62 -0
- data/rcapture/interceptable.rb +93 -0
- data/rcapture/module_doc.rb +61 -0
- data/rcapture/singleton_class.rb +12 -0
- data/rcapture/symbol.rb +7 -0
- data/test/acceptance/acc_array.rb +36 -0
- data/test/acceptance/acc_inheritance.rb +61 -0
- data/test/acceptance/acc_modify_arguments.rb +50 -0
- data/test/acceptance/acc_new_with_block.rb +52 -0
- data/test/acceptance/acc_policies.rb +37 -0
- data/test/benchmark/benchmark_capture.rb +60 -0
- data/test/unit/test_capture_status.rb +66 -0
- data/test/unit/test_captured_info.rb +93 -0
- data/test/unit/test_method_with_blocks.rb +32 -0
- data/test/unit/test_modify_arguments.rb +99 -0
- data/test/unit/test_return_value.rb +38 -0
- data/test/unit/test_self_capture.rb +40 -0
- data/test/unit/test_singleton_vs_class.rb +37 -0
- data/test/unit/test_thread.rb +69 -0
- data/test/unit/test_visibility.rb +29 -0
- data/test/unit/testee.rb +27 -0
- metadata +108 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
include RCapture
|
10
|
+
|
11
|
+
class AcceptanceModifyArguments < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_pre
|
14
|
+
x = Array.new
|
15
|
+
x.extend(Interceptable)
|
16
|
+
x.capture_pre :methods => :<< do |ci|
|
17
|
+
ci.a[0] += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
x << 1 << 2
|
21
|
+
assert_equal([2, 3], x)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_pre_return
|
25
|
+
x = Array.new
|
26
|
+
x.extend(Interceptable)
|
27
|
+
x.capture_pre :methods => :<< do |ci|
|
28
|
+
ci.p = ci.s.length < 2
|
29
|
+
ci.r = ci.s
|
30
|
+
end
|
31
|
+
|
32
|
+
x << 1 << 2 << 3 << 4
|
33
|
+
assert_equal([1, 2], x)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_post_return
|
38
|
+
x = Array.new
|
39
|
+
x.extend(Interceptable)
|
40
|
+
x.capture_post :methods => :length do |ci|
|
41
|
+
ci.r -= 1
|
42
|
+
end
|
43
|
+
|
44
|
+
x << 1 << 2
|
45
|
+
assert_equal(1, x.length)
|
46
|
+
x << 1 << 2
|
47
|
+
assert_equal(3, x.length)
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
include RCapture
|
10
|
+
|
11
|
+
class X
|
12
|
+
include Interceptable
|
13
|
+
|
14
|
+
def initialize(name)
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def say_hello
|
19
|
+
puts "Hello, #{@name}!"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Y < X
|
24
|
+
def initialize
|
25
|
+
super("y")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class AcceptanceNewWithBlock < Test::Unit::TestCase
|
30
|
+
|
31
|
+
def test_new_with_block
|
32
|
+
|
33
|
+
X.capture_post :class_methods => :new do |ci|
|
34
|
+
ci.b.call(ci.r) if ci.b
|
35
|
+
end
|
36
|
+
|
37
|
+
x = X.new("as")
|
38
|
+
assert_instance_of(X, x)
|
39
|
+
|
40
|
+
X.new("christoph") do |x|
|
41
|
+
assert_instance_of(X, x)
|
42
|
+
x.say_hello
|
43
|
+
end
|
44
|
+
|
45
|
+
Y.new do |y|
|
46
|
+
assert_instance_of(Y, y)
|
47
|
+
y.say_hello
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
include RCapture
|
10
|
+
|
11
|
+
class Fixnum
|
12
|
+
include Interceptable
|
13
|
+
end
|
14
|
+
|
15
|
+
class AcceptancePolicies < Test::Unit::TestCase
|
16
|
+
|
17
|
+
def test_clamping_policy
|
18
|
+
|
19
|
+
min = 0
|
20
|
+
max = 1
|
21
|
+
clamp_policy = Proc.new do |ci|
|
22
|
+
ci.a.collect! do |v|
|
23
|
+
if v.instance_of?(Fixnum)
|
24
|
+
(v < min) ? min : ((v > max) ? max : v)
|
25
|
+
else
|
26
|
+
v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Fixnum.capture_pre :methods => [:+,:-], &clamp_policy
|
32
|
+
|
33
|
+
assert_equal(1, 0+1)
|
34
|
+
assert_equal(1, 0+4)
|
35
|
+
assert_equal(2, 0+4+2-30+3)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'test/unit/testee'
|
3
|
+
require 'benchmark'
|
4
|
+
require 'rcapture'
|
5
|
+
|
6
|
+
class Fixnum
|
7
|
+
include RCapture::Interceptable
|
8
|
+
end
|
9
|
+
|
10
|
+
class BenchmarkCapture < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def test_benchmark_native
|
13
|
+
n = 100000
|
14
|
+
puts "Benchmarking addition"
|
15
|
+
Benchmark.bm do |x|
|
16
|
+
x.report { n.times do; 1+1; end }
|
17
|
+
Fixnum.capture :methods => :+ do
|
18
|
+
end
|
19
|
+
x.report { n.times do; 1+1; end }
|
20
|
+
end
|
21
|
+
|
22
|
+
# On my machine Intel Q6600, 2.4GHz
|
23
|
+
#
|
24
|
+
# Ruby 1.8.6
|
25
|
+
# user system total real
|
26
|
+
# 0.015000 0.000000 0.015000 ( 0.027000)
|
27
|
+
# 1.610000 0.000000 1.610000 ( 1.629000)
|
28
|
+
# overhead is roughly 0,00001602 secs per invocation
|
29
|
+
#
|
30
|
+
# Ruby 1.9.1
|
31
|
+
# user system total real
|
32
|
+
# 0.000000 0.000000 0.000000 ( 0.009765)
|
33
|
+
# 0.359000 0.000000 0.359000 ( 0.356446)
|
34
|
+
# overhead is roughly 0,0000034 secs per invocation
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_benchmark_construct
|
38
|
+
n = 100000
|
39
|
+
puts "Benchmarking construction of new objects"
|
40
|
+
Benchmark.bm do |x|
|
41
|
+
x.report { n.times do; Testee.new; end }
|
42
|
+
Testee.capture :class_methods => :new do
|
43
|
+
end
|
44
|
+
x.report { n.times do; Testee.new; end }
|
45
|
+
end
|
46
|
+
|
47
|
+
# On my machine Intel Q6600, 2.4GHz
|
48
|
+
#
|
49
|
+
# user system total real
|
50
|
+
# 0.188000 0.000000 0.188000 ( 0.208000)
|
51
|
+
# 1.812000 0.000000 1.812000 ( 1.836000)
|
52
|
+
# overhead is roughly 0,00001628 secs per invocation
|
53
|
+
#
|
54
|
+
# Ruby 1.9.1
|
55
|
+
# user system total real
|
56
|
+
# 0.047000 0.000000 0.047000 ( 0.051757)
|
57
|
+
# 0.422000 0.000000 0.422000 ( 0.408203)
|
58
|
+
# overhead is roughly 0,00000357 secs per invocation
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'thread'
|
9
|
+
require 'rcapture'
|
10
|
+
include RCapture
|
11
|
+
|
12
|
+
class TestCaptureStatus < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def test_status
|
15
|
+
s = CaptureStatus.new(true)
|
16
|
+
assert(s.on?)
|
17
|
+
s.set(true); assert(s.on?)
|
18
|
+
s.set(true); assert(s.on?)
|
19
|
+
s.set(false); assert(s.off?)
|
20
|
+
s.set(false); assert(s.off?)
|
21
|
+
s.restore; assert(s.off?)
|
22
|
+
s.restore; assert(s.on?)
|
23
|
+
s.restore; assert(s.on?)
|
24
|
+
s.restore; assert(s.on?)
|
25
|
+
s.restore; assert(s.on?)
|
26
|
+
end
|
27
|
+
|
28
|
+
def calc(status)
|
29
|
+
return true if status.on?
|
30
|
+
return false if status.off?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_scope
|
34
|
+
s = CaptureStatus.new(true)
|
35
|
+
ret = s.use(false) do
|
36
|
+
self.calc(s)
|
37
|
+
end
|
38
|
+
assert(!ret)
|
39
|
+
assert(self.calc(s))
|
40
|
+
ret = s.use(true) do
|
41
|
+
self.calc(s)
|
42
|
+
end
|
43
|
+
assert(ret)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_thread_local
|
47
|
+
a_cs = nil
|
48
|
+
a_cs2 = nil
|
49
|
+
b_cs = nil
|
50
|
+
|
51
|
+
a = Thread.new do
|
52
|
+
a_cs = CaptureStatus.current
|
53
|
+
a_cs2 = CaptureStatus.current
|
54
|
+
end
|
55
|
+
|
56
|
+
b = Thread.new do
|
57
|
+
b_cs = CaptureStatus.current
|
58
|
+
end
|
59
|
+
|
60
|
+
a.join
|
61
|
+
b.join
|
62
|
+
|
63
|
+
assert_same(a_cs, a_cs2)
|
64
|
+
assert_not_same(a_cs, b_cs)
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
include RCapture
|
10
|
+
|
11
|
+
class TestCapturedInfo < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_info
|
14
|
+
ci = CapturedInfo.new
|
15
|
+
ci.fill([1,2], self, :test_info)
|
16
|
+
|
17
|
+
assert_equal([1,2], ci.args)
|
18
|
+
assert_same(self, ci.sender)
|
19
|
+
assert_same(:test_info, ci.method)
|
20
|
+
assert_equal(nil, ci.block)
|
21
|
+
assert_equal(nil, ci.return)
|
22
|
+
assert(ci.predicate)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_aliases
|
26
|
+
ci = CapturedInfo.new
|
27
|
+
ci.fill([1,2], self, :test_info)
|
28
|
+
|
29
|
+
assert_equal([1,2], ci.a)
|
30
|
+
assert_same(self, ci.s)
|
31
|
+
assert_same(:test_info, ci.m)
|
32
|
+
assert_equal(nil, ci.b)
|
33
|
+
assert_equal(nil, ci.r)
|
34
|
+
assert(ci.p)
|
35
|
+
|
36
|
+
ci.r = 4
|
37
|
+
ci.p = false
|
38
|
+
|
39
|
+
assert_equal(4, ci.r)
|
40
|
+
assert(!ci.p)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_pre_capture
|
44
|
+
a = []
|
45
|
+
a.extend(Interceptable)
|
46
|
+
a.capture_pre :methods => :<< do |cs|
|
47
|
+
assert_equal([1], cs.a)
|
48
|
+
assert_same(a, cs.s)
|
49
|
+
assert_same(:<<, cs.m)
|
50
|
+
assert_nil(cs.b)
|
51
|
+
assert(cs.p)
|
52
|
+
assert_nil(cs.r)
|
53
|
+
cs.r = :ok
|
54
|
+
cs.p = false
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal(:ok, a << 1)
|
58
|
+
assert_equal([], a)
|
59
|
+
|
60
|
+
proc = Proc.new do |v|
|
61
|
+
end
|
62
|
+
|
63
|
+
a.capture_pre :methods => :each do |cs|
|
64
|
+
assert_same(proc, cs.b)
|
65
|
+
end
|
66
|
+
a.each &proc
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_post_capture
|
70
|
+
a = []
|
71
|
+
a.extend(Interceptable)
|
72
|
+
a.capture_post :methods => :<< do |cs|
|
73
|
+
assert_equal([1], cs.a)
|
74
|
+
assert_same(a, cs.s)
|
75
|
+
assert_same(:<<, cs.m)
|
76
|
+
assert_same(a, cs.r)
|
77
|
+
assert_nil(cs.b)
|
78
|
+
assert(cs.p)
|
79
|
+
cs.r = :ok
|
80
|
+
end
|
81
|
+
|
82
|
+
assert_equal(:ok, a << 1)
|
83
|
+
assert_equal([1], a)
|
84
|
+
|
85
|
+
proc = Proc.new do |v|
|
86
|
+
end
|
87
|
+
|
88
|
+
a.capture_pre :methods => :each do |cs|
|
89
|
+
assert_same(proc, cs.b)
|
90
|
+
end
|
91
|
+
a.each &proc
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
|
10
|
+
class Array
|
11
|
+
include RCapture::Interceptable
|
12
|
+
end
|
13
|
+
|
14
|
+
class TestMethodWithBlocks < Test::Unit::TestCase
|
15
|
+
|
16
|
+
def test_array
|
17
|
+
count = 0
|
18
|
+
Array.capture :methods => :each do
|
19
|
+
count += 1
|
20
|
+
end
|
21
|
+
|
22
|
+
x = []
|
23
|
+
x << 1 << 2
|
24
|
+
sum = 0
|
25
|
+
x.each do |v|
|
26
|
+
sum += v
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_equal(1, count)
|
30
|
+
assert_equal(3, sum)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#
|
2
|
+
# (c) Christoph Heindl, 2010
|
3
|
+
# http://cheind.wordpress.com
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require 'rcapture'
|
9
|
+
|
10
|
+
class TestModifyArguments < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def test_capture_pre
|
13
|
+
x = []
|
14
|
+
x.extend(RCapture::Interceptable)
|
15
|
+
|
16
|
+
inc = Proc.new do |ci|
|
17
|
+
ci.a[0] += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
dec = Proc.new do |ci|
|
21
|
+
ci.a[0] -= 1
|
22
|
+
end
|
23
|
+
|
24
|
+
mul = Proc.new do |ci|
|
25
|
+
ci.a[0] *= 2
|
26
|
+
end
|
27
|
+
|
28
|
+
x.capture_pre :methods => :<<, &inc
|
29
|
+
x.capture_pre :methods => :<<, &mul
|
30
|
+
x.capture_pre :methods => :<<, &inc
|
31
|
+
x.capture_pre :methods => :<<, &dec
|
32
|
+
x.capture_pre :methods => :<<, &dec
|
33
|
+
|
34
|
+
x << 2 << 4
|
35
|
+
assert_equal([3,7], x)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_capture_post
|
39
|
+
x = []
|
40
|
+
x.extend(RCapture::Interceptable)
|
41
|
+
|
42
|
+
inc = Proc.new do |ci|
|
43
|
+
ci.r += 1
|
44
|
+
end
|
45
|
+
|
46
|
+
dec = Proc.new do |ci|
|
47
|
+
ci.r -= 1
|
48
|
+
end
|
49
|
+
|
50
|
+
mul = Proc.new do |ci|
|
51
|
+
ci.r *= 2
|
52
|
+
end
|
53
|
+
|
54
|
+
x.capture_post :methods => :[], &inc
|
55
|
+
x.capture_post :methods => :[], &mul
|
56
|
+
x.capture_post :methods => :[], &inc
|
57
|
+
x.capture_post :methods => :[], &dec
|
58
|
+
x.capture_post :methods => :[], &dec
|
59
|
+
|
60
|
+
x << 1 << 4
|
61
|
+
|
62
|
+
assert_equal(3, x[0])
|
63
|
+
assert_equal(9, x[1])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_capture_pre_post
|
67
|
+
x = []
|
68
|
+
x.extend(RCapture::Interceptable)
|
69
|
+
|
70
|
+
inc = Proc.new do |ci|
|
71
|
+
ci.a[0] += 1
|
72
|
+
end
|
73
|
+
|
74
|
+
mul = Proc.new do |ci|
|
75
|
+
ci.r *= 2
|
76
|
+
end
|
77
|
+
|
78
|
+
x.capture_pre :methods => :<<, &inc
|
79
|
+
x.capture_post :methods => :[], &mul
|
80
|
+
|
81
|
+
x << 2 << 7
|
82
|
+
assert_equal(6, x[0])
|
83
|
+
assert_equal(16, x[1])
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_capture_pre_return
|
87
|
+
x = []
|
88
|
+
x.extend(RCapture::Interceptable)
|
89
|
+
|
90
|
+
filter = Proc.new do |ci|
|
91
|
+
ci.r = ci.s
|
92
|
+
ci.p = ci.a[0] % 2 == 0
|
93
|
+
end
|
94
|
+
|
95
|
+
x.capture_pre :methods => :<<, &filter
|
96
|
+
x << 2 << 8 << 7 << 6 << 5
|
97
|
+
assert_equal([2,8,6], x)
|
98
|
+
end
|
99
|
+
end
|