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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.rdoc +5 -0
  3. data/README.rdoc +14 -0
  4. data/lib/live_ast/base.rb +7 -9
  5. data/lib/live_ast/irb_spy.rb +1 -1
  6. data/lib/live_ast/replace_caller.rb +14 -0
  7. data/lib/live_ast/version.rb +1 -1
  8. metadata +75 -116
  9. data/Rakefile +0 -62
  10. data/devel/levitate.rb +0 -184
  11. data/devel/levitate_config.rb +0 -4
  12. data/test/alias_test.rb +0 -25
  13. data/test/ast_eval/ast_eval_test.rb +0 -13
  14. data/test/ast_load/ast_load_test.rb +0 -47
  15. data/test/attr_test.rb +0 -26
  16. data/test/backtrace_test.rb +0 -161
  17. data/test/base/noninvasive_test.rb +0 -55
  18. data/test/base/reload_test.rb +0 -43
  19. data/test/covert_define_method_test.rb +0 -25
  20. data/test/def_test.rb +0 -37
  21. data/test/define_method_test.rb +0 -69
  22. data/test/define_singleton_method_test.rb +0 -17
  23. data/test/encoding_test/bad.rb +0 -1
  24. data/test/encoding_test/cp932.rb +0 -6
  25. data/test/encoding_test/default.rb +0 -5
  26. data/test/encoding_test/eucjp.rb +0 -6
  27. data/test/encoding_test/koi8.rb +0 -6
  28. data/test/encoding_test/koi8_shebang.rb +0 -7
  29. data/test/encoding_test/koi8_with_utf8bom.rb +0 -6
  30. data/test/encoding_test/usascii.rb +0 -6
  31. data/test/encoding_test/usascii_with_utf8bom.rb +0 -6
  32. data/test/encoding_test/utf8.rb +0 -6
  33. data/test/encoding_test/utf8bom.rb +0 -6
  34. data/test/encoding_test/utf8bom_only.rb +0 -5
  35. data/test/encoding_test/utf8dos.rb +0 -6
  36. data/test/encoding_test/utf8mac.rb +0 -6
  37. data/test/encoding_test/utf8mac_alt.rb +0 -6
  38. data/test/encoding_test/utf8unix.rb +0 -6
  39. data/test/encoding_test.rb +0 -54
  40. data/test/error_test.rb +0 -118
  41. data/test/eval_test.rb +0 -271
  42. data/test/flush_cache_test.rb +0 -102
  43. data/test/full/ast_reload_test.rb +0 -41
  44. data/test/full/replace_eval_test.rb +0 -433
  45. data/test/irb_test.rb +0 -43
  46. data/test/lambda_test.rb +0 -65
  47. data/test/load_path_test.rb +0 -77
  48. data/test/load_test.rb +0 -125
  49. data/test/main.rb +0 -134
  50. data/test/nested_test.rb +0 -31
  51. data/test/readme_test.rb +0 -16
  52. data/test/recursive_eval_test.rb +0 -53
  53. data/test/redefine_method_test.rb +0 -85
  54. data/test/rubygems_test.rb +0 -27
  55. data/test/rubyspec_test.rb +0 -39
  56. data/test/singleton_test.rb +0 -27
  57. data/test/stdlib_test.rb +0 -15
  58. data/test/thread_test.rb +0 -45
  59. data/test/to_ast/to_ast_feature_test.rb +0 -13
  60. data/test/to_ruby/to_ruby_feature_test.rb +0 -13
  61. data/test/to_ruby/to_ruby_test.rb +0 -101
