1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
require 'test/unit'
require_relative 'envutil'
class TestSyntax < Test::Unit::TestCase
def assert_valid_syntax(code, fname, mesg = fname)
code = code.dup.force_encoding("ascii-8bit")
code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
"#$&#{"\n" if $1 && !$2}BEGIN{throw tag, :ok}\n"
}
code.force_encoding("us-ascii")
verbose, $VERBOSE = $VERBOSE, nil
yield if defined?(yield)
assert_nothing_raised(SyntaxError, mesg) do
assert_equal(:ok, catch {|tag| eval(code, binding, fname, 0)}, mesg)
end
ensure
$VERBOSE = verbose
end
def test_syntax
assert_nothing_raised(Exception) do
for script in Dir[File.expand_path("../../../{lib,sample,ext,test}/**/*.rb", __FILE__)].sort
assert_valid_syntax(IO::read(script), script)
end
end
end
def test_must_ascii_compatible
require 'tempfile'
f = Tempfile.new("must_ac_")
Encoding.list.each do |enc|
next unless enc.ascii_compatible?
make_tmpsrc(f, "# -*- coding: #{enc.name} -*-")
assert_nothing_raised(ArgumentError, enc.name) {load(f.path)}
end
Encoding.list.each do |enc|
next if enc.ascii_compatible?
make_tmpsrc(f, "# -*- coding: #{enc.name} -*-")
assert_raise(ArgumentError, enc.name) {load(f.path)}
end
f.close!
end
def test_script_lines
require 'tempfile'
f = Tempfile.new("bug4361_")
bug4361 = '[ruby-dev:43168]'
with_script_lines do |debug_lines|
Encoding.list.each do |enc|
next unless enc.ascii_compatible?
make_tmpsrc(f, "# -*- coding: #{enc.name} -*-\n#----------------")
load(f.path)
assert_equal([f.path], debug_lines.keys)
assert_equal([enc, enc], debug_lines[f.path].map(&:encoding), bug4361)
end
end
f.close!
end
def test_newline_in_block_parameters
bug = '[ruby-dev:45292]'
["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params|
params = ["|", *params, "|"].join("\n")
assert_valid_syntax("1.times{#{params}}", __FILE__, "#{bug} #{params.inspect}")
end
end
tap do |_,
bug6115 = '[ruby-dev:45308]',
blockcall = '["elem"].each_with_object [] do end',
methods = [['map', 'no'], ['inject([])', 'with']],
blocks = [['do end', 'do'], ['{}', 'brace']],
*|
[%w'. dot', %w':: colon'].product(methods, blocks) do |(c, n1), (m, n2), (b, n3)|
m = m.tr_s('()', ' ').strip if n2 == 'do'
name = "test_#{n3}_block_after_blockcall_#{n1}_#{n2}_arg"
code = "#{blockcall}#{c}#{m} #{b}"
define_method(name) {assert_valid_syntax(code, bug6115)}
end
end
def test_keyword_rest
bug5989 = '[ruby-core:42455]'
assert_valid_syntax("def kwrest_test(**a) a; end", __FILE__, bug5989)
assert_valid_syntax("def kwrest_test2(**a, &b) end", __FILE__, bug5989)
o = Object.new
def o.kw(**a) a end
assert_equal({}, o.kw, bug5989)
assert_equal({foo: 1}, o.kw(foo: 1), bug5989)
assert_equal({foo: 1, bar: 2}, o.kw(foo: 1, bar: 2), bug5989)
end
def test_warn_grouped_expression
assert_warn("test:2: warning: (...) interpreted as grouped expression\n") do
assert_valid_syntax("foo \\\n(\n true)", "test") {$VERBOSE = true}
end
end
def test_warn_unreachable
assert_warn("test:3: warning: statement not reached\n") do
code = "loop do\n" "break\n" "foo\n" "end"
assert_valid_syntax(code, "test") {$VERBOSE = true}
end
end
private
def make_tmpsrc(f, src)
f.open
f.truncate(0)
f.puts(src)
f.close
end
def with_script_lines
script_lines = nil
debug_lines = {}
Object.class_eval do
if defined?(SCRIPT_LINES__)
script_lines = SCRIPT_LINES__
remove_const :SCRIPT_LINES__
end
const_set(:SCRIPT_LINES__, debug_lines)
end
yield debug_lines
ensure
Object.class_eval do
remove_const :SCRIPT_LINES__
const_set(:SCRIPT_LINES__, script_lines) if script_lines
end
end
end
|