mvz-live_ast 2.0.0 → 2.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.
- checksums.yaml +4 -4
- data/CHANGES.rdoc +5 -0
- data/README.rdoc +14 -0
- data/lib/live_ast/base.rb +7 -9
- data/lib/live_ast/irb_spy.rb +1 -1
- data/lib/live_ast/replace_caller.rb +14 -0
- data/lib/live_ast/version.rb +1 -1
- metadata +75 -116
- data/Rakefile +0 -62
- data/devel/levitate.rb +0 -184
- data/devel/levitate_config.rb +0 -4
- data/test/alias_test.rb +0 -25
- data/test/ast_eval/ast_eval_test.rb +0 -13
- data/test/ast_load/ast_load_test.rb +0 -47
- data/test/attr_test.rb +0 -26
- data/test/backtrace_test.rb +0 -161
- data/test/base/noninvasive_test.rb +0 -55
- data/test/base/reload_test.rb +0 -43
- data/test/covert_define_method_test.rb +0 -25
- data/test/def_test.rb +0 -37
- data/test/define_method_test.rb +0 -69
- data/test/define_singleton_method_test.rb +0 -17
- data/test/encoding_test/bad.rb +0 -1
- data/test/encoding_test/cp932.rb +0 -6
- data/test/encoding_test/default.rb +0 -5
- data/test/encoding_test/eucjp.rb +0 -6
- data/test/encoding_test/koi8.rb +0 -6
- data/test/encoding_test/koi8_shebang.rb +0 -7
- data/test/encoding_test/koi8_with_utf8bom.rb +0 -6
- data/test/encoding_test/usascii.rb +0 -6
- data/test/encoding_test/usascii_with_utf8bom.rb +0 -6
- data/test/encoding_test/utf8.rb +0 -6
- data/test/encoding_test/utf8bom.rb +0 -6
- data/test/encoding_test/utf8bom_only.rb +0 -5
- data/test/encoding_test/utf8dos.rb +0 -6
- data/test/encoding_test/utf8mac.rb +0 -6
- data/test/encoding_test/utf8mac_alt.rb +0 -6
- data/test/encoding_test/utf8unix.rb +0 -6
- data/test/encoding_test.rb +0 -54
- data/test/error_test.rb +0 -118
- data/test/eval_test.rb +0 -271
- data/test/flush_cache_test.rb +0 -102
- data/test/full/ast_reload_test.rb +0 -41
- data/test/full/replace_eval_test.rb +0 -433
- data/test/irb_test.rb +0 -43
- data/test/lambda_test.rb +0 -65
- data/test/load_path_test.rb +0 -77
- data/test/load_test.rb +0 -125
- data/test/main.rb +0 -134
- data/test/nested_test.rb +0 -31
- data/test/readme_test.rb +0 -16
- data/test/recursive_eval_test.rb +0 -53
- data/test/redefine_method_test.rb +0 -85
- data/test/rubygems_test.rb +0 -27
- data/test/rubyspec_test.rb +0 -39
- data/test/singleton_test.rb +0 -27
- data/test/stdlib_test.rb +0 -15
- data/test/thread_test.rb +0 -45
- data/test/to_ast/to_ast_feature_test.rb +0 -13
- data/test/to_ruby/to_ruby_feature_test.rb +0 -13
- data/test/to_ruby/to_ruby_test.rb +0 -101
data/test/error_test.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "main"
|
4
|
-
|
5
|
-
class ErrorTest < RegularTest
|
6
|
-
def test_multiple_lambda_same_line
|
7
|
-
a = lambda {}; b = lambda {}
|
8
|
-
ignore(b)
|
9
|
-
|
10
|
-
assert_raises LiveAST::MultipleDefinitionsOnSameLineError do
|
11
|
-
a.to_ast
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
DEFINE_A = lambda do
|
16
|
-
class A
|
17
|
-
def f; end; def g; end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_multi_defs
|
22
|
-
DEFINE_A.call
|
23
|
-
assert_raises LiveAST::MultipleDefinitionsOnSameLineError do
|
24
|
-
A.instance_method(:f).to_ast
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_ast_not_found
|
29
|
-
assert_raises LiveAST::ASTNotFoundError do
|
30
|
-
File.method(:open).to_ast
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_arg_error_too_many
|
35
|
-
orig = assert_raises ArgumentError do
|
36
|
-
eval("s", binding, "f", 99, nil)
|
37
|
-
end
|
38
|
-
|
39
|
-
live = assert_raises ArgumentError do
|
40
|
-
ast_eval("s", binding, "f", 99, nil)
|
41
|
-
end
|
42
|
-
|
43
|
-
assert_equal orig.message.sub("1..4", "2..4"), live.message
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_bad_args
|
47
|
-
[99, Object.new, File].each do |bad|
|
48
|
-
orig = assert_raises TypeError do
|
49
|
-
eval(bad, binding)
|
50
|
-
end
|
51
|
-
live = assert_raises TypeError do
|
52
|
-
ast_eval(bad, binding)
|
53
|
-
end
|
54
|
-
assert_equal orig.message, live.message
|
55
|
-
|
56
|
-
orig = assert_raises TypeError do
|
57
|
-
eval("3 + 4", binding, bad)
|
58
|
-
end
|
59
|
-
live = assert_raises TypeError do
|
60
|
-
ast_eval("3 + 4", binding, bad)
|
61
|
-
end
|
62
|
-
assert_equal orig.message, live.message
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_raw_eval
|
67
|
-
f = eval("lambda { }")
|
68
|
-
assert_raises LiveAST::RawEvalError do
|
69
|
-
f.to_ast
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_reload_with_raw_eval_one
|
74
|
-
ast_eval("lambda { }", binding)
|
75
|
-
eval("lambda { }")
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_reload_with_raw_eval_two
|
79
|
-
c = ast_eval %{
|
80
|
-
Class.new do
|
81
|
-
def f
|
82
|
-
end
|
83
|
-
end
|
84
|
-
}, binding
|
85
|
-
c.module_eval do
|
86
|
-
eval %{
|
87
|
-
remove_method :f
|
88
|
-
def f(x, y)
|
89
|
-
x + y
|
90
|
-
end
|
91
|
-
}
|
92
|
-
nil
|
93
|
-
end
|
94
|
-
|
95
|
-
assert_raises LiveAST::RawEvalError do
|
96
|
-
c.instance_method(:f).to_ast
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_bad_binding
|
101
|
-
orig = assert_raises TypeError do
|
102
|
-
eval("", "bogus")
|
103
|
-
end
|
104
|
-
|
105
|
-
live = assert_raises TypeError do
|
106
|
-
ast_eval("", "bogus")
|
107
|
-
end
|
108
|
-
|
109
|
-
assert_equal orig.message, live.message
|
110
|
-
end
|
111
|
-
|
112
|
-
def test_shenanigans
|
113
|
-
error = assert_raises RuntimeError do
|
114
|
-
LiveAST.load "foo.rb|ast@4"
|
115
|
-
end
|
116
|
-
assert_match(/revision token/, error.message)
|
117
|
-
end
|
118
|
-
end
|
data/test/eval_test.rb
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "main"
|
4
|
-
|
5
|
-
class EvalTest < RegularTest
|
6
|
-
DEFINE_A = lambda do
|
7
|
-
class A
|
8
|
-
ast_eval %{
|
9
|
-
def f(x, y)
|
10
|
-
x + y
|
11
|
-
end
|
12
|
-
}, binding
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_eval_method
|
17
|
-
DEFINE_A.call
|
18
|
-
assert_equal "#{self.class}::A", A.name
|
19
|
-
assert_equal A, A.instance_method(:f).owner
|
20
|
-
|
21
|
-
assert_equal binop_def(:f, :+),
|
22
|
-
A.instance_method(:f).to_ast
|
23
|
-
|
24
|
-
assert_equal binop_def(:f, :+),
|
25
|
-
A.new.method(:f).to_ast
|
26
|
-
end
|
27
|
-
|
28
|
-
DEFINE_B = lambda do
|
29
|
-
ast_eval %{
|
30
|
-
class B
|
31
|
-
def f(x, y)
|
32
|
-
x * y
|
33
|
-
end
|
34
|
-
end
|
35
|
-
}, binding
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_eval_class
|
39
|
-
DEFINE_B.call
|
40
|
-
assert_equal "#{self.class}::B", B.name
|
41
|
-
assert_equal B, B.instance_method(:f).owner
|
42
|
-
|
43
|
-
assert_equal binop_def(:f, :*),
|
44
|
-
B.instance_method(:f).to_ast
|
45
|
-
|
46
|
-
assert_equal binop_def(:f, :*),
|
47
|
-
B.new.method(:f).to_ast
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_eval_method_anon
|
51
|
-
klass = Class.new do
|
52
|
-
ast_eval %{
|
53
|
-
def f(x, y)
|
54
|
-
x - y
|
55
|
-
end
|
56
|
-
}, binding
|
57
|
-
end
|
58
|
-
|
59
|
-
assert_nil klass.name
|
60
|
-
assert_equal klass, klass.instance_method(:f).owner
|
61
|
-
|
62
|
-
assert_equal binop_def(:f, :-),
|
63
|
-
klass.instance_method(:f).to_ast
|
64
|
-
|
65
|
-
assert_equal binop_def(:f, :-),
|
66
|
-
klass.new.method(:f).to_ast
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_eval_class_anon
|
70
|
-
klass = ast_eval %{
|
71
|
-
Class.new do
|
72
|
-
def f(x, y)
|
73
|
-
x / y
|
74
|
-
end
|
75
|
-
end
|
76
|
-
}, binding
|
77
|
-
|
78
|
-
assert_nil klass.name
|
79
|
-
assert_equal klass, klass.instance_method(:f).owner
|
80
|
-
|
81
|
-
assert_equal binop_def(:f, :/),
|
82
|
-
klass.instance_method(:f).to_ast
|
83
|
-
|
84
|
-
assert_equal binop_def(:f, :/),
|
85
|
-
klass.new.method(:f).to_ast
|
86
|
-
end
|
87
|
-
|
88
|
-
DEFINE_C = lambda do
|
89
|
-
class C
|
90
|
-
ast_eval %{
|
91
|
-
define_method :g do |x, y|
|
92
|
-
x + y
|
93
|
-
end
|
94
|
-
}, binding
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_eval_method_dynamic
|
99
|
-
DEFINE_C.call
|
100
|
-
assert_equal "#{self.class}::C", C.name
|
101
|
-
assert_equal C, C.instance_method(:g).owner
|
102
|
-
|
103
|
-
assert_equal binop_define_method(:g, :+),
|
104
|
-
C.instance_method(:g).to_ast
|
105
|
-
|
106
|
-
assert_equal binop_define_method(:g, :+),
|
107
|
-
C.new.method(:g).to_ast
|
108
|
-
end
|
109
|
-
|
110
|
-
DEFINE_D = lambda do
|
111
|
-
ast_eval %{
|
112
|
-
class D
|
113
|
-
define_method :g do |x, y|
|
114
|
-
x * y
|
115
|
-
end
|
116
|
-
end
|
117
|
-
}, binding
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_eval_class_dynamic
|
121
|
-
DEFINE_D.call
|
122
|
-
assert_equal "#{self.class}::D", D.name
|
123
|
-
assert_equal D, D.instance_method(:g).owner
|
124
|
-
|
125
|
-
assert_equal binop_define_method(:g, :*),
|
126
|
-
D.instance_method(:g).to_ast
|
127
|
-
|
128
|
-
assert_equal binop_define_method(:g, :*),
|
129
|
-
D.new.method(:g).to_ast
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_eval_method_anon_dynamic
|
133
|
-
klass = Class.new do
|
134
|
-
ast_eval %{
|
135
|
-
define_method :g do |x, y|
|
136
|
-
x - y
|
137
|
-
end
|
138
|
-
}, binding
|
139
|
-
end
|
140
|
-
|
141
|
-
assert_nil klass.name
|
142
|
-
assert_equal klass, klass.instance_method(:g).owner
|
143
|
-
|
144
|
-
assert_equal binop_define_method(:g, :-),
|
145
|
-
klass.instance_method(:g).to_ast
|
146
|
-
|
147
|
-
assert_equal binop_define_method(:g, :-),
|
148
|
-
klass.new.method(:g).to_ast
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_eval_class_anon_dynamic
|
152
|
-
klass = ast_eval %{
|
153
|
-
Class.new do
|
154
|
-
define_method :g do |x, y|
|
155
|
-
x / y
|
156
|
-
end
|
157
|
-
end
|
158
|
-
}, binding
|
159
|
-
|
160
|
-
assert_nil klass.name
|
161
|
-
assert_equal klass, klass.instance_method(:g).owner
|
162
|
-
|
163
|
-
assert_equal binop_define_method(:g, :/),
|
164
|
-
klass.instance_method(:g).to_ast
|
165
|
-
|
166
|
-
assert_equal binop_define_method(:g, :/),
|
167
|
-
klass.new.method(:g).to_ast
|
168
|
-
end
|
169
|
-
|
170
|
-
DEFINE_GH = lambda do
|
171
|
-
ast_eval %{
|
172
|
-
class G
|
173
|
-
def f
|
174
|
-
"G#f"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
class H
|
179
|
-
def g
|
180
|
-
"H#g"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
}, binding
|
184
|
-
end
|
185
|
-
|
186
|
-
def test_reuse_string
|
187
|
-
DEFINE_GH.call
|
188
|
-
assert_equal "#{self.class}::G", G.name
|
189
|
-
assert_equal "#{self.class}::H", H.name
|
190
|
-
|
191
|
-
assert_equal no_arg_def(:f, "G#f"),
|
192
|
-
G.instance_method(:f).to_ast
|
193
|
-
|
194
|
-
assert_equal no_arg_def(:f, "G#f"),
|
195
|
-
G.new.method(:f).to_ast
|
196
|
-
|
197
|
-
assert_equal no_arg_def(:g, "H#g"),
|
198
|
-
H.instance_method(:g).to_ast
|
199
|
-
|
200
|
-
assert_equal no_arg_def(:g, "H#g"),
|
201
|
-
H.new.method(:g).to_ast
|
202
|
-
end
|
203
|
-
|
204
|
-
def test_module_eval
|
205
|
-
klass = Class.new
|
206
|
-
klass.module_eval do
|
207
|
-
ast_eval %{
|
208
|
-
def f
|
209
|
-
"z"
|
210
|
-
end
|
211
|
-
}, binding
|
212
|
-
end
|
213
|
-
|
214
|
-
assert_equal klass, klass.instance_method(:f).owner
|
215
|
-
|
216
|
-
assert_equal no_arg_def(:f, "z"),
|
217
|
-
klass.instance_method(:f).to_ast
|
218
|
-
|
219
|
-
assert_equal no_arg_def(:f, "z"),
|
220
|
-
klass.new.method(:f).to_ast
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_singleton_class
|
224
|
-
obj = Object.new
|
225
|
-
obj.singleton_class.module_eval do
|
226
|
-
ast_eval %{
|
227
|
-
def f
|
228
|
-
"singleton"
|
229
|
-
end
|
230
|
-
}, binding
|
231
|
-
end
|
232
|
-
|
233
|
-
assert_equal no_arg_def(:f, "singleton"),
|
234
|
-
obj.method(:f).to_ast
|
235
|
-
end
|
236
|
-
|
237
|
-
def test_proc_in_eval
|
238
|
-
a = ast_eval %{ proc { |x, y| x + y } }, binding
|
239
|
-
|
240
|
-
assert_equal binop_block(:proc, :+), a.to_ast
|
241
|
-
end
|
242
|
-
|
243
|
-
def test_proc_new_in_eval
|
244
|
-
a = ast_eval %{ Proc.new { |x, y| x * y } }, binding
|
245
|
-
|
246
|
-
assert_equal binop_proc_new(:*), a.to_ast
|
247
|
-
end
|
248
|
-
|
249
|
-
def test_method_block_in_eval
|
250
|
-
a = ast_eval %{ return_block { |x, y| x - y } }, binding
|
251
|
-
|
252
|
-
assert_equal binop_block(:return_block, :-), a.to_ast
|
253
|
-
end
|
254
|
-
|
255
|
-
def test_lambda_in_eval
|
256
|
-
a = ast_eval %{ lambda { |x, y| x / y } }, binding
|
257
|
-
|
258
|
-
assert_equal binop_block(:lambda, :/), a.to_ast
|
259
|
-
|
260
|
-
# sanity check
|
261
|
-
assert_not_equal binop_block(:lambda, :+), a.to_ast
|
262
|
-
end
|
263
|
-
|
264
|
-
# from rubyspec
|
265
|
-
def test_to_str_on_file
|
266
|
-
file = MiniTest::Mock.new
|
267
|
-
file.expect(:to_str, "zebra.rb")
|
268
|
-
ast_eval "33 + 44", binding, file
|
269
|
-
file.verify
|
270
|
-
end
|
271
|
-
end
|
data/test/flush_cache_test.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "main"
|
4
|
-
|
5
|
-
# test for flushing side-effects: unsort this TestCase from other
|
6
|
-
# TestCases.
|
7
|
-
|
8
|
-
define_unsorted_test_case "FlushCacheTest", RegularTest do
|
9
|
-
def test_cache
|
10
|
-
# testing global state of cache -- must be sequential
|
11
|
-
uncached_method_from_require
|
12
|
-
uncached_method_from_eval
|
13
|
-
cached_method_from_eval
|
14
|
-
lost_method_from_require
|
15
|
-
flush_lambda
|
16
|
-
end
|
17
|
-
|
18
|
-
def uncached_method_from_require
|
19
|
-
klass = Class.new do
|
20
|
-
def f; end
|
21
|
-
|
22
|
-
def g; end
|
23
|
-
end
|
24
|
-
|
25
|
-
LiveAST.flush_cache
|
26
|
-
|
27
|
-
#
|
28
|
-
# file never made it into the cache; unaffected by flush
|
29
|
-
#
|
30
|
-
assert_nothing_raised do
|
31
|
-
klass.instance_method(:g).to_ast
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def uncached_method_from_eval
|
36
|
-
klass = Class.new do
|
37
|
-
ast_eval %{
|
38
|
-
def f ; end
|
39
|
-
def g ; end
|
40
|
-
}, binding
|
41
|
-
end
|
42
|
-
|
43
|
-
LiveAST.flush_cache
|
44
|
-
|
45
|
-
assert_raises LiveAST::ASTNotFoundError do
|
46
|
-
klass.instance_method(:g).to_ast
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def cached_method_from_eval
|
51
|
-
klass = Class.new do
|
52
|
-
ast_eval %{
|
53
|
-
def f ; end
|
54
|
-
def g ; end
|
55
|
-
}, binding
|
56
|
-
end
|
57
|
-
|
58
|
-
f_ast = klass.instance_method(:f).to_ast
|
59
|
-
|
60
|
-
LiveAST.flush_cache
|
61
|
-
|
62
|
-
assert_equal f_ast.object_id,
|
63
|
-
klass.instance_method(:f).to_ast.object_id
|
64
|
-
|
65
|
-
assert_raises LiveAST::ASTNotFoundError do
|
66
|
-
klass.instance_method(:g).to_ast
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def lost_method_from_require
|
71
|
-
klass = Class.new do
|
72
|
-
def f; end
|
73
|
-
|
74
|
-
def g; end
|
75
|
-
end
|
76
|
-
|
77
|
-
# check that previous flushing did not cause side effect
|
78
|
-
assert_nothing_raised do
|
79
|
-
klass.instance_method(:f).to_ast
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def flush_lambda
|
84
|
-
a, b = ast_eval %{
|
85
|
-
[
|
86
|
-
lambda { "aaa" },
|
87
|
-
lambda { "bbb" },
|
88
|
-
]
|
89
|
-
}, binding
|
90
|
-
|
91
|
-
a_ast = a.to_ast
|
92
|
-
assert_equal no_arg_block(:lambda, "aaa"), a_ast
|
93
|
-
|
94
|
-
LiveAST.flush_cache
|
95
|
-
|
96
|
-
assert_equal a_ast.object_id, a.to_ast.object_id
|
97
|
-
|
98
|
-
assert_raises LiveAST::ASTNotFoundError do
|
99
|
-
b.to_ast
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "main"
|
4
|
-
|
5
|
-
class ASTReloadTest < ReplaceEvalTest
|
6
|
-
include FileUtils
|
7
|
-
|
8
|
-
def test_reloading
|
9
|
-
ast_reload
|
10
|
-
end
|
11
|
-
|
12
|
-
def ast_reload
|
13
|
-
code1 = %{
|
14
|
-
class ASTReloadTest::C
|
15
|
-
def f
|
16
|
-
"first C#f"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
}
|
20
|
-
|
21
|
-
code2 = %{
|
22
|
-
class ASTReloadTest::C
|
23
|
-
def f
|
24
|
-
"second C#f"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
}
|
28
|
-
|
29
|
-
temp_file code1 do |file|
|
30
|
-
load file
|
31
|
-
|
32
|
-
LiveAST.ast(C.instance_method(:f))
|
33
|
-
|
34
|
-
write_file file, code2
|
35
|
-
load file
|
36
|
-
|
37
|
-
assert_equal no_arg_def(:f, "second C#f"),
|
38
|
-
LiveAST.ast(C.instance_method(:f))
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|