mvz-live_ast 1.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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.rdoc +93 -0
  3. data/README.rdoc +419 -0
  4. data/Rakefile +21 -0
  5. data/devel/levitate.rb +853 -0
  6. data/devel/levitate_config.rb +4 -0
  7. data/lib/live_ast.rb +4 -0
  8. data/lib/live_ast/ast_eval.rb +11 -0
  9. data/lib/live_ast/ast_load.rb +15 -0
  10. data/lib/live_ast/base.rb +73 -0
  11. data/lib/live_ast/common.rb +48 -0
  12. data/lib/live_ast/error.rb +20 -0
  13. data/lib/live_ast/evaler.rb +32 -0
  14. data/lib/live_ast/full.rb +2 -0
  15. data/lib/live_ast/irb_spy.rb +43 -0
  16. data/lib/live_ast/linker.rb +122 -0
  17. data/lib/live_ast/loader.rb +60 -0
  18. data/lib/live_ast/reader.rb +26 -0
  19. data/lib/live_ast/replace_eval.rb +121 -0
  20. data/lib/live_ast/replace_load.rb +14 -0
  21. data/lib/live_ast/replace_raise.rb +18 -0
  22. data/lib/live_ast/ruby_parser.rb +36 -0
  23. data/lib/live_ast/ruby_parser/test.rb +197 -0
  24. data/lib/live_ast/ruby_parser/unparser.rb +13 -0
  25. data/lib/live_ast/to_ast.rb +26 -0
  26. data/lib/live_ast/to_ruby.rb +24 -0
  27. data/lib/live_ast/version.rb +3 -0
  28. data/test/ast_eval_feature_test.rb +11 -0
  29. data/test/ast_load_feature_test.rb +11 -0
  30. data/test/attr_test.rb +24 -0
  31. data/test/backtrace_test.rb +158 -0
  32. data/test/covert_define_method_test.rb +23 -0
  33. data/test/def_test.rb +35 -0
  34. data/test/define_method_test.rb +67 -0
  35. data/test/define_singleton_method_test.rb +15 -0
  36. data/test/encoding_test.rb +52 -0
  37. data/test/encoding_test/bad.rb +1 -0
  38. data/test/encoding_test/cp932.rb +6 -0
  39. data/test/encoding_test/default.rb +5 -0
  40. data/test/encoding_test/eucjp.rb +6 -0
  41. data/test/encoding_test/koi8.rb +6 -0
  42. data/test/encoding_test/koi8_shebang.rb +7 -0
  43. data/test/encoding_test/koi8_with_utf8bom.rb +6 -0
  44. data/test/encoding_test/usascii.rb +6 -0
  45. data/test/encoding_test/usascii_with_utf8bom.rb +6 -0
  46. data/test/encoding_test/utf8.rb +6 -0
  47. data/test/encoding_test/utf8bom.rb +6 -0
  48. data/test/encoding_test/utf8bom_only.rb +5 -0
  49. data/test/encoding_test/utf8dos.rb +6 -0
  50. data/test/encoding_test/utf8mac.rb +6 -0
  51. data/test/encoding_test/utf8mac_alt.rb +6 -0
  52. data/test/encoding_test/utf8unix.rb +6 -0
  53. data/test/error_test.rb +116 -0
  54. data/test/eval_test.rb +269 -0
  55. data/test/flush_cache_test.rb +98 -0
  56. data/test/irb_test.rb +25 -0
  57. data/test/lambda_test.rb +56 -0
  58. data/test/load_path_test.rb +78 -0
  59. data/test/load_test.rb +123 -0
  60. data/test/main.rb +140 -0
  61. data/test/nested_test.rb +29 -0
  62. data/test/noninvasive_test.rb +51 -0
  63. data/test/readme_test.rb +16 -0
  64. data/test/recursive_eval_test.rb +52 -0
  65. data/test/redefine_method_test.rb +83 -0
  66. data/test/reload_test.rb +105 -0
  67. data/test/replace_eval_test.rb +405 -0
  68. data/test/rubygems_test.rb +25 -0
  69. data/test/rubyspec_test.rb +39 -0
  70. data/test/singleton_test.rb +25 -0
  71. data/test/stdlib_test.rb +13 -0
  72. data/test/thread_test.rb +44 -0
  73. data/test/to_ast_feature_test.rb +15 -0
  74. data/test/to_ruby_feature_test.rb +15 -0
  75. data/test/to_ruby_test.rb +87 -0
  76. metadata +275 -0
