PageRenderTime 37ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/test/ruby/test_syntax.rb

http://github.com/ruby/ruby
Ruby | 1617 lines | 1493 code | 111 blank | 13 comment | 5 complexity | d2f9e0489bba37932f7bb476fa72bcb7 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. # frozen_string_literal: false
  2. require 'test/unit'
  3. class TestSyntax < Test::Unit::TestCase
  4. using Module.new {
  5. refine(Object) do
  6. def `(s) #`
  7. s
  8. end
  9. end
  10. }
  11. def assert_syntax_files(test)
  12. srcdir = File.expand_path("../../..", __FILE__)
  13. srcdir = File.join(srcdir, test)
  14. assert_separately(%W[--disable-gem - #{srcdir}],
  15. __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY)
  16. dir = ARGV.shift
  17. for script in Dir["#{dir}/**/*.rb"].sort
  18. assert_valid_syntax(IO::read(script), script)
  19. end
  20. eom
  21. end
  22. def test_syntax_lib; assert_syntax_files("lib"); end
  23. def test_syntax_sample; assert_syntax_files("sample"); end
  24. def test_syntax_ext; assert_syntax_files("ext"); end
  25. def test_syntax_test; assert_syntax_files("test"); end
  26. def test_defined_empty_argument
  27. bug8220 = '[ruby-core:53999] [Bug #8220]'
  28. assert_ruby_status(%w[--disable-gem], 'puts defined? ()', bug8220)
  29. end
  30. def test_must_ascii_compatible
  31. require 'tempfile'
  32. f = Tempfile.new("must_ac_")
  33. Encoding.list.each do |enc|
  34. next unless enc.ascii_compatible?
  35. make_tmpsrc(f, "# -*- coding: #{enc.name} -*-")
  36. assert_nothing_raised(ArgumentError, enc.name) {load(f.path)}
  37. end
  38. Encoding.list.each do |enc|
  39. next if enc.ascii_compatible?
  40. make_tmpsrc(f, "# -*- coding: #{enc.name} -*-")
  41. assert_raise(ArgumentError, enc.name) {load(f.path)}
  42. end
  43. ensure
  44. f&.close!
  45. end
  46. def test_script_lines
  47. require 'tempfile'
  48. f = Tempfile.new("bug4361_")
  49. bug4361 = '[ruby-dev:43168]'
  50. with_script_lines do |debug_lines|
  51. Encoding.list.each do |enc|
  52. next unless enc.ascii_compatible?
  53. make_tmpsrc(f, "# -*- coding: #{enc.name} -*-\n#----------------")
  54. load(f.path)
  55. assert_equal([f.path], debug_lines.keys)
  56. assert_equal([enc, enc], debug_lines[f.path].map(&:encoding), bug4361)
  57. end
  58. end
  59. ensure
  60. f&.close!
  61. end
  62. def test_newline_in_block_parameters
  63. bug = '[ruby-dev:45292]'
  64. ["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params|
  65. params = ["|", *params, "|"].join("\n")
  66. assert_valid_syntax("1.times{#{params}}", __FILE__, "#{bug} #{params.inspect}")
  67. end
  68. end
  69. tap do |_,
  70. bug6115 = '[ruby-dev:45308]',
  71. blockcall = '["elem"].each_with_object [] do end',
  72. methods = [['map', 'no'], ['inject([])', 'with']],
  73. blocks = [['do end', 'do'], ['{}', 'brace']],
  74. *|
  75. [%w'. dot', %w':: colon'].product(methods, blocks) do |(c, n1), (m, n2), (b, n3)|
  76. m = m.tr_s('()', ' ').strip if n2 == 'do'
  77. name = "test_#{n3}_block_after_blockcall_#{n1}_#{n2}_arg"
  78. code = "#{blockcall}#{c}#{m} #{b}"
  79. define_method(name) {assert_valid_syntax(code, bug6115)}
  80. end
  81. end
  82. def test_do_block_in_cmdarg
  83. bug9726 = '[ruby-core:61950] [Bug #9726]'
  84. assert_valid_syntax("tap (proc do end)", __FILE__, bug9726)
  85. end
  86. def test_hash_kwsplat_hash
  87. kw = {}
  88. h = {a: 1}
  89. assert_equal({}, {**{}})
  90. assert_equal({}, {**kw})
  91. assert_equal(h, {**h})
  92. assert_equal(false, {**{}}.frozen?)
  93. assert_equal(false, {**kw}.equal?(kw))
  94. assert_equal(false, {**h}.equal?(h))
  95. end
  96. def test_array_kwsplat_hash
  97. kw = {}
  98. h = {a: 1}
  99. assert_equal([], [**{}])
  100. assert_equal([], [**kw])
  101. assert_equal([h], [**h])
  102. assert_equal([{}], [{}])
  103. assert_equal([kw], [kw])
  104. assert_equal([h], [h])
  105. assert_equal([1], [1, **{}])
  106. assert_equal([1], [1, **kw])
  107. assert_equal([1, h], [1, **h])
  108. assert_equal([1, {}], [1, {}])
  109. assert_equal([1, kw], [1, kw])
  110. assert_equal([1, h], [1, h])
  111. assert_equal([], [**kw, **kw])
  112. assert_equal([], [**kw, **{}, **kw])
  113. assert_equal([1], [1, **kw, **{}, **kw])
  114. assert_equal([{}], [{}, **kw, **kw])
  115. assert_equal([kw], [kw, **kw, **kw])
  116. assert_equal([h], [h, **kw, **kw])
  117. assert_equal([h, h], [h, **kw, **kw, **h])
  118. assert_equal([h, {:a=>2}], [h, **{}, **h, a: 2])
  119. assert_equal([h, h], [h, **{}, a: 2, **h])
  120. assert_equal([h, h], [h, a: 2, **{}, **h])
  121. assert_equal([h, h], [h, a: 2, **h, **{}])
  122. assert_equal([h, {:a=>2}], [h, **h, a: 2, **{}])
  123. assert_equal([h, {:a=>2}], [h, **h, **{}, a: 2])
  124. end
  125. def test_normal_argument
  126. assert_valid_syntax('def foo(x) end')
  127. assert_syntax_error('def foo(X) end', /constant/)
  128. assert_syntax_error('def foo(@x) end', /instance variable/)
  129. assert_syntax_error('def foo(@@x) end', /class variable/)
  130. end
  131. def test_optional_argument
  132. assert_valid_syntax('def foo(x=nil) end')
  133. assert_syntax_error('def foo(X=nil) end', /constant/)
  134. assert_syntax_error('def foo(@x=nil) end', /instance variable/)
  135. assert_syntax_error('def foo(@@x=nil) end', /class variable/)
  136. end
  137. def test_keyword_rest
  138. bug5989 = '[ruby-core:42455]'
  139. assert_valid_syntax("def kwrest_test(**a) a; end", __FILE__, bug5989)
  140. assert_valid_syntax("def kwrest_test2(**a, &b) end", __FILE__, bug5989)
  141. o = Object.new
  142. def o.kw(**a) a end
  143. assert_equal({}, o.kw, bug5989)
  144. assert_equal({foo: 1}, o.kw(foo: 1), bug5989)
  145. assert_equal({foo: 1, bar: 2}, o.kw(foo: 1, bar: 2), bug5989)
  146. EnvUtil.under_gc_stress do
  147. eval("def o.m(k: 0) k end")
  148. end
  149. assert_equal(42, o.m(k: 42), '[ruby-core:45744]')
  150. bug7922 = '[ruby-core:52744] [Bug #7922]'
  151. def o.bug7922(**) end
  152. assert_nothing_raised(ArgumentError, bug7922) {o.bug7922(foo: 42)}
  153. end
  154. class KW2
  155. def kw(k1: 1, k2: 2) [k1, k2] end
  156. end
  157. def test_keyword_splat
  158. assert_valid_syntax("foo(**h)", __FILE__)
  159. o = KW2.new
  160. h = {k1: 11, k2: 12}
  161. assert_equal([11, 12], o.kw(**h))
  162. assert_equal([11, 12], o.kw(k2: 22, **h))
  163. assert_equal([11, 22], o.kw(**h, **{k2: 22}))
  164. assert_equal([11, 12], o.kw(**{k2: 22}, **h))
  165. end
  166. def test_keyword_duplicated_splat
  167. bug10315 = '[ruby-core:65368] [Bug #10315]'
  168. o = KW2.new
  169. assert_equal([23, 2], o.kw(**{k1: 22}, **{k1: 23}), bug10315)
  170. h = {k3: 31}
  171. assert_raise(ArgumentError) {o.kw(**h)}
  172. h = {"k1"=>11, k2: 12}
  173. assert_raise(ArgumentError) {o.kw(**h)}
  174. end
  175. def test_keyword_duplicated
  176. bug10315 = '[ruby-core:65625] [Bug #10315]'
  177. a = []
  178. def a.add(x) push(x); x; end
  179. def a.f(k:) k; end
  180. a.clear
  181. r = nil
  182. assert_warn(/duplicated/) {r = eval("a.f(k: a.add(1), k: a.add(2))")}
  183. assert_equal(2, r)
  184. assert_equal([1, 2], a, bug10315)
  185. a.clear
  186. r = nil
  187. assert_warn(/duplicated/) {r = eval("a.f(**{k: a.add(1), k: a.add(2)})")}
  188. assert_equal(2, r)
  189. assert_equal([1, 2], a, bug10315)
  190. end
  191. def test_keyword_empty_splat
  192. assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
  193. begin;
  194. bug10719 = '[ruby-core:67446] [Bug #10719]'
  195. assert_valid_syntax("foo(a: 1, **{})", bug10719)
  196. end;
  197. assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
  198. begin;
  199. bug13756 = '[ruby-core:82113] [Bug #13756]'
  200. assert_valid_syntax("defined? foo(**{})", bug13756)
  201. end;
  202. assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
  203. begin;
  204. bug15271 = '[ruby-core:89648] [Bug #15271]'
  205. assert_valid_syntax("a **{}", bug15271)
  206. end;
  207. end
  208. def test_keyword_self_reference
  209. message = /circular argument reference - var/
  210. assert_syntax_error("def foo(var: defined?(var)) var end", message)
  211. assert_syntax_error("def foo(var: var) var end", message)
  212. assert_syntax_error("def foo(var: bar(var)) var end", message)
  213. assert_syntax_error("def foo(var: bar {var}) var end", message)
  214. o = Object.new
  215. assert_warn("") do
  216. o.instance_eval("def foo(var: bar {|var| var}) var end")
  217. end
  218. o = Object.new
  219. assert_warn("") do
  220. o.instance_eval("def foo(var: bar {| | var}) var end")
  221. end
  222. o = Object.new
  223. assert_warn("") do
  224. o.instance_eval("def foo(var: bar {|| var}) var end")
  225. end
  226. o = Object.new
  227. assert_warn("") do
  228. o.instance_eval("def foo(var: def bar(var) var; end) var end")
  229. end
  230. o = Object.new
  231. assert_warn("") do
  232. o.instance_eval("proc {|var: 1| var}")
  233. end
  234. end
  235. def test_keyword_invalid_name
  236. bug11663 = '[ruby-core:71356] [Bug #11663]'
  237. assert_syntax_error('def foo(arg1?:) end', /arg1\?/, bug11663)
  238. assert_syntax_error('def foo(arg1?:, arg2:) end', /arg1\?/, bug11663)
  239. assert_syntax_error('proc {|arg1?:|}', /arg1\?/, bug11663)
  240. assert_syntax_error('proc {|arg1?:, arg2:|}', /arg1\?/, bug11663)
  241. bug10545 = '[ruby-dev:48742] [Bug #10545]'
  242. assert_syntax_error('def foo(FOO: a) end', /constant/, bug10545)
  243. assert_syntax_error('def foo(@foo: a) end', /instance variable/)
  244. assert_syntax_error('def foo(@@foo: a) end', /class variable/)
  245. end
  246. def test_keywords_specified_and_not_accepted
  247. assert_syntax_error('def foo(a:, **nil) end', /unexpected/)
  248. assert_syntax_error('def foo(a:, **nil, &b) end', /unexpected/)
  249. assert_syntax_error('def foo(**a, **nil) end', /unexpected/)
  250. assert_syntax_error('def foo(**a, **nil, &b) end', /unexpected/)
  251. assert_syntax_error('def foo(**nil, **a) end', /unexpected/)
  252. assert_syntax_error('def foo(**nil, **a, &b) end', /unexpected/)
  253. assert_syntax_error('proc do |a:, **nil| end', /unexpected/)
  254. assert_syntax_error('proc do |a:, **nil, &b| end', /unexpected/)
  255. assert_syntax_error('proc do |**a, **nil| end', /unexpected/)
  256. assert_syntax_error('proc do |**a, **nil, &b| end', /unexpected/)
  257. assert_syntax_error('proc do |**nil, **a| end', /unexpected/)
  258. assert_syntax_error('proc do |**nil, **a, &b| end', /unexpected/)
  259. end
  260. def test_optional_self_reference
  261. message = /circular argument reference - var/
  262. assert_syntax_error("def foo(var = defined?(var)) var end", message)
  263. assert_syntax_error("def foo(var = var) var end", message)
  264. assert_syntax_error("def foo(var = bar(var)) var end", message)
  265. assert_syntax_error("def foo(var = bar {var}) var end", message)
  266. assert_syntax_error("def foo(var = (def bar;end; var)) var end", message)
  267. assert_syntax_error("def foo(var = (def self.bar;end; var)) var end", message)
  268. o = Object.new
  269. assert_warn("") do
  270. o.instance_eval("def foo(var = bar {|var| var}) var end")
  271. end
  272. o = Object.new
  273. assert_warn("") do
  274. o.instance_eval("def foo(var = bar {| | var}) var end")
  275. end
  276. o = Object.new
  277. assert_warn("") do
  278. o.instance_eval("def foo(var = bar {|| var}) var end")
  279. end
  280. o = Object.new
  281. assert_warn("") do
  282. o.instance_eval("def foo(var = def bar(var) var; end) var end")
  283. end
  284. o = Object.new
  285. assert_warn("") do
  286. o.instance_eval("proc {|var = 1| var}")
  287. end
  288. end
  289. def test_warn_grouped_expression
  290. bug5214 = '[ruby-core:39050]'
  291. assert_warning("", bug5214) do
  292. assert_valid_syntax("foo \\\n(\n true)", "test", verbose: true)
  293. end
  294. end
  295. def test_warn_unreachable
  296. assert_warning("test:3: warning: statement not reached\n") do
  297. code = "loop do\n" "break\n" "foo\n" "end"
  298. assert_valid_syntax(code, "test", verbose: true)
  299. end
  300. end
  301. def test_warn_balanced
  302. warning = <<WARN
  303. test:1: warning: `%s' after local variable or literal is interpreted as binary operator
  304. test:1: warning: even though it seems like %s
  305. WARN
  306. [
  307. [:**, "argument prefix"],
  308. [:*, "argument prefix"],
  309. [:<<, "here document"],
  310. [:&, "argument prefix"],
  311. [:+, "unary operator"],
  312. [:-, "unary operator"],
  313. [:/, "regexp literal"],
  314. [:%, "string literal"],
  315. ].each do |op, syn|
  316. all_assertions do |a|
  317. ["puts 1 #{op}0", "puts :a #{op}0", "m = 1; puts m #{op}0"].each do |src|
  318. a.for(src) do
  319. assert_warning(warning % [op, syn], src) do
  320. assert_valid_syntax(src, "test", verbose: true)
  321. end
  322. end
  323. end
  324. end
  325. end
  326. end
  327. def test_cmd_symbol_after_keyword
  328. bug6347 = '[ruby-dev:45563]'
  329. assert_not_label(:foo, 'if true then not_label:foo end', bug6347)
  330. assert_not_label(:foo, 'if false; else not_label:foo end', bug6347)
  331. assert_not_label(:foo, 'begin not_label:foo end', bug6347)
  332. assert_not_label(:foo, 'begin ensure not_label:foo end', bug6347)
  333. end
  334. def test_cmd_symbol_in_string
  335. bug6347 = '[ruby-dev:45563]'
  336. assert_not_label(:foo, '"#{not_label:foo}"', bug6347)
  337. end
  338. def test_cmd_symbol_singleton_class
  339. bug6347 = '[ruby-dev:45563]'
  340. @not_label = self
  341. assert_not_label(:foo, 'class << not_label:foo; end', bug6347)
  342. end
  343. def test_cmd_symbol_superclass
  344. bug6347 = '[ruby-dev:45563]'
  345. @not_label = Object
  346. assert_not_label(:foo, 'class Foo < not_label:foo; end', bug6347)
  347. end
  348. def test_no_label_with_percent
  349. assert_syntax_error('{%"a": 1}', /unexpected ':'/)
  350. assert_syntax_error("{%'a': 1}", /unexpected ':'/)
  351. assert_syntax_error('{%Q"a": 1}', /unexpected ':'/)
  352. assert_syntax_error("{%Q'a': 1}", /unexpected ':'/)
  353. assert_syntax_error('{%q"a": 1}', /unexpected ':'/)
  354. assert_syntax_error("{%q'a': 1}", /unexpected ':'/)
  355. end
  356. def test_block_after_cond
  357. bug10653 = '[ruby-dev:48790] [Bug #10653]'
  358. assert_valid_syntax("false ? raise {} : tap {}", bug10653)
  359. assert_valid_syntax("false ? raise do end : tap do end", bug10653)
  360. end
  361. def test_paren_after_label
  362. bug11456 = '[ruby-dev:49221] [Bug #11456]'
  363. assert_valid_syntax("{foo: (1 rescue 0)}", bug11456)
  364. assert_valid_syntax("{foo: /=/}", bug11456)
  365. end
  366. def test_percent_string_after_label
  367. bug11812 = '[ruby-core:72084]'
  368. assert_valid_syntax('{label:%w(*)}', bug11812)
  369. assert_valid_syntax('{label: %w(*)}', bug11812)
  370. end
  371. def test_heredoc_after_label
  372. bug11849 = '[ruby-core:72396] [Bug #11849]'
  373. assert_valid_syntax("{label:<<DOC\n""DOC\n""}", bug11849)
  374. assert_valid_syntax("{label:<<-DOC\n""DOC\n""}", bug11849)
  375. assert_valid_syntax("{label:<<~DOC\n""DOC\n""}", bug11849)
  376. assert_valid_syntax("{label: <<DOC\n""DOC\n""}", bug11849)
  377. assert_valid_syntax("{label: <<-DOC\n""DOC\n""}", bug11849)
  378. assert_valid_syntax("{label: <<~DOC\n""DOC\n""}", bug11849)
  379. end
  380. def test_cmdarg_kwarg_lvar_clashing_method
  381. bug12073 = '[ruby-core:73816] [Bug#12073]'
  382. a = a = 1
  383. assert_valid_syntax("a b: 1")
  384. assert_valid_syntax("a = 1; a b: 1", bug12073)
  385. end
  386. def test_duplicated_arg
  387. assert_syntax_error("def foo(a, a) end", /duplicated argument name/)
  388. assert_valid_syntax("def foo(_, _) end")
  389. (obj = Object.new).instance_eval("def foo(_, x, _) x end")
  390. assert_equal(2, obj.foo(1, 2, 3))
  391. end
  392. def test_duplicated_rest
  393. assert_syntax_error("def foo(a, *a) end", /duplicated argument name/)
  394. assert_valid_syntax("def foo(_, *_) end")
  395. (obj = Object.new).instance_eval("def foo(_, x, *_) x end")
  396. assert_equal(2, obj.foo(1, 2, 3))
  397. end
  398. def test_duplicated_opt
  399. assert_syntax_error("def foo(a, a=1) end", /duplicated argument name/)
  400. assert_valid_syntax("def foo(_, _=1) end")
  401. (obj = Object.new).instance_eval("def foo(_, x, _=42) x end")
  402. assert_equal(2, obj.foo(1, 2))
  403. end
  404. def test_duplicated_opt_rest
  405. assert_syntax_error("def foo(a=1, *a) end", /duplicated argument name/)
  406. assert_valid_syntax("def foo(_=1, *_) end")
  407. (obj = Object.new).instance_eval("def foo(_, x=42, *_) x end")
  408. assert_equal(42, obj.foo(1))
  409. assert_equal(2, obj.foo(1, 2))
  410. end
  411. def test_duplicated_rest_opt
  412. assert_syntax_error("def foo(*a, a=1) end", /duplicated argument name/)
  413. end
  414. def test_duplicated_rest_post
  415. assert_syntax_error("def foo(*a, a) end", /duplicated argument name/)
  416. assert_valid_syntax("def foo(*_, _) end")
  417. (obj = Object.new).instance_eval("def foo(*_, x, _) x end")
  418. assert_equal(2, obj.foo(1, 2, 3))
  419. assert_equal(2, obj.foo(2, 3))
  420. (obj = Object.new).instance_eval("def foo(*_, _, x) x end")
  421. assert_equal(3, obj.foo(1, 2, 3))
  422. assert_equal(3, obj.foo(2, 3))
  423. end
  424. def test_duplicated_opt_post
  425. assert_syntax_error("def foo(a=1, a) end", /duplicated argument name/)
  426. assert_valid_syntax("def foo(_=1, _) end")
  427. (obj = Object.new).instance_eval("def foo(_=1, x, _) x end")
  428. assert_equal(2, obj.foo(1, 2, 3))
  429. assert_equal(2, obj.foo(2, 3))
  430. (obj = Object.new).instance_eval("def foo(_=1, _, x) x end")
  431. assert_equal(3, obj.foo(1, 2, 3))
  432. assert_equal(3, obj.foo(2, 3))
  433. end
  434. def test_duplicated_kw
  435. assert_syntax_error("def foo(a, a: 1) end", /duplicated argument name/)
  436. assert_valid_syntax("def foo(_, _: 1) end")
  437. (obj = Object.new).instance_eval("def foo(_, x, _: 1) x end")
  438. assert_equal(3, obj.foo(2, 3))
  439. assert_equal(3, obj.foo(2, 3, _: 42))
  440. (obj = Object.new).instance_eval("def foo(x, _, _: 1) x end")
  441. assert_equal(2, obj.foo(2, 3))
  442. assert_equal(2, obj.foo(2, 3, _: 42))
  443. end
  444. def test_duplicated_rest_kw
  445. assert_syntax_error("def foo(*a, a: 1) end", /duplicated argument name/)
  446. assert_nothing_raised {def foo(*_, _: 1) end}
  447. (obj = Object.new).instance_eval("def foo(*_, x: 42, _: 1) x end")
  448. assert_equal(42, obj.foo(42))
  449. assert_equal(42, obj.foo(2, _: 0))
  450. assert_equal(2, obj.foo(x: 2, _: 0))
  451. end
  452. def test_duplicated_opt_kw
  453. assert_syntax_error("def foo(a=1, a: 1) end", /duplicated argument name/)
  454. assert_valid_syntax("def foo(_=1, _: 1) end")
  455. (obj = Object.new).instance_eval("def foo(_=42, x, _: 1) x end")
  456. assert_equal(0, obj.foo(0))
  457. assert_equal(0, obj.foo(0, _: 3))
  458. end
  459. def test_duplicated_kw_kwrest
  460. assert_syntax_error("def foo(a: 1, **a) end", /duplicated argument name/)
  461. assert_valid_syntax("def foo(_: 1, **_) end")
  462. (obj = Object.new).instance_eval("def foo(_: 1, x: 42, **_) x end")
  463. assert_equal(42, obj.foo())
  464. assert_equal(42, obj.foo(a: 0))
  465. assert_equal(42, obj.foo(_: 0, a: 0))
  466. assert_equal(1, obj.foo(_: 0, x: 1, a: 0))
  467. end
  468. def test_duplicated_rest_kwrest
  469. assert_syntax_error("def foo(*a, **a) end", /duplicated argument name/)
  470. assert_valid_syntax("def foo(*_, **_) end")
  471. (obj = Object.new).instance_eval("def foo(*_, x, **_) x end")
  472. assert_equal(1, obj.foo(1))
  473. assert_equal(1, obj.foo(1, a: 0))
  474. assert_equal(2, obj.foo(1, 2, a: 0))
  475. end
  476. def test_duplicated_opt_kwrest
  477. assert_syntax_error("def foo(a=1, **a) end", /duplicated argument name/)
  478. assert_valid_syntax("def foo(_=1, **_) end")
  479. (obj = Object.new).instance_eval("def foo(_=42, x, **_) x end")
  480. assert_equal(1, obj.foo(1))
  481. assert_equal(1, obj.foo(1, a: 0))
  482. assert_equal(1, obj.foo(0, 1, a: 0))
  483. end
  484. def test_duplicated_when
  485. w = 'warning: duplicated `when\' clause with line 3 is ignored'
  486. assert_warning(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m) {
  487. eval %q{
  488. case 1
  489. when 1, 1
  490. when 1, 1
  491. when 1, 1
  492. end
  493. }
  494. }
  495. assert_warning(/#{w}/) {#/3: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){
  496. a = a = 1
  497. eval %q{
  498. case 1
  499. when 1, 1
  500. when 1, a
  501. when 1, 1
  502. end
  503. }
  504. }
  505. end
  506. def test_duplicated_when_check_option
  507. w = /duplicated `when\' clause with line 3 is ignored/
  508. assert_in_out_err(%[-wc], "#{<<~"begin;"}\n#{<<~'end;'}", ["Syntax OK"], w)
  509. begin;
  510. case 1
  511. when 1
  512. when 1
  513. end
  514. end;
  515. end
  516. def test_invalid_break
  517. assert_syntax_error("def m; break; end", /Invalid break/)
  518. assert_syntax_error('/#{break}/', /Invalid break/)
  519. assert_syntax_error('/#{break}/o', /Invalid break/)
  520. end
  521. def test_invalid_next
  522. assert_syntax_error("def m; next; end", /Invalid next/)
  523. assert_syntax_error('/#{next}/', /Invalid next/)
  524. assert_syntax_error('/#{next}/o', /Invalid next/)
  525. end
  526. def test_lambda_with_space
  527. feature6390 = '[ruby-dev:45605]'
  528. assert_valid_syntax("-> (x, y) {}", __FILE__, feature6390)
  529. end
  530. def test_do_block_in_cmdarg_begin
  531. bug6419 = '[ruby-dev:45631]'
  532. assert_valid_syntax("p begin 1.times do 1 end end", __FILE__, bug6419)
  533. end
  534. def test_do_block_in_call_args
  535. bug9308 = '[ruby-core:59342] [Bug #9308]'
  536. assert_valid_syntax("bar def foo; self.each do end end", bug9308)
  537. end
  538. def test_do_block_in_lambda
  539. bug11107 = '[ruby-core:69017] [Bug #11107]'
  540. assert_valid_syntax('p ->() do a() do end end', bug11107)
  541. end
  542. def test_do_block_after_lambda
  543. bug11380 = '[ruby-core:70067] [Bug #11380]'
  544. assert_valid_syntax('p -> { :hello }, a: 1 do end', bug11380)
  545. end
  546. def test_reserved_method_no_args
  547. bug6403 = '[ruby-dev:45626]'
  548. assert_valid_syntax("def self; :foo; end", __FILE__, bug6403)
  549. end
  550. def test_unassignable
  551. gvar = global_variables
  552. %w[self nil true false __FILE__ __LINE__ __ENCODING__].each do |kwd|
  553. assert_syntax_error("#{kwd} = nil", /Can't .* #{kwd}$/)
  554. assert_equal(gvar, global_variables)
  555. end
  556. end
  557. Bug7559 = '[ruby-dev:46737]'
  558. def test_lineno_command_call_quote
  559. expected = __LINE__ + 1
  560. actual = caller_lineno "a
  561. b
  562. c
  563. d
  564. e"
  565. assert_equal(expected, actual, "#{Bug7559}: ")
  566. end
  567. def assert_dedented_heredoc(expect, result, mesg = "")
  568. all_assertions(mesg) do |a|
  569. %w[eos "eos" 'eos' `eos`].each do |eos|
  570. a.for(eos) do
  571. assert_equal(eval("<<-#{eos}\n#{expect}eos\n"),
  572. eval("<<~#{eos}\n#{result}eos\n"))
  573. end
  574. end
  575. end
  576. end
  577. def test_dedented_heredoc_without_indentation
  578. result = " y\n" \
  579. "z\n"
  580. expect = result
  581. assert_dedented_heredoc(expect, result)
  582. end
  583. def test_dedented_heredoc_with_indentation
  584. result = " a\n" \
  585. " b\n"
  586. expect = " a\n" \
  587. "b\n"
  588. assert_dedented_heredoc(expect, result)
  589. end
  590. def test_dedented_heredoc_with_blank_less_indented_line
  591. # the blank line has two leading spaces
  592. result = " a\n" \
  593. " \n" \
  594. " b\n"
  595. expect = "a\n" \
  596. "\n" \
  597. "b\n"
  598. assert_dedented_heredoc(expect, result)
  599. end
  600. def test_dedented_heredoc_with_blank_less_indented_line_escaped
  601. result = " a\n" \
  602. "\\ \\ \n" \
  603. " b\n"
  604. expect = result
  605. assert_dedented_heredoc(expect, result)
  606. end
  607. def test_dedented_heredoc_with_blank_more_indented_line
  608. # the blank line has six leading spaces
  609. result = " a\n" \
  610. " \n" \
  611. " b\n"
  612. expect = "a\n" \
  613. " \n" \
  614. "b\n"
  615. assert_dedented_heredoc(expect, result)
  616. end
  617. def test_dedented_heredoc_with_blank_more_indented_line_escaped
  618. result = " a\n" \
  619. "\\ \\ \\ \\ \\ \\ \n" \
  620. " b\n"
  621. expect = result
  622. assert_dedented_heredoc(expect, result)
  623. end
  624. def test_dedented_heredoc_with_empty_line
  625. result = " This would contain specially formatted text.\n" \
  626. "\n" \
  627. " That might span many lines\n"
  628. expect = 'This would contain specially formatted text.'"\n" \
  629. ''"\n" \
  630. 'That might span many lines'"\n"
  631. assert_dedented_heredoc(expect, result)
  632. end
  633. def test_dedented_heredoc_with_interpolated_expression
  634. result = ' #{1}a'"\n" \
  635. " zy\n"
  636. expect = ' #{1}a'"\n" \
  637. "zy\n"
  638. assert_dedented_heredoc(expect, result)
  639. end
  640. def test_dedented_heredoc_with_interpolated_string
  641. w = w = ""
  642. result = " \#{mesg} a\n" \
  643. " zy\n"
  644. expect = '#{mesg} a'"\n" \
  645. ' zy'"\n"
  646. assert_dedented_heredoc(expect, result)
  647. end
  648. def test_dedented_heredoc_with_newline
  649. bug11989 = '[ruby-core:72855] [Bug #11989] after escaped newline should not be dedented'
  650. result = ' x\n'" y\n" \
  651. " z\n"
  652. expect = 'x\n'" y\n" \
  653. "z\n"
  654. assert_dedented_heredoc(expect, result, bug11989)
  655. end
  656. def test_dedented_heredoc_with_concatenation
  657. bug11990 = '[ruby-core:72857] [Bug #11990] concatenated string should not be dedented'
  658. %w[eos "eos" 'eos'].each do |eos|
  659. assert_equal("x\n y",
  660. eval("<<~#{eos} ' y'\n x\neos\n"),
  661. "#{bug11990} with #{eos}")
  662. end
  663. %w[eos "eos" 'eos' `eos`].each do |eos|
  664. _, expect = eval("[<<~#{eos}, ' x']\n"" y\n""eos\n")
  665. assert_equal(' x', expect, bug11990)
  666. end
  667. end
  668. def test_dedented_heredoc_expr_at_beginning
  669. result = " a\n" \
  670. '#{1}'"\n"
  671. expected = " a\n" \
  672. '#{1}'"\n"
  673. assert_dedented_heredoc(expected, result)
  674. end
  675. def test_dedented_heredoc_expr_string
  676. result = ' one#{" two "}'"\n"
  677. expected = 'one#{" two "}'"\n"
  678. assert_dedented_heredoc(expected, result)
  679. end
  680. def test_dedented_heredoc_continued_line
  681. result = " 1\\\n" " 2\n"
  682. expected = "1\\\n" "2\n"
  683. assert_dedented_heredoc(expected, result)
  684. assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /can't find string "TEXT"/)
  685. begin;
  686. <<-TEXT
  687. \
  688. TEXT
  689. end;
  690. assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /can't find string "TEXT"/)
  691. begin;
  692. <<~TEXT
  693. \
  694. TEXT
  695. end;
  696. assert_equal(" TEXT\n", eval("<<~eos\n" " \\\n" "TEXT\n" "eos\n"))
  697. end
  698. def test_lineno_after_heredoc
  699. bug7559 = '[ruby-dev:46737]'
  700. expected, _, actual = __LINE__, <<eom, __LINE__
  701. a
  702. b
  703. c
  704. d
  705. eom
  706. assert_equal(expected, actual, bug7559)
  707. end
  708. def test_dedented_heredoc_invalid_identifer
  709. assert_syntax_error('<<~ "#{}"', /unexpected <</)
  710. end
  711. def test_dedented_heredoc_concatenation
  712. assert_equal("\n0\n1", eval("<<~0 '1'\n \n0\#{}\n0"))
  713. end
  714. def test_heredoc_mixed_encoding
  715. e = assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source')
  716. #encoding: cp932
  717. <<-TEXT
  718. \xe9\x9d\u1234
  719. TEXT
  720. HEREDOC
  721. assert_not_match(/end-of-input/, e.message)
  722. e = assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source')
  723. #encoding: cp932
  724. <<-TEXT
  725. \xe9\x9d
  726. \u1234
  727. TEXT
  728. HEREDOC
  729. assert_not_match(/end-of-input/, e.message)
  730. e = assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source')
  731. #encoding: cp932
  732. <<-TEXT
  733. \u1234\xe9\x9d
  734. TEXT
  735. HEREDOC
  736. assert_not_match(/end-of-input/, e.message)
  737. e = assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source')
  738. #encoding: cp932
  739. <<-TEXT
  740. \u1234
  741. \xe9\x9d
  742. TEXT
  743. HEREDOC
  744. assert_not_match(/end-of-input/, e.message)
  745. end
  746. def test_lineno_operation_brace_block
  747. expected = __LINE__ + 1
  748. actual = caller_lineno\
  749. {}
  750. assert_equal(expected, actual)
  751. end
  752. def assert_constant_reassignment_nested(preset, op, expected, err = [], bug = '[Bug #5449]')
  753. [
  754. ["p ", ""], # no-pop
  755. ["", "p Foo::Bar"], # pop
  756. ].each do |p1, p2|
  757. src = <<-EOM.gsub(/^\s*\n/, '')
  758. class Foo
  759. #{"Bar = " + preset if preset}
  760. end
  761. #{p1}Foo::Bar #{op}= 42
  762. #{p2}
  763. EOM
  764. msg = "\# #{bug}\n#{src}"
  765. assert_valid_syntax(src, caller_locations(1, 1)[0].path, msg)
  766. assert_in_out_err([], src, expected, err, msg)
  767. end
  768. end
  769. def test_constant_reassignment_nested
  770. already = /already initialized constant Foo::Bar/
  771. uninitialized = /uninitialized constant Foo::Bar/
  772. assert_constant_reassignment_nested(nil, "||", %w[42])
  773. assert_constant_reassignment_nested("false", "||", %w[42], already)
  774. assert_constant_reassignment_nested("true", "||", %w[true])
  775. assert_constant_reassignment_nested(nil, "&&", [], uninitialized)
  776. assert_constant_reassignment_nested("false", "&&", %w[false])
  777. assert_constant_reassignment_nested("true", "&&", %w[42], already)
  778. assert_constant_reassignment_nested(nil, "+", [], uninitialized)
  779. assert_constant_reassignment_nested("false", "+", [], /undefined method/)
  780. assert_constant_reassignment_nested("11", "+", %w[53], already)
  781. end
  782. def assert_constant_reassignment_toplevel(preset, op, expected, err = [], bug = '[Bug #5449]')
  783. [
  784. ["p ", ""], # no-pop
  785. ["", "p ::Bar"], # pop
  786. ].each do |p1, p2|
  787. src = <<-EOM.gsub(/^\s*\n/, '')
  788. #{"Bar = " + preset if preset}
  789. class Foo
  790. #{p1}::Bar #{op}= 42
  791. #{p2}
  792. end
  793. EOM
  794. msg = "\# #{bug}\n#{src}"
  795. assert_valid_syntax(src, caller_locations(1, 1)[0].path, msg)
  796. assert_in_out_err([], src, expected, err, msg)
  797. end
  798. end
  799. def test_constant_reassignment_toplevel
  800. already = /already initialized constant Bar/
  801. uninitialized = /uninitialized constant Bar/
  802. assert_constant_reassignment_toplevel(nil, "||", %w[42])
  803. assert_constant_reassignment_toplevel("false", "||", %w[42], already)
  804. assert_constant_reassignment_toplevel("true", "||", %w[true])
  805. assert_constant_reassignment_toplevel(nil, "&&", [], uninitialized)
  806. assert_constant_reassignment_toplevel("false", "&&", %w[false])
  807. assert_constant_reassignment_toplevel("true", "&&", %w[42], already)
  808. assert_constant_reassignment_toplevel(nil, "+", [], uninitialized)
  809. assert_constant_reassignment_toplevel("false", "+", [], /undefined method/)
  810. assert_constant_reassignment_toplevel("11", "+", %w[53], already)
  811. end
  812. def test_integer_suffix
  813. ["1if true", "begin 1end"].each do |src|
  814. assert_valid_syntax(src)
  815. assert_equal(1, eval(src), src)
  816. end
  817. end
  818. def test_value_of_def
  819. assert_separately [], <<-EOS
  820. assert_equal(:foo, (def foo; end))
  821. assert_equal(:foo, (def (Object.new).foo; end))
  822. EOS
  823. end
  824. def test_heredoc_cr
  825. assert_syntax_error("puts <<""EOS\n""ng\n""EOS\r""NO\n", /can't find string "EOS" anywhere before EOF/)
  826. end
  827. def test_heredoc_no_terminator
  828. assert_syntax_error("puts <<""A\n", /can't find string "A" anywhere before EOF/)
  829. assert_syntax_error("puts <<""A + <<""B\n", /can't find string "A" anywhere before EOF/)
  830. assert_syntax_error("puts <<""A + <<""B\n", /can't find string "B" anywhere before EOF/)
  831. end
  832. def test_unterminated_heredoc
  833. assert_syntax_error("<<\"EOS\n\nEOS\n", /unterminated/)
  834. assert_syntax_error("<<\"EOS\n\"\nEOS\n", /unterminated/)
  835. end
  836. def test_unterminated_heredoc_cr
  837. %W[\r\n \n].each do |nl|
  838. assert_syntax_error("<<\"\r\"#{nl}\r#{nl}", /unterminated/, nil, "CR with #{nl.inspect}")
  839. end
  840. end
  841. def test__END___cr
  842. assert_syntax_error("__END__\r<<<<<\n", /unexpected <</)
  843. end
  844. def test_warning_for_cr
  845. feature8699 = '[ruby-core:56240] [Feature #8699]'
  846. s = assert_warning(/encountered \\r/, feature8699) do
  847. eval("'\r'\r")
  848. end
  849. assert_equal("\r", s)
  850. s = assert_warning('') do
  851. eval("'\r'\r\n")
  852. end
  853. assert_equal("\r", s)
  854. end
  855. def test_unexpected_fraction
  856. msg = /unexpected fraction/
  857. assert_syntax_error("0x0.0", msg)
  858. assert_syntax_error("0b0.0", msg)
  859. assert_syntax_error("0d0.0", msg)
  860. assert_syntax_error("0o0.0", msg)
  861. assert_syntax_error("0.0.0", msg)
  862. end
  863. def test_error_message_encoding
  864. bug10114 = '[ruby-core:64228] [Bug #10114]'
  865. code = "# -*- coding: utf-8 -*-\n" "def n \"\u{2208}\"; end"
  866. assert_syntax_error(code, /def n "\u{2208}"; end/, bug10114)
  867. end
  868. def test_null_range_cmdarg
  869. bug10957 = '[ruby-core:68477] [Bug #10957]'
  870. assert_ruby_status(['-c', '-e', 'p ()..0'], "", bug10957)
  871. assert_ruby_status(['-c', '-e', 'p ()...0'], "", bug10957)
  872. assert_syntax_error('0..%q.', /unterminated string/, bug10957)
  873. assert_syntax_error('0...%q.', /unterminated string/, bug10957)
  874. end
  875. def test_range_at_eol
  876. assert_warn(/\.\.\. at EOL/) {eval("1...\n2")}
  877. assert_warn('') {eval("(1...)")}
  878. assert_warn('') {eval("(1...\n2)")}
  879. assert_warn('') {eval("{a: 1...\n2}")}
  880. end
  881. def test_too_big_nth_ref
  882. bug11192 = '[ruby-core:69393] [Bug #11192]'
  883. assert_warn(/too big/, bug11192) do
  884. eval('$99999999999999999')
  885. end
  886. end
  887. def test_invalid_symbol_space
  888. assert_syntax_error(": foo", /unexpected ':'/)
  889. assert_syntax_error(": #\n foo", /unexpected ':'/)
  890. assert_syntax_error(":#\n foo", /unexpected ':'/)
  891. end
  892. def test_invalid_literal_message
  893. assert_syntax_error("def :foo", /unexpected symbol literal/)
  894. assert_syntax_error("def 'foo'", /unexpected string literal/)
  895. end
  896. def test_fluent_dot
  897. assert_valid_syntax("a\n.foo")
  898. assert_valid_syntax("a\n&.foo")
  899. assert_valid_syntax("a #\n#\n.foo\n")
  900. assert_valid_syntax("a #\n#\n&.foo\n")
  901. end
  902. def test_safe_call_in_massign_lhs
  903. assert_syntax_error("*a&.x=0", /multiple assignment destination/)
  904. assert_syntax_error("a&.x,=0", /multiple assignment destination/)
  905. end
  906. def test_no_warning_logop_literal
  907. assert_warning("") do
  908. eval("true||raise;nil")
  909. end
  910. assert_warning("") do
  911. eval("false&&raise;nil")
  912. end
  913. assert_warning("") do
  914. eval("''||raise;nil")
  915. end
  916. end
  917. def test_warning_literal_in_condition
  918. assert_warn(/literal in condition/) do
  919. eval('1 if ""')
  920. end
  921. assert_warn(/literal in condition/) do
  922. eval('1 if //')
  923. end
  924. assert_warning(/literal in condition/) do
  925. eval('1 if 1')
  926. end
  927. assert_warning(/literal in condition/) do
  928. eval('1 if :foo')
  929. end
  930. assert_warning(/literal in condition/) do
  931. eval('1 if :"#{"foo".upcase}"')
  932. end
  933. assert_warn('') do
  934. eval('1 if !""')
  935. end
  936. assert_warn('') do
  937. eval('1 if !//')
  938. end
  939. assert_warn('') do
  940. eval('1 if !(true..false)')
  941. end
  942. assert_warning('') do
  943. eval('1 if !1')
  944. end
  945. assert_warning('') do
  946. eval('1 if !:foo')
  947. end
  948. assert_warning('') do
  949. eval('1 if !:"#{"foo".upcase}"')
  950. end
  951. end
  952. def test_warning_literal_in_flip_flop
  953. assert_warn(/literal in flip-flop/) do
  954. eval('1 if ""..false')
  955. end
  956. assert_warning(/literal in flip-flop/) do
  957. eval('1 if :foo..false')
  958. end
  959. assert_warning(/literal in flip-flop/) do
  960. eval('1 if :"#{"foo".upcase}"..false')
  961. end
  962. assert_warn(/literal in flip-flop/) do
  963. eval('1 if ""...false')
  964. end
  965. assert_warning(/literal in flip-flop/) do
  966. eval('1 if :foo...false')
  967. end
  968. assert_warning(/literal in flip-flop/) do
  969. eval('1 if :"#{"foo".upcase}"...false')
  970. end
  971. end
  972. def test_alias_symbol
  973. bug8851 = '[ruby-dev:47681] [Bug #8851]'
  974. formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)']
  975. all_assertions(bug8851) do |all|
  976. formats.product(formats) do |form1, form2|
  977. all.for(code = "alias #{form1 % 'a'} #{form2 % 'p'}") do
  978. assert_valid_syntax(code)
  979. end
  980. end
  981. end
  982. end
  983. def test_undef_symbol
  984. bug8851 = '[ruby-dev:47681] [Bug #8851]'
  985. formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)']
  986. all_assertions(bug8851) do |all|
  987. formats.product(formats) do |form1, form2|
  988. all.for(code = "undef #{form1 % 'a'}, #{form2 % 'p'}") do
  989. assert_valid_syntax(code)
  990. end
  991. end
  992. end
  993. end
  994. def test_parenthesised_statement_argument
  995. assert_syntax_error("foo(bar rescue nil)", /unexpected `rescue' modifier/)
  996. assert_valid_syntax("foo (bar rescue nil)")
  997. end
  998. def test_cmdarg_in_paren
  999. bug11873 = '[ruby-core:72482] [Bug #11873]'
  1000. assert_valid_syntax %q{a b{c d}, :e do end}, bug11873
  1001. assert_valid_syntax %q{a b(c d), :e do end}, bug11873
  1002. assert_valid_syntax %q{a b{c(d)}, :e do end}, bug11873
  1003. assert_valid_syntax %q{a b(c(d)), :e do end}, bug11873
  1004. assert_valid_syntax %q{a b{c d}, 1 do end}, bug11873
  1005. assert_valid_syntax %q{a b(c d), 1 do end}, bug11873
  1006. assert_valid_syntax %q{a b{c(d)}, 1 do end}, bug11873
  1007. assert_valid_syntax %q{a b(c(d)), 1 do end}, bug11873
  1008. assert_valid_syntax %q{a b{c d}, "x" do end}, bug11873
  1009. assert_valid_syntax %q{a b(c d), "x" do end}, bug11873
  1010. assert_valid_syntax %q{a b{c(d)}, "x" do end}, bug11873
  1011. assert_valid_syntax %q{a b(c(d)), "x" do end}, bug11873
  1012. end
  1013. def test_block_after_cmdarg_in_paren
  1014. bug11873 = '[ruby-core:72482] [Bug #11873]'
  1015. def bug11873.p(*);end;
  1016. assert_raise(LocalJumpError, bug11873) do
  1017. bug11873.instance_eval do
  1018. p p{p p;p(p)}, tap do
  1019. raise SyntaxError, "should not be passed to tap"
  1020. end
  1021. end
  1022. end
  1023. assert_raise(LocalJumpError, bug11873) do
  1024. bug11873.instance_eval do
  1025. p p{p(p);p p}, tap do
  1026. raise SyntaxError, "should not be passed to tap"
  1027. end
  1028. end
  1029. end
  1030. end
  1031. def test_do_block_in_hash_brace
  1032. bug13073 = '[ruby-core:78837] [Bug #13073]'
  1033. assert_valid_syntax 'p :foo, {a: proc do end, b: proc do end}', bug13073
  1034. assert_valid_syntax 'p :foo, {:a => proc do end, b: proc do end}', bug13073
  1035. assert_valid_syntax 'p :foo, {"a": proc do end, b: proc do end}', bug13073
  1036. assert_valid_syntax 'p :foo, {** proc do end, b: proc do end}', bug13073
  1037. assert_valid_syntax 'p :foo, {proc do end => proc do end, b: proc do end}', bug13073
  1038. end
  1039. def test_do_after_local_variable
  1040. obj = Object.new
  1041. def obj.m; yield; end
  1042. result = assert_nothing_raised(SyntaxError) do
  1043. obj.instance_eval("m = 1; m do :ok end")
  1044. end
  1045. assert_equal(:ok, result)
  1046. end
  1047. def test_brace_after_local_variable
  1048. obj = Object.new
  1049. def obj.m; yield; end
  1050. result = assert_nothing_raised(SyntaxError) do
  1051. obj.instance_eval("m = 1; m {:ok}")
  1052. end
  1053. assert_equal(:ok, result)
  1054. end
  1055. def test_brace_after_literal_argument
  1056. bug = '[ruby-core:81037] [Bug #13547]'
  1057. error = /unexpected '{'/
  1058. assert_syntax_error('m "x" {}', error)
  1059. assert_syntax_error('m 1 {}', error, bug)
  1060. assert_syntax_error('m 1.0 {}', error, bug)
  1061. assert_syntax_error('m :m {}', error, bug)
  1062. assert_syntax_error('m :"#{m}" {}', error, bug)
  1063. assert_syntax_error('m ?x {}', error, bug)
  1064. assert_syntax_error('m %[] {}', error, bug)
  1065. assert_syntax_error('m 0..1 {}', error, bug)
  1066. assert_syntax_error('m [] {}', error, bug)
  1067. end
  1068. def test_return_toplevel
  1069. feature4840 = '[ruby-core:36785] [Feature #4840]'
  1070. line = __LINE__+2
  1071. code = "#{<<~"begin;"}#{<<~'end;'}"
  1072. begin;
  1073. return; raise
  1074. begin return; rescue SystemExit; exit false; end
  1075. begin return; ensure puts "ensured"; end #=> ensured
  1076. begin ensure return; end
  1077. begin raise; ensure; return; end
  1078. begin raise; rescue; return; end
  1079. return false; raise
  1080. return 1; raise
  1081. "#{return}"
  1082. raise((return; "should not raise"))
  1083. begin raise; ensure return; end; self
  1084. begin raise; ensure return; end and self
  1085. nil&defined?0--begin e=no_method_error(); return; 0;end
  1086. return puts('ignored') #=> ignored
  1087. end;
  1088. .split(/\n/).map {|s|[(line+=1), *s.split(/#=> /, 2)]}
  1089. failed = proc do |n, s|
  1090. RubyVM::InstructionSequence.compile(s, __FILE__, nil, n).disasm
  1091. end
  1092. Tempfile.create(%w"test_return_ .rb") do |lib|
  1093. lib.close
  1094. args = %W[-W0 -r#{lib.path}]
  1095. all_assertions_foreach(feature4840, *[:main, :lib].product([:class, :top], code)) do |main, klass, (n, s, *ex)|
  1096. if klass == :class
  1097. s = "class X; #{s}; end"
  1098. if main == :main
  1099. assert_in_out_err(%[-W0], s, [], /return/, proc {failed[n, s]}, success: false)
  1100. else
  1101. File.write(lib, s)
  1102. assert_in_out_err(args, "", [], /return/, proc {failed[n, s]}, success: false)
  1103. end
  1104. else
  1105. if main == :main
  1106. assert_in_out_err(%[-W0], s, ex, [], proc {failed[n, s]}, success: true)
  1107. else
  1108. File.write(lib, s)
  1109. assert_in_out_err(args, "", ex, [], proc {failed[n, s]}, success: true)
  1110. end
  1111. end
  1112. end
  1113. end
  1114. end
  1115. def test_return_toplevel_with_argument
  1116. assert_warn(/argument of top-level return is ignored/) {eval("return 1")}
  1117. end
  1118. def test_return_in_proc_in_class
  1119. assert_in_out_err(['-e', 'class TestSyntax; proc{ return }.call; end'], "", [], /^-e:1:.*unexpected return \(LocalJumpError\)/)
  1120. end
  1121. def test_syntax_error_in_rescue
  1122. bug12613 = '[ruby-core:76531] [Bug #12613]'
  1123. assert_syntax_error("#{<<-"begin;"}\n#{<<-"end;"}", /Invalid retry/, bug12613)
  1124. begin;
  1125. while true
  1126. begin
  1127. p
  1128. rescue
  1129. retry
  1130. else
  1131. retry
  1132. end
  1133. break
  1134. end
  1135. end;
  1136. end
  1137. def test_syntax_error_at_newline
  1138. expected = "\n ^"
  1139. assert_syntax_error("%[abcdef", expected)
  1140. assert_syntax_error("%[abcdef\n", expected)
  1141. end
  1142. def test_invalid_jump
  1143. assert_in_out_err(%w[-e redo], "", [], /^-e:1: /)
  1144. end
  1145. def test_keyword_not_parens
  1146. assert_valid_syntax("not()")
  1147. end
  1148. def test_rescue_do_end_raised
  1149. result = []
  1150. assert_raise(RuntimeError) do
  1151. eval("#{<<-"begin;"}\n#{<<-"end;"}")
  1152. begin;
  1153. tap do
  1154. result << :begin
  1155. raise "An exception occurred!"
  1156. ensure
  1157. result << :ensure
  1158. end
  1159. end;
  1160. end
  1161. assert_equal([:begin, :ensure], result)
  1162. end
  1163. def test_rescue_do_end_rescued
  1164. result = []
  1165. assert_nothing_raised(RuntimeError) do
  1166. eval("#{<<-"begin;"}\n#{<<-"end;"}")
  1167. begin;
  1168. tap do
  1169. result << :begin
  1170. raise "An exception occurred!"
  1171. rescue
  1172. result << :rescue
  1173. else
  1174. result << :else
  1175. ensure
  1176. result << :ensure
  1177. end
  1178. end;
  1179. end
  1180. assert_equal([:begin, :rescue, :ensure], result)
  1181. end
  1182. def test_rescue_do_end_no_raise
  1183. result = []
  1184. assert_nothing_raised(RuntimeError) do
  1185. eval("#{<<-"begin;"}\n#{<<-"end;"}")
  1186. begin;
  1187. tap do
  1188. result << :begin
  1189. rescue
  1190. result << :rescue
  1191. else
  1192. result << :else
  1193. ensure
  1194. result << :ensure
  1195. end
  1196. end;
  1197. end
  1198. assert_equal([:begin, :else, :ensure], result)
  1199. end
  1200. def test_rescue_do_end_ensure_result
  1201. result = eval("#{<<-"begin;"}\n#{<<-"end;"}")
  1202. begin;
  1203. proc do
  1204. :begin
  1205. ensure
  1206. :ensure
  1207. end.call
  1208. end;
  1209. assert_equal(:begin, result)
  1210. end
  1211. def test_rescue_do_end_ensure_in_lambda
  1212. result = []
  1213. eval("#{<<-"begin;"}\n#{<<-"end;"}")
  1214. begin;
  1215. -> do
  1216. result << :begin
  1217. raise "An exception occurred!"
  1218. rescue
  1219. result << :rescue
  1220. else
  1221. result << :else
  1222. ensure
  1223. result << :ensure
  1224. end.call
  1225. end;
  1226. assert_equal([:begin, :rescue, :ensure], result)
  1227. end
  1228. def test_return_in_loop
  1229. obj = Object.new
  1230. def obj.test
  1231. x = nil
  1232. return until x unless x
  1233. end
  1234. assert_nil obj.test
  1235. end
  1236. def test_method_call_location
  1237. line = __LINE__+5
  1238. e = assert_raise(NoMethodError) do
  1239. 1.upto(0) do
  1240. end
  1241. .
  1242. foo(
  1243. 1,
  1244. 2,
  1245. )
  1246. end
  1247. assert_equal(line, e.backtrace_locations[0].lineno)
  1248. line = __LINE__+5
  1249. e = assert_raise(NoMethodError) do
  1250. 1.upto 0 do
  1251. end
  1252. .
  1253. foo(
  1254. 1,
  1255. 2,
  1256. )
  1257. end
  1258. assert_equal(line, e.backtrace_locations[0].lineno)
  1259. end
  1260. def test_methoddef_endless
  1261. assert_syntax_error('private def foo = 42', /unexpected '='/)
  1262. assert_valid_syntax('private def foo() = 42')
  1263. assert_valid_syntax('private def inc(x) = x + 1')
  1264. assert_syntax_error('private def obj.foo = 42', /unexpected '='/)
  1265. assert_valid_syntax('private def obj.foo() = 42')
  1266. assert_valid_syntax('private def obj.inc(x) = x + 1')
  1267. eval('def self.inc(x) = x + 1 => @x')
  1268. assert_equal(:inc, @x)
  1269. end
  1270. def test_methoddef_in_cond
  1271. assert_valid_syntax('while def foo; tap do end; end; break; end')
  1272. assert_valid_syntax('while def foo a = tap do end; end; break; end')
  1273. end
  1274. def test_classdef_in_cond
  1275. assert_valid_syntax('while class Foo; tap do end; end; break; end')
  1276. assert_valid_syntax('while class Foo a = tap do end; end; break; end')
  1277. end
  1278. def test_command_with_cmd_brace_block
  1279. assert_valid_syntax('obj.foo (1) {}')
  1280. assert_valid_syntax('obj::foo (1) {}')
  1281. end
  1282. def test_numbered_parameter
  1283. assert_valid_syntax('proc {_1}')
  1284. assert_equal(3, eval('[1,2].then {_1+_2}'))
  1285. assert_equal("12", eval('[1,2].then {"#{_1}#{_2}"}'))
  1286. assert_equal([1, 2], eval('[1,2].then {_1}'))
  1287. assert_equal(3, eval('->{_1+_2}.call(1,2)'))
  1288. assert_equal(4, eval('->(a=->{_1}){a}.call.call(4)'))
  1289. assert_equal(5, eval('-> a: ->{_1} {a}.call.call(5)'))
  1290. assert_syntax_error('proc {|| _1}', /ordinary parameter is defined/)
  1291. assert_syntax_error('proc {|;a| _1}', /ordinary parameter is defined/)
  1292. assert_syntax_error("proc {|\n| _1}", /ordinary parameter is defined/)
  1293. assert_syntax_error('proc {|x| _1}', /ordinary parameter is defined/)
  1294. assert_syntax_error('proc {_1; proc {_2}}', /numbered parameter is already used/)
  1295. assert_syntax_error('proc {proc {_1}; _2}', /numbered parameter is already used/)
  1296. assert_syntax_error('->(){_1}', /ordinary parameter is defined/)
  1297. assert_syntax_error('->(x){_1}', /ordinary parameter is defined/)
  1298. assert_syntax_error('->x{_1}', /ordinary parameter is defined/)
  1299. assert_syntax_error('->x:_2{}', /ordinary parameter is defined/)
  1300. assert_syntax_error('->x=_1{}', /ordinary parameter is defined/)
  1301. assert_syntax_error('-> {_1; -> {_2}}', /numbered parameter is already used/)
  1302. assert_syntax_error('-> {-> {_1}; _2}', /numbered parameter is already used/)
  1303. assert_syntax_error('proc {_1; _1 = nil}', /Can't assign to numbered parameter _1/)
  1304. mesg = proc {|n| /`_#{n}' is reserved for numbered parameter/}
  1305. assert_warn(mesg[1]) {eval('proc {_1 = nil}')}
  1306. assert_warn(mesg[2]) {eval('_2=1')}
  1307. assert_warn(mesg[3]) {eval('proc {|_3|}')}
  1308. assert_warn(mesg[4]) {instance_eval('def x(_4) end')}
  1309. assert_warn(mesg[5]) {instance_eval('def _5; end')}
  1310. assert_warn(mesg[6]) {instance_eval('def self._6; end')}
  1311. assert_raise_with_message(NameError, /undefined local variable or method `_1'/) {
  1312. eval('_1')
  1313. }
  1314. ['class C', 'class << C', 'module M', 'def m', 'def o.m'].each do |c|
  1315. assert_valid_syntax("->{#{c};->{_1};end;_1}\n")
  1316. assert_valid_syntax("->{_1;#{c};->{_1};end}\n")
  1317. end
  1318. 1.times {
  1319. [
  1320. _1,
  1321. assert_equal([:a], eval("[:a].map{_1}")),
  1322. assert_raise(NameError) {eval("_1")},
  1323. ]
  1324. }
  1325. end
  1326. def test_value_expr_in_condition
  1327. mesg = /void value expression/
  1328. assert_syntax_error("tap {a = (true ? next : break)}", mesg)
  1329. assert_valid_syntax("tap {a = (true ? true : break)}")
  1330. assert_valid_syntax("tap {a = (break if false)}")
  1331. assert_valid_syntax("tap {a = (break unless true)}")
  1332. end
  1333. def test_argument_forwarding
  1334. assert_valid_syntax('def foo(...) bar(...) end')
  1335. assert_valid_syntax('def foo(...) end')
  1336. assert_syntax_error('iter do |...| end', /unexpected/)
  1337. assert_syntax_error('iter {|...|}', /unexpected/)
  1338. assert_syntax_error('->... {}', /unexpected/)
  1339. assert_syntax_error('->(...) {}', /unexpected/)
  1340. assert_syntax_error('def foo(x, y, z) bar(...); end', /unexpected/)
  1341. assert_syntax_error('def foo(x, y, z) super(...); end', /unexpected/)
  1342. assert_syntax_error('def foo(...) yield(...); end', /unexpected/)
  1343. assert_syntax_error('def foo(...) return(...); end', /unexpected/)
  1344. assert_syntax_error('def foo(...) a = (...); end', /unexpected/)
  1345. assert_syntax_error('def foo(...) [...]; end', /unexpected/)
  1346. assert_syntax_error('def foo(...) foo[...]; end', /unexpected/)
  1347. assert_syntax_error('def foo(...) foo[...] = x; end', /unexpected/)
  1348. assert_syntax_error('def foo(...) foo(...) { }; end', /both block arg and actual block given/)
  1349. assert_syntax_error('def foo(...) defined?(...); end', /unexpected/)
  1350. obj1 = Object.new
  1351. def obj1.bar(*args, **kws, &block)
  1352. if block
  1353. block.call(args, kws)
  1354. else
  1355. [args, kws]
  1356. end
  1357. end
  1358. obj1.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
  1359. klass = Class.new {
  1360. def foo(*args, **kws, &block)
  1361. if block
  1362. block.call(args, kws)
  1363. else
  1364. [args, kws]
  1365. end
  1366. end
  1367. }
  1368. obj2 = klass.new
  1369. obj2.instance_eval('def foo(...) super(...) end', __FILE__, __LINE__)
  1370. obj3 = Object.new
  1371. def obj3.bar(*args, &block)
  1372. if kws = Hash.try_convert(args.last)
  1373. args.pop
  1374. else
  1375. kws = {}
  1376. end
  1377. if block
  1378. block.call(args, kws)
  1379. else
  1380. [args, kws]
  1381. end
  1382. end
  1383. obj3.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
  1384. [obj1, obj2, obj3].each do |obj|
  1385. assert_warning('') {
  1386. assert_equal([[1, 2, 3], {k1: 4, k2: 5}], obj.foo(1, 2, 3, k1: 4, k2: 5) {|*x| x})
  1387. }
  1388. assert_warning('') {
  1389. assert_equal([[1, 2, 3], {k1: 4, k2: 5}], obj.foo(1, 2, 3, k1: 4, k2: 5))
  1390. }
  1391. array = obj == obj3 ? [] : [{}]
  1392. assert_warning('') {
  1393. assert_equal([array, {}], obj.foo({}) {|*x| x})
  1394. }
  1395. assert_warning('') {
  1396. assert_equal([array, {}], obj.foo({}))
  1397. }
  1398. assert_equal(-1, obj.method(:foo).arity)
  1399. parameters = obj.method(:foo).parameters
  1400. assert_equal(:rest, parameters.dig(0, 0))
  1401. assert_equal(:block, parameters.dig(1, 0))
  1402. end
  1403. end
  1404. def test_rightward_assign
  1405. assert_equal(1, eval("1 => a"))
  1406. assert_equal([2,3], eval("13.divmod(5) => a,b; [a, b]"))
  1407. assert_equal([2,3,2,3], eval("13.divmod(5) => a,b => c, d; [a, b, c, d]"))
  1408. assert_equal(3, eval("1+2 => a"))
  1409. end
  1410. private
  1411. def not_label(x) @result = x; @not_label ||= nil end
  1412. def assert_not_label(expected, src, message = nil)
  1413. @result = nil
  1414. assert_nothing_raised(SyntaxError, message) {eval(src)}
  1415. assert_equal(expected, @result, message)
  1416. end
  1417. def make_tmpsrc(f, src)
  1418. f.open
  1419. f.truncate(0)
  1420. f.puts(src)
  1421. f.close
  1422. end
  1423. def with_script_lines
  1424. script_lines = nil
  1425. debug_lines = {}
  1426. Object.class_eval do
  1427. if defined?(SCRIPT_LINES__)
  1428. script_lines = SCRIPT_LINES__
  1429. remove_const :SCRIPT_LINES__
  1430. end
  1431. const_set(:SCRIPT_LINES__, debug_lines)
  1432. end
  1433. yield debug_lines
  1434. ensure
  1435. Object.class_eval do
  1436. remove_const :SCRIPT_L

Large files files are truncated, but you can click here to view the full file