mvz-live_ast 1.1.1 → 1.1.2
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 +14 -0
- data/Rakefile +48 -9
- data/devel/levitate.rb +5 -674
- data/lib/live_ast/common.rb +22 -21
- data/lib/live_ast/error.rb +2 -2
- data/lib/live_ast/irb_spy.rb +4 -6
- data/lib/live_ast/linker.rb +7 -7
- data/lib/live_ast/loader.rb +6 -6
- data/lib/live_ast/reader.rb +2 -2
- data/lib/live_ast/replace_eval.rb +27 -31
- data/lib/live_ast/replace_load.rb +1 -1
- data/lib/live_ast/ruby_parser.rb +24 -22
- data/lib/live_ast/ruby_parser/test.rb +183 -179
- data/lib/live_ast/ruby_parser/unparser.rb +10 -6
- data/lib/live_ast/to_ast.rb +1 -1
- data/lib/live_ast/version.rb +1 -1
- data/test/ast_eval/ast_eval_test.rb +11 -0
- data/test/ast_load/ast_load_test.rb +45 -0
- data/test/backtrace_test.rb +29 -28
- data/test/{noninvasive_test.rb → base/noninvasive_test.rb} +7 -5
- data/test/base/reload_test.rb +41 -0
- data/test/covert_define_method_test.rb +1 -1
- data/test/define_method_test.rb +5 -5
- data/test/encoding_test.rb +5 -5
- data/test/error_test.rb +6 -6
- data/test/eval_test.rb +7 -7
- data/test/flush_cache_test.rb +6 -6
- data/test/full/ast_reload_test.rb +39 -0
- data/test/{replace_eval_test.rb → full/replace_eval_test.rb} +31 -12
- data/test/irb_test.rb +1 -1
- data/test/lambda_test.rb +7 -0
- data/test/load_path_test.rb +12 -12
- data/test/load_test.rb +35 -35
- data/test/main.rb +19 -27
- data/test/nested_test.rb +1 -1
- data/test/readme_test.rb +1 -3
- data/test/recursive_eval_test.rb +2 -3
- data/test/redefine_method_test.rb +2 -2
- data/test/rubygems_test.rb +1 -1
- data/test/rubyspec_test.rb +3 -3
- data/test/stdlib_test.rb +1 -1
- data/test/thread_test.rb +1 -2
- data/test/to_ast/to_ast_feature_test.rb +11 -0
- data/test/to_ruby/to_ruby_feature_test.rb +11 -0
- data/test/{to_ruby_test.rb → to_ruby/to_ruby_test.rb} +2 -2
- metadata +93 -91
- data/test/ast_eval_feature_test.rb +0 -11
- data/test/ast_load_feature_test.rb +0 -11
- data/test/reload_test.rb +0 -105
- data/test/to_ast_feature_test.rb +0 -15
- data/test/to_ruby_feature_test.rb +0 -15
data/test/flush_cache_test.rb
CHANGED
@@ -15,8 +15,8 @@ define_unsorted_test_case "FlushCacheTest", RegularTest do
|
|
15
15
|
|
16
16
|
def uncached_method_from_require
|
17
17
|
klass = Class.new do
|
18
|
-
def f
|
19
|
-
def g
|
18
|
+
def f; end
|
19
|
+
def g; end
|
20
20
|
end
|
21
21
|
|
22
22
|
LiveAST.flush_cache
|
@@ -66,8 +66,8 @@ define_unsorted_test_case "FlushCacheTest", RegularTest do
|
|
66
66
|
|
67
67
|
def lost_method_from_require
|
68
68
|
klass = Class.new do
|
69
|
-
def f
|
70
|
-
def g
|
69
|
+
def f; end
|
70
|
+
def g; end
|
71
71
|
end
|
72
72
|
|
73
73
|
# check that previous flushing did not cause side effect
|
@@ -83,14 +83,14 @@ define_unsorted_test_case "FlushCacheTest", RegularTest do
|
|
83
83
|
lambda { "bbb" },
|
84
84
|
]
|
85
85
|
}, binding
|
86
|
-
|
86
|
+
|
87
87
|
a_ast = a.to_ast
|
88
88
|
assert_equal no_arg_block(:lambda, "aaa"), a_ast
|
89
89
|
|
90
90
|
LiveAST.flush_cache
|
91
91
|
|
92
92
|
assert_equal a_ast.object_id, a.to_ast.object_id
|
93
|
-
|
93
|
+
|
94
94
|
assert_raises LiveAST::ASTNotFoundError do
|
95
95
|
b.to_ast
|
96
96
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'main'
|
2
|
+
|
3
|
+
class ASTReloadTest < ReplaceEvalTest
|
4
|
+
include FileUtils
|
5
|
+
|
6
|
+
def test_reloading
|
7
|
+
ast_reload
|
8
|
+
end
|
9
|
+
|
10
|
+
def ast_reload
|
11
|
+
code_1 = %{
|
12
|
+
class ASTReloadTest::C
|
13
|
+
def f
|
14
|
+
"first C#f"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
code_2 = %{
|
20
|
+
class ASTReloadTest::C
|
21
|
+
def f
|
22
|
+
"second C#f"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
}
|
26
|
+
|
27
|
+
temp_file code_1 do |file|
|
28
|
+
load file
|
29
|
+
|
30
|
+
LiveAST.ast(C.instance_method(:f))
|
31
|
+
|
32
|
+
write_file file, code_2
|
33
|
+
load file
|
34
|
+
|
35
|
+
assert_equal no_arg_def(:f, "second C#f"),
|
36
|
+
LiveAST.ast(C.instance_method(:f))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'main'
|
2
2
|
|
3
|
-
class
|
3
|
+
class FullReplaceEvalTest < ReplaceEvalTest
|
4
4
|
RESULT = {}
|
5
5
|
|
6
6
|
def setup
|
@@ -34,7 +34,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
34
34
|
|
35
35
|
def test_def_class
|
36
36
|
DEFINE_B.call
|
37
|
-
assert_equal "
|
37
|
+
assert_equal "FullReplaceEvalTest::B", B.name
|
38
38
|
assert_equal binop_def(:f, :/), B.instance_method(:f).to_ast
|
39
39
|
end
|
40
40
|
|
@@ -94,7 +94,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
94
94
|
}
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
module S
|
99
99
|
class T
|
100
100
|
eval %{
|
@@ -105,7 +105,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def test_const_lookup_3
|
110
110
|
DEFINE_QS.call
|
111
111
|
Q::R.new.f
|
@@ -157,7 +157,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
157
157
|
end
|
158
158
|
assert_equal orig.message, live.message
|
159
159
|
|
160
|
-
[[nil], [Object.new], [3], [4,3,2], (1..10).to_a].each do |args|
|
160
|
+
[[nil], [Object.new], [3], [4, 3, 2], (1..10).to_a].each do |args|
|
161
161
|
orig = assert_raises ArgumentError, TypeError do
|
162
162
|
Object.new.live_ast_original_instance_eval(*args)
|
163
163
|
end
|
@@ -169,12 +169,31 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
+
describe "instance_eval argument errors" do
|
173
|
+
before do
|
174
|
+
require 'live_ast/full'
|
175
|
+
end
|
176
|
+
|
177
|
+
let(:orig) { assert_raises(ArgumentError, TypeError) {
|
178
|
+
Object.new.live_ast_original_instance_eval(*args) } }
|
179
|
+
let(:live) { assert_raises(ArgumentError, TypeError) {
|
180
|
+
Object.new.instance_eval(*args) } }
|
181
|
+
|
182
|
+
describe "when the second argument is nil" do
|
183
|
+
let(:args) { ['1', nil] }
|
184
|
+
it "raises the same error as the original" do
|
185
|
+
assert_equal orig.message, live.message
|
186
|
+
assert_equal orig.class, live.class
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
172
191
|
def test_instance_eval_arg_error_with_block
|
173
192
|
orig = assert_raises ArgumentError do
|
174
|
-
Object.new.live_ast_original_instance_eval(3,4,5) {
|
193
|
+
Object.new.live_ast_original_instance_eval(3, 4, 5) {}
|
175
194
|
end
|
176
195
|
live = assert_raises ArgumentError do
|
177
|
-
Object.new.instance_eval(3,4,5) {
|
196
|
+
Object.new.instance_eval(3, 4, 5) {}
|
178
197
|
end
|
179
198
|
assert_equal orig.message, live.message
|
180
199
|
end
|
@@ -223,7 +242,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
223
242
|
self[:g] = lambda { "g" }
|
224
243
|
}
|
225
244
|
assert_equal y, live[:y]
|
226
|
-
|
245
|
+
|
227
246
|
assert_equal no_arg_block(:lambda, "g"), live[:g].to_ast
|
228
247
|
end
|
229
248
|
|
@@ -309,7 +328,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
309
328
|
unfixable do
|
310
329
|
assert_equal orig, live
|
311
330
|
end
|
312
|
-
|
331
|
+
|
313
332
|
live.first.sub!(/#{Regexp.quote LiveAST::Linker::REVISION_TOKEN}.*\Z/, "")
|
314
333
|
assert_equal orig, live
|
315
334
|
assert_equal ["test", 102], live
|
@@ -388,7 +407,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
388
407
|
def test_basic_object
|
389
408
|
::BasicObject.new.instance_eval %{
|
390
409
|
t = 33
|
391
|
-
::
|
410
|
+
::FullReplaceEvalTest::RESULT[:bo_test] = t + 44
|
392
411
|
}
|
393
412
|
assert_equal 77, RESULT[:bo_test]
|
394
413
|
end
|
@@ -400,7 +419,7 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
|
|
400
419
|
end
|
401
420
|
|
402
421
|
def test_instance_variables
|
403
|
-
assert_equal 99, Z.new.instance_eval{ @t }
|
422
|
+
assert_equal 99, Z.new.instance_eval { @t }
|
404
423
|
assert_equal 99, Z.new.instance_eval("@t")
|
405
424
|
end
|
406
425
|
end
|
data/test/irb_test.rb
CHANGED
data/test/lambda_test.rb
CHANGED
@@ -26,6 +26,13 @@ class LambdaTest < RegularTest
|
|
26
26
|
assert_equal expected, a.to_ast
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_stabby_lambda
|
30
|
+
a = ->(x, y) { x - y }
|
31
|
+
|
32
|
+
expected = binop_block(:lambda, :-)
|
33
|
+
assert_equal expected, a.to_ast
|
34
|
+
end
|
35
|
+
|
29
36
|
def test_proc
|
30
37
|
a = proc { |x, y| x / y }
|
31
38
|
|
data/test/load_path_test.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require_relative 'main'
|
2
2
|
|
3
|
-
class
|
3
|
+
class LoadPathTest < BaseTest
|
4
4
|
include FileUtils
|
5
|
-
|
5
|
+
|
6
6
|
def test_load_path
|
7
7
|
$LOAD_PATH.unshift DATA_DIR
|
8
8
|
begin
|
@@ -17,9 +17,9 @@ class AAA_LoadPathTest < BaseTest
|
|
17
17
|
$LOAD_PATH.shift
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def test_chdir
|
22
|
-
mkdir DATA_DIR, :
|
22
|
+
mkdir DATA_DIR, verbose: false rescue nil
|
23
23
|
Dir.chdir(DATA_DIR) do
|
24
24
|
check_load
|
25
25
|
check_errors
|
@@ -43,9 +43,9 @@ class AAA_LoadPathTest < BaseTest
|
|
43
43
|
Object.send(:remove_method, :hello) rescue nil
|
44
44
|
load "foo.rb"
|
45
45
|
assert_equal "password", hello
|
46
|
-
|
46
|
+
|
47
47
|
write_file path, code_2
|
48
|
-
|
48
|
+
|
49
49
|
Object.send(:remove_method, :goodbye) rescue nil
|
50
50
|
LiveAST.load "foo.rb"
|
51
51
|
assert_equal "bubbleboy", goodbye
|
@@ -63,13 +63,13 @@ class AAA_LoadPathTest < BaseTest
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def check_errors
|
66
|
-
temp_file "# do nothing", "foo.rb" do |
|
66
|
+
temp_file "# do nothing", "foo.rb" do |_path|
|
67
67
|
[
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
"foo",
|
69
|
+
"",
|
70
|
+
"/usr",
|
71
|
+
".",
|
72
|
+
"..",
|
73
73
|
].each do |file|
|
74
74
|
compare_load_errors(file)
|
75
75
|
end
|
data/test/load_test.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require_relative 'main'
|
2
2
|
require_relative '../devel/levitate'
|
3
3
|
|
4
|
-
class
|
4
|
+
class LoadFileTest < BaseTest
|
5
5
|
class << self
|
6
6
|
attr_accessor :flag
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_a_no_locals_created
|
10
10
|
code = %{
|
11
|
-
|
11
|
+
LoadFileTest.flag = :code_a
|
12
12
|
FOO = 77
|
13
13
|
x = 33
|
14
14
|
y = 99
|
@@ -17,8 +17,8 @@ class AAA_LoadFileTest < BaseTest
|
|
17
17
|
temp_file code do |file|
|
18
18
|
ret = LiveAST.load file
|
19
19
|
assert_equal true, ret
|
20
|
-
assert_equal :code_a,
|
21
|
-
|
20
|
+
assert_equal :code_a, LoadFileTest.flag
|
21
|
+
|
22
22
|
assert_raises NameError do
|
23
23
|
eval("x", TOPLEVEL_BINDING)
|
24
24
|
end
|
@@ -29,33 +29,33 @@ class AAA_LoadFileTest < BaseTest
|
|
29
29
|
|
30
30
|
def test_b_no_locals_modified
|
31
31
|
code = %{
|
32
|
-
|
32
|
+
LoadFileTest.flag = :code_b
|
33
33
|
r = 55
|
34
34
|
}
|
35
35
|
|
36
36
|
temp_file code do |file|
|
37
37
|
eval("r = 66", TOPLEVEL_BINDING)
|
38
|
-
|
38
|
+
|
39
39
|
ret = LiveAST.load file
|
40
40
|
assert_equal true, ret
|
41
|
-
assert_equal :code_b,
|
42
|
-
|
41
|
+
assert_equal :code_b, LoadFileTest.flag
|
42
|
+
|
43
43
|
actual = eval("r", TOPLEVEL_BINDING)
|
44
44
|
assert_equal 66, actual
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def test_c_wrap
|
49
49
|
code = %{
|
50
|
-
|
50
|
+
LoadFileTest.flag = :code_c
|
51
51
|
ZOOM = 111
|
52
52
|
}
|
53
53
|
|
54
54
|
temp_file code do |file|
|
55
55
|
ret = LiveAST.load file, true
|
56
56
|
assert_equal true, ret
|
57
|
-
assert_equal :code_c,
|
58
|
-
|
57
|
+
assert_equal :code_c, LoadFileTest.flag
|
58
|
+
|
59
59
|
assert_raises NameError do
|
60
60
|
ZOOM
|
61
61
|
end
|
@@ -68,12 +68,12 @@ class AAA_LoadFileTest < BaseTest
|
|
68
68
|
|
69
69
|
def test_d_empty_locals_list
|
70
70
|
code = %{
|
71
|
-
|
71
|
+
LoadFileTest.from_d
|
72
72
|
}
|
73
|
-
|
73
|
+
|
74
74
|
temp_file code do |file|
|
75
75
|
LiveAST.load file
|
76
|
-
assert_equal :code_d,
|
76
|
+
assert_equal :code_d, LoadFileTest.flag
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -81,27 +81,27 @@ class AAA_LoadFileTest < BaseTest
|
|
81
81
|
lib = File.expand_path(File.dirname(__FILE__) + "/../lib")
|
82
82
|
|
83
83
|
[
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
84
|
+
# respects a loaded file setting $VERBOSE = true
|
85
|
+
[
|
86
|
+
"false",
|
87
|
+
"true",
|
88
|
+
lambda { |file|
|
89
|
+
Levitate.run file
|
90
|
+
}
|
91
|
+
],
|
92
|
+
|
93
|
+
# unfixable: does not respect a loaded file setting $VERBOSE = nil
|
94
|
+
[
|
95
|
+
"true",
|
96
|
+
"false",
|
97
|
+
lambda { |file|
|
98
|
+
unfixable do
|
99
|
+
assert_nothing_raised do
|
100
|
+
Levitate.run file
|
101
|
+
end
|
101
102
|
end
|
102
|
-
|
103
|
-
|
104
|
-
]
|
103
|
+
}
|
104
|
+
]
|
105
105
|
].each do |main_value, loaded_value, action|
|
106
106
|
loaded_code = %{
|
107
107
|
$VERBOSE = #{loaded_value}
|
data/test/main.rb
CHANGED
@@ -5,7 +5,6 @@ require 'pp'
|
|
5
5
|
require 'find'
|
6
6
|
require 'fileutils'
|
7
7
|
|
8
|
-
require 'minitest/unit'
|
9
8
|
require 'minitest/mock'
|
10
9
|
require 'minitest/autorun'
|
11
10
|
|
@@ -19,10 +18,10 @@ def define_unsorted_test_case(name, superclass, &block)
|
|
19
18
|
Object.const_set "#{letter}#{name}", klass
|
20
19
|
end
|
21
20
|
|
22
|
-
class JLMiniTest < MiniTest::
|
21
|
+
class JLMiniTest < MiniTest::Test
|
23
22
|
def self.test_methods
|
24
23
|
default = super
|
25
|
-
onlies = default.select { |m| m =~
|
24
|
+
onlies = default.select { |m| m =~ /__only\Z/ }
|
26
25
|
if onlies.empty?
|
27
26
|
default
|
28
27
|
else
|
@@ -32,7 +31,7 @@ class JLMiniTest < MiniTest::Unit::TestCase
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def delim(char)
|
35
|
-
"\n" << (char*72) << "\n"
|
34
|
+
"\n" << (char * 72) << "\n"
|
36
35
|
end
|
37
36
|
|
38
37
|
def mu_pp(obj)
|
@@ -42,11 +41,9 @@ class JLMiniTest < MiniTest::Unit::TestCase
|
|
42
41
|
end
|
43
42
|
|
44
43
|
def unfixable
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rescue MiniTest::Assertion
|
49
|
-
end
|
44
|
+
yield
|
45
|
+
raise "claimed to be unfixable, but assertion succeeded"
|
46
|
+
rescue MiniTest::Assertion
|
50
47
|
end
|
51
48
|
|
52
49
|
def assert_nothing_raised
|
@@ -54,13 +51,13 @@ class JLMiniTest < MiniTest::Unit::TestCase
|
|
54
51
|
assert_nil nil
|
55
52
|
rescue => ex
|
56
53
|
raise MiniTest::Assertion,
|
57
|
-
|
54
|
+
exception_details(ex, "Expected nothing raised, but got:")
|
58
55
|
end
|
59
56
|
|
60
|
-
%w
|
57
|
+
%w(
|
61
58
|
empty equal in_delta in_epsilon includes instance_of
|
62
59
|
kind_of match nil operator respond_to same
|
63
|
-
|
60
|
+
).each { |name|
|
64
61
|
alias_method "assert_not_#{name}", "refute_#{name}"
|
65
62
|
}
|
66
63
|
end
|
@@ -97,14 +94,12 @@ class BaseTest < JLMiniTest
|
|
97
94
|
end
|
98
95
|
|
99
96
|
def exception_backtrace
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
e.backtrace
|
104
|
-
end
|
97
|
+
yield
|
98
|
+
rescue Exception => e
|
99
|
+
e.backtrace
|
105
100
|
end
|
106
101
|
|
107
|
-
def ignore(*
|
102
|
+
def ignore(*_args)
|
108
103
|
end
|
109
104
|
end
|
110
105
|
|
@@ -122,18 +117,15 @@ class ReplaceEvalTest < BaseTest
|
|
122
117
|
require 'live_ast/full'
|
123
118
|
true
|
124
119
|
rescue LoadError
|
125
|
-
if RUBY_ENGINE == "ruby"
|
126
|
-
raise "need: gem install boc"
|
127
|
-
end
|
120
|
+
raise "need: gem install binding_of_caller" if RUBY_ENGINE == "ruby"
|
128
121
|
false
|
129
122
|
end
|
130
123
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
124
|
+
return if ok
|
125
|
+
self.class.class_eval do
|
126
|
+
instance_methods(false).each do |m|
|
127
|
+
remove_method(m)
|
128
|
+
define_method(m) {}
|
137
129
|
end
|
138
130
|
end
|
139
131
|
end
|