mvz-live_ast 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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