ruby-decompiler 0.0.1
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.
- data/README.rdoc +38 -0
- data/lib/decompiler/method/as_code.rb +58 -0
- data/lib/decompiler/method/as_expression.rb +33 -0
- data/lib/decompiler/method/origin.rb +29 -0
- data/lib/decompiler/method/signature.rb +147 -0
- data/lib/decompiler/method/signature/argument.rb +102 -0
- data/lib/decompiler/method/signature/iseq.rb +52 -0
- data/lib/decompiler/method/signature/node.rb +160 -0
- data/lib/decompiler/method/signature/signature.rb +23 -0
- data/lib/decompiler/module/as_code.rb +45 -0
- data/lib/decompiler/node/as_code.rb +233 -0
- data/lib/decompiler/node/as_expression.rb +619 -0
- data/lib/decompiler/proc/as_code.rb +23 -0
- data/lib/decompiler/proc/as_expression.rb +16 -0
- data/lib/decompiler/proc/signature.rb +184 -0
- data/lib/decompiler/vm/bytedecoder.rb +866 -0
- data/lib/decompiler/vm/iseq/as_code.rb +27 -0
- data/lib/decompiler/vm/iseq/as_expression.rb +26 -0
- data/test/test_as_code.rb +261 -0
- data/test/test_as_expression.rb +229 -0
- data/test/test_methodsig.rb +267 -0
- metadata +105 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'internal/vm'
|
2
|
+
|
3
|
+
if defined?(RubyVM::InstructionSequence) then
|
4
|
+
require 'internal/vm/bytedecoder'
|
5
|
+
|
6
|
+
class RubyVM
|
7
|
+
class InstructionSequence
|
8
|
+
def as_code(indent=0)
|
9
|
+
env = Internal::ByteDecoder::Environment.new(local_table())
|
10
|
+
opt_pc = self.opt_pc
|
11
|
+
self.bytedecode(env, opt_pc)
|
12
|
+
expressions = env.expressions + env.stack
|
13
|
+
if expressions.length == 0 then
|
14
|
+
return nil
|
15
|
+
elsif expressions.length == 1 and
|
16
|
+
expressions[0].is_a?(Internal::ByteDecoder::Expression::Literal) and
|
17
|
+
expressions[0].value == nil then
|
18
|
+
return nil
|
19
|
+
else
|
20
|
+
expressions.map! { |e| "#{' '*indent}#{e}" }
|
21
|
+
return expressions.join("\n")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'internal/vm'
|
2
|
+
|
3
|
+
if defined?(RubyVM::InstructionSequence) then
|
4
|
+
require 'internal/vm/bytedecoder'
|
5
|
+
|
6
|
+
class RubyVM
|
7
|
+
class InstructionSequence
|
8
|
+
def as_expression
|
9
|
+
env = Internal::ByteDecoder::Environment.new(local_table())
|
10
|
+
opt_pc = self.opt_pc
|
11
|
+
self.bytedecode(env, opt_pc)
|
12
|
+
expressions = env.expressions + env.stack
|
13
|
+
if expressions.length == 0 then
|
14
|
+
return nil
|
15
|
+
elsif expressions.length == 1 and
|
16
|
+
expressions[0].is_a?(Internal::ByteDecoder::Expression::Literal) and
|
17
|
+
expressions[0].value == nil then
|
18
|
+
return nil
|
19
|
+
else
|
20
|
+
return expressions.join('; ')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
dir = File.dirname(__FILE__)
|
5
|
+
$:.unshift(dir) if not $:.include?(dir)
|
6
|
+
$:.unshift("#{dir}/../lib") if not $:.include?("#{dir}/../lib")
|
7
|
+
$:.unshift("#{dir}/../ext") if not $:.include?("#{dir}/../ext")
|
8
|
+
|
9
|
+
require 'internal/node/as_code'
|
10
|
+
require 'internal/method/as_code'
|
11
|
+
require 'internal/module/as_code'
|
12
|
+
require 'internal/proc/as_code'
|
13
|
+
|
14
|
+
require 'expression_samples'
|
15
|
+
|
16
|
+
$stdout.sync = true
|
17
|
+
$stderr.sync = true
|
18
|
+
|
19
|
+
class TC_As_Code < Test::Unit::TestCase
|
20
|
+
MAJOR = Config::CONFIG['MAJOR'].to_i
|
21
|
+
MINOR = Config::CONFIG['MINOR'].to_i
|
22
|
+
TEENY = Config::CONFIG['TEENY'].to_i
|
23
|
+
RUBY_VERSION_CODE = MAJOR * 100 + MINOR * 10 + TEENY
|
24
|
+
|
25
|
+
extend Test::Unit::Assertions
|
26
|
+
|
27
|
+
# Some of the samples use this
|
28
|
+
def foo(*a, &b)
|
29
|
+
return b.call(1, 2) if b
|
30
|
+
return a
|
31
|
+
end
|
32
|
+
|
33
|
+
EXPRESSION_SAMPLES.each do |name, code|
|
34
|
+
p = proc {
|
35
|
+
p_orig = eval("proc { #{code} }")
|
36
|
+
code_new = p_orig.body.as_code
|
37
|
+
# p code, code_new
|
38
|
+
p_new = eval("proc { #{code_new} }")
|
39
|
+
result_orig = result_new = nil
|
40
|
+
exc_orig = exc_new = nil
|
41
|
+
timeout(1) { begin; result_orig = p_orig.call; rescue; exc_orig = $!; end }
|
42
|
+
timeout(1) { begin; result_new = p_new.call; rescue; exc_new = $!; end }
|
43
|
+
assert_equal(
|
44
|
+
exc_orig.class,
|
45
|
+
exc_new.class,
|
46
|
+
"Expected #{exc_orig.inspect} but got #{exc_new.inspect} " + \
|
47
|
+
"(code_orig=#{code}, code_new=#{code_new})")
|
48
|
+
if exc_orig and exc_new then
|
49
|
+
assert_equal(exc_orig.message, exc_new.message)
|
50
|
+
end
|
51
|
+
assert_equal(result_orig, result_new)
|
52
|
+
}
|
53
|
+
define_method "test_#{name}", p
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(test_method_name)
|
57
|
+
# TODO: This seems to be the only way to get tests defined with #
|
58
|
+
# define_method to run on 1.8.1 and earlier.
|
59
|
+
catch(:invalid_test) { super(test_method_name) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_no_args
|
63
|
+
42
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_method_no_args_as_code
|
67
|
+
m = method(:method_no_args)
|
68
|
+
assert_equal "def method_no_args()\n 42\nend", m.as_code
|
69
|
+
end
|
70
|
+
|
71
|
+
def method_one_arg(a)
|
72
|
+
42
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_method_one_arg_as_code
|
76
|
+
m = method(:method_one_arg)
|
77
|
+
assert_equal "def method_one_arg(a)\n 42\nend", m.as_code
|
78
|
+
end
|
79
|
+
|
80
|
+
def method_two_args(a, b)
|
81
|
+
42
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_method_two_args_as_code
|
85
|
+
m = method(:method_two_args)
|
86
|
+
assert_equal "def method_two_args(a, b)\n 42\nend", m.as_code
|
87
|
+
end
|
88
|
+
|
89
|
+
def method_rest_arg(*rest)
|
90
|
+
42
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_method_rest_arg_as_code
|
94
|
+
m = method(:method_rest_arg)
|
95
|
+
assert_equal "def method_rest_arg(*rest)\n 42\nend", m.as_code
|
96
|
+
end
|
97
|
+
|
98
|
+
def method_block_arg(&block)
|
99
|
+
42
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_method_block_arg_as_code
|
103
|
+
m = method(:method_block_arg)
|
104
|
+
assert_equal "def method_block_arg(&block)\n 42\nend", m.as_code
|
105
|
+
end
|
106
|
+
|
107
|
+
def method_rest_and_block_arg(*rest, &block)
|
108
|
+
42
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_method_rest_and_block_arg_as_code
|
112
|
+
m = method(:method_rest_and_block_arg)
|
113
|
+
assert_equal "def method_rest_and_block_arg(*rest, &block)\n 42\nend", m.as_code
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)
|
117
|
+
42
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_method_two_args_and_rest_and_block_arg_as_code
|
121
|
+
m = method(:method_two_args_and_rest_and_block_arg)
|
122
|
+
assert_equal "def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)\n 42\nend", m.as_code
|
123
|
+
end
|
124
|
+
|
125
|
+
def method_with_body(a, b)
|
126
|
+
a + b
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_method_with_body_as_code
|
130
|
+
m = method(:method_with_body)
|
131
|
+
assert_equal "def method_with_body(a, b)\n a + b\nend", m.as_code
|
132
|
+
end
|
133
|
+
|
134
|
+
def method_begin_ensure_as_code(a, b, *rest, &block)
|
135
|
+
begin
|
136
|
+
if not a and not b then
|
137
|
+
raise "Need more input!"
|
138
|
+
end
|
139
|
+
return a + b
|
140
|
+
ensure
|
141
|
+
puts "In ensure block"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_method_begin_ensure_as_code
|
146
|
+
m = method(:method_begin_ensure_as_code)
|
147
|
+
if RUBY_VERSION_CODE >= 190 then
|
148
|
+
ret = ''
|
149
|
+
else
|
150
|
+
ret = 'return '
|
151
|
+
end
|
152
|
+
|
153
|
+
assert_equal <<-END.chomp, m.as_code(3)
|
154
|
+
def method_begin_ensure_as_code(a, b, *rest, &block)
|
155
|
+
begin
|
156
|
+
(raise("Need more input!")) if (not a and not b)
|
157
|
+
#{ret}a + b
|
158
|
+
ensure
|
159
|
+
puts("In ensure block")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
END
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_proc_no_args_as_code
|
166
|
+
p = proc { }
|
167
|
+
assert_equal "proc do\nend", p.as_code
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_proc_empty_args_as_code
|
171
|
+
if not defined?(RubyVM) then
|
172
|
+
# indistinguishable from proc { } on YARV
|
173
|
+
p = proc { || }
|
174
|
+
assert_equal "proc do ||\nend", p.as_code
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_proc_one_arg_as_code
|
179
|
+
p = proc { |a| }
|
180
|
+
assert_equal "proc do |a|\nend", p.as_code
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_proc_one_array_arg_as_expression
|
184
|
+
p = proc { |a,| }
|
185
|
+
assert_equal "proc do |a,|\nend", p.as_code
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_proc_two_args_as_code
|
189
|
+
p = proc { |a, b| }
|
190
|
+
assert_equal "proc do |a, b|\nend", p.as_code
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_proc_rest_arg_as_code
|
194
|
+
p = proc { |*rest| }
|
195
|
+
assert_equal "proc do |*rest|\nend", p.as_code
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_proc_two_args_and_rest_arg_as_code
|
199
|
+
p = proc { |a, b, *rest| }
|
200
|
+
assert_equal "proc do |a, b, *rest|\nend", p.as_code
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_proc_with_body_as_code
|
204
|
+
p = proc { |a, b| a + b }
|
205
|
+
assert_equal "proc do |a, b|\n a + b\nend", p.as_code
|
206
|
+
end
|
207
|
+
|
208
|
+
def setup
|
209
|
+
@foo = 42
|
210
|
+
end
|
211
|
+
|
212
|
+
# 1.7 and later
|
213
|
+
def foo(*args)
|
214
|
+
return args
|
215
|
+
end
|
216
|
+
|
217
|
+
def remove_foo
|
218
|
+
self.class.remove_foo
|
219
|
+
end
|
220
|
+
|
221
|
+
# 1.6
|
222
|
+
def self.foo(*args)
|
223
|
+
return args
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.remove_foo
|
227
|
+
self.class_eval { remove_const(:FOO) if const_defined?(:FOO) }
|
228
|
+
end
|
229
|
+
|
230
|
+
@@foo = 10
|
231
|
+
|
232
|
+
FOO = 57
|
233
|
+
|
234
|
+
class ObjectWithFooAccessor
|
235
|
+
attr_accessor :foo
|
236
|
+
end
|
237
|
+
|
238
|
+
OWFA = ObjectWithFooAccessor.new
|
239
|
+
end
|
240
|
+
|
241
|
+
if __FILE__ == $0 then
|
242
|
+
require 'test/unit/ui/console/testrunner'
|
243
|
+
|
244
|
+
if Test::Unit.const_defined?(:AutoRunner) then
|
245
|
+
exit Test::Unit::AutoRunner.run
|
246
|
+
else
|
247
|
+
if ARGV.empty? then
|
248
|
+
suite = TC_As_Code.suite
|
249
|
+
else
|
250
|
+
suite = Test::Unit::TestSuite.new('TC_As_Code')
|
251
|
+
TC_As_Code.suite.tests.each do |test|
|
252
|
+
ARGV.each do |arg|
|
253
|
+
suite << test if /#{arg}/ =~ test.name
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
result = Test::Unit::UI::Console::TestRunner.run(suite)
|
258
|
+
exit(result.error_count + result.failure_count)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
dir = File.dirname(__FILE__)
|
5
|
+
$:.unshift(dir) if not $:.include?(dir)
|
6
|
+
$:.unshift("#{dir}/../lib") if not $:.include?("#{dir}/../lib")
|
7
|
+
$:.unshift("#{dir}/../ext") if not $:.include?("#{dir}/../ext")
|
8
|
+
|
9
|
+
require 'internal/node/as_expression'
|
10
|
+
require 'internal/method/as_expression'
|
11
|
+
require 'internal/proc/as_expression'
|
12
|
+
|
13
|
+
require 'expression_samples'
|
14
|
+
|
15
|
+
$stdout.sync = true
|
16
|
+
$stderr.sync = true
|
17
|
+
|
18
|
+
class TC_As_Expression < Test::Unit::TestCase
|
19
|
+
extend Test::Unit::Assertions
|
20
|
+
|
21
|
+
# Some of the samples use this
|
22
|
+
def foo(*a, &b)
|
23
|
+
return b.call(1, 2) if b
|
24
|
+
return a
|
25
|
+
end
|
26
|
+
|
27
|
+
EXPRESSION_SAMPLES.each do |name, code|
|
28
|
+
p = proc {
|
29
|
+
p_orig = eval("proc { #{code} }")
|
30
|
+
code_new = p_orig.body.as_expression
|
31
|
+
# p code, code_new
|
32
|
+
p_new = eval("proc { #{code_new} }")
|
33
|
+
result_orig = result_new = nil
|
34
|
+
exc_orig = exc_new = nil
|
35
|
+
timeout(1) { begin; result_orig = p_orig.call; rescue; exc_orig = $!; end }
|
36
|
+
timeout(1) { begin; result_new = p_new.call; rescue; exc_new = $!; end }
|
37
|
+
assert_equal(result_orig, result_new)
|
38
|
+
assert_equal(exc_orig.class, exc_new.class)
|
39
|
+
if exc_orig and exc_new then
|
40
|
+
assert_equal(exc_orig.message, exc_new.message)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
define_method "test_#{name}", p
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(test_method_name)
|
47
|
+
# TODO: This seems to be the only way to get tests defined with #
|
48
|
+
# define_method to run on 1.8.1 and earlier.
|
49
|
+
catch(:invalid_test) { super(test_method_name) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_no_args
|
53
|
+
42
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_method_no_args_as_expression
|
57
|
+
m = method(:method_no_args)
|
58
|
+
assert_equal 'def method_no_args(); 42; end', m.as_expression
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_one_arg(a)
|
62
|
+
42
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_method_one_arg_as_expression
|
66
|
+
m = method(:method_one_arg)
|
67
|
+
assert_equal 'def method_one_arg(a); 42; end', m.as_expression
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_two_args(a, b)
|
71
|
+
42
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_method_two_args_as_expression
|
75
|
+
m = method(:method_two_args)
|
76
|
+
assert_equal 'def method_two_args(a, b); 42; end', m.as_expression
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_rest_arg(*rest)
|
80
|
+
42
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_method_rest_arg_as_expression
|
84
|
+
m = method(:method_rest_arg)
|
85
|
+
assert_equal 'def method_rest_arg(*rest); 42; end', m.as_expression
|
86
|
+
end
|
87
|
+
|
88
|
+
def method_block_arg(&block)
|
89
|
+
42
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_method_block_arg_as_expression
|
93
|
+
m = method(:method_block_arg)
|
94
|
+
assert_equal 'def method_block_arg(&block); 42; end', m.as_expression
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_rest_and_block_arg(*rest, &block)
|
98
|
+
42
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_method_rest_and_block_arg_as_expression
|
102
|
+
m = method(:method_rest_and_block_arg)
|
103
|
+
assert_equal 'def method_rest_and_block_arg(*rest, &block); 42; end', m.as_expression
|
104
|
+
end
|
105
|
+
|
106
|
+
def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)
|
107
|
+
42
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_method_two_args_and_rest_and_block_arg_as_expression
|
111
|
+
m = method(:method_two_args_and_rest_and_block_arg)
|
112
|
+
assert_equal 'def method_two_args_and_rest_and_block_arg(a, b, *rest, &block); 42; end', m.as_expression
|
113
|
+
end
|
114
|
+
|
115
|
+
def method_two_default_args(a = 1, b = 2)
|
116
|
+
42
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_method_two_default_args_as_expression
|
120
|
+
m = method(:method_two_default_args)
|
121
|
+
assert_equal('def method_two_default_args(a=1, b=2); 42; end', m.as_expression)
|
122
|
+
end
|
123
|
+
|
124
|
+
def method_with_body(a, b)
|
125
|
+
a + b
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_method_with_body_as_expression
|
129
|
+
m = method(:method_with_body)
|
130
|
+
assert_equal 'def method_with_body(a, b); a + b; end', m.as_expression
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_proc_no_args_as_expression
|
134
|
+
p = proc { }
|
135
|
+
assert_equal 'proc { }', p.as_expression
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_proc_empty_args_as_expression
|
139
|
+
if not defined?(RubyVM) then
|
140
|
+
# indistinguishable from proc { } on YARV
|
141
|
+
p = proc { || }
|
142
|
+
assert_equal 'proc { || }', p.as_expression
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_proc_one_arg_as_expression
|
147
|
+
p = proc { |a| }
|
148
|
+
assert_equal 'proc { |a| }', p.as_expression
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_proc_one_array_arg_as_expression
|
152
|
+
p = proc { |a,| }
|
153
|
+
assert_equal 'proc { |a,| }', p.as_expression
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_proc_two_args_as_expression
|
157
|
+
p = proc { |a, b| }
|
158
|
+
assert_equal 'proc { |a, b| }', p.as_expression
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_proc_rest_arg_as_expression
|
162
|
+
p = proc { |*rest| }
|
163
|
+
assert_equal 'proc { |*rest| }', p.as_expression
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_proc_two_args_and_rest_arg_as_expression
|
167
|
+
p = proc { |a, b, *rest| }
|
168
|
+
assert_equal 'proc { |a, b, *rest| }', p.as_expression
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_proc_with_body_as_expression
|
172
|
+
p = proc { |a, b| a + b }
|
173
|
+
assert_equal 'proc { |a, b| a + b }', p.as_expression
|
174
|
+
end
|
175
|
+
|
176
|
+
def setup
|
177
|
+
@foo = 42
|
178
|
+
end
|
179
|
+
|
180
|
+
# 1.7 and later
|
181
|
+
def foo(*args)
|
182
|
+
return args
|
183
|
+
end
|
184
|
+
|
185
|
+
def remove_foo
|
186
|
+
self.class.remove_foo
|
187
|
+
end
|
188
|
+
|
189
|
+
# 1.6
|
190
|
+
def self.foo(*args)
|
191
|
+
return args
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.remove_foo
|
195
|
+
self.class_eval { remove_const(:FOO) if const_defined?(:FOO) }
|
196
|
+
end
|
197
|
+
|
198
|
+
@@foo = 10
|
199
|
+
|
200
|
+
FOO = 57
|
201
|
+
|
202
|
+
class ObjectWithFooAccessor
|
203
|
+
attr_accessor :foo
|
204
|
+
end
|
205
|
+
|
206
|
+
OWFA = ObjectWithFooAccessor.new
|
207
|
+
end
|
208
|
+
|
209
|
+
if __FILE__ == $0 then
|
210
|
+
require 'test/unit/ui/console/testrunner'
|
211
|
+
|
212
|
+
if Test::Unit.const_defined?(:AutoRunner) then
|
213
|
+
exit Test::Unit::AutoRunner.run
|
214
|
+
else
|
215
|
+
if ARGV.empty? then
|
216
|
+
suite = TC_As_Expression.suite
|
217
|
+
else
|
218
|
+
suite = Test::Unit::TestSuite.new('TC_As_Expression')
|
219
|
+
TC_As_Expression.suite.tests.each do |test|
|
220
|
+
ARGV.each do |arg|
|
221
|
+
suite << test if /#{arg}/ =~ test.name
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
result = Test::Unit::UI::Console::TestRunner.run(suite)
|
226
|
+
exit(result.error_count + result.failure_count)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|