data/test/load_test.rb DELETED
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
- require_relative "../devel/levitate"
5
-
6
- class LoadFileTest < BaseTest
7
- class << self
8
- attr_accessor :flag
9
- end
10
-
11
- def test_a_no_locals_created
12
- code = %{
13
- LoadFileTest.flag = :code_a
14
- FOO = 77
15
- x = 33
16
- y = 99
17
- }
18
-
19
- temp_file code do |file|
20
- ret = LiveAST.load file
21
- assert_equal true, ret
22
- assert_equal :code_a, LoadFileTest.flag
23
-
24
- assert_raises NameError do
25
- eval("x", TOPLEVEL_BINDING)
26
- end
27
-
28
- assert_equal 77, ::FOO
29
- end
30
- end
31
-
32
- def test_b_no_locals_modified
33
- code = %{
34
- LoadFileTest.flag = :code_b
35
- r = 55
36
- }
37
-
38
- temp_file code do |file|
39
- eval("r = 66", TOPLEVEL_BINDING)
40
-
41
- ret = LiveAST.load file
42
- assert_equal true, ret
43
- assert_equal :code_b, LoadFileTest.flag
44
-
45
- actual = eval("r", TOPLEVEL_BINDING)
46
- assert_equal 66, actual
47
- end
48
- end
49
-
50
- def test_c_wrap
51
- code = %{
52
- LoadFileTest.flag = :code_c
53
- ZOOM = 111
54
- }
55
-
56
- temp_file code do |file|
57
- ret = LiveAST.load file, true
58
- assert_equal true, ret
59
- assert_equal :code_c, LoadFileTest.flag
60
-
61
- assert_raises NameError do
62
- ZOOM
63
- end
64
- end
65
- end
66
-
67
- def self.from_d
68
- self.flag = :code_d
69
- end
70
-
71
- def test_d_empty_locals_list
72
- code = %{
73
- LoadFileTest.from_d
74
- }
75
-
76
- temp_file code do |file|
77
- LiveAST.load file
78
- assert_equal :code_d, LoadFileTest.flag
79
- end
80
- end
81
-
82
- def test_verbose_respected
83
- lib = File.expand_path("../lib", File.dirname(__FILE__))
84
-
85
- [
86
- # respects a loaded file setting $VERBOSE = true
87
- [
88
- "false",
89
- "true",
90
- lambda { |file|
91
- Levitate.run file
92
- }
93
- ],
94
-
95
- # unfixable: does not respect a loaded file setting $VERBOSE = nil
96
- [
97
- "true",
98
- "false",
99
- lambda { |file|
100
- unfixable do
101
- assert_nothing_raised do
102
- Levitate.run file
103
- end
104
- end
105
- }
106
- ]
107
- ].each do |main_value, loaded_value, action|
108
- loaded_code = %{
109
- $VERBOSE = #{loaded_value}
110
- }
111
-
112
- temp_file loaded_code do |loaded_file|
113
- main_code = %{
114
- $LOAD_PATH.unshift '#{lib}'
115
- require 'live_ast/base'
116
- toplevel_local = 444
117
- $VERBOSE = #{main_value}
118
- LiveAST.load '#{loaded_file}'
119
- $VERBOSE == #{loaded_value} or exit(1)
120
- }
121
- temp_file main_code, &action
122
- end
123
- end
124
- end
125
- end
data/test/main.rb DELETED
@@ -1,134 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__))
4
-
5
- # require first for stdlib_test
6
- require "pp"
7
- require "find"
8
- require "fileutils"
9
-
10
- require "minitest/mock"
11
- require "minitest/autorun"
12
-
13
- $VERBOSE = true
14
-
15
- require "live_ast/base"
16
-
17
- def define_unsorted_test_case(name, superclass, &block)
18
- klass = Class.new superclass, &block
19
- letter = ("A".."Z").to_a[rand(26)]
20
- Object.const_set "#{letter}#{name}", klass
21
- end
22
-
23
- class JLMiniTest < MiniTest::Test
24
- def self.test_methods
25
- default = super
26
- onlies = default.select { |m| m =~ /__only\Z/ }
27
- if onlies.empty?
28
- default
29
- else
30
- puts "\nNOTE: running ONLY *__only tests for #{self}"
31
- onlies
32
- end
33
- end
34
-
35
- def delim(char)
36
- "\n#{char * 72}\n"
37
- end
38
-
39
- def mu_pp(obj)
40
- +"" <<
41
- delim("_") <<
42
- obj.pretty_inspect.chomp <<
43
- delim("=")
44
- end
45
-
46
- def unfixable
47
- yield
48
- raise "claimed to be unfixable, but assertion succeeded"
49
- rescue MiniTest::Assertion
50
- end
51
-
52
- def assert_nothing_raised
53
- yield
54
- assert_nil nil
55
- rescue StandardError => e
56
- raise MiniTest::Assertion,
57
- exception_details(e, "Expected nothing raised, but got:")
58
- end
59
-
60
- %w(
61
- empty equal in_delta in_epsilon includes instance_of
62
- kind_of match nil operator respond_to same
63
- ).each { |name|
64
- alias_method "assert_not_#{name}", "refute_#{name}"
65
- }
66
- end
67
-
68
- class BaseTest < JLMiniTest
69
- include LiveAST.parser::Test
70
-
71
- DATA_DIR = File.expand_path("data", File.dirname(__FILE__))
72
-
73
- def self.stdlib_has_source?
74
- RUBY_ENGINE != "jruby"
75
- end
76
-
77
- def temp_file(code, basename = nil)
78
- basename ||= ("a".."z").to_a.shuffle.join + ".rb"
79
- path = File.join(DATA_DIR, basename)
80
-
81
- write_file path, code if code
82
- begin
83
- yield path
84
- ensure
85
- FileUtils.rm_f path
86
- end
87
- end
88
-
89
- def write_file(file, contents)
90
- File.open(file, "w") { |f| f.print contents }
91
- end
92
-
93
- def return_block(&block)
94
- block
95
- end
96
-
97
- def exception_backtrace
98
- yield
99
- rescue Exception => e
100
- e.backtrace
101
- end
102
-
103
- def ignore(*_args); end
104
- end
105
-
106
- class RegularTest < BaseTest
107
- def setup
108
- super
109
- require "live_ast"
110
- end
111
- end
112
-
113
- class ReplaceEvalTest < BaseTest
114
- def initialize(*args)
115
- super
116
- ok = begin
117
- require "live_ast/full"
118
- true
119
- rescue LoadError
120
- raise "need: gem install bindings" if RUBY_ENGINE == "ruby"
121
-
122
- false
123
- end
124
-
125
- return if ok
126
-
127
- self.class.class_eval do
128
- instance_methods(false).each do |m|
129
- remove_method(m)
130
- define_method(m) { nil }
131
- end
132
- end
133
- end
134
- end
data/test/nested_test.rb DELETED
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- class NestedTest < RegularTest
6
- def test_lambda
7
- a = lambda {
8
- lambda {
9
- "33"
10
- }
11
- }
12
-
13
- assert_equal nested_lambdas("33"), a.to_ast
14
- assert_equal no_arg_block(:lambda, "33"), a.call.to_ast
15
- end
16
-
17
- class A
18
- def f
19
- Class.new do
20
- def g
21
- "44"
22
- end
23
- end
24
- end
25
- end
26
-
27
- def test_defs
28
- assert_equal nested_defs(:f, :g, "44"), A.instance_method(:f).to_ast
29
- assert_equal no_arg_def(:g, "44"), A.new.f.instance_method(:g).to_ast
30
- end
31
- end
data/test/readme_test.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
- require_relative "../devel/levitate"
5
-
6
- if RUBY_ENGINE != "jruby" # jruby takes about a minute
7
- sections = [
8
- "Synopsis",
9
- "+to_ruby+",
10
- "Noninvasive Interface",
11
- "Pure Ruby and +ast_eval+",
12
- "Full Integration"
13
- ]
14
-
15
- Levitate.doc_to_test("README.rdoc", *sections)
16
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- class RecursiveEvalTest < RegularTest
6
- DEFINE = lambda do
7
- ast_eval %{
8
- class A
9
- ast_eval %{
10
- def f
11
- "A#f"
12
- end
13
- }, binding
14
-
15
- ast_eval %{
16
- ast_eval %{
17
- remove_method :f
18
- def f(x, y)
19
- x + y
20
- end
21
-
22
- def g
23
- "A#g"
24
- end
25
- }, binding
26
-
27
- LAMBDA = ast_eval %{
28
- lambda { |x, y| x * y }
29
- }, binding
30
- }, binding
31
- end
32
- }, binding
33
- end
34
-
35
- def test_method
36
- defined?(A) or DEFINE.call
37
- assert_equal "#{self.class}::A", A.name
38
-
39
- assert_equal binop_def(:f, :+),
40
- A.instance_method(:f).to_ast
41
-
42
- assert_equal no_arg_def(:g, "A#g"),
43
- A.instance_method(:g).to_ast
44
- end
45
-
46
- def test_lambda
47
- defined?(A) or DEFINE.call
48
- assert_equal "#{self.class}::A", A.name
49
-
50
- assert_equal binop_block(:lambda, :*),
51
- A::LAMBDA.to_ast
52
- end
53
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- class RedefineMethodTest < RegularTest
6
- DEFINE_A = lambda do
7
- class A
8
- def f
9
- "old A#f"
10
- end
11
-
12
- PREVIOUS_Af = instance_method(:f)
13
- remove_method :f
14
-
15
- def f(x, y)
16
- x * y
17
- end
18
- end
19
- end
20
-
21
- def test_inclass_redef
22
- DEFINE_A.call
23
-
24
- assert_equal binop_def(:f, :*),
25
- A.instance_method(:f).to_ast
26
-
27
- assert_equal no_arg_def(:f, "old A#f"),
28
- A::PREVIOUS_Af.to_ast
29
- end
30
-
31
- DEFINE_B = lambda do
32
- class B
33
- def f
34
- "old B#f"
35
- end
36
- end
37
- end
38
-
39
- def test_dynamic_redef
40
- DEFINE_B.call
41
-
42
- assert_equal "old B#f", B.new.f
43
- assert_equal no_arg_def(:f, "old B#f"), B.instance_method(:f).to_ast
44
-
45
- B.class_eval do
46
- remove_method :f
47
- define_method :f do |x, y|
48
- x - y
49
- end
50
- end
51
-
52
- assert_equal 11, B.new.f(44, 33)
53
-
54
- assert_equal binop_define_method(:f, :-),
55
- B.instance_method(:f).to_ast
56
- end
57
-
58
- DEFINE_C = lambda do
59
- class C
60
- def f
61
- "old C#f"
62
- end
63
- end
64
- end
65
-
66
- def test_dynamic_redef_with_eval
67
- DEFINE_C.call
68
-
69
- assert_equal "old C#f", C.new.f
70
-
71
- C.class_eval do
72
- ast_eval %{
73
- remove_method :f
74
- define_method :f do |x, y|
75
- x * y
76
- end
77
- }, binding
78
- end
79
-
80
- assert_equal 12, C.new.f(3, 4)
81
-
82
- assert_equal binop_define_method(:f, :*),
83
- C.instance_method(:f).to_ast
84
- end
85
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
- require_relative "../devel/levitate"
5
-
6
- class RubygemsTest < RegularTest
7
- def test_rubygems
8
- lib = File.expand_path("../lib", File.dirname(__FILE__))
9
- extra_req =
10
- if defined?(LiveASTRipper) && LiveAST.parser == LiveASTRipper
11
- %{require 'live_ast_ripper'}
12
- else
13
- ""
14
- end
15
- result = Levitate.run_code_and_capture %{
16
- $LOAD_PATH.unshift '#{lib}'
17
- #{extra_req}
18
- require 'live_ast/full'
19
- LiveAST.parser::Test
20
- f = eval %{
21
- lambda { 'abc' }
22
- }
23
- p f.to_ast
24
- }
25
- assert_equal no_arg_block(:lambda, "abc").to_s, result.chomp
26
- end
27
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
- require_relative "../devel/levitate"
5
-
6
- #
7
- # Tests against rubyspec branch which discards '|ast@' tokens
8
- #
9
- if ENV["LIVE_AST_RUBYSPEC_HOME"]
10
- class RubySpecTest < RegularTest
11
- FILES = [
12
- "core/basicobject/instance_eval_spec.rb",
13
- "core/binding/eval_spec.rb",
14
- "core/kernel/eval_spec.rb",
15
- "core/kernel/instance_eval_spec.rb",
16
- "core/module/class_eval_spec.rb",
17
- "core/module/module_eval_spec.rb"
18
- ].freeze
19
-
20
- def setup
21
- super
22
- puts "\n==== rubyspec"
23
- end
24
-
25
- FILES.each do |file|
26
- mname = "test_" + file.tr("/", "_").chop!.chop!.chop!
27
- define_method mname do
28
- Dir.chdir ENV["LIVE_AST_RUBYSPEC_HOME"] do
29
- cmd =
30
- ["mspec", "-t", Levitate.ruby_bin] +
31
- (["-T"] * Levitate.ruby_opts.size).zip(Levitate.ruby_opts).flatten +
32
- [file]
33
-
34
- assert system(*cmd)
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- class SingletonTest < RegularTest
6
- class A
7
- def self.f
8
- "A.f"
9
- end
10
- end
11
-
12
- def test_self_dot
13
- expected = singleton_no_arg_def(:f, "A.f")
14
- assert_equal expected, A.method(:f).to_ast
15
- end
16
-
17
- class B
18
- def B.f(x, y)
19
- x + y
20
- end
21
- end
22
-
23
- def test_name_dot
24
- expected = singleton_binop_def(:B, :f, :+)
25
- assert_equal expected, B.method(:f).to_ast
26
- end
27
- end
data/test/stdlib_test.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- class StdlibTest < RegularTest
6
- if stdlib_has_source?
7
- def test_pp
8
- assert_not_nil method(:pp).to_ast
9
- end
10
-
11
- def test_find
12
- assert_not_nil Find.method(:find).to_ast
13
- end
14
- end
15
- end
data/test/thread_test.rb DELETED
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "main"
4
-
5
- require "thread"
6
-
7
- class ThreadTest < RegularTest
8
- def test_threads
9
- klass = nil
10
- mutex = Mutex.new
11
- stop = false
12
- results = []
13
- num_threads = 50
14
-
15
- workers = (0...num_threads).map {
16
- Thread.new {
17
- until stop
18
- if klass
19
- found = klass.instance_method(:f).to_ast
20
- mutex.synchronize {
21
- results << found
22
- }
23
- break
24
- end
25
- end
26
- }
27
- }
28
-
29
- klass = Class.new do
30
- def f
31
- "anon#f"
32
- end
33
- end
34
-
35
- sleep(0.2)
36
- stop = true
37
-
38
- workers.each(&:join)
39
-
40
- assert_equal num_threads, results.size
41
- results.each { |result|
42
- assert_equal no_arg_def(:f, "anon#f"), result
43
- }
44
- end
45
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "main"
4
-
5
- require "live_ast/to_ast"
6
-
7
- class ToASTFeatureTest < BaseTest
8
- def test_require
9
- [Method, UnboundMethod, Proc].each { |obj|
10
- assert obj.instance_methods.include?(:to_ast)
11
- }
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "main"
4
-
5
- require "live_ast/to_ruby"
6
-
7
- class ToRubyFeatureTest < BaseTest
8
- def test_defines_to_ruby
9
- [Method, UnboundMethod, Proc].each { |obj|
10
- assert obj.instance_methods.include?(:to_ruby)
11
- }
12
- end
13
- end