1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/test/ruby/test_syntax.rb
nobu 64ae33a18a parse.y: fix GC problem of keyword rest argument
* parse.y (new_args_tail_gen): fix GC problem of keyword rest
  argument.  the wrapped struct should be bound to the wrapping node
  before assignment of child nodes, to get rid of the case the
  children are referred by only the struct pointer which is not a
  subject of GC.  [ruby-core:45744]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36161 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-21 08:20:51 +00:00

221 lines
6.4 KiB
Ruby

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)
EnvUtil.under_gc_stress do
eval("def o.m(k: 0) k end")
end
assert_equal(42, o.m(k: 42), '[ruby-core:45744]')
end
def test_keyword_splat
assert_valid_syntax("foo(**h)", __FILE__)
o = Object.new
def o.kw(k1: 1, k2: 2) [k1, k2] end
h = {k1: 11, k2: 12}
assert_equal([11, 12], o.kw(**h))
assert_equal([11, 22], o.kw(k2: 22, **h))
assert_equal([11, 12], o.kw(**h, **{k2: 22}))
assert_equal([11, 22], o.kw(**{k2: 22}, **h))
h = {k3: 31}
assert_raise(ArgumentError) {o.kw(**h)}
h = {"k1"=>11, k2: 12}
assert_raise(TypeError) {o.kw(**h)}
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
def test_cmd_symbol_after_keyword
bug6347 = '[ruby-dev:45563]'
assert_not_label(:foo, 'if true then not_label:foo end', bug6347)
assert_not_label(:foo, 'if false; else not_label:foo end', bug6347)
assert_not_label(:foo, 'begin not_label:foo end', bug6347)
assert_not_label(:foo, 'begin ensure not_label:foo end', bug6347)
end
def test_cmd_symbol_in_string
bug6347 = '[ruby-dev:45563]'
assert_not_label(:foo, '"#{not_label:foo}"', bug6347)
end
def test_cmd_symbol_singleton_class
bug6347 = '[ruby-dev:45563]'
@not_label = self
assert_not_label(:foo, 'class << not_label:foo; end', bug6347)
end
def test_cmd_symbol_superclass
bug6347 = '[ruby-dev:45563]'
@not_label = Object
assert_not_label(:foo, 'class Foo < not_label:foo; end', bug6347)
end
def test_duplicated_when
w = 'warning: duplicated when clause is ignored'
assert_warn(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){
eval %q{
case 1
when 1, 1
when 1, 1
when 1, 1
end
}
}
assert_warn(/#{w}/){#/3: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){
a = 1
eval %q{
case 1
when 1, 1
when 1, a
when 1, 1
end
}
}
end
def test_lambda_with_space
feature6390 = '[ruby-dev:45605]'
assert_valid_syntax("-> (x, y) {}", __FILE__, feature6390)
end
def test_do_block_in_cmdarg_begin
bug6419 = '[ruby-dev:45631]'
assert_valid_syntax("p begin 1.times do 1 end end", __FILE__, bug6419)
end
def test_reserved_method_no_args
bug6403 = '[ruby-dev:45626]'
assert_valid_syntax("def self; :foo; end", __FILE__, bug6403)
end
private
def not_label(x) @result = x; @not_label ||= nil end
def assert_not_label(expected, src, message = nil)
@result = nil
assert_nothing_raised(SyntaxError, message) {eval(src)}
assert_equal(expected, @result, message)
end
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