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,24 @@
1
+ require 'live_ast/base'
2
+
3
+ [Method, UnboundMethod, Proc].each do |klass|
4
+ klass.class_eval do
5
+ def to_ruby #:nodoc:
6
+ LiveAST.parser::Unparser.unparse(LiveAST.ast(self))
7
+ end
8
+ end
9
+ end
10
+
11
+ class Method
12
+ # :method: to_ruby
13
+ # Generate ruby code which reflects the AST of this object.
14
+ end
15
+
16
+ class UnboundMethod
17
+ # :method: to_ruby
18
+ # Generate ruby code which reflects the AST of this object.
19
+ end
20
+
21
+ class Proc
22
+ # :method: to_ruby
23
+ # Generate ruby code which reflects the AST of this object.
24
+ end
@@ -0,0 +1,3 @@
1
+ module LiveAST
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'main'
2
+
3
+ class AAB_ASTEvalFeatureTest < BaseTest
4
+ def test_require
5
+ assert !private_methods.include?(:ast_eval)
6
+
7
+ require 'live_ast/ast_eval'
8
+
9
+ assert private_methods.include?(:ast_eval)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'main'
2
+
3
+ class AAB_ASTLoadFeatureTest < BaseTest
4
+ def test_require
5
+ assert !private_methods.include?(:ast_load)
6
+
7
+ require 'live_ast/ast_load'
8
+
9
+ assert private_methods.include?(:ast_load)
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'main'
2
+
3
+ class AttrTest < RegularTest
4
+ class A
5
+ attr_accessor :f
6
+ attr_reader :g
7
+ attr_writer :h
8
+ end
9
+
10
+ def test_attr
11
+ assert_raises LiveAST::ASTNotFoundError do
12
+ A.instance_method(:f).to_ast
13
+ end
14
+ assert_raises LiveAST::ASTNotFoundError do
15
+ A.instance_method(:f=).to_ast
16
+ end
17
+ assert_raises LiveAST::ASTNotFoundError do
18
+ A.instance_method(:g).to_ast
19
+ end
20
+ assert_raises LiveAST::ASTNotFoundError do
21
+ A.instance_method(:h=).to_ast
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,158 @@
1
+ require_relative 'main'
2
+
3
+ # test for raise redefinition side-effects: unsort this TestCase from
4
+ # other TestCases.
5
+
6
+ define_unsorted_test_case "BacktraceTest", RegularTest do
7
+ def test_raise_in_eval
8
+ 3.times do
9
+ orig = exception_backtrace do
10
+ eval %{
11
+
12
+ raise
13
+
14
+
15
+ }, binding, "somewhere", 1000
16
+ end
17
+
18
+ live = exception_backtrace do
19
+ ast_eval %{
20
+
21
+ raise
22
+
23
+
24
+ }, binding, "somewhere", 1000
25
+ end
26
+
27
+ assert_equal orig.first, live.first
28
+ assert_match(/somewhere:1002/, live.first)
29
+ end
30
+ end
31
+
32
+ def test_raise_no_overrides
33
+ 3.times do
34
+ orig = exception_backtrace do
35
+ eval %{
36
+
37
+
38
+ raise
39
+
40
+ }, binding, __FILE__, (__LINE__ + 9)
41
+ end
42
+
43
+ live = exception_backtrace do
44
+ ast_eval %{
45
+
46
+
47
+ raise
48
+
49
+ }, binding
50
+ end
51
+
52
+ assert_equal orig.first, live.first
53
+ here = Regexp.quote __FILE__
54
+ assert_match(/#{here}/, live.first)
55
+ end
56
+ end
57
+
58
+ def test_raise_using_overrides
59
+ 3.times do
60
+ orig = exception_backtrace do
61
+ eval %{
62
+
63
+
64
+ raise
65
+
66
+ }, binding, __FILE__, (__LINE__ + 9)
67
+ end
68
+
69
+ live = exception_backtrace do
70
+ ast_eval %{
71
+
72
+
73
+ raise
74
+
75
+ }, binding, __FILE__, __LINE__
76
+ end
77
+
78
+ assert_equal orig.first, live.first
79
+ here = Regexp.quote __FILE__
80
+ assert_match(/#{here}/, live.first)
81
+ end
82
+ end
83
+
84
+ def test_raise_using_only_file_override
85
+ 3.times do
86
+ orig = exception_backtrace do
87
+ eval %{
88
+
89
+
90
+ raise
91
+
92
+ }, binding, __FILE__
93
+ end
94
+
95
+ live = exception_backtrace do
96
+ ast_eval %{
97
+
98
+
99
+ raise
100
+
101
+ }, binding, __FILE__
102
+ end
103
+
104
+ assert_equal orig.first, live.first
105
+ here = Regexp.quote __FILE__
106
+ assert_match(/#{here}/, live.first)
107
+ end
108
+ end
109
+
110
+ def test_raise_after_eval
111
+ raise_after_eval("raise", false)
112
+ raise_after_eval("1/0", false)
113
+
114
+ require 'live_ast/replace_raise'
115
+
116
+ raise_after_eval("raise", true)
117
+ raise_after_eval("1/0", false)
118
+ end
119
+
120
+ def raise_after_eval(code, will_succeed)
121
+ 3.times do
122
+ orig = eval %{
123
+
124
+ lambda { #{code} }
125
+
126
+
127
+ }, binding, "somewhere", 1000
128
+
129
+ live = ast_eval %{
130
+
131
+ lambda { #{code} }
132
+
133
+
134
+ }, binding, "somewhere", 1000
135
+
136
+ orig_top = exception_backtrace { orig.call }.first
137
+ live_top = exception_backtrace { live.call }.first
138
+
139
+ assert_equal orig_top, LiveAST.strip_token(live_top)
140
+
141
+ if will_succeed
142
+ assert_equal orig_top, live_top
143
+ assert_match(/somewhere:1002/, live_top)
144
+ else
145
+ assert_not_equal orig_top, live_top
146
+ assert_match(/somewhere.*?:1002/, live_top)
147
+ end
148
+ end
149
+ end
150
+
151
+ def test_tokens_stripped
152
+ exception_backtrace do
153
+ ast_eval %{ ast_eval %{ ast_eval %{raise}, binding }, binding }, binding
154
+ end.each do |line|
155
+ assert_nil line.index(LiveAST::Linker::REVISION_TOKEN)
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'main'
2
+
3
+ class CovertDefineMethodTest < RegularTest
4
+ DEFINE = lambda do
5
+ class A
6
+ def A.my_def(*args, &block)
7
+ define_method(*args, &block)
8
+ end
9
+
10
+ my_def :h do |x, y|
11
+ x + y
12
+ end
13
+ end
14
+ end
15
+
16
+ def test_covert_define_method
17
+ DEFINE.call
18
+ assert_equal 77, A.new.h(33, 44)
19
+
20
+ assert_equal binop_define_method(:h, :+, :my_def),
21
+ A.instance_method(:h).to_ast
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'main'
2
+
3
+ class DefTest < RegularTest
4
+ class A
5
+ def f
6
+ "A#f"
7
+ end
8
+ end
9
+
10
+ def test_def_unbound_method_a
11
+ expected = no_arg_def(:f, "A#f")
12
+ assert_equal expected, A.instance_method(:f).to_ast
13
+ end
14
+
15
+ def test_def_method_a
16
+ expected = no_arg_def(:f, "A#f")
17
+ assert_equal expected, A.new.method(:f).to_ast
18
+ end
19
+
20
+ class B
21
+ def f(x, y)
22
+ x + y
23
+ end
24
+ end
25
+
26
+ def test_def_unbound_method_b
27
+ expected = binop_def(:f, :+)
28
+ assert_equal expected, B.instance_method(:f).to_ast
29
+ end
30
+
31
+ def test_def_instance_method_b
32
+ expected = binop_def(:f, :+)
33
+ assert_equal expected, B.new.method(:f).to_ast
34
+ end
35
+ end
@@ -0,0 +1,67 @@
1
+ require_relative 'main'
2
+
3
+ class DefineMethodTest < RegularTest
4
+ WITH_BLOCKS = lambda do
5
+ class A
6
+ {
7
+ :f => :+,
8
+ :g => :*,
9
+ :h => :-,
10
+ }.each_pair do |name, op|
11
+ case op
12
+ when :+
13
+ define_method name do |x, y|
14
+ x + y
15
+ end
16
+ when :*
17
+ define_method name do |x, y|
18
+ x * y
19
+ end
20
+ when :-
21
+ define_method name do |x, y|
22
+ x - y
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def test_with_block
30
+ WITH_BLOCKS.call
31
+
32
+ assert_equal binop_define_method_with_var(:name, :+),
33
+ A.instance_method(:f).to_ast
34
+
35
+ assert_equal binop_define_method_with_var(:name, :*),
36
+ A.instance_method(:g).to_ast
37
+
38
+ assert_equal binop_define_method_with_var(:name, :-),
39
+ A.instance_method(:h).to_ast
40
+ end
41
+
42
+ WITH_PROCS = lambda do
43
+ class B
44
+ op = lambda { |x, y| x / y }
45
+
46
+ no_arg = proc { "B#f" }
47
+
48
+ define_method :g, &no_arg ; define_method :f, &op
49
+ end
50
+ end
51
+
52
+ def test_via_block
53
+ WITH_PROCS.call
54
+
55
+ assert_equal binop_block(:lambda, :/),
56
+ B.instance_method(:f).to_ast
57
+
58
+ assert_equal binop_block(:lambda, :/),
59
+ B.new.method(:f).to_ast
60
+
61
+ assert_equal no_arg_block(:proc, "B#f"),
62
+ B.instance_method(:g).to_ast
63
+
64
+ assert_equal no_arg_block(:proc, "B#f"),
65
+ B.new.method(:g).to_ast
66
+ end
67
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'main'
2
+
3
+ class DefineSingletonMethodTest < RegularTest
4
+ def test_define_singleton_method
5
+ a = Object.new
6
+ a.define_singleton_method :f do |x, y|
7
+ x + y
8
+ end
9
+
10
+ assert_equal 77, a.f(33, 44)
11
+
12
+ assert_equal binop_define_singleton_method(:f, :+, :a),
13
+ a.singleton_class.instance_method(:f).to_ast
14
+ end
15
+ end
@@ -0,0 +1,52 @@
1
+ require_relative 'main'
2
+
3
+ class AllEncodingTest < RegularTest
4
+ ENC_TESTS = Hash[*%w[
5
+ default US-ASCII
6
+ usascii US-ASCII
7
+ utf8 UTF-8
8
+ utf8unix UTF-8
9
+ utf8mac UTF-8
10
+ utf8mac_alt UTF8-MAC
11
+ utf8dos UTF-8
12
+ utf8bom UTF-8
13
+ utf8bom_only UTF-8
14
+ usascii_with_utf8bom US-ASCII
15
+ koi8_with_utf8bom KOI8-R
16
+ cp932 Windows-31J
17
+ eucjp EUC-JP
18
+ koi8 KOI8-R
19
+ koi8_shebang KOI8-R
20
+ ]]
21
+
22
+ ENC_TESTS.each_pair do |abbr, name|
23
+ define_method "test_#{abbr}" do
24
+ require_relative "encoding_test/#{abbr}"
25
+ self.class.class_eval { include EncodingTest }
26
+
27
+ str = send("#{abbr}_string")
28
+ assert_equal name, str.encoding.to_s
29
+
30
+ ast = EncodingTest.instance_method("#{abbr}_string").to_ast
31
+ assert_equal "UTF-8", no_arg_def_return(ast).encoding.to_s
32
+
33
+ LiveAST.load "./test/encoding_test/#{abbr}.rb"
34
+
35
+ ast = EncodingTest.instance_method("#{abbr}_string").to_ast
36
+ assert_equal "UTF-8", no_arg_def_return(ast).encoding.to_s
37
+ end
38
+ end
39
+
40
+ def test_bad
41
+ orig = assert_raises ArgumentError do
42
+ live_ast_original_load "./test/encoding_test/bad.rb"
43
+ end
44
+ live = assert_raises ArgumentError do
45
+ LiveAST.load "./test/encoding_test/bad.rb"
46
+ end
47
+ # inconsistent punctuation from Ruby
48
+ re = %r!\Aunknown encoding name\s*[-:]\s*feynman-diagram\Z!
49
+ assert_match re, orig.message
50
+ assert_match re, live.message
51
+ end
52
+ end
@@ -0,0 +1 @@
1
+ # encoding: feynman-diagram
@@ -0,0 +1,6 @@
1
+ # -*- coding: cp932 -*-
2
+ module EncodingTest
3
+ def cp932_string
4
+ "�傫�Ȕ��Ƃ˂��B"
5
+ end
6
+ end