summaryrefslogtreecommitdiff
path: root/spec/ruby/core/argf
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/argf')
-rw-r--r--spec/ruby/core/argf/argf_spec.rb11
-rw-r--r--spec/ruby/core/argf/argv_spec.rb19
-rw-r--r--spec/ruby/core/argf/binmode_spec.rb43
-rw-r--r--spec/ruby/core/argf/close_spec.rb35
-rw-r--r--spec/ruby/core/argf/closed_spec.rb18
-rw-r--r--spec/ruby/core/argf/each_byte_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_char_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_codepoint_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_line_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_spec.rb6
-rw-r--r--spec/ruby/core/argf/eof_spec.rb10
-rw-r--r--spec/ruby/core/argf/file_spec.rb21
-rw-r--r--spec/ruby/core/argf/filename_spec.rb6
-rw-r--r--spec/ruby/core/argf/fileno_spec.rb6
-rw-r--r--spec/ruby/core/argf/fixtures/bin_file.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/file1.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/file2.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/filename.rb3
-rw-r--r--spec/ruby/core/argf/fixtures/lineno.rb5
-rw-r--r--spec/ruby/core/argf/fixtures/rewind.rb5
-rw-r--r--spec/ruby/core/argf/fixtures/stdin.txt2
-rw-r--r--spec/ruby/core/argf/getc_spec.rb20
-rw-r--r--spec/ruby/core/argf/gets_spec.rb49
-rw-r--r--spec/ruby/core/argf/lineno_spec.rb30
-rw-r--r--spec/ruby/core/argf/path_spec.rb6
-rw-r--r--spec/ruby/core/argf/pos_spec.rb38
-rw-r--r--spec/ruby/core/argf/read_nonblock_spec.rb80
-rw-r--r--spec/ruby/core/argf/read_spec.rb85
-rw-r--r--spec/ruby/core/argf/readchar_spec.rb19
-rw-r--r--spec/ruby/core/argf/readline_spec.rb23
-rw-r--r--spec/ruby/core/argf/readlines_spec.rb6
-rw-r--r--spec/ruby/core/argf/readpartial_spec.rb75
-rw-r--r--spec/ruby/core/argf/rewind_spec.rb39
-rw-r--r--spec/ruby/core/argf/seek_spec.rb63
-rw-r--r--spec/ruby/core/argf/set_encoding_spec.rb41
-rw-r--r--spec/ruby/core/argf/shared/each_byte.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_char.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_codepoint.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_line.rb62
-rw-r--r--spec/ruby/core/argf/shared/eof.rb24
-rw-r--r--spec/ruby/core/argf/shared/filename.rb28
-rw-r--r--spec/ruby/core/argf/shared/fileno.rb24
-rw-r--r--spec/ruby/core/argf/shared/getc.rb17
-rw-r--r--spec/ruby/core/argf/shared/gets.rb99
-rw-r--r--spec/ruby/core/argf/shared/pos.rb31
-rw-r--r--spec/ruby/core/argf/shared/read.rb58
-rw-r--r--spec/ruby/core/argf/shared/readlines.rb22
-rw-r--r--spec/ruby/core/argf/skip_spec.rb42
-rw-r--r--spec/ruby/core/argf/tell_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_a_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_i_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_io_spec.rb23
-rw-r--r--spec/ruby/core/argf/to_s_spec.rb14
53 files changed, 1430 insertions, 0 deletions
diff --git a/spec/ruby/core/argf/argf_spec.rb b/spec/ruby/core/argf/argf_spec.rb
new file mode 100644
index 0000000000..f9468539bb
--- /dev/null
+++ b/spec/ruby/core/argf/argf_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../spec_helper'
+
+describe "ARGF" do
+ it "is extended by the Enumerable module" do
+ ARGF.should.is_a?(Enumerable)
+ end
+
+ it "is an instance of ARGF.class" do
+ ARGF.should.instance_of?(ARGF.class)
+ end
+end
diff --git a/spec/ruby/core/argf/argv_spec.rb b/spec/ruby/core/argf/argv_spec.rb
new file mode 100644
index 0000000000..77dfe78c21
--- /dev/null
+++ b/spec/ruby/core/argf/argv_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.argv" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "returns ARGV for the initial ARGF" do
+ ARGF.argv.should.equal? ARGV
+ end
+
+ it "returns the remaining arguments to treat" do
+ argf [@file1, @file2] do
+ # @file1 is stored in current file
+ @argf.argv.should == [@file2]
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/binmode_spec.rb b/spec/ruby/core/argf/binmode_spec.rb
new file mode 100644
index 0000000000..5288e3199d
--- /dev/null
+++ b/spec/ruby/core/argf/binmode_spec.rb
@@ -0,0 +1,43 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.binmode" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ @bin_file = fixture __FILE__, "bin_file.txt"
+ end
+
+ it "returns self" do
+ argf [@bin_file] do
+ @argf.binmode.should.equal? @argf
+ end
+ end
+
+ platform_is :windows do
+ it "puts reading into binmode" do
+ argf [@bin_file, @bin_file] do
+ @argf.gets.should == "test\n"
+ @argf.binmode
+ @argf.gets.should == "test\r\n"
+ end
+ end
+
+ it "puts all subsequent streams reading through ARGF into binmode" do
+ argf [@bin_file, @bin_file] do
+ @argf.binmode
+ @argf.gets.should == "test\r\n"
+ @argf.gets.should == "test\r\n"
+ end
+ end
+ end
+
+ it "sets the file's encoding to BINARY" do
+ argf [@bin_file, @file1] do
+ @argf.binmode
+ @argf.should.binmode?
+ @argf.gets.encoding.should == Encoding::BINARY
+ @argf.skip
+ @argf.read.encoding.should == Encoding::BINARY
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/close_spec.rb b/spec/ruby/core/argf/close_spec.rb
new file mode 100644
index 0000000000..8ca7d71dc2
--- /dev/null
+++ b/spec/ruby/core/argf/close_spec.rb
@@ -0,0 +1,35 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.close" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+ end
+
+ it "closes the current open stream" do
+ argf [@file1_name, @file2_name] do
+ io = @argf.to_io
+ @argf.close
+ io.closed?.should == true
+ end
+ end
+
+ it "returns self" do
+ argf [@file1_name, @file2_name] do
+ @argf.close.should.equal?(@argf)
+ end
+ end
+
+ it "doesn't raise an IOError if called on a closed stream" do
+ argf [@file1_name] do
+ -> { @argf.close }.should_not.raise
+ -> { @argf.close }.should_not.raise
+ end
+ end
+end
+
+describe "ARGF.close" do
+ it "does not close STDIN" do
+ ruby_exe("ARGV.replace(['-']); ARGF.close; print ARGF.closed?").should == "false"
+ end
+end
diff --git a/spec/ruby/core/argf/closed_spec.rb b/spec/ruby/core/argf/closed_spec.rb
new file mode 100644
index 0000000000..769381e8c3
--- /dev/null
+++ b/spec/ruby/core/argf/closed_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.closed?" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+ end
+
+ it "returns true if the current stream has been closed" do
+ argf [@file1_name, @file2_name] do
+ stream = @argf.to_io
+ stream.close
+
+ @argf.closed?.should == true
+ stream.reopen(@argf.filename, 'r')
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/each_byte_spec.rb b/spec/ruby/core/argf/each_byte_spec.rb
new file mode 100644
index 0000000000..c5cce9f250
--- /dev/null
+++ b/spec/ruby/core/argf/each_byte_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_byte'
+
+describe "ARGF.each_byte" do
+ it_behaves_like :argf_each_byte, :each_byte
+end
diff --git a/spec/ruby/core/argf/each_char_spec.rb b/spec/ruby/core/argf/each_char_spec.rb
new file mode 100644
index 0000000000..724e5e6e3e
--- /dev/null
+++ b/spec/ruby/core/argf/each_char_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_char'
+
+describe "ARGF.each_char" do
+ it_behaves_like :argf_each_char, :each_char
+end
diff --git a/spec/ruby/core/argf/each_codepoint_spec.rb b/spec/ruby/core/argf/each_codepoint_spec.rb
new file mode 100644
index 0000000000..0bf8bf9764
--- /dev/null
+++ b/spec/ruby/core/argf/each_codepoint_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_codepoint'
+
+describe "ARGF.each_codepoint" do
+ it_behaves_like :argf_each_codepoint, :each_codepoint
+end
diff --git a/spec/ruby/core/argf/each_line_spec.rb b/spec/ruby/core/argf/each_line_spec.rb
new file mode 100644
index 0000000000..52a7e5c411
--- /dev/null
+++ b/spec/ruby/core/argf/each_line_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
+
+describe "ARGF.each_line" do
+ it_behaves_like :argf_each_line, :each_line
+end
diff --git a/spec/ruby/core/argf/each_spec.rb b/spec/ruby/core/argf/each_spec.rb
new file mode 100644
index 0000000000..5742ba43bd
--- /dev/null
+++ b/spec/ruby/core/argf/each_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
+
+describe "ARGF.each" do
+ it_behaves_like :argf_each_line, :each
+end
diff --git a/spec/ruby/core/argf/eof_spec.rb b/spec/ruby/core/argf/eof_spec.rb
new file mode 100644
index 0000000000..518f6e566e
--- /dev/null
+++ b/spec/ruby/core/argf/eof_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../spec_helper'
+require_relative 'shared/eof'
+
+describe "ARGF.eof" do
+ it_behaves_like :argf_eof, :eof
+end
+
+describe "ARGF.eof?" do
+ it_behaves_like :argf_eof, :eof?
+end
diff --git a/spec/ruby/core/argf/file_spec.rb b/spec/ruby/core/argf/file_spec.rb
new file mode 100644
index 0000000000..df8552d457
--- /dev/null
+++ b/spec/ruby/core/argf/file_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.file" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "returns the current file object on each file" do
+ argf [@file1, @file2] do
+ result = []
+ # returns first current file even when not yet open
+ result << @argf.file.path
+ result << @argf.file.path while @argf.gets
+ # returns last current file even when closed
+ result << @argf.file.path
+ result.should == [@file1, @file1, @file1, @file2, @file2, @file2]
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/filename_spec.rb b/spec/ruby/core/argf/filename_spec.rb
new file mode 100644
index 0000000000..7c0446269d
--- /dev/null
+++ b/spec/ruby/core/argf/filename_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/filename'
+
+describe "ARGF.filename" do
+ it_behaves_like :argf_filename, :filename
+end
diff --git a/spec/ruby/core/argf/fileno_spec.rb b/spec/ruby/core/argf/fileno_spec.rb
new file mode 100644
index 0000000000..29d50c3582
--- /dev/null
+++ b/spec/ruby/core/argf/fileno_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/fileno'
+
+describe "ARGF.fileno" do
+ it_behaves_like :argf_fileno, :fileno
+end
diff --git a/spec/ruby/core/argf/fixtures/bin_file.txt b/spec/ruby/core/argf/fixtures/bin_file.txt
new file mode 100644
index 0000000000..2545e9037e
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/bin_file.txt
@@ -0,0 +1,2 @@
+test
+test
diff --git a/spec/ruby/core/argf/fixtures/file1.txt b/spec/ruby/core/argf/fixtures/file1.txt
new file mode 100644
index 0000000000..1c89bfbd82
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/file1.txt
@@ -0,0 +1,2 @@
+file1.1
+file1.2
diff --git a/spec/ruby/core/argf/fixtures/file2.txt b/spec/ruby/core/argf/fixtures/file2.txt
new file mode 100644
index 0000000000..62e8dba00b
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/file2.txt
@@ -0,0 +1,2 @@
+line2.1
+line2.2
diff --git a/spec/ruby/core/argf/fixtures/filename.rb b/spec/ruby/core/argf/fixtures/filename.rb
new file mode 100644
index 0000000000..599c97dd57
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/filename.rb
@@ -0,0 +1,3 @@
+puts $FILENAME while ARGF.gets
+# returns last current file even when closed
+puts $FILENAME
diff --git a/spec/ruby/core/argf/fixtures/lineno.rb b/spec/ruby/core/argf/fixtures/lineno.rb
new file mode 100644
index 0000000000..079cc92e8e
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/lineno.rb
@@ -0,0 +1,5 @@
+puts $.
+ARGF.gets
+puts $.
+ARGF.gets
+puts $.
diff --git a/spec/ruby/core/argf/fixtures/rewind.rb b/spec/ruby/core/argf/fixtures/rewind.rb
new file mode 100644
index 0000000000..90a334cd89
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/rewind.rb
@@ -0,0 +1,5 @@
+puts ARGF.lineno
+ARGF.gets
+puts ARGF.lineno
+ARGF.rewind
+puts ARGF.lineno
diff --git a/spec/ruby/core/argf/fixtures/stdin.txt b/spec/ruby/core/argf/fixtures/stdin.txt
new file mode 100644
index 0000000000..063cdcb1d4
--- /dev/null
+++ b/spec/ruby/core/argf/fixtures/stdin.txt
@@ -0,0 +1,2 @@
+stdin.1
+stdin.2
diff --git a/spec/ruby/core/argf/getc_spec.rb b/spec/ruby/core/argf/getc_spec.rb
new file mode 100644
index 0000000000..dc5de9b7df
--- /dev/null
+++ b/spec/ruby/core/argf/getc_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../spec_helper'
+require_relative 'shared/getc'
+
+describe "ARGF.getc" do
+ it_behaves_like :argf_getc, :getc
+end
+
+describe "ARGF.getc" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "returns nil when end of stream reached" do
+ argf [@file1, @file2] do
+ @argf.read
+ @argf.getc.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/gets_spec.rb b/spec/ruby/core/argf/gets_spec.rb
new file mode 100644
index 0000000000..cc7673b190
--- /dev/null
+++ b/spec/ruby/core/argf/gets_spec.rb
@@ -0,0 +1,49 @@
+require_relative '../../spec_helper'
+require_relative 'shared/gets'
+
+describe "ARGF.gets" do
+ it_behaves_like :argf_gets, :gets
+end
+
+describe "ARGF.gets" do
+ it_behaves_like :argf_gets_inplace_edit, :gets
+end
+
+describe "ARGF.gets" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @file1 = File.readlines @file1_name
+ @file2 = File.readlines @file2_name
+ end
+
+ it "returns nil when reaching end of files" do
+ argf [@file1_name, @file2_name] do
+ total = @file1.size + @file2.size
+ total.times { @argf.gets }
+ @argf.gets.should == nil
+ end
+ end
+
+ before :each do
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
+
+ Encoding.default_external = Encoding::UTF_8
+ Encoding.default_internal = nil
+ end
+
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ end
+
+ it "reads the contents of the file with default encoding" do
+ Encoding.default_external = Encoding::US_ASCII
+ argf [@file1_name, @file2_name] do
+ @argf.gets.encoding.should == Encoding::US_ASCII
+ end
+ end
+
+end
diff --git a/spec/ruby/core/argf/lineno_spec.rb b/spec/ruby/core/argf/lineno_spec.rb
new file mode 100644
index 0000000000..72a108c187
--- /dev/null
+++ b/spec/ruby/core/argf/lineno_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.lineno" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ # TODO: break this into four specs
+ it "returns the current line number on each file" do
+ argf [@file1, @file2] do
+ @argf.lineno = 0
+ @argf.gets
+ @argf.lineno.should == 1
+ @argf.gets
+ @argf.lineno.should == 2
+ @argf.gets
+ @argf.lineno.should == 3
+ @argf.gets
+ @argf.lineno.should == 4
+ end
+ end
+
+ it "aliases to $." do
+ script = fixture __FILE__, "lineno.rb"
+ out = ruby_exe(script, args: [@file1, @file2])
+ out.should == "0\n1\n2\n"
+ end
+end
diff --git a/spec/ruby/core/argf/path_spec.rb b/spec/ruby/core/argf/path_spec.rb
new file mode 100644
index 0000000000..7120f7d0e3
--- /dev/null
+++ b/spec/ruby/core/argf/path_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/filename'
+
+describe "ARGF.path" do
+ it_behaves_like :argf_filename, :path
+end
diff --git a/spec/ruby/core/argf/pos_spec.rb b/spec/ruby/core/argf/pos_spec.rb
new file mode 100644
index 0000000000..fb3f25b945
--- /dev/null
+++ b/spec/ruby/core/argf/pos_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../spec_helper'
+require_relative 'shared/pos'
+
+describe "ARGF.pos" do
+ it_behaves_like :argf_pos, :pos
+end
+
+describe "ARGF.pos=" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @file1 = File.readlines @file1_name
+ @file2 = File.readlines @file2_name
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "sets the correct position in files" do
+ argf [@file1_name, @file2_name] do
+ @argf.pos = @file1.first.size
+ @argf.gets.should == @file1.last
+ @argf.pos = 0
+ @argf.gets.should == @file1.first
+
+ # finish reading file1
+ @argf.gets
+
+ @argf.gets
+ @argf.pos = 1
+ @argf.gets.should == @file2.first[1..-1]
+
+ @argf.pos = @file2.first.size + @file2.last.size - 1
+ @argf.gets.should == @file2.last[-1,1]
+ @argf.pos = 1000
+ @argf.read.should == ""
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/read_nonblock_spec.rb b/spec/ruby/core/argf/read_nonblock_spec.rb
new file mode 100644
index 0000000000..5c6bd52d80
--- /dev/null
+++ b/spec/ruby/core/argf/read_nonblock_spec.rb
@@ -0,0 +1,80 @@
+require_relative '../../spec_helper'
+require_relative 'shared/read'
+
+platform_is_not :windows do
+ describe 'ARGF.read_nonblock' do
+ it_behaves_like :argf_read, :read_nonblock
+
+ before do
+ @file1_name = fixture(__FILE__, 'file1.txt')
+ @file2_name = fixture(__FILE__, 'file2.txt')
+
+ @file1 = File.read(@file1_name)
+ @file2 = File.read(@file2_name)
+
+ @chunk1 = File.read(@file1_name, 4)
+ @chunk2 = File.read(@file2_name, 4)
+ end
+
+ it 'reads up to the given amount of bytes' do
+ argf [@file1_name] do
+ @argf.read_nonblock(4).should == @chunk1
+ end
+ end
+
+ describe 'when using multiple files' do
+ it 'reads up to the given amount of bytes from the first file' do
+ argf [@file1_name, @file2_name] do
+ @argf.read_nonblock(4).should == @chunk1
+ end
+ end
+
+ it 'returns an empty String when reading after having read the first file in its entirety' do
+ argf [@file1_name, @file2_name] do
+ @argf.read_nonblock(File.size(@file1_name)).should == @file1
+ @argf.read_nonblock(4).should == ''
+ end
+ end
+ end
+
+ it 'reads up to the given bytes from STDIN' do
+ stdin = ruby_exe('print ARGF.read_nonblock(4)', :args => "< #{@file1_name}")
+
+ stdin.should == @chunk1
+ end
+
+ it 'reads up to the given bytes from a file when a file and STDIN are present' do
+ stdin = ruby_exe("print ARGF.read_nonblock(4)", :args => "#{@file1_name} - < #{@file2_name}")
+
+ stdin.should == @chunk1
+ end
+
+ context "with STDIN" do
+ before do
+ @r, @w = IO.pipe
+ @stdin = $stdin
+ $stdin = @r
+ end
+
+ after do
+ $stdin = @stdin
+ @w.close
+ @r.close unless @r.closed?
+ end
+
+ it 'raises IO::EAGAINWaitReadable when empty' do
+ argf ['-'] do
+ -> {
+ @argf.read_nonblock(4)
+ }.should.raise(IO::EAGAINWaitReadable)
+ end
+ end
+
+ it 'returns :wait_readable when the :exception is set to false' do
+ argf ['-'] do
+ @argf.read_nonblock(4, nil, exception: false).should == :wait_readable
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/read_spec.rb b/spec/ruby/core/argf/read_spec.rb
new file mode 100644
index 0000000000..bbeef95456
--- /dev/null
+++ b/spec/ruby/core/argf/read_spec.rb
@@ -0,0 +1,85 @@
+require_relative '../../spec_helper'
+require_relative 'shared/read'
+
+describe "ARGF.read" do
+ it_behaves_like :argf_read, :read
+
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+ @stdin_name = fixture __FILE__, "stdin.txt"
+
+ @file1 = File.read @file1_name
+ @file2 = File.read @file2_name
+ @stdin = File.read @stdin_name
+ end
+
+ it "reads the contents of a file" do
+ argf [@file1_name] do
+ @argf.read().should == @file1
+ end
+ end
+
+ it "treats first nil argument as no length limit" do
+ argf [@file1_name] do
+ @argf.read(nil).should == @file1
+ end
+ end
+
+ it "reads the contents of two files" do
+ argf [@file1_name, @file2_name] do
+ @argf.read.should == @file1 + @file2
+ end
+ end
+
+ it "reads the contents of one file and some characters from the second" do
+ argf [@file1_name, @file2_name] do
+ len = @file1.size + (@file2.size / 2)
+ @argf.read(len).should == (@file1 + @file2)[0,len]
+ end
+ end
+
+ it "reads across two files consecutively" do
+ argf [@file1_name, @file2_name] do
+ @argf.read(@file1.size - 2).should == @file1[0..-3]
+ @argf.read(2+5).should == @file1[-2..-1] + @file2[0,5]
+ end
+ end
+
+ it "reads the contents of stdin" do
+ stdin = ruby_exe("print ARGF.read", args: "< #{@stdin_name}")
+ stdin.should == @stdin
+ end
+
+ it "reads the contents of one file and stdin" do
+ stdin = ruby_exe("print ARGF.read", args: "#{@file1_name} - < #{@stdin_name}")
+ stdin.should == @file1 + @stdin
+ end
+
+ it "reads the contents of the same file twice" do
+ argf [@file1_name, @file1_name] do
+ @argf.read.should == @file1 + @file1
+ end
+ end
+
+
+ before :each do
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
+
+ Encoding.default_external = Encoding::UTF_8
+ Encoding.default_internal = nil
+ end
+
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ end
+
+ it "reads the contents of the file with default encoding" do
+ Encoding.default_external = Encoding::US_ASCII
+ argf [@file1_name, @file2_name] do
+ @argf.read.encoding.should == Encoding::US_ASCII
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/readchar_spec.rb b/spec/ruby/core/argf/readchar_spec.rb
new file mode 100644
index 0000000000..63632721ec
--- /dev/null
+++ b/spec/ruby/core/argf/readchar_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../spec_helper'
+require_relative 'shared/getc'
+
+describe "ARGF.getc" do
+ it_behaves_like :argf_getc, :readchar
+end
+
+describe "ARGF.readchar" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "raises EOFError when end of stream reached" do
+ argf [@file1, @file2] do
+ -> { while @argf.readchar; end }.should.raise(EOFError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/readline_spec.rb b/spec/ruby/core/argf/readline_spec.rb
new file mode 100644
index 0000000000..8c23549b1b
--- /dev/null
+++ b/spec/ruby/core/argf/readline_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../spec_helper'
+require_relative 'shared/gets'
+
+describe "ARGF.readline" do
+ it_behaves_like :argf_gets, :readline
+end
+
+describe "ARGF.readline" do
+ it_behaves_like :argf_gets_inplace_edit, :readline
+end
+
+describe "ARGF.readline" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "raises an EOFError when reaching end of files" do
+ argf [@file1, @file2] do
+ -> { while @argf.readline; end }.should.raise(EOFError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/readlines_spec.rb b/spec/ruby/core/argf/readlines_spec.rb
new file mode 100644
index 0000000000..30be936dab
--- /dev/null
+++ b/spec/ruby/core/argf/readlines_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/readlines'
+
+describe "ARGF.readlines" do
+ it_behaves_like :argf_readlines, :readlines
+end
diff --git a/spec/ruby/core/argf/readpartial_spec.rb b/spec/ruby/core/argf/readpartial_spec.rb
new file mode 100644
index 0000000000..9f04e72cc2
--- /dev/null
+++ b/spec/ruby/core/argf/readpartial_spec.rb
@@ -0,0 +1,75 @@
+require_relative '../../spec_helper'
+require_relative 'shared/read'
+
+describe "ARGF.readpartial" do
+ it_behaves_like :argf_read, :readpartial
+
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+ @stdin_name = fixture __FILE__, "stdin.txt"
+
+ @file1 = File.read @file1_name
+ @file2 = File.read @file2_name
+ @stdin = File.read @stdin_name
+ end
+
+ it "raises an ArgumentError if called without a maximum read length" do
+ argf [@file1_name] do
+ -> { @argf.readpartial }.should.raise(ArgumentError)
+ end
+ end
+
+ it "reads maximum number of bytes from one file at a time" do
+ argf [@file1_name, @file2_name] do
+ len = @file1.size + @file2.size
+ @argf.readpartial(len).should == @file1
+ end
+ end
+
+ it "clears output buffer even if EOFError is raised because @argf is at end" do
+ begin
+ output = +"to be cleared"
+
+ argf [@file1_name] do
+ @argf.read
+ @argf.readpartial(1, output)
+ end
+ rescue EOFError
+ output.should == ""
+ end
+ end
+
+ it "reads maximum number of bytes from one file at a time" do
+ argf [@file1_name, @file2_name] do
+ len = @file1.size + @file2.size
+ @argf.readpartial(len).should == @file1
+ end
+ end
+
+ it "returns an empty string if EOFError is raised while reading any but the last file" do
+ argf [@file1_name, @file2_name] do
+ @argf.readpartial(@file1.size)
+ @argf.readpartial(1).should == ""
+ end
+ end
+
+ it "raises an EOFError if the exception was raised while reading the last file" do
+ argf [@file1_name, @file2_name] do
+ @argf.readpartial(@file1.size)
+ @argf.readpartial(1)
+ @argf.readpartial(@file2.size)
+ -> { @argf.readpartial(1) }.should.raise(EOFError)
+ -> { @argf.readpartial(1) }.should.raise(EOFError)
+ end
+ end
+
+ it "raises an EOFError if the exception was raised while reading STDIN" do
+ ruby_str = <<-STR
+ print ARGF.readpartial(#{@stdin.size})
+ ARGF.readpartial(1) rescue print $!.class
+ STR
+ stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}")
+ stdin.should == @stdin + "EOFError"
+ end
+end
diff --git a/spec/ruby/core/argf/rewind_spec.rb b/spec/ruby/core/argf/rewind_spec.rb
new file mode 100644
index 0000000000..9255f790fe
--- /dev/null
+++ b/spec/ruby/core/argf/rewind_spec.rb
@@ -0,0 +1,39 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.rewind" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @file1 = File.readlines @file1_name
+ @file2 = File.readlines @file2_name
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "goes back to beginning of current file" do
+ argf [@file1_name, @file2_name] do
+ @argf.gets
+ @argf.rewind
+ @argf.gets.should == @file1.first
+
+ @argf.gets # finish reading file1
+
+ @argf.gets
+ @argf.rewind
+ @argf.gets.should == @file2.first
+ end
+ end
+
+ it "resets ARGF.lineno to 0" do
+ script = fixture __FILE__, "rewind.rb"
+ out = ruby_exe(script, args: [@file1_name, @file2_name])
+ out.should == "0\n1\n0\n"
+ end
+
+ it "raises an ArgumentError when end of stream reached" do
+ argf [@file1_name, @file2_name] do
+ @argf.read
+ -> { @argf.rewind }.should.raise(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/seek_spec.rb b/spec/ruby/core/argf/seek_spec.rb
new file mode 100644
index 0000000000..c1ea1ea438
--- /dev/null
+++ b/spec/ruby/core/argf/seek_spec.rb
@@ -0,0 +1,63 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.seek" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @file1 = File.readlines @file1_name
+ @file2 = File.readlines @file2_name
+ end
+
+ it "sets the absolute position relative to beginning of file" do
+ argf [@file1_name, @file2_name] do
+ @argf.seek 2
+ @argf.gets.should == @file1.first[2..-1]
+ @argf.seek @file1.first.size
+ @argf.gets.should == @file1.last
+ @argf.seek 0, IO::SEEK_END
+ @argf.gets.should == @file2.first
+ end
+ end
+
+ it "sets the position relative to current position in file" do
+ argf [@file1_name, @file2_name] do
+ @argf.seek(0, IO::SEEK_CUR)
+ @argf.gets.should == @file1.first
+ @argf.seek(-@file1.first.size+2, IO::SEEK_CUR)
+ @argf.gets.should == @file1.first[2..-1]
+ @argf.seek(1, IO::SEEK_CUR)
+ @argf.gets.should == @file1.last[1..-1]
+ @argf.seek(3, IO::SEEK_CUR)
+ @argf.gets.should == @file2.first
+ @argf.seek(@file1.last.size, IO::SEEK_CUR)
+ @argf.gets.should == nil
+ end
+ end
+
+ it "sets the absolute position relative to end of file" do
+ argf [@file1_name, @file2_name] do
+ @argf.seek(-@file1.first.size-@file1.last.size, IO::SEEK_END)
+ @argf.gets.should == @file1.first
+ @argf.seek(-6, IO::SEEK_END)
+ @argf.gets.should == @file1.last[-6..-1]
+ @argf.seek(-4, IO::SEEK_END)
+ @argf.gets.should == @file1.last[4..-1]
+ @argf.gets.should == @file2.first
+ @argf.seek(-6, IO::SEEK_END)
+ @argf.gets.should == @file2.last[-6..-1]
+ end
+ end
+end
+
+describe "ARGF.seek" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ end
+
+ it "takes at least one argument (offset)" do
+ argf [@file1_name] do
+ -> { @argf.seek }.should.raise(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/set_encoding_spec.rb b/spec/ruby/core/argf/set_encoding_spec.rb
new file mode 100644
index 0000000000..a871e084b6
--- /dev/null
+++ b/spec/ruby/core/argf/set_encoding_spec.rb
@@ -0,0 +1,41 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.set_encoding" do
+ before :each do
+ @file = fixture __FILE__, "file1.txt"
+ end
+
+ it "sets the external encoding when passed an encoding instance" do
+ argf [@file] do
+ @argf.set_encoding(Encoding::US_ASCII)
+ @argf.external_encoding.should == Encoding::US_ASCII
+ @argf.gets.encoding.should == Encoding::US_ASCII
+ end
+ end
+
+ it "sets the external encoding when passed an encoding name" do
+ argf [@file] do
+ @argf.set_encoding("us-ascii")
+ @argf.external_encoding.should == Encoding::US_ASCII
+ @argf.gets.encoding.should == Encoding::US_ASCII
+ end
+ end
+
+ it "sets the external, internal encoding when passed two encoding instances" do
+ argf [@file] do
+ @argf.set_encoding(Encoding::US_ASCII, Encoding::EUC_JP)
+ @argf.external_encoding.should == Encoding::US_ASCII
+ @argf.internal_encoding.should == Encoding::EUC_JP
+ @argf.gets.encoding.should == Encoding::EUC_JP
+ end
+ end
+
+ it "sets the external, internal encoding when passed 'ext:int' String" do
+ argf [@file] do
+ @argf.set_encoding("us-ascii:euc-jp")
+ @argf.external_encoding.should == Encoding::US_ASCII
+ @argf.internal_encoding.should == Encoding::EUC_JP
+ @argf.gets.encoding.should == Encoding::EUC_JP
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/each_byte.rb b/spec/ruby/core/argf/shared/each_byte.rb
new file mode 100644
index 0000000000..48c9ae04f8
--- /dev/null
+++ b/spec/ruby/core/argf/shared/each_byte.rb
@@ -0,0 +1,58 @@
+describe :argf_each_byte, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @bytes = []
+ File.read(@file1_name).each_byte { |b| @bytes << b }
+ File.read(@file2_name).each_byte { |b| @bytes << b }
+ end
+
+ it "yields each byte of all streams to the passed block" do
+ argf [@file1_name, @file2_name] do
+ bytes = []
+ @argf.send(@method) { |b| bytes << b }
+ bytes.should == @bytes
+ end
+ end
+
+ it "returns self when passed a block" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method) {}.should.equal?(@argf)
+ end
+ end
+
+ it "returns an Enumerator when passed no block" do
+ argf [@file1_name, @file2_name] do
+ enum = @argf.send(@method)
+ enum.should.instance_of?(Enumerator)
+
+ bytes = []
+ enum.each { |b| bytes << b }
+ bytes.should == @bytes
+ end
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ argf [@file1_name, @file2_name] do
+ enum = @argf.send(@method)
+ enum.should.instance_of?(Enumerator)
+
+ bytes = []
+ enum.each { |b| bytes << b }
+ bytes.should == @bytes
+ end
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method).size.should == nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/each_char.rb b/spec/ruby/core/argf/shared/each_char.rb
new file mode 100644
index 0000000000..4b5e8452ab
--- /dev/null
+++ b/spec/ruby/core/argf/shared/each_char.rb
@@ -0,0 +1,58 @@
+describe :argf_each_char, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @chars = []
+ File.read(@file1_name).each_char { |c| @chars << c }
+ File.read(@file2_name).each_char { |c| @chars << c }
+ end
+
+ it "yields each char of all streams to the passed block" do
+ argf [@file1_name, @file2_name] do
+ chars = []
+ @argf.send(@method) { |c| chars << c }
+ chars.should == @chars
+ end
+ end
+
+ it "returns self when passed a block" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method) {}.should.equal?(@argf)
+ end
+ end
+
+ it "returns an Enumerator when passed no block" do
+ argf [@file1_name, @file2_name] do
+ enum = @argf.send(@method)
+ enum.should.instance_of?(Enumerator)
+
+ chars = []
+ enum.each { |c| chars << c }
+ chars.should == @chars
+ end
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ argf [@file1_name, @file2_name] do
+ enum = @argf.send(@method)
+ enum.should.instance_of?(Enumerator)
+
+ chars = []
+ enum.each { |c| chars << c }
+ chars.should == @chars
+ end
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method).size.should == nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/each_codepoint.rb b/spec/ruby/core/argf/shared/each_codepoint.rb
new file mode 100644
index 0000000000..3137306ad5
--- /dev/null
+++ b/spec/ruby/core/argf/shared/each_codepoint.rb
@@ -0,0 +1,58 @@
+describe :argf_each_codepoint, shared: true do
+ before :each do
+ file1_name = fixture __FILE__, "file1.txt"
+ file2_name = fixture __FILE__, "file2.txt"
+ @filenames = [file1_name, file2_name]
+
+ @codepoints = File.read(file1_name).codepoints
+ @codepoints.concat File.read(file2_name).codepoints
+ end
+
+ it "is a public method" do
+ argf @filenames do
+ @argf.public_methods(false).should.include?(@method)
+ end
+ end
+
+ it "does not require arguments" do
+ argf @filenames do
+ @argf.method(@method).arity.should == 0
+ end
+ end
+
+ it "returns self when passed a block" do
+ argf @filenames do
+ @argf.send(@method) {}.should.equal?(@argf)
+ end
+ end
+
+ it "returns an Enumerator when passed no block" do
+ argf @filenames do
+ @argf.send(@method).should.instance_of?(Enumerator)
+ end
+ end
+
+ it "yields each codepoint of all streams" do
+ argf @filenames do
+ @argf.send(@method).to_a.should == @codepoints
+ end
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ argf @filenames do
+ @argf.send(@method).should.instance_of?(Enumerator)
+ end
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ argf @filenames do
+ @argf.send(@method).size.should == nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/each_line.rb b/spec/ruby/core/argf/shared/each_line.rb
new file mode 100644
index 0000000000..7e66e38803
--- /dev/null
+++ b/spec/ruby/core/argf/shared/each_line.rb
@@ -0,0 +1,62 @@
+describe :argf_each_line, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @lines = File.readlines @file1_name
+ @lines += File.readlines @file2_name
+ end
+
+ it "is a public method" do
+ argf [@file1_name, @file2_name] do
+ @argf.public_methods(false).should.include?(@method)
+ end
+ end
+
+ it "requires multiple arguments" do
+ argf [@file1_name, @file2_name] do
+ @argf.method(@method).arity.should < 0
+ end
+ end
+
+ it "reads each line of files" do
+ argf [@file1_name, @file2_name] do
+ lines = []
+ @argf.send(@method) { |b| lines << b }
+ lines.should == @lines
+ end
+ end
+
+ it "returns self when passed a block" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method) {}.should.equal?(@argf)
+ end
+ end
+
+ describe "with a separator" do
+ it "yields each separated section of all streams" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method, '.').to_a.should ==
+ (File.readlines(@file1_name, '.') + File.readlines(@file2_name, '.'))
+ end
+ end
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method).should.instance_of?(Enumerator)
+ end
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ argf [@file1_name, @file2_name] do
+ @argf.send(@method).size.should == nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/eof.rb b/spec/ruby/core/argf/shared/eof.rb
new file mode 100644
index 0000000000..8b3897b952
--- /dev/null
+++ b/spec/ruby/core/argf/shared/eof.rb
@@ -0,0 +1,24 @@
+describe :argf_eof, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "returns true when reaching the end of a file" do
+ argf [@file1, @file2] do
+ result = []
+ while @argf.gets
+ result << @argf.send(@method)
+ end
+ result.should == [false, true, false, true]
+ end
+ end
+
+ it "raises IOError when called on a closed stream" do
+ argf [@file1] do
+ @argf.read
+ -> { @argf.send(@method) }.should.raise(IOError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/filename.rb b/spec/ruby/core/argf/shared/filename.rb
new file mode 100644
index 0000000000..f47c673dc0
--- /dev/null
+++ b/spec/ruby/core/argf/shared/filename.rb
@@ -0,0 +1,28 @@
+describe :argf_filename, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "returns the current file name on each file" do
+ argf [@file1, @file2] do
+ result = []
+ # returns first current file even when not yet open
+ result << @argf.send(@method)
+ result << @argf.send(@method) while @argf.gets
+ # returns last current file even when closed
+ result << @argf.send(@method)
+
+ result.map! { |f| File.expand_path(f) }
+ result.should == [@file1, @file1, @file1, @file2, @file2, @file2]
+ end
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "sets the $FILENAME global variable with the current file name on each file" do
+ script = fixture __FILE__, "filename.rb"
+ out = ruby_exe(script, args: [@file1, @file2])
+ out.should == "#{@file1}\n#{@file1}\n#{@file2}\n#{@file2}\n#{@file2}\n"
+ end
+end
diff --git a/spec/ruby/core/argf/shared/fileno.rb b/spec/ruby/core/argf/shared/fileno.rb
new file mode 100644
index 0000000000..e605be46e3
--- /dev/null
+++ b/spec/ruby/core/argf/shared/fileno.rb
@@ -0,0 +1,24 @@
+describe :argf_fileno, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "returns the current file number on each file" do
+ argf [@file1, @file2] do
+ result = []
+ # returns first current file even when not yet open
+ result << @argf.send(@method) while @argf.gets
+ # returns last current file even when closed
+ result.map { |d| d.class }.should == [Integer, Integer, Integer, Integer]
+ end
+ end
+
+ it "raises an ArgumentError when called on a closed stream" do
+ argf [@file1] do
+ @argf.read
+ -> { @argf.send(@method) }.should.raise(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/getc.rb b/spec/ruby/core/argf/shared/getc.rb
new file mode 100644
index 0000000000..d63372d9d7
--- /dev/null
+++ b/spec/ruby/core/argf/shared/getc.rb
@@ -0,0 +1,17 @@
+describe :argf_getc, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+
+ @chars = File.read @file1
+ @chars += File.read @file2
+ end
+
+ it "reads each char of files" do
+ argf [@file1, @file2] do
+ chars = +""
+ @chars.size.times { chars << @argf.send(@method) }
+ chars.should == @chars
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/gets.rb b/spec/ruby/core/argf/shared/gets.rb
new file mode 100644
index 0000000000..160d24c27b
--- /dev/null
+++ b/spec/ruby/core/argf/shared/gets.rb
@@ -0,0 +1,99 @@
+describe :argf_gets, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+ @stdin_name = fixture __FILE__, "stdin.txt"
+
+ @file1 = File.readlines @file1_name
+ @file2 = File.readlines @file2_name
+ @stdin = File.read @stdin_name
+ end
+
+ it "reads one line of a file" do
+ argf [@file1_name] do
+ @argf.send(@method).should == @file1.first
+ end
+ end
+
+ it "reads all lines of a file" do
+ argf [@file1_name] do
+ lines = []
+ @file1.size.times { lines << @argf.send(@method) }
+ lines.should == @file1
+ end
+ end
+
+ it "reads all lines of stdin" do
+ total = @stdin.count $/
+ stdin = ruby_exe(
+ "#{total}.times { print ARGF.send(#{@method.inspect}) }",
+ args: "< #{@stdin_name}")
+ stdin.should == @stdin
+ end
+
+ it "reads all lines of two files" do
+ argf [@file1_name, @file2_name] do
+ total = @file1.size + @file2.size
+ lines = []
+ total.times { lines << @argf.send(@method) }
+ lines.should == @file1 + @file2
+ end
+ end
+
+ it "sets $_ global variable with each line read" do
+ argf [@file1_name, @file2_name] do
+ total = @file1.size + @file2.size
+ total.times do
+ line = @argf.send(@method)
+ $_.should == line
+ end
+ end
+ end
+end
+
+describe :argf_gets_inplace_edit, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @tmp1_name = tmp "file1.txt"
+ @tmp2_name = tmp "file2.txt"
+
+ @tmp1_name_bak = @tmp1_name + ".bak"
+ @tmp2_name_bak = @tmp2_name + ".bak"
+
+ cp @file1_name, @tmp1_name
+ cp @file2_name, @tmp2_name
+
+ method = "ARGF.send(#{@method.inspect})"
+ @code = "begin while line = #{method} do puts 'x' end rescue EOFError; end"
+ end
+
+ after :each do
+ rm_r @tmp1_name, @tmp2_name, @tmp1_name_bak, @tmp2_name_bak
+ end
+
+ # -i with no backup extension is not supported on Windows
+ platform_is_not :windows do
+ it "modifies the files when in place edit mode is on" do
+ ruby_exe(@code,
+ options: "-i",
+ args: "#{@tmp1_name} #{@tmp2_name}")
+
+ File.read(@tmp1_name).should == "x\nx\n"
+ File.read(@tmp2_name).should == "x\nx\n"
+ end
+ end
+
+ it "modifies and backups two files when in place edit mode is on" do
+ ruby_exe(@code,
+ options: "-i.bak",
+ args: "#{@tmp1_name} #{@tmp2_name}")
+
+ File.read(@tmp1_name).should == "x\nx\n"
+ File.read(@tmp2_name).should == "x\nx\n"
+
+ File.read(@tmp1_name_bak).should == "file1.1\nfile1.2\n"
+ File.read(@tmp2_name_bak).should == "line2.1\nline2.2\n"
+ end
+end
diff --git a/spec/ruby/core/argf/shared/pos.rb b/spec/ruby/core/argf/shared/pos.rb
new file mode 100644
index 0000000000..f859d3a29d
--- /dev/null
+++ b/spec/ruby/core/argf/shared/pos.rb
@@ -0,0 +1,31 @@
+describe :argf_pos, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "gives the correct position for each read operation" do
+ argf [@file1, @file2] do
+ size1 = File.size(@file1)
+ size2 = File.size(@file2)
+
+ @argf.read(2)
+ @argf.send(@method).should == 2
+ @argf.read(size1-2)
+ @argf.send(@method).should == size1
+ @argf.read(6)
+ @argf.send(@method).should == 6
+ @argf.rewind
+ @argf.send(@method).should == 0
+ @argf.read(size2)
+ @argf.send(@method).should == size2
+ end
+ end
+
+ it "raises an ArgumentError when called on a closed stream" do
+ argf [@file1] do
+ @argf.read
+ -> { @argf.send(@method) }.should.raise(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/read.rb b/spec/ruby/core/argf/shared/read.rb
new file mode 100644
index 0000000000..e76d022139
--- /dev/null
+++ b/spec/ruby/core/argf/shared/read.rb
@@ -0,0 +1,58 @@
+describe :argf_read, shared: true do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @stdin_name = fixture __FILE__, "stdin.txt"
+
+ @file1 = File.read @file1_name
+ @stdin = File.read @stdin_name
+ end
+
+ it "treats second nil argument as no output buffer" do
+ argf [@file1_name] do
+ @argf.send(@method, @file1.size, nil).should == @file1
+ end
+ end
+
+ it "treats second argument as an output buffer" do
+ argf [@file1_name] do
+ buffer = +""
+ @argf.send(@method, @file1.size, buffer)
+ buffer.should == @file1
+ end
+ end
+
+ it "clears output buffer before appending to it" do
+ argf [@file1_name] do
+ buffer = +"to be cleared"
+ @argf.send(@method, @file1.size, buffer)
+ buffer.should == @file1
+ end
+ end
+
+ it "reads a number of bytes from the first file" do
+ argf [@file1_name] do
+ @argf.send(@method, 5).should == @file1[0, 5]
+ end
+ end
+
+ it "reads from a single file consecutively" do
+ argf [@file1_name] do
+ @argf.send(@method, 1).should == @file1[0, 1]
+ @argf.send(@method, 2).should == @file1[1, 2]
+ @argf.send(@method, 3).should == @file1[3, 3]
+ end
+ end
+
+ it "reads a number of bytes from stdin" do
+ stdin = ruby_exe("print ARGF.#{@method}(10)", :args => "< #{@stdin_name}")
+ stdin.should == @stdin[0, 10]
+ end
+
+ platform_is_not :windows do
+ it "reads the contents of a special device file" do
+ argf ['/dev/zero'] do
+ @argf.send(@method, 100).should == "\000" * 100
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/shared/readlines.rb b/spec/ruby/core/argf/shared/readlines.rb
new file mode 100644
index 0000000000..505fa94acb
--- /dev/null
+++ b/spec/ruby/core/argf/shared/readlines.rb
@@ -0,0 +1,22 @@
+describe :argf_readlines, shared: true do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+
+ @lines = File.readlines(@file1)
+ @lines += File.readlines(@file2)
+ end
+
+ it "reads all lines of all files" do
+ argf [@file1, @file2] do
+ @argf.send(@method).should == @lines
+ end
+ end
+
+ it "returns an empty Array when end of stream reached" do
+ argf [@file1, @file2] do
+ @argf.read
+ @argf.send(@method).should == []
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/skip_spec.rb b/spec/ruby/core/argf/skip_spec.rb
new file mode 100644
index 0000000000..bb1c0ae110
--- /dev/null
+++ b/spec/ruby/core/argf/skip_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.skip" do
+ before :each do
+ @file1_name = fixture __FILE__, "file1.txt"
+ @file2_name = fixture __FILE__, "file2.txt"
+
+ @file2 = File.readlines @file2_name
+ end
+
+ it "skips the current file" do
+ argf [@file1_name, @file2_name] do
+ @argf.read(1)
+ @argf.skip
+ @argf.gets.should == @file2.first
+ end
+ end
+
+ it "has no effect when called twice in a row" do
+ argf [@file1_name, @file2_name] do
+ @argf.read(1)
+ @argf.skip
+ @argf.skip
+ @argf.gets.should == @file2.first
+ end
+ end
+
+ it "has no effect at end of stream" do
+ argf [@file1_name, @file2_name] do
+ @argf.read
+ @argf.skip
+ @argf.gets.should == nil
+ end
+ end
+
+ # This bypasses argf helper because the helper will call argf.file
+ # which as a side-effect calls argf.file which will initialize
+ # internals of ARGF enough for this to work.
+ it "has no effect when nothing has been processed yet" do
+ -> { ARGF.class.new(@file1_name).skip }.should_not.raise
+ end
+end
diff --git a/spec/ruby/core/argf/tell_spec.rb b/spec/ruby/core/argf/tell_spec.rb
new file mode 100644
index 0000000000..16d9f29920
--- /dev/null
+++ b/spec/ruby/core/argf/tell_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/pos'
+
+describe "ARGF.tell" do
+ it_behaves_like :argf_pos, :tell
+end
diff --git a/spec/ruby/core/argf/to_a_spec.rb b/spec/ruby/core/argf/to_a_spec.rb
new file mode 100644
index 0000000000..b17a93db33
--- /dev/null
+++ b/spec/ruby/core/argf/to_a_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/readlines'
+
+describe "ARGF.to_a" do
+ it_behaves_like :argf_readlines, :to_a
+end
diff --git a/spec/ruby/core/argf/to_i_spec.rb b/spec/ruby/core/argf/to_i_spec.rb
new file mode 100644
index 0000000000..2183de6cd4
--- /dev/null
+++ b/spec/ruby/core/argf/to_i_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../../spec_helper'
+require_relative 'shared/fileno'
+
+describe "ARGF.to_i" do
+ it_behaves_like :argf_fileno, :to_i
+end
diff --git a/spec/ruby/core/argf/to_io_spec.rb b/spec/ruby/core/argf/to_io_spec.rb
new file mode 100644
index 0000000000..ab5de58bcf
--- /dev/null
+++ b/spec/ruby/core/argf/to_io_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.to_io" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ # NOTE: this test assumes that fixtures files have two lines each
+ it "returns the IO of the current file" do
+ argf [@file1, @file2] do
+ result = []
+ 4.times do
+ @argf.gets
+ result << @argf.to_io
+ end
+
+ result.each { |io| io.should.is_a?(IO) }
+ result[0].should == result[1]
+ result[2].should == result[3]
+ end
+ end
+end
diff --git a/spec/ruby/core/argf/to_s_spec.rb b/spec/ruby/core/argf/to_s_spec.rb
new file mode 100644
index 0000000000..3f505898f4
--- /dev/null
+++ b/spec/ruby/core/argf/to_s_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../spec_helper'
+
+describe "ARGF.to_s" do
+ before :each do
+ @file1 = fixture __FILE__, "file1.txt"
+ @file2 = fixture __FILE__, "file2.txt"
+ end
+
+ it "returns 'ARGF'" do
+ argf [@file1, @file2] do
+ @argf.to_s.should == "ARGF"
+ end
+ end
+end