serializable_proc 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/HISTORY.txt +9 -0
- data/README.rdoc +28 -10
- data/VERSION +1 -1
- data/lib/serializable_proc/binding.rb +27 -32
- data/lib/serializable_proc/fixes.rb +1 -1
- data/lib/serializable_proc/isolatable.rb +59 -0
- data/lib/serializable_proc/parsers/pt.rb +2 -5
- data/lib/serializable_proc/parsers/rp.rb +29 -29
- data/lib/serializable_proc/parsers.rb +22 -0
- data/lib/serializable_proc.rb +76 -10
- data/serializable_proc.gemspec +51 -21
- data/spec/bounded_vars/class_vars_spec.rb +60 -0
- data/spec/bounded_vars/class_vars_within_block_scope_spec.rb +31 -0
- data/spec/bounded_vars/errors_spec.rb +27 -0
- data/spec/bounded_vars/global_vars_spec.rb +60 -0
- data/spec/bounded_vars/global_vars_within_block_scope_spec.rb +31 -0
- data/spec/bounded_vars/instance_vars_spec.rb +60 -0
- data/spec/bounded_vars/instance_vars_within_block_scope_spec.rb +31 -0
- data/spec/bounded_vars/local_vars_spec.rb +60 -0
- data/spec/bounded_vars/local_vars_within_block_scope_spec.rb +31 -0
- data/spec/code_block/errors_spec.rb +65 -0
- data/spec/{multiple_arities_serializable_proc_spec.rb → code_block/multiple_arities_spec.rb} +2 -2
- data/spec/{optional_arity_serializable_proc_spec.rb → code_block/optional_arity_spec.rb} +2 -2
- data/spec/code_block/renaming_vars_spec.rb +160 -0
- data/spec/{one_arity_serializable_proc_spec.rb → code_block/single_arity_spec.rb} +2 -2
- data/spec/{zero_arity_serializable_proc_spec.rb → code_block/zero_arity_spec.rb} +2 -2
- data/spec/proc_like/extras_spec.rb +82 -0
- data/spec/proc_like/invoking_with_args_spec.rb +58 -0
- data/spec/proc_like/invoking_with_class_vars_spec.rb +96 -0
- data/spec/proc_like/invoking_with_global_vars_spec.rb +79 -0
- data/spec/proc_like/invoking_with_instance_vars_spec.rb +79 -0
- data/spec/proc_like/invoking_with_local_vars_spec.rb +79 -0
- data/spec/{marshalling_spec.rb → proc_like/marshalling_spec.rb} +1 -1
- data/spec/proc_like/others_spec.rb +106 -0
- data/spec/spec_helper.rb +10 -0
- metadata +52 -22
- data/lib/serializable_proc/sandboxer.rb +0 -24
- data/spec/extracting_bound_variables_spec.rb +0 -99
- data/spec/initializing_errors_spec.rb +0 -95
- data/spec/proc_like_spec.rb +0 -191
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Extra functionalities' do
|
4
|
+
|
5
|
+
describe '>> to_sexp (empty proc)' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@s_proc = SerializableProc.new{}
|
9
|
+
@expected = {
|
10
|
+
:extracted => s(:iter, s(:call, nil, :proc, s(:arglist)), nil),
|
11
|
+
:runnable => s(:iter, s(:call, nil, :proc, s(:arglist)), nil)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'return sexp representation of extracted code w debug unspecified' do
|
16
|
+
@s_proc.to_sexp.should.equal(@expected[:extracted])
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'return sexp representation of extracted code w debug as false' do
|
20
|
+
@s_proc.to_sexp(false).should.equal(@expected[:extracted])
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'return sexp representation of extracted code w debug as true' do
|
24
|
+
@s_proc.to_sexp(true).should.equal(@expected[:runnable])
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '>> to_sexp (single statement proc)' do
|
30
|
+
|
31
|
+
before do
|
32
|
+
@s_proc = SerializableProc.new{ @x }
|
33
|
+
@expected = {
|
34
|
+
:extracted => s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:ivar, :@x)),
|
35
|
+
:runnable => s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:lvar, :ivar_x))
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'return sexp representation of extracted code w debug unspecified' do
|
40
|
+
@s_proc.to_sexp.should.equal(@expected[:extracted])
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'return sexp representation of extracted code w debug as false' do
|
44
|
+
@s_proc.to_sexp(false).should.equal(@expected[:extracted])
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'return sexp representation of extracted code w debug as true' do
|
48
|
+
@s_proc.to_sexp(true).should.equal(@expected[:runnable])
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '>> to_sexp (multi statements proc)' do
|
54
|
+
|
55
|
+
before do
|
56
|
+
@s_proc = SerializableProc.new do
|
57
|
+
@a = 1
|
58
|
+
@b = 2
|
59
|
+
end
|
60
|
+
@expected = {
|
61
|
+
:extracted => s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:block,
|
62
|
+
s(:iasgn, :@a, s(:lit, 1)), s(:iasgn, :@b, s(:lit, 2)))),
|
63
|
+
:runnable => s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:block,
|
64
|
+
s(:lasgn, :ivar_a, s(:lit, 1)), s(:lasgn, :ivar_b, s(:lit, 2))))
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'return sexp representation of extracted code w debug unspecified' do
|
69
|
+
@s_proc.to_sexp.should.equal(@expected[:extracted])
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'return sexp representation of extracted code w debug as false' do
|
73
|
+
@s_proc.to_sexp(false).should.equal(@expected[:extracted])
|
74
|
+
end
|
75
|
+
|
76
|
+
should 'return sexp representation of extracted code w debug as true' do
|
77
|
+
@s_proc.to_sexp(true).should.equal(@expected[:runnable])
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
[:[], :call].each do |invoke|
|
4
|
+
describe "Invoking with args using :#{invoke}" do
|
5
|
+
|
6
|
+
describe '>> wo specified binding' do
|
7
|
+
|
8
|
+
should 'return yield result given no arg' do
|
9
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
10
|
+
s_proc.send(invoke).should.equal(%w{b c})
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'return yield result given single arg' do
|
14
|
+
s_proc = SerializableProc.new {|i| %w{b c}.map{|x| x*i } }
|
15
|
+
s_proc.send(invoke, 2).should.equal(%w{bb cc})
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'return yield result given optional args' do
|
19
|
+
s_proc = SerializableProc.new {|*args| %w{b c}.map{|x| [x,args].flatten.join } }
|
20
|
+
s_proc.send(invoke, '1', '2').should.equal(%w{b12 c12})
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'return yield result given multiple args' do
|
24
|
+
s_proc = SerializableProc.new {|i, j| %w{b c}.map{|x| x*i*j } }
|
25
|
+
s_proc.send(invoke, 2, 3).should.equal(%w{bbbbbb cccccc})
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '>> w specified binding' do
|
31
|
+
|
32
|
+
should 'return yield result given no arg' do
|
33
|
+
x = 'a'
|
34
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
35
|
+
s_proc.send(invoke, binding).should.equal(%w{b c})
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'return yield result given single arg' do
|
39
|
+
x = 'a'
|
40
|
+
s_proc = SerializableProc.new {|i| %w{b c}.map{|x| x*i } }
|
41
|
+
s_proc.send(invoke, 2, binding).should.equal(%w{bb cc})
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'return yield result given optional args' do
|
45
|
+
x = 'a'
|
46
|
+
s_proc = SerializableProc.new {|*args| %w{b c}.map{|x| [x,args].flatten.join } }
|
47
|
+
s_proc.send(invoke, '1', '2', binding).should.equal(%w{b12 c12})
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'return yield result given multiple args' do
|
51
|
+
x = 'a'
|
52
|
+
s_proc = SerializableProc.new {|i, j| %w{b c}.map{|x| x*i*j } }
|
53
|
+
s_proc.send(invoke, 2, 3, binding).should.equal(%w{bbbbbb cccccc})
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
[:[], :call].each do |invoke|
|
4
|
+
describe "Invoking with class vars using :#{invoke}" do
|
5
|
+
|
6
|
+
describe '>> (w isolation)' do
|
7
|
+
|
8
|
+
should 'not be affected by out-of-scope changes when wo specified binding' do
|
9
|
+
@@x, @@y = 'awe', 'some'
|
10
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
11
|
+
@@x, @@y = 'wonder', 'ful'
|
12
|
+
s_proc.send(invoke).should.equal('handsome')
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'not effect out-of-scope changes when wo specified binding' do
|
16
|
+
@@x, @@y = 'awe', 'some'
|
17
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
18
|
+
@@x, @@y = 'wonder', 'ful'
|
19
|
+
s_proc.send(invoke)
|
20
|
+
@@x.should.equal('wonder')
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not be affected by out-of-scope changes even when w specified binding' do
|
24
|
+
@@x, @@y = 'awe', 'some'
|
25
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
26
|
+
@@x, @@y = 'wonder', 'ful'
|
27
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'not effect out-of-scope changes even when w specified binding' do
|
31
|
+
@@x, @@y = 'awe', 'some'
|
32
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
33
|
+
@@x, @@y = 'wonder', 'ful'
|
34
|
+
s_proc.send(invoke, binding)
|
35
|
+
@@x.should.equal('wonder')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '>> (wo isolation)' do
|
41
|
+
|
42
|
+
if RUBY_VERSION.include?('1.9.')
|
43
|
+
|
44
|
+
should 'raise NameError when wo specified binding' do
|
45
|
+
@@x, @@y = 'wonder', 'ful'
|
46
|
+
s_proc = SerializableProc.new do
|
47
|
+
@@_not_isolated_vars = :class
|
48
|
+
@@x.sub!('awe','hand')
|
49
|
+
@@x + @@y
|
50
|
+
end
|
51
|
+
@@x, @@y = 'awe', 'some'
|
52
|
+
lambda { s_proc.send(invoke) }.should.raise(NameError)
|
53
|
+
end
|
54
|
+
|
55
|
+
else
|
56
|
+
|
57
|
+
should 'reflect out-of-scope vars even when wo specified binding' do
|
58
|
+
@@x, @@y = 'wonder', 'ful'
|
59
|
+
s_proc = SerializableProc.new do
|
60
|
+
@@_not_isolated_vars = :class
|
61
|
+
@@x.sub!('awe','hand')
|
62
|
+
@@x + @@y
|
63
|
+
end
|
64
|
+
@@x, @@y = 'awe', 'some'
|
65
|
+
s_proc.send(invoke).should.equal('handsome')
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'be affected by out-of-scope changes w specified binding' do
|
71
|
+
@@x, @@y = 'wonder', 'ful'
|
72
|
+
s_proc = SerializableProc.new do
|
73
|
+
@@_not_isolated_vars = :class
|
74
|
+
@@x.sub!('awe','hand')
|
75
|
+
@@x + @@y
|
76
|
+
end
|
77
|
+
@@x, @@y = 'awe', 'some'
|
78
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
79
|
+
end
|
80
|
+
|
81
|
+
should 'effect out-of-scope changes w specified binding' do
|
82
|
+
@@x, @@y = 'wonder', 'ful'
|
83
|
+
s_proc = SerializableProc.new do
|
84
|
+
@@_not_isolated_vars = :class
|
85
|
+
@@x.sub!('awe','hand')
|
86
|
+
@@x + @@y
|
87
|
+
end
|
88
|
+
@@x, @@y = 'awe', 'some'
|
89
|
+
s_proc.send(invoke, binding)
|
90
|
+
@@x.should.equal('hand')
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
[:[], :call].each do |invoke|
|
4
|
+
describe "Invoking with global vars using :#{invoke}" do
|
5
|
+
|
6
|
+
describe '>> (w isolation)' do
|
7
|
+
|
8
|
+
should 'not be affected by out-of-scope changes when wo specified binding' do
|
9
|
+
$x, $y = 'awe', 'some'
|
10
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
11
|
+
$x, $y = 'wonder', 'ful'
|
12
|
+
s_proc.send(invoke).should.equal('handsome')
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'not effect out-of-scope changes when wo specified binding' do
|
16
|
+
$x, $y = 'awe', 'some'
|
17
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
18
|
+
$x, $y = 'wonder', 'ful'
|
19
|
+
s_proc.send(invoke)
|
20
|
+
$x.should.equal('wonder')
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not be affected by out-of-scope changes even when w specified binding' do
|
24
|
+
$x, $y = 'awe', 'some'
|
25
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
26
|
+
$x, $y = 'wonder', 'ful'
|
27
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'not effect out-of-scope changes even when w specified binding' do
|
31
|
+
$x, $y = 'awe', 'some'
|
32
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
33
|
+
$x, $y = 'wonder', 'ful'
|
34
|
+
s_proc.send(invoke, binding)
|
35
|
+
$x.should.equal('wonder')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '>> (wo isolation)' do
|
41
|
+
|
42
|
+
should 'reflect out-of-scope vars even when wo specified binding' do
|
43
|
+
$x, $y = 'wonder', 'ful'
|
44
|
+
s_proc = SerializableProc.new do
|
45
|
+
@@_not_isolated_vars = :global
|
46
|
+
$x.sub!('awe','hand')
|
47
|
+
$x + $y
|
48
|
+
end
|
49
|
+
$x, $y = 'awe', 'some'
|
50
|
+
s_proc.send(invoke).should.equal('handsome')
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'be affected by out-of-scope changes w specified binding' do
|
54
|
+
$x, $y = 'wonder', 'ful'
|
55
|
+
s_proc = SerializableProc.new do
|
56
|
+
@@_not_isolated_vars = :global
|
57
|
+
$x.sub!('awe','hand')
|
58
|
+
$x + $y
|
59
|
+
end
|
60
|
+
$x, $y = 'awe', 'some'
|
61
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'effect out-of-scope changes w specified binding' do
|
65
|
+
$x, $y = 'wonder', 'ful'
|
66
|
+
s_proc = SerializableProc.new do
|
67
|
+
@@_not_isolated_vars = :global
|
68
|
+
$x.sub!('awe','hand')
|
69
|
+
$x + $y
|
70
|
+
end
|
71
|
+
$x, $y = 'awe', 'some'
|
72
|
+
s_proc.send(invoke, binding)
|
73
|
+
$x.should.equal('hand')
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
[:[], :call].each do |invoke|
|
4
|
+
describe "Invoking with instance vars using :#{invoke}" do
|
5
|
+
|
6
|
+
describe '>> (w isolation)' do
|
7
|
+
|
8
|
+
should 'not be affected by out-of-scope changes when wo specified binding' do
|
9
|
+
@x, @y = 'awe', 'some'
|
10
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
11
|
+
@x, @y = 'wonder', 'ful'
|
12
|
+
s_proc.send(invoke).should.equal('handsome')
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'not effect out-of-scope changes when wo specified binding' do
|
16
|
+
@x, @y = 'awe', 'some'
|
17
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
18
|
+
@x, @y = 'wonder', 'ful'
|
19
|
+
s_proc.send(invoke)
|
20
|
+
@x.should.equal('wonder')
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not be affected by out-of-scope changes even when w specified binding' do
|
24
|
+
@x, @y = 'awe', 'some'
|
25
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
26
|
+
@x, @y = 'wonder', 'ful'
|
27
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'not effect out-of-scope changes even when w specified binding' do
|
31
|
+
@x, @y = 'awe', 'some'
|
32
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
33
|
+
@x, @y = 'wonder', 'ful'
|
34
|
+
s_proc.send(invoke, binding)
|
35
|
+
@x.should.equal('wonder')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '>> (wo isolation)' do
|
41
|
+
|
42
|
+
should 'raise NameError when wo specified binding' do
|
43
|
+
@x, @y = 'wonder', 'ful'
|
44
|
+
s_proc = SerializableProc.new do
|
45
|
+
@@_not_isolated_vars = :instance
|
46
|
+
@x.sub!('awe','hand')
|
47
|
+
@x + @y
|
48
|
+
end
|
49
|
+
@x, @y = 'awe', 'some'
|
50
|
+
lambda { s_proc.send(invoke) }.should.raise(NameError)
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'be affected by out-of-scope changes w specified binding' do
|
54
|
+
@x, @y = 'wonder', 'ful'
|
55
|
+
s_proc = SerializableProc.new do
|
56
|
+
@@_not_isolated_vars = :instance
|
57
|
+
@x.sub!('awe','hand')
|
58
|
+
@x + @y
|
59
|
+
end
|
60
|
+
@x, @y = 'awe', 'some'
|
61
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'effect out-of-scope changes w specified binding' do
|
65
|
+
@x, @y = 'wonder', 'ful'
|
66
|
+
s_proc = SerializableProc.new do
|
67
|
+
@@_not_isolated_vars = :instance
|
68
|
+
@x.sub!('awe','hand')
|
69
|
+
@x + @y
|
70
|
+
end
|
71
|
+
@x, @y = 'awe', 'some'
|
72
|
+
s_proc.send(invoke, binding)
|
73
|
+
@x.should.equal('hand')
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
[:[], :call].each do |invoke|
|
4
|
+
describe "Invoking with local vars using :#{invoke}" do
|
5
|
+
|
6
|
+
describe '>> (w isolation)' do
|
7
|
+
|
8
|
+
should 'not be affected by out-of-scope changes when wo specified binding' do
|
9
|
+
x, y = 'awe', 'some'
|
10
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
11
|
+
x, y = 'wonder', 'ful'
|
12
|
+
s_proc.send(invoke).should.equal('handsome')
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'not effect out-of-scope changes when wo specified binding' do
|
16
|
+
x, y = 'awe', 'some'
|
17
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
18
|
+
x, y = 'wonder', 'ful'
|
19
|
+
s_proc.send(invoke)
|
20
|
+
x.should.equal('wonder')
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not be affected by out-of-scope changes even when w specified binding' do
|
24
|
+
x, y = 'awe', 'some'
|
25
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
26
|
+
x, y = 'wonder', 'ful'
|
27
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'not effect out-of-scope changes even when w specified binding' do
|
31
|
+
x, y = 'awe', 'some'
|
32
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
33
|
+
x, y = 'wonder', 'ful'
|
34
|
+
s_proc.send(invoke, binding)
|
35
|
+
x.should.equal('wonder')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '>> (wo isolation)' do
|
41
|
+
|
42
|
+
should 'raise NameError when wo specified binding' do
|
43
|
+
x, y = 'wonder', 'ful'
|
44
|
+
s_proc = SerializableProc.new do
|
45
|
+
@@_not_isolated_vars = :local
|
46
|
+
x.sub!('awe','hand')
|
47
|
+
x + y
|
48
|
+
end
|
49
|
+
x, y = 'awe', 'some'
|
50
|
+
lambda { s_proc.send(invoke) }.should.raise(NameError)
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'be affected by out-of-scope changes w specified binding' do
|
54
|
+
x, y = 'wonder', 'ful'
|
55
|
+
s_proc = SerializableProc.new do
|
56
|
+
@@_not_isolated_vars = :local
|
57
|
+
x.sub!('awe','hand')
|
58
|
+
x + y
|
59
|
+
end
|
60
|
+
x, y = 'awe', 'some'
|
61
|
+
s_proc.send(invoke, binding).should.equal('handsome')
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'effect out-of-scope changes w specified binding' do
|
65
|
+
x, y = 'wonder', 'ful'
|
66
|
+
s_proc = SerializableProc.new do
|
67
|
+
@@_not_isolated_vars = :local
|
68
|
+
x.sub!('awe','hand')
|
69
|
+
x + y
|
70
|
+
end
|
71
|
+
x, y = 'awe', 'some'
|
72
|
+
s_proc.send(invoke, binding)
|
73
|
+
x.should.equal('hand')
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Being proc like' do
|
4
|
+
|
5
|
+
describe '>> ==' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@proc = SerializableProc.new{ %w{a b}.map{|x| x } }
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'return true if comparing to itself' do
|
12
|
+
@proc.should.equal(@proc)
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'return true if another SerializableProc has the same code' do
|
16
|
+
SerializableProc.new{ %w{a b}.map{|x| x } }.should.equal(@proc)
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'return false if another SerializableProc does not have the same code' do
|
20
|
+
SerializableProc.new{ %w{b c}.map{|x| x } }.should.not.equal(@proc)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '>> clone' do
|
26
|
+
should 'return a serializable proc that yields +ve ==' do
|
27
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
28
|
+
clone = s_proc.clone
|
29
|
+
clone.should.equal(s_proc)
|
30
|
+
clone.object_id.should.not.equal(s_proc.object_id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '>> to_proc' do
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def work(&block) ; yield ; end
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'return a non-serializable proc' do
|
41
|
+
o_proc = lambda { %w{b c}.map{|x| x } }
|
42
|
+
s_proc = SerializableProc.new(&o_proc)
|
43
|
+
n_proc = s_proc.to_proc
|
44
|
+
s_proc.should.not == n_proc
|
45
|
+
n_proc.class.should == Proc
|
46
|
+
n_proc.call.should.equal(o_proc.call)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "support passing to a method using '&' char" do
|
50
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
51
|
+
work(&s_proc).should.equal(%w{b c})
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '>> to_s' do
|
57
|
+
extend SerializableProc::Spec::Helpers
|
58
|
+
|
59
|
+
should 'return extracted code when debug is unspecified' do
|
60
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
61
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s.should.be \
|
62
|
+
having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'return extracted code w debug as false' do
|
66
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
67
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s(false).should.be \
|
68
|
+
having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
|
69
|
+
end
|
70
|
+
|
71
|
+
should 'return runnable code w debug as true' do
|
72
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
73
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s(true).should.be \
|
74
|
+
having_same_semantics_as('lambda { [lvar_x, ivar_x, cvar_x, gvar_x] }')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '>> arity' do
|
79
|
+
{
|
80
|
+
__LINE__ => lambda { },
|
81
|
+
__LINE__ => lambda {|x| },
|
82
|
+
__LINE__ => lambda {|x,y| },
|
83
|
+
__LINE__ => lambda {|*x| },
|
84
|
+
__LINE__ => lambda {|x, *y| },
|
85
|
+
__LINE__ => lambda {|(x,y)| },
|
86
|
+
}.each do |debug, block|
|
87
|
+
should "return arity of initializing block [##{debug}]" do
|
88
|
+
SerializableProc.new(&block).arity.should.equal(block.arity)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '>> binding' do
|
94
|
+
should 'raise NotImplementedError' do
|
95
|
+
lambda { SerializableProc.new { x }.binding }.should.raise(NotImplementedError)
|
96
|
+
end
|
97
|
+
# should 'return binding that contains duplicated contextual reference values' do
|
98
|
+
# x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
99
|
+
# expected = {'x' => x.dup, '@x' => @x.dup, '@@x' => @@x.dup, '$x' => $x.dup}
|
100
|
+
# s_proc = SerializableProc.new { [x, @x, @@x, $x] }
|
101
|
+
# x, @x, @@x, $x = 'ly', 'iy', 'cy', 'gy'
|
102
|
+
# expected.each{|k,v| s_proc.binding.eval(k).should.equal(v) }
|
103
|
+
# end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -39,6 +39,12 @@ class SerializableProc
|
|
39
39
|
lambda {|code1| normalize[code1].should.equal(normalize[code2]) }
|
40
40
|
end
|
41
41
|
|
42
|
+
def having_runnable_code_as(code)
|
43
|
+
lambda do |s_proc|
|
44
|
+
s_proc.code[:runnable].should.be having_same_semantics_as(code)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
42
48
|
def same_object_as(o2)
|
43
49
|
lambda {|o1| o1.object_id == o2.object_id }
|
44
50
|
end
|
@@ -78,6 +84,10 @@ class SerializableProc
|
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
87
|
+
def should_have_empty_binding(s_proc)
|
88
|
+
s_proc.binding_dump.should.be.empty
|
89
|
+
end
|
90
|
+
|
81
91
|
def should_handle_proc_variable(file, code, test_args)
|
82
92
|
test_args.each do |line, block|
|
83
93
|
should "handle proc variable [##{line}]" do
|