serializable_proc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/HISTORY.txt +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +132 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/lib/serializable_proc/binding.rb +53 -0
- data/lib/serializable_proc/marshalable.rb +51 -0
- data/lib/serializable_proc/parsers/pt.rb +16 -0
- data/lib/serializable_proc/parsers/rp.rb +93 -0
- data/lib/serializable_proc/parsers.rb +8 -0
- data/lib/serializable_proc/sandboxer.rb +24 -0
- data/lib/serializable_proc.rb +169 -0
- data/spec/extracting_bound_variables_spec.rb +99 -0
- data/spec/initializing_errors_spec.rb +95 -0
- data/spec/marshalling_spec.rb +51 -0
- data/spec/multiple_arities_serializable_proc_spec.rb +159 -0
- data/spec/one_arity_serializable_proc_spec.rb +159 -0
- data/spec/optional_arity_serializable_proc_spec.rb +160 -0
- data/spec/proc_like_spec.rb +191 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/zero_arity_serializable_proc_spec.rb +159 -0
- metadata +127 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'One arity serializable proc' do
|
4
|
+
|
5
|
+
extend SerializableProc::Spec::Helpers
|
6
|
+
|
7
|
+
expected_file = File.expand_path(__FILE__)
|
8
|
+
expected_code = "lambda { |lvar_arg| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
|
9
|
+
|
10
|
+
should_handle_proc_variable expected_file, expected_code, {
|
11
|
+
# ////////////////////////////////////////////////////////////////////////
|
12
|
+
# >> Always newlinling
|
13
|
+
# ////////////////////////////////////////////////////////////////////////
|
14
|
+
__LINE__ =>
|
15
|
+
lambda do |arg|
|
16
|
+
%w{a b}.map do |x|
|
17
|
+
puts x
|
18
|
+
end
|
19
|
+
end,
|
20
|
+
__LINE__ =>
|
21
|
+
lambda { |arg|
|
22
|
+
%w{a b}.map{|x|
|
23
|
+
puts x
|
24
|
+
}
|
25
|
+
},
|
26
|
+
__LINE__ =>
|
27
|
+
proc do |arg|
|
28
|
+
%w{a b}.map do |x|
|
29
|
+
puts x
|
30
|
+
end
|
31
|
+
end,
|
32
|
+
__LINE__ =>
|
33
|
+
lambda { |arg|
|
34
|
+
%w{a b}.map{|x|
|
35
|
+
puts x
|
36
|
+
}
|
37
|
+
},
|
38
|
+
__LINE__ =>
|
39
|
+
Proc.new do |arg|
|
40
|
+
%w{a b}.map do |x|
|
41
|
+
puts x
|
42
|
+
end
|
43
|
+
end,
|
44
|
+
__LINE__ =>
|
45
|
+
Proc.new { |arg|
|
46
|
+
%w{a b}.map{|x|
|
47
|
+
puts x
|
48
|
+
}
|
49
|
+
},
|
50
|
+
# ////////////////////////////////////////////////////////////////////////
|
51
|
+
# >> Partial newlining
|
52
|
+
# ////////////////////////////////////////////////////////////////////////
|
53
|
+
__LINE__ =>
|
54
|
+
lambda do |arg|
|
55
|
+
%w{a b}.map do |x| puts x end
|
56
|
+
end,
|
57
|
+
__LINE__ =>
|
58
|
+
lambda { |arg|
|
59
|
+
%w{a b}.map{|x| puts x }
|
60
|
+
},
|
61
|
+
__LINE__ =>
|
62
|
+
proc do |arg|
|
63
|
+
%w{a b}.map do |x| puts x end
|
64
|
+
end,
|
65
|
+
__LINE__ =>
|
66
|
+
lambda { |arg|
|
67
|
+
%w{a b}.map{|x| puts x }
|
68
|
+
},
|
69
|
+
__LINE__ =>
|
70
|
+
Proc.new do |arg|
|
71
|
+
%w{a b}.map do |x| puts x end
|
72
|
+
end,
|
73
|
+
__LINE__ =>
|
74
|
+
Proc.new { |arg|
|
75
|
+
%w{a b}.map{|x| puts x }
|
76
|
+
},
|
77
|
+
# ////////////////////////////////////////////////////////////////////////
|
78
|
+
# >> No newlining
|
79
|
+
# ////////////////////////////////////////////////////////////////////////
|
80
|
+
__LINE__ =>
|
81
|
+
lambda do |arg| %w{a b}.map do |x| puts x end end,
|
82
|
+
__LINE__ =>
|
83
|
+
lambda { |arg| %w{a b}.map{|x| puts x } },
|
84
|
+
__LINE__ =>
|
85
|
+
proc do |arg| %w{a b}.map do |x| puts x end end,
|
86
|
+
__LINE__ =>
|
87
|
+
lambda { |arg| %w{a b}.map{|x| puts x } },
|
88
|
+
__LINE__ =>
|
89
|
+
Proc.new do |arg| %w{a b}.map do |x| puts x end end,
|
90
|
+
__LINE__ =>
|
91
|
+
Proc.new { |arg| %w{a b}.map{|x| puts x } },
|
92
|
+
}
|
93
|
+
|
94
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
95
|
+
(
|
96
|
+
SerializableProc.new do |arg|
|
97
|
+
%w{a b}.map{|x| puts x }
|
98
|
+
end
|
99
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
100
|
+
end
|
101
|
+
|
102
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
103
|
+
(SerializableProc.new do |arg| %w{a b}.map{|x| puts x } end).
|
104
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
105
|
+
end
|
106
|
+
|
107
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
108
|
+
(
|
109
|
+
SerializableProc.new { |arg|
|
110
|
+
%w{a b}.map{|x| puts x }
|
111
|
+
}
|
112
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
113
|
+
end
|
114
|
+
|
115
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
116
|
+
(SerializableProc.new { |arg| %w{a b}.map{|x| puts x } }).
|
117
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
118
|
+
end
|
119
|
+
|
120
|
+
should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
|
121
|
+
(SerializableProc.new(&(lambda { |arg| %w{a b}.map{|x| puts x } }))).
|
122
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
|
126
|
+
(
|
127
|
+
SerializableProc.new(&(lambda do |arg|
|
128
|
+
%w{a b}.map{|x| puts x }
|
129
|
+
end))
|
130
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
|
134
|
+
(SerializableProc.new(&(proc { |arg| %w{a b}.map{|x| puts x } }))).
|
135
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
|
139
|
+
(
|
140
|
+
SerializableProc.new(&(proc do |arg|
|
141
|
+
%w{a b}.map{|x| puts x }
|
142
|
+
end))
|
143
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
|
147
|
+
(SerializableProc.new(&(Proc.new { |arg| %w{a b}.map{|x| puts x } }))).
|
148
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
149
|
+
end
|
150
|
+
|
151
|
+
should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
|
152
|
+
(
|
153
|
+
SerializableProc.new(&(Proc.new do |arg|
|
154
|
+
%w{a b}.map{|x| puts x }
|
155
|
+
end))
|
156
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Optional arity serializable proc' do
|
4
|
+
|
5
|
+
extend SerializableProc::Spec::Helpers
|
6
|
+
|
7
|
+
expected_file = File.expand_path(__FILE__)
|
8
|
+
expected_code = "lambda { |*lvar_args| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
|
9
|
+
|
10
|
+
should_handle_proc_variable expected_file, expected_code, {
|
11
|
+
# ////////////////////////////////////////////////////////////////////////
|
12
|
+
# >> Always newlinling
|
13
|
+
# ////////////////////////////////////////////////////////////////////////
|
14
|
+
__LINE__ =>
|
15
|
+
lambda do |*args|
|
16
|
+
%w{a b}.map do |x|
|
17
|
+
puts x
|
18
|
+
end
|
19
|
+
end,
|
20
|
+
__LINE__ =>
|
21
|
+
lambda { |*args|
|
22
|
+
%w{a b}.map{|x|
|
23
|
+
puts x
|
24
|
+
}
|
25
|
+
},
|
26
|
+
__LINE__ =>
|
27
|
+
proc do |*args|
|
28
|
+
%w{a b}.map do |x|
|
29
|
+
puts x
|
30
|
+
end
|
31
|
+
end,
|
32
|
+
__LINE__ =>
|
33
|
+
lambda { |*args|
|
34
|
+
%w{a b}.map{|x|
|
35
|
+
puts x
|
36
|
+
}
|
37
|
+
},
|
38
|
+
__LINE__ =>
|
39
|
+
Proc.new do |*args|
|
40
|
+
%w{a b}.map do |x|
|
41
|
+
puts x
|
42
|
+
end
|
43
|
+
end,
|
44
|
+
__LINE__ =>
|
45
|
+
Proc.new { |*args|
|
46
|
+
%w{a b}.map{|x|
|
47
|
+
puts x
|
48
|
+
}
|
49
|
+
},
|
50
|
+
# ////////////////////////////////////////////////////////////////////////
|
51
|
+
# >> Partial newlining
|
52
|
+
# ////////////////////////////////////////////////////////////////////////
|
53
|
+
__LINE__ =>
|
54
|
+
lambda do |*args|
|
55
|
+
%w{a b}.map do |x| puts x end
|
56
|
+
end,
|
57
|
+
__LINE__ =>
|
58
|
+
lambda { |*args|
|
59
|
+
%w{a b}.map{|x| puts x }
|
60
|
+
},
|
61
|
+
__LINE__ =>
|
62
|
+
proc do |*args|
|
63
|
+
%w{a b}.map do |x| puts x end
|
64
|
+
end,
|
65
|
+
__LINE__ =>
|
66
|
+
lambda { |*args|
|
67
|
+
%w{a b}.map{|x| puts x }
|
68
|
+
},
|
69
|
+
__LINE__ =>
|
70
|
+
Proc.new do |*args|
|
71
|
+
%w{a b}.map do |x| puts x end
|
72
|
+
end,
|
73
|
+
__LINE__ =>
|
74
|
+
Proc.new { |*args|
|
75
|
+
%w{a b}.map{|x| puts x }
|
76
|
+
},
|
77
|
+
# ////////////////////////////////////////////////////////////////////////
|
78
|
+
# >> No newlining
|
79
|
+
# ////////////////////////////////////////////////////////////////////////
|
80
|
+
__LINE__ =>
|
81
|
+
lambda do |*args| %w{a b}.map do |x| puts x end end,
|
82
|
+
__LINE__ =>
|
83
|
+
lambda { |*args| %w{a b}.map{|x| puts x } },
|
84
|
+
__LINE__ =>
|
85
|
+
proc do |*args| %w{a b}.map do |x| puts x end end,
|
86
|
+
__LINE__ =>
|
87
|
+
lambda { |*args| %w{a b}.map{|x| puts x } },
|
88
|
+
__LINE__ =>
|
89
|
+
Proc.new do |*args| %w{a b}.map do |x| puts x end end,
|
90
|
+
__LINE__ =>
|
91
|
+
Proc.new { |*args| %w{a b}.map{|x| puts x } },
|
92
|
+
}
|
93
|
+
|
94
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
95
|
+
(
|
96
|
+
SerializableProc.new do |*args|
|
97
|
+
%w{a b}.map{|x| puts x }
|
98
|
+
end
|
99
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
100
|
+
end
|
101
|
+
|
102
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
103
|
+
(SerializableProc.new do |*args| %w{a b}.map{|x| puts x } end).
|
104
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
105
|
+
end
|
106
|
+
|
107
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
108
|
+
(
|
109
|
+
SerializableProc.new { |*args|
|
110
|
+
%w{a b}.map{|x| puts x }
|
111
|
+
}
|
112
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
113
|
+
end
|
114
|
+
|
115
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
116
|
+
(SerializableProc.new { |*args| %w{a b}.map{|x| puts x } }).
|
117
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
118
|
+
end
|
119
|
+
|
120
|
+
should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
|
121
|
+
(SerializableProc.new(&(lambda { |*args| %w{a b}.map{|x| puts x } }))).
|
122
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
|
126
|
+
(
|
127
|
+
SerializableProc.new(&(lambda do |*args|
|
128
|
+
%w{a b}.map{|x| puts x }
|
129
|
+
end))
|
130
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
|
134
|
+
(SerializableProc.new(&(proc { |*args| %w{a b}.map{|x| puts x } }))).
|
135
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
|
139
|
+
(
|
140
|
+
SerializableProc.new(&(proc do |*args|
|
141
|
+
%w{a b}.map{|x| puts x }
|
142
|
+
end))
|
143
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
|
147
|
+
(SerializableProc.new(&(Proc.new { |*args| %w{a b}.map{|x| puts x } }))).
|
148
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
149
|
+
end
|
150
|
+
|
151
|
+
should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
|
152
|
+
(
|
153
|
+
SerializableProc.new(&(Proc.new do |*args|
|
154
|
+
%w{a b}.map{|x| puts x }
|
155
|
+
end))
|
156
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,191 @@
|
|
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 '>> call (alias [])' do
|
26
|
+
|
27
|
+
should 'return yield result given no arg' do
|
28
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
29
|
+
expected = %w{b c}
|
30
|
+
s_proc.call.should.equal(expected)
|
31
|
+
s_proc[].should.equal(expected)
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'reflect bound instance variable value (unaffected by outside-scope change)' do
|
35
|
+
x, y = 'awe', 'some'
|
36
|
+
expected = 'hand' + y
|
37
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
38
|
+
x, y = 'wonder', 'ful'
|
39
|
+
s_proc.call.should.equal(expected)
|
40
|
+
s_proc[].should.equal(expected)
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'not affect any outside-scope change to instance variable' do
|
44
|
+
x, y = 'awe', 'some'
|
45
|
+
s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
|
46
|
+
x, y = 'wonder', 'ful'
|
47
|
+
s_proc.call ; s_proc[]
|
48
|
+
x.should.equal('wonder')
|
49
|
+
y.should.equal('ful')
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'reflect bound instance variable value (unaffected by outside-scope change)' do
|
53
|
+
@x, @y = 'awe', 'some'
|
54
|
+
expected = 'hand' + @y
|
55
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
56
|
+
@x, @y = 'wonder', 'ful'
|
57
|
+
s_proc.call.should.equal(expected)
|
58
|
+
s_proc[].should.equal(expected)
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'not affect any outside-scope change to instance variable' do
|
62
|
+
@x, @y = 'awe', 'some'
|
63
|
+
s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
|
64
|
+
@x, @y = 'wonder', 'ful'
|
65
|
+
s_proc.call ; s_proc[]
|
66
|
+
@x.should.equal('wonder')
|
67
|
+
@y.should.equal('ful')
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'reflect bound class variable value (unaffected by outside-scope change)' do
|
71
|
+
@@x, @@y = 'awe', 'some'
|
72
|
+
expected = 'hand' + @@y
|
73
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
74
|
+
@@x, @@y = 'wonder', 'ful'
|
75
|
+
s_proc.call.should.equal(expected)
|
76
|
+
s_proc[].should.equal(expected)
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'not affect any outside-scope change to class variable' do
|
80
|
+
@@x, @@y = 'awe', 'some'
|
81
|
+
s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
|
82
|
+
@@x, @@y = 'wonder', 'ful'
|
83
|
+
s_proc.call ; s_proc[]
|
84
|
+
@@x.should.equal('wonder')
|
85
|
+
@@y.should.equal('ful')
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'reflect bound global variable value (unaffected by outside-scope change)' do
|
89
|
+
$x, $y = 'awe', 'some'
|
90
|
+
expected = 'hand' + $y
|
91
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
92
|
+
$x, $y = 'wonder', 'ful'
|
93
|
+
s_proc.call.should.equal(expected)
|
94
|
+
s_proc[].should.equal(expected)
|
95
|
+
end
|
96
|
+
|
97
|
+
should 'not affect any outside-scope change to global variable' do
|
98
|
+
$x, $y = 'awe', 'some'
|
99
|
+
s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
|
100
|
+
$x, $y = 'wonder', 'ful'
|
101
|
+
s_proc.call ; s_proc[]
|
102
|
+
$x.should.equal('wonder')
|
103
|
+
$y.should.equal('ful')
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '>> clone' do
|
109
|
+
should 'return a serializable proc that yields +ve ==' do
|
110
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
111
|
+
clone = s_proc.clone
|
112
|
+
clone.should.equal(s_proc)
|
113
|
+
clone.object_id.should.not.equal(s_proc.object_id)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '>> binding' do
|
118
|
+
should 'raise NotImplementedError' do
|
119
|
+
lambda { SerializableProc.new { x }.binding }.should.raise(NotImplementedError)
|
120
|
+
end
|
121
|
+
# should 'return binding that contains duplicated contextual reference values' do
|
122
|
+
# x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
123
|
+
# expected = {'x' => x.dup, '@x' => @x.dup, '@@x' => @@x.dup, '$x' => $x.dup}
|
124
|
+
# s_proc = SerializableProc.new { [x, @x, @@x, $x] }
|
125
|
+
# x, @x, @@x, $x = 'ly', 'iy', 'cy', 'gy'
|
126
|
+
# expected.each{|k,v| s_proc.binding.eval(k).should.equal(v) }
|
127
|
+
# end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '>> to_proc' do
|
131
|
+
|
132
|
+
class << self
|
133
|
+
def work(&block) ; yield ; end
|
134
|
+
end
|
135
|
+
|
136
|
+
should 'return a non-serializable proc' do
|
137
|
+
o_proc = lambda { %w{b c}.map{|x| x } }
|
138
|
+
s_proc = SerializableProc.new(&o_proc)
|
139
|
+
n_proc = s_proc.to_proc
|
140
|
+
s_proc.should.not == n_proc
|
141
|
+
n_proc.class.should == Proc
|
142
|
+
n_proc.call.should.equal(o_proc.call)
|
143
|
+
end
|
144
|
+
|
145
|
+
should "support passing to a method using '&' char" do
|
146
|
+
s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
|
147
|
+
work(&s_proc).should.equal(%w{b c})
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '>> to_s' do
|
153
|
+
|
154
|
+
extend SerializableProc::Spec::Helpers
|
155
|
+
|
156
|
+
should 'return extracted code when debug is not specified' do
|
157
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
158
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s.should.be \
|
159
|
+
having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
|
160
|
+
end
|
161
|
+
|
162
|
+
should 'return extracted code when debug is turned off' do
|
163
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
164
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s(false).should.be \
|
165
|
+
having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
|
166
|
+
end
|
167
|
+
|
168
|
+
should 'return runnable code when debug is turned on' do
|
169
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
170
|
+
SerializableProc.new{ [x,@x,@@x,$x] }.to_s(true).should.be \
|
171
|
+
having_same_semantics_as('lambda { [lvar_x, ivar_x, cvar_x, gvar_x] }')
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '>> arity' do
|
177
|
+
{
|
178
|
+
__LINE__ => lambda { },
|
179
|
+
__LINE__ => lambda {|x| },
|
180
|
+
__LINE__ => lambda {|x,y| },
|
181
|
+
__LINE__ => lambda {|*x| },
|
182
|
+
__LINE__ => lambda {|x, *y| },
|
183
|
+
__LINE__ => lambda {|(x,y)| },
|
184
|
+
}.each do |debug, block|
|
185
|
+
should "return arity of initializing block [##{debug}]" do
|
186
|
+
SerializableProc.new(&block).arity.should.equal(block.arity)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bacon'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'ruby2ruby'
|
5
|
+
|
6
|
+
$parse_tree_installed =
|
7
|
+
begin
|
8
|
+
require 'parse_tree'
|
9
|
+
true
|
10
|
+
rescue LoadError
|
11
|
+
require 'ruby_parser'
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
16
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
17
|
+
require 'serializable_proc'
|
18
|
+
|
19
|
+
Bacon.summary_on_exit
|
20
|
+
|
21
|
+
class SerializableProc
|
22
|
+
|
23
|
+
attr_reader :code, :file, :line
|
24
|
+
|
25
|
+
def binding_dump
|
26
|
+
@binding.instance_variable_get(:@vars)
|
27
|
+
end
|
28
|
+
|
29
|
+
module Spec
|
30
|
+
|
31
|
+
module Matchers
|
32
|
+
|
33
|
+
def having_same_semantics_as(code2)
|
34
|
+
to_code = lambda{|sexp| ::Ruby2Ruby.new.process(sexp) }
|
35
|
+
to_sexp = $parse_tree_installed ?
|
36
|
+
lambda{|code| Unifier.new.process(::ParseTree.translate(code)) } :
|
37
|
+
lambda{|code| ::RubyParser.new.parse(code) }
|
38
|
+
normalize = lambda{|code| to_code[to_sexp[code]].sub('lambda','proc') }
|
39
|
+
lambda {|code1| normalize[code1].should.equal(normalize[code2]) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def same_object_as(o2)
|
43
|
+
lambda {|o1| o1.object_id == o2.object_id }
|
44
|
+
end
|
45
|
+
|
46
|
+
def having_expected_proc_attrs(file, line, code)
|
47
|
+
lambda do |s_proc|
|
48
|
+
s_proc.code[:runnable].should.be having_same_semantics_as(code)
|
49
|
+
s_proc.file.should.equal(file)
|
50
|
+
s_proc.line.should.equal(line)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def raising_cannot_serialize_variable_error(var)
|
55
|
+
lambda do |block|
|
56
|
+
block.should.raise(SerializableProc::CannotSerializeVariableError).
|
57
|
+
message.should.equal('Variable %s cannot be serialized !!' % var)
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def raising_cannot_analyse_error(descrp)
|
63
|
+
lambda do |block|
|
64
|
+
block.should.raise(SerializableProc::CannotAnalyseCodeError).message.should.
|
65
|
+
equal("Static code analysis can only handle single occurrence of #{descrp} per line !!")
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
module Macros
|
73
|
+
|
74
|
+
def should_have_expected_binding(s_proc, expected)
|
75
|
+
s_proc.binding_dump.should.equal(expected)
|
76
|
+
expected.each do |key, val|
|
77
|
+
(s_proc.binding_dump[key].should.not.be same_object_as(val)) if val
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def should_handle_proc_variable(file, code, test_args)
|
82
|
+
test_args.each do |line, block|
|
83
|
+
should "handle proc variable [##{line}]" do
|
84
|
+
s_proc = SerializableProc.new(&block)
|
85
|
+
s_proc.code[:runnable].should.be having_same_semantics_as(code)
|
86
|
+
s_proc.file.should.equal(file)
|
87
|
+
s_proc.line.should.equal(line.succ)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
module Helpers
|
95
|
+
include Macros
|
96
|
+
include Matchers
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|