@@ -0,0 +1,5 @@
1
+ module EncodingTest
2
+ def default_string
3
+ "Cats and large boxes." # google translate
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: euc-jp -*-
2
+ module EncodingTest
3
+ def eucjp_string
4
+ "�礭��Ȣ�Ȥͤ���"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: koi8-r -*-
2
+ module EncodingTest
3
+ def koi8_string
4
+ "� ���������� ������� ���������� �� 20 ��������"
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: koi8-r -*-
3
+ module EncodingTest
4
+ def koi8_shebang_string
5
+ "� ���������� ������� ���������� �� 20 ��������"
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: koi8-r -*-
2
+ module EncodingTest
3
+ def koi8_with_utf8bom_string
4
+ "� ���������� ������� ���������� �� 20 ��������"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: us-ascii
2
+ module EncodingTest
3
+ def usascii_string
4
+ "Cats and large boxes." # google translate
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: us-ascii
2
+ module EncodingTest
3
+ def usascii_with_utf8bom_string
4
+ "Cats and large boxes."
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ module EncodingTest
3
+ def utf8_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ module EncodingTest
3
+ def utf8bom_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module EncodingTest
2
+ def utf8bom_only_string
3
+ "大きな箱とねこ。"
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8-dos -*-
2
+ module EncodingTest
3
+ def utf8dos_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8-mac -*-
2
+ module EncodingTest
3
+ def utf8mac_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf8-mac -*-
2
+ module EncodingTest
3
+ def utf8mac_alt_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8-unix -*-
2
+ module EncodingTest
3
+ def utf8unix_string
4
+ "大きな箱とねこ。"
5
+ end
6
+ end
@@ -0,0 +1,116 @@
1
+ require_relative 'main'
2
+
3
+ class ErrorTest < RegularTest
4
+ def test_multiple_lambda_same_line
5
+ a = lambda { } ; b = lambda { }
6
+ ignore(b)
7
+
8
+ assert_raises LiveAST::MultipleDefinitionsOnSameLineError do
9
+ a.to_ast
10
+ end
11
+ end
12
+
13
+ DEFINE_A = lambda do
14
+ class A
15
+ def f ; end ; def g ; end
16
+ end
17
+ end
18
+
19
+ def test_multi_defs
20
+ DEFINE_A.call
21
+ assert_raises LiveAST::MultipleDefinitionsOnSameLineError do
22
+ A.instance_method(:f).to_ast
23
+ end
24
+ end
25
+
26
+ def test_ast_not_found
27
+ assert_raises LiveAST::ASTNotFoundError do
28
+ File.method(:open).to_ast
29
+ end
30
+ end
31
+
32
+ def test_arg_error_too_many
33
+ orig = assert_raises ArgumentError do
34
+ eval("s", binding, "f", 99, nil)
35
+ end
36
+
37
+ live = assert_raises ArgumentError do
38
+ ast_eval("s", binding, "f", 99, nil)
39
+ end
40
+
41
+ assert_equal orig.message.sub("1..4", "2..4"), live.message
42
+ end
43
+
44
+ def test_bad_args
45
+ [99, Object.new, File].each do |bad|
46
+ orig = assert_raises TypeError do
47
+ eval(bad, binding)
48
+ end
49
+ live = assert_raises TypeError do
50
+ ast_eval(bad, binding)
51
+ end
52
+ assert_equal orig.message, live.message
53
+
54
+ orig = assert_raises TypeError do
55
+ eval("3 + 4", binding, bad)
56
+ end
57
+ live = assert_raises TypeError do
58
+ ast_eval("3 + 4", binding, bad)
59
+ end
60
+ assert_equal orig.message, live.message
61
+ end
62
+ end
63
+
64
+ def test_raw_eval
65
+ f = eval("lambda { }")
66
+ assert_raises LiveAST::RawEvalError do
67
+ f.to_ast
68
+ end
69
+ end
70
+
71
+ def test_reload_with_raw_eval_1
72
+ ast_eval("lambda { }", binding)
73
+ eval("lambda { }")
74
+ end
75
+
76
+ def test_reload_with_raw_eval_2
77
+ c = ast_eval %{
78
+ Class.new do
79
+ def f
80
+ end
81
+ end
82
+ }, binding
83
+ c.module_eval do
84
+ eval %{
85
+ remove_method :f
86
+ def f(x, y)
87
+ x + y
88
+ end
89
+ }
90
+ nil
91
+ end
92
+
93
+ assert_raises LiveAST::RawEvalError do
94
+ c.instance_method(:f).to_ast
95
+ end
96
+ end
97
+
98
+ def test_bad_binding
99
+ orig = assert_raises TypeError do
100
+ eval("", "bogus")
101
+ end
102
+
103
+ live = assert_raises TypeError do
104
+ ast_eval("", "bogus")
105
+ end
106
+
107
+ assert_equal orig.message, live.message
108
+ end
109
+
110
+ def test_shenanigans
111
+ error = assert_raises RuntimeError do
112
+ LiveAST.load "foo.rb|ast@4"
113
+ end
114
+ assert_match(/revision token/, error.message)
115
+ end
116
+ end
@@ -0,0 +1,269 @@
1
+ require_relative 'main'
2
+
3
+ class EvalTest < RegularTest
4
+ DEFINE_A = lambda do
5
+ class A
6
+ ast_eval %{
7
+ def f(x, y)
8
+ x + y
9
+ end
10
+ }, binding
11
+ end
12
+ end
13
+
14
+ def test_eval_method
15
+ DEFINE_A.call
16
+ assert_equal "#{self.class}::A", A.name
17
+ assert_equal A, A.instance_method(:f).owner
18
+
19
+ assert_equal binop_def(:f, :+),
20
+ A.instance_method(:f).to_ast
21
+
22
+ assert_equal binop_def(:f, :+),
23
+ A.new.method(:f).to_ast
24
+ end
25
+
26
+ DEFINE_B = lambda do
27
+ ast_eval %{
28
+ class B
29
+ def f(x, y)
30
+ x * y
31
+ end
32
+ end
33
+ }, binding
34
+ end
35
+
36
+ def test_eval_class
37
+ DEFINE_B.call
38
+ assert_equal "#{self.class}::B", B.name
39
+ assert_equal B, B.instance_method(:f).owner
40
+
41
+ assert_equal binop_def(:f, :*),
42
+ B.instance_method(:f).to_ast
43
+
44
+ assert_equal binop_def(:f, :*),
45
+ B.new.method(:f).to_ast
46
+ end
47
+
48
+ def test_eval_method_anon
49
+ klass = Class.new do
50
+ ast_eval %{
51
+ def f(x, y)
52
+ x - y
53
+ end
54
+ }, binding
55
+ end
56
+
57
+ assert_nil klass.name
58
+ assert_equal klass, klass.instance_method(:f).owner
59
+
60
+ assert_equal binop_def(:f, :-),
61
+ klass.instance_method(:f).to_ast
62
+
63
+ assert_equal binop_def(:f, :-),
64
+ klass.new.method(:f).to_ast
65
+ end
66
+
67
+ def test_eval_class_anon
68
+ klass = ast_eval %{
69
+ Class.new do
70
+ def f(x, y)
71
+ x / y
72
+ end
73
+ end
74
+ }, binding
75
+
76
+ assert_nil klass.name
77
+ assert_equal klass, klass.instance_method(:f).owner
78
+
79
+ assert_equal binop_def(:f, :/),
80
+ klass.instance_method(:f).to_ast
81
+
82
+ assert_equal binop_def(:f, :/),
83
+ klass.new.method(:f).to_ast
84
+ end
85
+
86
+ DEFINE_C = lambda do
87
+ class C
88
+ ast_eval %{
89
+ define_method :g do |x, y|
90
+ x + y
91
+ end
92
+ }, binding
93
+ end
94
+ end
95
+
96
+ def test_eval_method_dynamic
97
+ DEFINE_C.call
98
+ assert_equal "#{self.class}::C", C.name
99
+ assert_equal C, C.instance_method(:g).owner
100
+
101
+ assert_equal binop_define_method(:g, :+),
102
+ C.instance_method(:g).to_ast
103
+
104
+ assert_equal binop_define_method(:g, :+),
105
+ C.new.method(:g).to_ast
106
+ end
107
+
108
+ DEFINE_D = lambda do
109
+ ast_eval %{
110
+ class D
111
+ define_method :g do |x, y|
112
+ x * y
113
+ end
114
+ end
115
+ }, binding
116
+ end
117
+
118
+ def test_eval_class_dynamic
119
+ DEFINE_D.call
120
+ assert_equal "#{self.class}::D", D.name
121
+ assert_equal D, D.instance_method(:g).owner
122
+
123
+ assert_equal binop_define_method(:g, :*),
124
+ D.instance_method(:g).to_ast
125
+
126
+ assert_equal binop_define_method(:g, :*),
127
+ D.new.method(:g).to_ast
128
+ end
129
+
130
+ def test_eval_method_anon_dynamic
131
+ klass = Class.new do
132
+ ast_eval %{
133
+ define_method :g do |x, y|
134
+ x - y
135
+ end
136
+ }, binding
137
+ end
138
+
139
+ assert_nil klass.name
140
+ assert_equal klass, klass.instance_method(:g).owner
141
+
142
+ assert_equal binop_define_method(:g, :-),
143
+ klass.instance_method(:g).to_ast
144
+
145
+ assert_equal binop_define_method(:g, :-),
146
+ klass.new.method(:g).to_ast
147
+ end
148
+
149
+ def test_eval_class_anon_dynamic
150
+ klass = ast_eval %{
151
+ Class.new do
152
+ define_method :g do |x, y|
153
+ x / y
154
+ end
155
+ end
156
+ }, binding
157
+
158
+ assert_nil klass.name
159
+ assert_equal klass, klass.instance_method(:g).owner
160
+
161
+ assert_equal binop_define_method(:g, :/),
162
+ klass.instance_method(:g).to_ast
163
+
164
+ assert_equal binop_define_method(:g, :/),
165
+ klass.new.method(:g).to_ast
166
+ end
167
+
168
+ DEFINE_GH = lambda do
169
+ ast_eval %{
170
+ class G
171
+ def f
172
+ "G#f"
173
+ end
174
+ end
175
+
176
+ class H
177
+ def g
178
+ "H#g"
179
+ end
180
+ end
181
+ }, binding
182
+ end
183
+
184
+ def test_reuse_string
185
+ DEFINE_GH.call
186
+ assert_equal "#{self.class}::G", G.name
187
+ assert_equal "#{self.class}::H", H.name
188
+
189
+ assert_equal no_arg_def(:f, "G#f"),
190
+ G.instance_method(:f).to_ast
191
+
192
+ assert_equal no_arg_def(:f, "G#f"),
193
+ G.new.method(:f).to_ast
194
+
195
+ assert_equal no_arg_def(:g, "H#g"),
196
+ H.instance_method(:g).to_ast
197
+
198
+ assert_equal no_arg_def(:g, "H#g"),
199
+ H.new.method(:g).to_ast
200
+ end
201
+
202
+ def test_module_eval
203
+ klass = Class.new
204
+ klass.module_eval do
205
+ ast_eval %{
206
+ def f
207
+ "z"
208
+ end
209
+ }, binding
210
+ end
211
+
212
+ assert_equal klass, klass.instance_method(:f).owner
213
+
214
+ assert_equal no_arg_def(:f, "z"),
215
+ klass.instance_method(:f).to_ast
216
+
217
+ assert_equal no_arg_def(:f, "z"),
218
+ klass.new.method(:f).to_ast
219
+ end
220
+
221
+ def test_singleton_class
222
+ obj = Object.new
223
+ obj.singleton_class.module_eval do
224
+ ast_eval %{
225
+ def f
226
+ "singleton"
227
+ end
228
+ }, binding
229
+ end
230
+
231
+ assert_equal no_arg_def(:f, "singleton"),
232
+ obj.method(:f).to_ast
233
+ end
234
+
235
+ def test_proc_in_eval
236
+ a = ast_eval %{ proc { |x, y| x + y } }, binding
237
+
238
+ assert_equal binop_block(:proc, :+), a.to_ast
239
+ end
240
+
241
+ def test_proc_new_in_eval
242
+ a = ast_eval %{ Proc.new { |x, y| x * y } }, binding
243
+
244
+ assert_equal binop_proc_new(:*), a.to_ast
245
+ end
246
+
247
+ def test_method_block_in_eval
248
+ a = ast_eval %{ return_block { |x, y| x - y } }, binding
249
+
250
+ assert_equal binop_block(:return_block, :-), a.to_ast
251
+ end
252
+
253
+ def test_lambda_in_eval
254
+ a = ast_eval %{ lambda { |x, y| x / y } }, binding
255
+
256
+ assert_equal binop_block(:lambda, :/), a.to_ast
257
+
258
+ # sanity check
259
+ assert_not_equal binop_block(:lambda, :+), a.to_ast
260
+ end
261
+
262
+ # from rubyspec
263
+ def test_to_str_on_file
264
+ file = MiniTest::Mock.new
265
+ file.expect(:to_str, "zebra.rb")
266
+ ast_eval "33 + 44", binding, file
267
+ file.verify
268
+ end
269
+ end