serializable_proc 0.1.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.
- 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
|