PageRenderTime 62ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/test/ruby/test_argf.rb

http://github.com/ruby/ruby
Ruby | 1084 lines | 996 code | 86 blank | 2 comment | 26 complexity | 2a43b4c3476b7b1f181aa32284bad7f4 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require 'test/unit'
  3. require 'timeout'
  4. require 'tmpdir'
  5. require 'tempfile'
  6. require 'fileutils'
  7. class TestArgf < Test::Unit::TestCase
  8. def setup
  9. @tmpdir = Dir.mktmpdir
  10. @tmp_count = 0
  11. @t1 = make_tempfile0("argf-foo")
  12. @t1.binmode
  13. @t1.puts "1"
  14. @t1.puts "2"
  15. @t1.close
  16. @t2 = make_tempfile0("argf-bar")
  17. @t2.binmode
  18. @t2.puts "3"
  19. @t2.puts "4"
  20. @t2.close
  21. @t3 = make_tempfile0("argf-baz")
  22. @t3.binmode
  23. @t3.puts "5"
  24. @t3.puts "6"
  25. @t3.close
  26. end
  27. def teardown
  28. FileUtils.rmtree(@tmpdir)
  29. end
  30. def make_tempfile0(basename)
  31. @tmp_count += 1
  32. open("#{@tmpdir}/#{basename}-#{@tmp_count}", "w")
  33. end
  34. def make_tempfile(basename = "argf-qux")
  35. t = make_tempfile0(basename)
  36. t.puts "foo"
  37. t.puts "bar"
  38. t.puts "baz"
  39. t.close
  40. t
  41. end
  42. def ruby(*args, external_encoding: Encoding::UTF_8)
  43. args = ['-e', '$>.write($<.read)'] if args.empty?
  44. ruby = EnvUtil.rubybin
  45. f = IO.popen([ruby] + args, 'r+', external_encoding: external_encoding)
  46. yield(f)
  47. ensure
  48. f.close unless !f || f.closed?
  49. end
  50. def no_safe_rename
  51. /cygwin|mswin|mingw|bccwin/ =~ RUBY_PLATFORM
  52. end
  53. def assert_src_expected(src, args = nil, line: caller_locations(1, 1)[0].lineno+1)
  54. args ||= [@t1.path, @t2.path, @t3.path]
  55. expected = src.split(/^/)
  56. ruby('-e', src, *args) do |f|
  57. expected.each_with_index do |e, i|
  58. /#=> *(.*)/ =~ e or next
  59. a = f.gets
  60. assert_not_nil(a, "[ruby-dev:34445]: remained")
  61. assert_equal($1, a.chomp, "[ruby-dev:34445]: line #{line+i}")
  62. end
  63. end
  64. end
  65. def test_argf
  66. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  67. {#
  68. a = ARGF
  69. b = a.dup
  70. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
  71. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
  72. a.rewind
  73. b.rewind
  74. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
  75. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
  76. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["3", 3, "3", 3]
  77. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["4", 4, "4", 4]
  78. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 5]
  79. a.rewind
  80. b.rewind
  81. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 5]
  82. p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["6", 6, "6", 6]
  83. };
  84. end
  85. def test_lineno
  86. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  87. {#
  88. a = ARGF
  89. a.gets; p($.) #=> 1
  90. a.gets; p($.) #=> 2
  91. a.gets; p($.) #=> 3
  92. a.rewind; p($.) #=> 3
  93. a.gets; p($.) #=> 3
  94. a.gets; p($.) #=> 4
  95. a.rewind; p($.) #=> 4
  96. a.gets; p($.) #=> 3
  97. a.lineno = 1000; p($.) #=> 1000
  98. a.gets; p($.) #=> 1001
  99. a.gets; p($.) #=> 1002
  100. $. = 2000
  101. a.gets; p($.) #=> 2001
  102. a.gets; p($.) #=> 2001
  103. };
  104. end
  105. def test_lineno2
  106. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  107. {#
  108. a = ARGF.dup
  109. a.gets; p($.) #=> 1
  110. a.gets; p($.) #=> 2
  111. a.gets; p($.) #=> 1
  112. a.rewind; p($.) #=> 1
  113. a.gets; p($.) #=> 1
  114. a.gets; p($.) #=> 2
  115. a.gets; p($.) #=> 1
  116. a.lineno = 1000; p($.) #=> 1
  117. a.gets; p($.) #=> 2
  118. a.gets; p($.) #=> 2
  119. $. = 2000
  120. a.gets; p($.) #=> 2000
  121. a.gets; p($.) #=> 2000
  122. };
  123. end
  124. def test_lineno3
  125. expected = %w"1 1 1 2 2 2 3 3 1 4 4 2"
  126. assert_in_out_err(["-", @t1.path, @t2.path],
  127. "#{<<~"{#"}\n#{<<~'};'}", expected, [], "[ruby-core:25205]")
  128. {#
  129. ARGF.each do |line|
  130. puts [$., ARGF.lineno, ARGF.file.lineno]
  131. end
  132. };
  133. end
  134. def test_new_lineno_each
  135. f = ARGF.class.new(@t1.path, @t2.path, @t3.path)
  136. result = []
  137. f.each {|line| result << [f.lineno, line]; break if result.size == 3}
  138. assert_equal(3, f.lineno)
  139. assert_equal((1..3).map {|i| [i, "#{i}\n"]}, result)
  140. f.rewind
  141. assert_equal(2, f.lineno)
  142. ensure
  143. f.close
  144. end
  145. def test_new_lineno_each_char
  146. f = ARGF.class.new(@t1.path, @t2.path, @t3.path)
  147. f.each_char.to_a
  148. assert_equal(0, f.lineno)
  149. ensure
  150. f.close
  151. end
  152. def test_inplace
  153. assert_in_out_err(["-", @t1.path, @t2.path, @t3.path],
  154. "#{<<~"{#"}\n#{<<~'};'}")
  155. {#
  156. ARGF.inplace_mode = '.bak'
  157. while line = ARGF.gets
  158. puts line.chomp + '.new'
  159. end
  160. };
  161. assert_equal("1.new\n2.new\n", File.read(@t1.path))
  162. assert_equal("3.new\n4.new\n", File.read(@t2.path))
  163. assert_equal("5.new\n6.new\n", File.read(@t3.path))
  164. assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
  165. assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
  166. assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
  167. end
  168. def test_inplace2
  169. assert_in_out_err(["-", @t1.path, @t2.path, @t3.path],
  170. "#{<<~"{#"}\n#{<<~'};'}")
  171. {#
  172. ARGF.inplace_mode = '.bak'
  173. puts ARGF.gets.chomp + '.new'
  174. puts ARGF.gets.chomp + '.new'
  175. p ARGF.inplace_mode
  176. ARGF.inplace_mode = nil
  177. puts ARGF.gets.chomp + '.new'
  178. puts ARGF.gets.chomp + '.new'
  179. p ARGF.inplace_mode
  180. ARGF.inplace_mode = '.bak'
  181. puts ARGF.gets.chomp + '.new'
  182. p ARGF.inplace_mode
  183. ARGF.inplace_mode = nil
  184. puts ARGF.gets.chomp + '.new'
  185. };
  186. assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
  187. assert_equal("3\n4\n", File.read(@t2.path))
  188. assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
  189. assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
  190. assert_equal(false, File.file?(@t2.path + ".bak"))
  191. assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
  192. end
  193. def test_inplace3
  194. assert_in_out_err(["-i.bak", "-", @t1.path, @t2.path, @t3.path],
  195. "#{<<~"{#"}\n#{<<~'};'}")
  196. {#
  197. puts ARGF.gets.chomp + '.new'
  198. puts ARGF.gets.chomp + '.new'
  199. p $-i
  200. $-i = nil
  201. puts ARGF.gets.chomp + '.new'
  202. puts ARGF.gets.chomp + '.new'
  203. p $-i
  204. $-i = '.bak'
  205. puts ARGF.gets.chomp + '.new'
  206. p $-i
  207. $-i = nil
  208. puts ARGF.gets.chomp + '.new'
  209. };
  210. assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
  211. assert_equal("3\n4\n", File.read(@t2.path))
  212. assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
  213. assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
  214. assert_equal(false, File.file?(@t2.path + ".bak"))
  215. assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
  216. end
  217. def test_inplace_rename_impossible
  218. t = make_tempfile
  219. assert_in_out_err(["-", t.path], "#{<<~"{#"}\n#{<<~'};'}") do |r, e|
  220. {#
  221. ARGF.inplace_mode = '/\\\\:'
  222. while line = ARGF.gets
  223. puts line.chomp + '.new'
  224. end
  225. };
  226. assert_match(/Can't rename .* to .*: .*. skipping file/, e.first) #'
  227. assert_equal([], r)
  228. assert_equal("foo\nbar\nbaz\n", File.read(t.path))
  229. end
  230. base = "argf-\u{30c6 30b9 30c8}"
  231. name = "#{@tmpdir}/#{base}"
  232. File.write(name, "foo")
  233. argf = ARGF.class.new(name)
  234. argf.inplace_mode = '/\\:'
  235. assert_warning(/#{base}/) {argf.gets}
  236. end
  237. def test_inplace_nonascii
  238. ext = Encoding.default_external or
  239. skip "no default external encoding"
  240. t = nil
  241. ["\u{3042}", "\u{e9}"].any? do |n|
  242. t = make_tempfile(n.encode(ext))
  243. rescue Encoding::UndefinedConversionError
  244. end
  245. t or skip "no name to test"
  246. assert_in_out_err(["-i.bak", "-", t.path],
  247. "#{<<~"{#"}\n#{<<~'};'}")
  248. {#
  249. puts ARGF.gets.chomp + '.new'
  250. puts ARGF.gets.chomp + '.new'
  251. puts ARGF.gets.chomp + '.new'
  252. };
  253. assert_equal("foo.new\n""bar.new\n""baz.new\n", File.read(t.path))
  254. assert_equal("foo\n""bar\n""baz\n", File.read(t.path + ".bak"))
  255. end
  256. def test_inplace_no_backup
  257. t = make_tempfile
  258. assert_in_out_err(["-", t.path], "#{<<~"{#"}\n#{<<~'};'}") do |r, e|
  259. {#
  260. ARGF.inplace_mode = ''
  261. while line = ARGF.gets
  262. puts line.chomp + '.new'
  263. end
  264. };
  265. if no_safe_rename
  266. assert_match(/Can't do inplace edit without backup/, e.join) #'
  267. else
  268. assert_equal([], e)
  269. assert_equal([], r)
  270. assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
  271. end
  272. end
  273. end
  274. def test_inplace_dup
  275. t = make_tempfile
  276. assert_in_out_err(["-", t.path], "#{<<~"{#"}\n#{<<~'};'}", [], [])
  277. {#
  278. ARGF.inplace_mode = '.bak'
  279. f = ARGF.dup
  280. while line = f.gets
  281. puts line.chomp + '.new'
  282. end
  283. };
  284. assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
  285. end
  286. def test_inplace_stdin
  287. assert_in_out_err(["-", "-"], "#{<<~"{#"}\n#{<<~'};'}", [], /Can't do inplace edit for stdio; skipping/)
  288. {#
  289. ARGF.inplace_mode = '.bak'
  290. f = ARGF.dup
  291. while line = f.gets
  292. puts line.chomp + '.new'
  293. end
  294. };
  295. end
  296. def test_inplace_stdin2
  297. assert_in_out_err(["-"], "#{<<~"{#"}\n#{<<~'};'}", [], /Can't do inplace edit for stdio/)
  298. {#
  299. ARGF.inplace_mode = '.bak'
  300. while line = ARGF.gets
  301. puts line.chomp + '.new'
  302. end
  303. };
  304. end
  305. def test_inplace_invalid_backup
  306. assert_raise(ArgumentError, '[ruby-dev:50272] [Bug #13960]') {
  307. ARGF.inplace_mode = "a\0"
  308. }
  309. end
  310. def test_inplace_to_path
  311. base = "argf-test"
  312. name = "#{@tmpdir}/#{base}"
  313. File.write(name, "foo")
  314. stdout = $stdout
  315. argf = ARGF.class.new(Struct.new(:to_path).new(name))
  316. begin
  317. result = argf.gets
  318. ensure
  319. $stdout = stdout
  320. argf.close
  321. end
  322. assert_equal("foo", result)
  323. end
  324. def test_inplace_ascii_incompatible_path
  325. base = "argf-\u{30c6 30b9 30c8}"
  326. name = "#{@tmpdir}/#{base}"
  327. File.write(name, "foo")
  328. stdout = $stdout
  329. argf = ARGF.class.new(name.encode(Encoding::UTF_16LE))
  330. assert_raise(Encoding::CompatibilityError) do
  331. argf.gets
  332. end
  333. ensure
  334. $stdout = stdout
  335. end
  336. def test_inplace_suffix_encoding
  337. base = "argf-\u{30c6 30b9 30c8}"
  338. name = "#{@tmpdir}/#{base}"
  339. suffix = "-bak"
  340. File.write(name, "foo")
  341. stdout = $stdout
  342. argf = ARGF.class.new(name)
  343. argf.inplace_mode = suffix.encode(Encoding::UTF_16LE)
  344. begin
  345. argf.each do |s|
  346. puts "+"+s
  347. end
  348. ensure
  349. $stdout.close unless $stdout == stdout
  350. $stdout = stdout
  351. end
  352. assert_file.exist?(name)
  353. assert_equal("+foo\n", File.read(name))
  354. assert_file.not_exist?(name+"-")
  355. assert_file.exist?(name+suffix)
  356. assert_equal("foo", File.read(name+suffix))
  357. end
  358. def test_encoding
  359. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  360. {#
  361. p ARGF.external_encoding.is_a?(Encoding)
  362. p ARGF.internal_encoding.is_a?(Encoding)
  363. ARGF.gets
  364. p ARGF.external_encoding.is_a?(Encoding)
  365. p ARGF.internal_encoding
  366. };
  367. assert_equal("true\ntrue\ntrue\nnil\n", f.read)
  368. end
  369. end
  370. def test_tell
  371. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  372. {#
  373. begin
  374. ARGF.binmode
  375. loop do
  376. p ARGF.tell
  377. p ARGF.gets
  378. end
  379. rescue ArgumentError
  380. puts "end"
  381. end
  382. };
  383. a = f.read.split("\n")
  384. [0, 2, 4, 2, 4, 2, 4].map {|i| i.to_s }.
  385. zip((1..6).map {|i| '"' + i.to_s + '\n"' } + ["nil"]).flatten.
  386. each do |x|
  387. assert_equal(x, a.shift)
  388. end
  389. assert_equal('end', a.shift)
  390. end
  391. end
  392. def test_seek
  393. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  394. {#
  395. ARGF.seek(4)
  396. p ARGF.gets #=> "3\n"
  397. ARGF.seek(0, IO::SEEK_END)
  398. p ARGF.gets #=> "5\n"
  399. ARGF.seek(4)
  400. p ARGF.gets #=> nil
  401. begin
  402. ARGF.seek(0)
  403. rescue
  404. puts "end" #=> end
  405. end
  406. };
  407. end
  408. def test_set_pos
  409. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  410. {#
  411. ARGF.pos = 4
  412. p ARGF.gets #=> "3\n"
  413. ARGF.pos = 4
  414. p ARGF.gets #=> "5\n"
  415. ARGF.pos = 4
  416. p ARGF.gets #=> nil
  417. begin
  418. ARGF.pos = 4
  419. rescue
  420. puts "end" #=> end
  421. end
  422. };
  423. end
  424. def test_rewind
  425. assert_src_expected("#{<<~"{#"}\n#{<<~'};'}")
  426. {#
  427. ARGF.pos = 4
  428. ARGF.rewind
  429. p ARGF.gets #=> "1\n"
  430. ARGF.pos = 4
  431. p ARGF.gets #=> "3\n"
  432. ARGF.pos = 4
  433. p ARGF.gets #=> "5\n"
  434. ARGF.pos = 4
  435. p ARGF.gets #=> nil
  436. begin
  437. ARGF.rewind
  438. rescue
  439. puts "end" #=> end
  440. end
  441. };
  442. end
  443. def test_fileno
  444. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  445. {#
  446. p ARGF.fileno
  447. ARGF.gets
  448. ARGF.gets
  449. p ARGF.fileno
  450. ARGF.gets
  451. ARGF.gets
  452. p ARGF.fileno
  453. ARGF.gets
  454. ARGF.gets
  455. p ARGF.fileno
  456. ARGF.gets
  457. begin
  458. ARGF.fileno
  459. rescue
  460. puts "end"
  461. end
  462. };
  463. a = f.read.split("\n")
  464. fd1, fd2, fd3, fd4, tag = a
  465. assert_match(/^\d+$/, fd1)
  466. assert_match(/^\d+$/, fd2)
  467. assert_match(/^\d+$/, fd3)
  468. assert_match(/^\d+$/, fd4)
  469. assert_equal('end', tag)
  470. end
  471. end
  472. def test_to_io
  473. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  474. {#
  475. 8.times do
  476. p ARGF.to_io
  477. ARGF.gets
  478. end
  479. };
  480. a = f.read.split("\n")
  481. f11, f12, f13, f21, f22, f31, f32, f4 = a
  482. assert_equal(f11, f12)
  483. assert_equal(f11, f13)
  484. assert_equal(f21, f22)
  485. assert_equal(f31, f32)
  486. assert_match(/\(closed\)/, f4)
  487. f4.sub!(/ \(closed\)/, "")
  488. assert_equal(f31, f4)
  489. end
  490. end
  491. def test_eof
  492. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  493. {#
  494. begin
  495. 8.times do
  496. p ARGF.eof?
  497. ARGF.gets
  498. end
  499. rescue IOError
  500. puts "end"
  501. end
  502. };
  503. a = f.read.split("\n")
  504. (%w(false) + (%w(false true) * 3) + %w(end)).each do |x|
  505. assert_equal(x, a.shift)
  506. end
  507. end
  508. t1 = open("#{@tmpdir}/argf-hoge", "w")
  509. t1.binmode
  510. t1.puts "foo"
  511. t1.close
  512. t2 = open("#{@tmpdir}/argf-moge", "w")
  513. t2.binmode
  514. t2.puts "bar"
  515. t2.close
  516. ruby('-e', 'STDERR.reopen(STDOUT); ARGF.gets; ARGF.skip; p ARGF.eof?', t1.path, t2.path) do |f|
  517. assert_equal(%w(false), f.read.split(/\n/))
  518. end
  519. end
  520. def test_read
  521. ruby('-e', "p ARGF.read(8)", @t1.path, @t2.path, @t3.path) do |f|
  522. assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
  523. end
  524. end
  525. def test_read2
  526. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  527. {#
  528. s = ""
  529. ARGF.read(8, s)
  530. p s
  531. };
  532. assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
  533. end
  534. end
  535. def test_read2_with_not_empty_buffer
  536. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  537. {#
  538. s = "0123456789"
  539. ARGF.read(8, s)
  540. p s
  541. };
  542. assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
  543. end
  544. end
  545. def test_read3
  546. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  547. {#
  548. nil while ARGF.gets
  549. p ARGF.read
  550. p ARGF.read(0, "")
  551. };
  552. assert_equal("nil\n\"\"\n", f.read)
  553. end
  554. end
  555. def test_readpartial
  556. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  557. {#
  558. s = ""
  559. begin
  560. loop do
  561. s << ARGF.readpartial(1)
  562. t = ""; ARGF.readpartial(1, t); s << t
  563. # not empty buffer
  564. u = "abcdef"; ARGF.readpartial(1, u); s << u
  565. end
  566. rescue EOFError
  567. puts s
  568. end
  569. };
  570. assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
  571. end
  572. end
  573. def test_readpartial2
  574. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}") do |f|
  575. {#
  576. s = ""
  577. begin
  578. loop do
  579. s << ARGF.readpartial(1)
  580. t = ""; ARGF.readpartial(1, t); s << t
  581. end
  582. rescue EOFError
  583. $stdout.binmode
  584. puts s
  585. end
  586. };
  587. f.binmode
  588. f.puts("foo")
  589. f.puts("bar")
  590. f.puts("baz")
  591. f.close_write
  592. assert_equal("foo\nbar\nbaz\n", f.read)
  593. end
  594. end
  595. def test_readpartial_eof_twice
  596. ruby('-W1', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path) do |f|
  597. {#
  598. $stderr = $stdout
  599. print ARGF.readpartial(256)
  600. ARGF.readpartial(256) rescue p($!.class)
  601. ARGF.readpartial(256) rescue p($!.class)
  602. };
  603. assert_equal("1\n2\nEOFError\nEOFError\n", f.read)
  604. end
  605. end
  606. def test_getc
  607. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  608. {#
  609. s = ""
  610. while c = ARGF.getc
  611. s << c
  612. end
  613. puts s
  614. };
  615. assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
  616. end
  617. end
  618. def test_getbyte
  619. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  620. {#
  621. s = []
  622. while c = ARGF.getbyte
  623. s << c
  624. end
  625. p s
  626. };
  627. assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
  628. end
  629. end
  630. def test_readchar
  631. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  632. {#
  633. s = ""
  634. begin
  635. while c = ARGF.readchar
  636. s << c
  637. end
  638. rescue EOFError
  639. puts s
  640. end
  641. };
  642. assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
  643. end
  644. end
  645. def test_readbyte
  646. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  647. {#
  648. begin
  649. s = []
  650. while c = ARGF.readbyte
  651. s << c
  652. end
  653. rescue EOFError
  654. p s
  655. end
  656. };
  657. assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
  658. end
  659. end
  660. def test_each_line
  661. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  662. {#
  663. s = []
  664. ARGF.each_line {|l| s << l }
  665. p s
  666. };
  667. assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
  668. end
  669. end
  670. def test_each_line_paragraph
  671. assert_in_out_err(['-e', 'ARGF.each_line("") {|para| p para}'], "a\n\nb\n",
  672. ["\"a\\n\\n\"", "\"b\\n\""], [])
  673. end
  674. def test_each_line_chomp
  675. assert_in_out_err(['-e', 'ARGF.each_line(chomp: false) {|para| p para}'], "a\nb\n",
  676. ["\"a\\n\"", "\"b\\n\""], [])
  677. assert_in_out_err(['-e', 'ARGF.each_line(chomp: true) {|para| p para}'], "a\nb\n",
  678. ["\"a\"", "\"b\""], [])
  679. end
  680. def test_each_byte
  681. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  682. {#
  683. s = []
  684. ARGF.each_byte {|c| s << c }
  685. p s
  686. };
  687. assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
  688. end
  689. end
  690. def test_each_char
  691. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  692. {#
  693. s = ""
  694. ARGF.each_char {|c| s << c }
  695. puts s
  696. };
  697. assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
  698. end
  699. end
  700. def test_filename
  701. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  702. {#
  703. begin
  704. puts ARGF.filename.dump
  705. end while ARGF.gets
  706. puts ARGF.filename.dump
  707. };
  708. a = f.read.split("\n")
  709. assert_equal(@t1.path.dump, a.shift)
  710. assert_equal(@t1.path.dump, a.shift)
  711. assert_equal(@t1.path.dump, a.shift)
  712. assert_equal(@t2.path.dump, a.shift)
  713. assert_equal(@t2.path.dump, a.shift)
  714. assert_equal(@t3.path.dump, a.shift)
  715. assert_equal(@t3.path.dump, a.shift)
  716. assert_equal(@t3.path.dump, a.shift)
  717. end
  718. end
  719. def test_filename2
  720. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  721. {#
  722. begin
  723. puts $FILENAME.dump
  724. end while ARGF.gets
  725. puts $FILENAME.dump
  726. };
  727. a = f.read.split("\n")
  728. assert_equal(@t1.path.dump, a.shift)
  729. assert_equal(@t1.path.dump, a.shift)
  730. assert_equal(@t1.path.dump, a.shift)
  731. assert_equal(@t2.path.dump, a.shift)
  732. assert_equal(@t2.path.dump, a.shift)
  733. assert_equal(@t3.path.dump, a.shift)
  734. assert_equal(@t3.path.dump, a.shift)
  735. assert_equal(@t3.path.dump, a.shift)
  736. end
  737. end
  738. def test_file
  739. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  740. {#
  741. begin
  742. puts ARGF.file.path.dump
  743. end while ARGF.gets
  744. puts ARGF.file.path.dump
  745. };
  746. a = f.read.split("\n")
  747. assert_equal(@t1.path.dump, a.shift)
  748. assert_equal(@t1.path.dump, a.shift)
  749. assert_equal(@t1.path.dump, a.shift)
  750. assert_equal(@t2.path.dump, a.shift)
  751. assert_equal(@t2.path.dump, a.shift)
  752. assert_equal(@t3.path.dump, a.shift)
  753. assert_equal(@t3.path.dump, a.shift)
  754. assert_equal(@t3.path.dump, a.shift)
  755. end
  756. end
  757. def test_binmode
  758. bug5268 = '[ruby-core:39234]'
  759. open(@t3.path, "wb") {|f| f.write "5\r\n6\r\n"}
  760. ruby('-e', "ARGF.binmode; STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
  761. f.binmode
  762. assert_equal("1\n2\n3\n4\n5\r\n6\r\n", f.read, bug5268)
  763. end
  764. end
  765. def test_textmode
  766. bug5268 = '[ruby-core:39234]'
  767. open(@t3.path, "wb") {|f| f.write "5\r\n6\r\n"}
  768. ruby('-e', "STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
  769. f.binmode
  770. assert_equal("1\n2\n3\n4\n5\n6\n", f.read, bug5268)
  771. end
  772. end unless IO::BINARY.zero?
  773. def test_skip
  774. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  775. {#
  776. ARGF.skip
  777. puts ARGF.gets
  778. ARGF.skip
  779. puts ARGF.read
  780. };
  781. assert_equal("1\n3\n4\n5\n6\n", f.read)
  782. end
  783. end
  784. def test_skip_in_each_line
  785. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  786. {#
  787. ARGF.each_line {|l| print l; ARGF.skip}
  788. };
  789. assert_equal("1\n3\n5\n", f.read, '[ruby-list:49185]')
  790. end
  791. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  792. {#
  793. ARGF.each_line {|l| ARGF.skip; puts [l, ARGF.gets].map {|s| s ? s.chomp : s.inspect}.join("+")}
  794. };
  795. assert_equal("1+3\n4+5\n6+nil\n", f.read, '[ruby-list:49185]')
  796. end
  797. end
  798. def test_skip_in_each_byte
  799. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  800. {#
  801. ARGF.each_byte {|l| print l; ARGF.skip}
  802. };
  803. assert_equal("135".unpack("C*").join(""), f.read, '[ruby-list:49185]')
  804. end
  805. end
  806. def test_skip_in_each_char
  807. [[@t1, "\u{3042}"], [@t2, "\u{3044}"], [@t3, "\u{3046}"]].each do |f, s|
  808. File.write(f.path, s, mode: "w:utf-8")
  809. end
  810. ruby('-Eutf-8', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  811. {#
  812. ARGF.each_char {|l| print l; ARGF.skip}
  813. };
  814. assert_equal("\u{3042 3044 3046}", f.read, '[ruby-list:49185]')
  815. end
  816. end
  817. def test_skip_in_each_codepoint
  818. [[@t1, "\u{3042}"], [@t2, "\u{3044}"], [@t3, "\u{3046}"]].each do |f, s|
  819. File.write(f.path, s, mode: "w:utf-8")
  820. end
  821. ruby('-Eutf-8', '-Eutf-8', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  822. {#
  823. ARGF.each_codepoint {|l| printf "%x:", l; ARGF.skip}
  824. };
  825. assert_equal("3042:3044:3046:", f.read, '[ruby-list:49185]')
  826. end
  827. end
  828. def test_close
  829. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  830. {#
  831. ARGF.close
  832. puts ARGF.read
  833. };
  834. assert_equal("3\n4\n5\n6\n", f.read)
  835. end
  836. end
  837. def test_close_replace
  838. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}") do |f|
  839. paths = ['#{@t1.path}', '#{@t2.path}', '#{@t3.path}']
  840. {#
  841. ARGF.close
  842. ARGV.replace paths
  843. puts ARGF.read
  844. };
  845. assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
  846. end
  847. end
  848. def test_closed
  849. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  850. {#
  851. 3.times do
  852. p ARGF.closed?
  853. ARGF.gets
  854. ARGF.gets
  855. end
  856. p ARGF.closed?
  857. ARGF.gets
  858. p ARGF.closed?
  859. };
  860. assert_equal("false\nfalse\nfalse\nfalse\ntrue\n", f.read)
  861. end
  862. end
  863. def test_argv
  864. ruby('-e', "p ARGF.argv; p $*", @t1.path, @t2.path, @t3.path) do |f|
  865. assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
  866. assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
  867. end
  868. end
  869. def test_readlines_limit_0
  870. bug4024 = '[ruby-dev:42538]'
  871. t = make_tempfile
  872. argf = ARGF.class.new(t.path)
  873. begin
  874. assert_raise(ArgumentError, bug4024) do
  875. argf.readlines(0)
  876. end
  877. ensure
  878. argf.close
  879. end
  880. end
  881. def test_each_line_limit_0
  882. bug4024 = '[ruby-dev:42538]'
  883. t = make_tempfile
  884. argf = ARGF.class.new(t.path)
  885. begin
  886. assert_raise(ArgumentError, bug4024) do
  887. argf.each_line(0).next
  888. end
  889. ensure
  890. argf.close
  891. end
  892. end
  893. def test_unreadable
  894. bug4274 = '[ruby-core:34446]'
  895. paths = (1..2).map do
  896. t = Tempfile.new("bug4274-")
  897. path = t.path
  898. t.close!
  899. path
  900. end
  901. argf = ARGF.class.new(*paths)
  902. paths.each do |path|
  903. assert_raise_with_message(Errno::ENOENT, /- #{Regexp.quote(path)}\z/) {argf.gets}
  904. end
  905. assert_nil(argf.gets, bug4274)
  906. end
  907. def test_readlines_twice
  908. bug5952 = '[ruby-dev:45160]'
  909. assert_ruby_status(["-e", "2.times {STDIN.tty?; readlines}"], "", bug5952)
  910. end
  911. def test_lines
  912. ruby('-W1', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  913. {#
  914. $stderr = $stdout
  915. s = []
  916. ARGF.lines {|l| s << l }
  917. p s
  918. };
  919. assert_match(/deprecated/, f.gets)
  920. assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
  921. end
  922. end
  923. def test_bytes
  924. ruby('-W1', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  925. {#
  926. $stderr = $stdout
  927. print Marshal.dump(ARGF.bytes.to_a)
  928. };
  929. assert_match(/deprecated/, f.gets)
  930. assert_equal([49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10], Marshal.load(f.read))
  931. end
  932. end
  933. def test_chars
  934. ruby('-W1', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  935. {#
  936. $stderr = $stdout
  937. print [Marshal.dump(ARGF.chars.to_a)].pack('m')
  938. };
  939. assert_match(/deprecated/, f.gets)
  940. assert_equal(["1", "\n", "2", "\n", "3", "\n", "4", "\n", "5", "\n", "6", "\n"], Marshal.load(f.read.unpack('m').first))
  941. end
  942. end
  943. def test_codepoints
  944. ruby('-W1', '-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
  945. {#
  946. $stderr = $stdout
  947. print Marshal.dump(ARGF.codepoints.to_a)
  948. };
  949. assert_match(/deprecated/, f.gets)
  950. assert_equal([49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10], Marshal.load(f.read))
  951. end
  952. end
  953. def test_read_nonblock
  954. ruby('-e', "#{<<~"{#"}\n#{<<~'};'}") do |f|
  955. {#
  956. $stdout.sync = true
  957. :wait_readable == ARGF.read_nonblock(1, "", exception: false) or
  958. abort "did not return :wait_readable"
  959. begin
  960. ARGF.read_nonblock(1)
  961. abort 'fail to raise IO::WaitReadable'
  962. rescue IO::WaitReadable
  963. end
  964. puts 'starting select'
  965. IO.select([ARGF]) == [[ARGF], [], []] or
  966. abort 'did not awaken for readability (before byte)'
  967. buf = ''
  968. buf.object_id == ARGF.read_nonblock(1, buf).object_id or
  969. abort "read destination buffer failed"
  970. print buf
  971. IO.select([ARGF]) == [[ARGF], [], []] or
  972. abort 'did not awaken for readability (before EOF)'
  973. ARGF.read_nonblock(1, buf, exception: false) == nil or
  974. abort "EOF should return nil if exception: false"
  975. begin
  976. ARGF.read_nonblock(1, buf)
  977. abort 'fail to raise IO::WaitReadable'
  978. rescue EOFError
  979. puts 'done with eof'
  980. end
  981. };
  982. f.sync = true
  983. assert_equal "starting select\n", f.gets
  984. f.write('.') # wake up from IO.select
  985. assert_equal '.', f.read(1)
  986. f.close_write
  987. assert_equal "done with eof\n", f.gets
  988. end
  989. end
  990. def test_wrong_type
  991. assert_separately([], "#{<<~"{#"}\n#{<<~'};'}")
  992. {#
  993. bug11610 = '[ruby-core:71140] [Bug #11610]'
  994. ARGV[0] = nil
  995. assert_raise(TypeError, bug11610) {gets}
  996. };
  997. end
  998. end