summaryrefslogtreecommitdiff
path: root/spec/rubyspec/core/argf
diff options
context:
space:
mode:
Diffstat (limited to 'spec/rubyspec/core/argf')
-rw-r--r--spec/rubyspec/core/argf/argf_spec.rb11
-rw-r--r--spec/rubyspec/core/argf/argv_spec.rb19
-rw-r--r--spec/rubyspec/core/argf/binmode_spec.rb46
-rw-r--r--spec/rubyspec/core/argf/bytes_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/chars_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/close_spec.rb46
-rw-r--r--spec/rubyspec/core/argf/closed_spec.rb18
-rw-r--r--spec/rubyspec/core/argf/codepoints_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/each_byte_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/each_char_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/each_codepoint_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/each_line_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/each_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/eof_spec.rb10
-rw-r--r--spec/rubyspec/core/argf/file_spec.rb21
-rw-r--r--spec/rubyspec/core/argf/filename_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/fileno_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/fixtures/bin_file.txt2
-rw-r--r--spec/rubyspec/core/argf/fixtures/encoding.rb5
-rw-r--r--spec/rubyspec/core/argf/fixtures/file1.txt2
-rw-r--r--spec/rubyspec/core/argf/fixtures/file2.txt2
-rw-r--r--spec/rubyspec/core/argf/fixtures/filename.rb3
-rw-r--r--spec/rubyspec/core/argf/fixtures/lineno.rb5
-rw-r--r--spec/rubyspec/core/argf/fixtures/rewind.rb5
-rw-r--r--spec/rubyspec/core/argf/fixtures/stdin.txt2
-rw-r--r--spec/rubyspec/core/argf/getc_spec.rb20
-rw-r--r--spec/rubyspec/core/argf/gets_spec.rb51
-rw-r--r--spec/rubyspec/core/argf/lineno_spec.rb30
-rw-r--r--spec/rubyspec/core/argf/lines_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/path_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/pos_spec.rb38
-rw-r--r--spec/rubyspec/core/argf/read_nonblock_spec.rb82
-rw-r--r--spec/rubyspec/core/argf/read_spec.rb87
-rw-r--r--spec/rubyspec/core/argf/readchar_spec.rb19
-rw-r--r--spec/rubyspec/core/argf/readline_spec.rb23
-rw-r--r--spec/rubyspec/core/argf/readlines_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/readpartial_spec.rb77
-rw-r--r--spec/rubyspec/core/argf/rewind_spec.rb39
-rw-r--r--spec/rubyspec/core/argf/seek_spec.rb63
-rw-r--r--spec/rubyspec/core/argf/set_encoding_spec.rb28
-rw-r--r--spec/rubyspec/core/argf/shared/each_byte.rb58
-rw-r--r--spec/rubyspec/core/argf/shared/each_char.rb58
-rw-r--r--spec/rubyspec/core/argf/shared/each_codepoint.rb58
-rw-r--r--spec/rubyspec/core/argf/shared/each_line.rb62
-rw-r--r--spec/rubyspec/core/argf/shared/eof.rb24
-rw-r--r--spec/rubyspec/core/argf/shared/filename.rb28
-rw-r--r--spec/rubyspec/core/argf/shared/fileno.rb24
-rw-r--r--spec/rubyspec/core/argf/shared/getc.rb17
-rw-r--r--spec/rubyspec/core/argf/shared/gets.rb99
-rw-r--r--spec/rubyspec/core/argf/shared/pos.rb31
-rw-r--r--spec/rubyspec/core/argf/shared/read.rb58
-rw-r--r--spec/rubyspec/core/argf/shared/readlines.rb22
-rw-r--r--spec/rubyspec/core/argf/skip_spec.rb42
-rw-r--r--spec/rubyspec/core/argf/tell_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/to_a_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/to_i_spec.rb6
-rw-r--r--spec/rubyspec/core/argf/to_io_spec.rb23
-rw-r--r--spec/rubyspec/core/argf/to_s_spec.rb14
58 files changed, 1468 insertions, 0 deletions
diff --git a/spec/rubyspec/core/argf/argf_spec.rb b/spec/rubyspec/core/argf/argf_spec.rb
new file mode 100644
index 0000000000..b47e77c17f
--- /dev/null
+++ b/spec/rubyspec/core/argf/argf_spec.rb
@@ -0,0 +1,11 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "ARGF" do
+ it "is extended by the Enumerable module" do
+ ARGF.should be_kind_of(Enumerable)
+ end
+
+ it "is an instance of ARGF.class" do
+ ARGF.should be_an_instance_of(ARGF.class)
+ end
+end
diff --git a/spec/rubyspec/core/argf/argv_spec.rb b/spec/rubyspec/core/argf/argv_spec.rb
new file mode 100644
index 0000000000..e294b3993f
--- /dev/null
+++ b/spec/rubyspec/core/argf/argv_spec.rb
@@ -0,0 +1,19 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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/rubyspec/core/argf/binmode_spec.rb b/spec/rubyspec/core/argf/binmode_spec.rb
new file mode 100644
index 0000000000..3daf4f4345
--- /dev/null
+++ b/spec/rubyspec/core/argf/binmode_spec.rb
@@ -0,0 +1,46 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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
+ ruby_exe("puts(ARGF.binmode == ARGF)", args: @bin_file).chomp.should == 'true'
+ 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 alls subsequent stream 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
+
+ platform_is_not :windows do
+ # This does nothing on Unix but it should not raise any errors.
+ it "does not raise an error" do
+ ruby_exe("ARGF.binmode", args: @bin_file)
+ $?.should be_kind_of(Process::Status)
+ $?.to_i.should == 0
+ end
+ end
+
+ it "sets the file's encoding to ASCII-8BIT" do
+ script = fixture __FILE__, "encoding.rb"
+ output = "true\n#{Encoding::ASCII_8BIT}\n#{Encoding::ASCII_8BIT}\n"
+ ruby_exe(script, args: [@bin_file, @file1]).should == output
+ end
+end
diff --git a/spec/rubyspec/core/argf/bytes_spec.rb b/spec/rubyspec/core/argf/bytes_spec.rb
new file mode 100644
index 0000000000..01a3a3db0d
--- /dev/null
+++ b/spec/rubyspec/core/argf/bytes_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_byte', __FILE__)
+
+describe "ARGF.bytes" do
+ it_behaves_like :argf_each_byte, :bytes
+end
diff --git a/spec/rubyspec/core/argf/chars_spec.rb b/spec/rubyspec/core/argf/chars_spec.rb
new file mode 100644
index 0000000000..8c9e4844c0
--- /dev/null
+++ b/spec/rubyspec/core/argf/chars_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_char', __FILE__)
+
+describe "ARGF.chars" do
+ it_behaves_like :argf_each_char, :chars
+end
diff --git a/spec/rubyspec/core/argf/close_spec.rb b/spec/rubyspec/core/argf/close_spec.rb
new file mode 100644
index 0000000000..b56f7f5564
--- /dev/null
+++ b/spec/rubyspec/core/argf/close_spec.rb
@@ -0,0 +1,46 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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 be_true
+ end
+ end
+
+ it "returns self" do
+ argf [@file1_name, @file2_name] do
+ @argf.close.should equal(@argf)
+ end
+ end
+
+ ruby_version_is ""..."2.3" do
+ it "raises an IOError if called on a closed stream" do
+ argf [@file1_name] do
+ lambda { @argf.close }.should_not raise_error
+ lambda { @argf.close }.should raise_error(IOError)
+ end
+ end
+ end
+
+ ruby_version_is "2.3" do
+ it "doesn't raise an IOError if called on a closed stream" do
+ argf [@file1_name] do
+ lambda { @argf.close }.should_not raise_error
+ lambda { @argf.close }.should_not raise_error
+ end
+ 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/rubyspec/core/argf/closed_spec.rb b/spec/rubyspec/core/argf/closed_spec.rb
new file mode 100644
index 0000000000..745f102484
--- /dev/null
+++ b/spec/rubyspec/core/argf/closed_spec.rb
@@ -0,0 +1,18 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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 be_true
+ stream.reopen(@argf.filename, 'r')
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/codepoints_spec.rb b/spec/rubyspec/core/argf/codepoints_spec.rb
new file mode 100644
index 0000000000..cd839cbb8c
--- /dev/null
+++ b/spec/rubyspec/core/argf/codepoints_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_codepoint', __FILE__)
+
+describe "ARGF.codepoints" do
+ it_behaves_like :argf_each_codepoint, :codepoints
+end
diff --git a/spec/rubyspec/core/argf/each_byte_spec.rb b/spec/rubyspec/core/argf/each_byte_spec.rb
new file mode 100644
index 0000000000..8b4a62c2b1
--- /dev/null
+++ b/spec/rubyspec/core/argf/each_byte_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_byte', __FILE__)
+
+describe "ARGF.each_byte" do
+ it_behaves_like :argf_each_byte, :each_byte
+end
diff --git a/spec/rubyspec/core/argf/each_char_spec.rb b/spec/rubyspec/core/argf/each_char_spec.rb
new file mode 100644
index 0000000000..58ac0bf783
--- /dev/null
+++ b/spec/rubyspec/core/argf/each_char_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_char', __FILE__)
+
+describe "ARGF.each_char" do
+ it_behaves_like :argf_each_char, :each_char
+end
diff --git a/spec/rubyspec/core/argf/each_codepoint_spec.rb b/spec/rubyspec/core/argf/each_codepoint_spec.rb
new file mode 100644
index 0000000000..d0725841a7
--- /dev/null
+++ b/spec/rubyspec/core/argf/each_codepoint_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_codepoint', __FILE__)
+
+describe "ARGF.each_codepoint" do
+ it_behaves_like :argf_each_codepoint, :each_codepoint
+end
diff --git a/spec/rubyspec/core/argf/each_line_spec.rb b/spec/rubyspec/core/argf/each_line_spec.rb
new file mode 100644
index 0000000000..d37968af3d
--- /dev/null
+++ b/spec/rubyspec/core/argf/each_line_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_line', __FILE__)
+
+describe "ARGF.each_line" do
+ it_behaves_like :argf_each_line, :each_line
+end
diff --git a/spec/rubyspec/core/argf/each_spec.rb b/spec/rubyspec/core/argf/each_spec.rb
new file mode 100644
index 0000000000..5a1e0dc73c
--- /dev/null
+++ b/spec/rubyspec/core/argf/each_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_line', __FILE__)
+
+describe "ARGF.each" do
+ it_behaves_like :argf_each_line, :each
+end
diff --git a/spec/rubyspec/core/argf/eof_spec.rb b/spec/rubyspec/core/argf/eof_spec.rb
new file mode 100644
index 0000000000..534bf1f8d8
--- /dev/null
+++ b/spec/rubyspec/core/argf/eof_spec.rb
@@ -0,0 +1,10 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/eof', __FILE__)
+
+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/rubyspec/core/argf/file_spec.rb b/spec/rubyspec/core/argf/file_spec.rb
new file mode 100644
index 0000000000..248ffeff17
--- /dev/null
+++ b/spec/rubyspec/core/argf/file_spec.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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/rubyspec/core/argf/filename_spec.rb b/spec/rubyspec/core/argf/filename_spec.rb
new file mode 100644
index 0000000000..f7ebafa7c5
--- /dev/null
+++ b/spec/rubyspec/core/argf/filename_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/filename', __FILE__)
+
+describe "ARGF.filename" do
+ it_behaves_like :argf_filename, :filename
+end
diff --git a/spec/rubyspec/core/argf/fileno_spec.rb b/spec/rubyspec/core/argf/fileno_spec.rb
new file mode 100644
index 0000000000..b35047695c
--- /dev/null
+++ b/spec/rubyspec/core/argf/fileno_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/fileno', __FILE__)
+
+describe "ARGF.fileno" do
+ it_behaves_like :argf_fileno, :fileno
+end
diff --git a/spec/rubyspec/core/argf/fixtures/bin_file.txt b/spec/rubyspec/core/argf/fixtures/bin_file.txt
new file mode 100644
index 0000000000..2545e9037e
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/bin_file.txt
@@ -0,0 +1,2 @@
+test
+test
diff --git a/spec/rubyspec/core/argf/fixtures/encoding.rb b/spec/rubyspec/core/argf/fixtures/encoding.rb
new file mode 100644
index 0000000000..6e87e64346
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/encoding.rb
@@ -0,0 +1,5 @@
+ARGF.binmode
+puts ARGF.binmode?
+puts ARGF.gets.encoding
+ARGF.skip
+puts ARGF.read.encoding
diff --git a/spec/rubyspec/core/argf/fixtures/file1.txt b/spec/rubyspec/core/argf/fixtures/file1.txt
new file mode 100644
index 0000000000..1c89bfbd82
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/file1.txt
@@ -0,0 +1,2 @@
+file1.1
+file1.2
diff --git a/spec/rubyspec/core/argf/fixtures/file2.txt b/spec/rubyspec/core/argf/fixtures/file2.txt
new file mode 100644
index 0000000000..62e8dba00b
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/file2.txt
@@ -0,0 +1,2 @@
+line2.1
+line2.2
diff --git a/spec/rubyspec/core/argf/fixtures/filename.rb b/spec/rubyspec/core/argf/fixtures/filename.rb
new file mode 100644
index 0000000000..599c97dd57
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/fixtures/lineno.rb b/spec/rubyspec/core/argf/fixtures/lineno.rb
new file mode 100644
index 0000000000..079cc92e8e
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/lineno.rb
@@ -0,0 +1,5 @@
+puts $.
+ARGF.gets
+puts $.
+ARGF.gets
+puts $.
diff --git a/spec/rubyspec/core/argf/fixtures/rewind.rb b/spec/rubyspec/core/argf/fixtures/rewind.rb
new file mode 100644
index 0000000000..90a334cd89
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/fixtures/stdin.txt b/spec/rubyspec/core/argf/fixtures/stdin.txt
new file mode 100644
index 0000000000..063cdcb1d4
--- /dev/null
+++ b/spec/rubyspec/core/argf/fixtures/stdin.txt
@@ -0,0 +1,2 @@
+stdin.1
+stdin.2
diff --git a/spec/rubyspec/core/argf/getc_spec.rb b/spec/rubyspec/core/argf/getc_spec.rb
new file mode 100644
index 0000000000..de5e6fa73c
--- /dev/null
+++ b/spec/rubyspec/core/argf/getc_spec.rb
@@ -0,0 +1,20 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/getc', __FILE__)
+
+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/rubyspec/core/argf/gets_spec.rb b/spec/rubyspec/core/argf/gets_spec.rb
new file mode 100644
index 0000000000..b65aa076bd
--- /dev/null
+++ b/spec/rubyspec/core/argf/gets_spec.rb
@@ -0,0 +1,51 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/gets', __FILE__)
+
+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
+
+ with_feature :encoding do
+ 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
+
+end
diff --git a/spec/rubyspec/core/argf/lineno_spec.rb b/spec/rubyspec/core/argf/lineno_spec.rb
new file mode 100644
index 0000000000..13b1916fb1
--- /dev/null
+++ b/spec/rubyspec/core/argf/lineno_spec.rb
@@ -0,0 +1,30 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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/rubyspec/core/argf/lines_spec.rb b/spec/rubyspec/core/argf/lines_spec.rb
new file mode 100644
index 0000000000..ea3578e3a2
--- /dev/null
+++ b/spec/rubyspec/core/argf/lines_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/each_line', __FILE__)
+
+describe "ARGF.lines" do
+ it_behaves_like :argf_each_line, :lines
+end
diff --git a/spec/rubyspec/core/argf/path_spec.rb b/spec/rubyspec/core/argf/path_spec.rb
new file mode 100644
index 0000000000..098de8693a
--- /dev/null
+++ b/spec/rubyspec/core/argf/path_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/filename', __FILE__)
+
+describe "ARGF.path" do
+ it_behaves_like :argf_filename, :path
+end
diff --git a/spec/rubyspec/core/argf/pos_spec.rb b/spec/rubyspec/core/argf/pos_spec.rb
new file mode 100644
index 0000000000..b6e5c3a254
--- /dev/null
+++ b/spec/rubyspec/core/argf/pos_spec.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/pos', __FILE__)
+
+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/rubyspec/core/argf/read_nonblock_spec.rb b/spec/rubyspec/core/argf/read_nonblock_spec.rb
new file mode 100644
index 0000000000..8176a206e5
--- /dev/null
+++ b/spec/rubyspec/core/argf/read_nonblock_spec.rb
@@ -0,0 +1,82 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/read', __FILE__)
+
+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
+ lambda {
+ @argf.read_nonblock(4)
+ }.should raise_error(IO::EAGAINWaitReadable)
+ end
+ end
+
+ ruby_version_is "2.3" do
+ 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
+end
diff --git a/spec/rubyspec/core/argf/read_spec.rb b/spec/rubyspec/core/argf/read_spec.rb
new file mode 100644
index 0000000000..4eaaea46bb
--- /dev/null
+++ b/spec/rubyspec/core/argf/read_spec.rb
@@ -0,0 +1,87 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/read', __FILE__)
+
+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
+
+ with_feature :encoding do
+
+ 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
+end
diff --git a/spec/rubyspec/core/argf/readchar_spec.rb b/spec/rubyspec/core/argf/readchar_spec.rb
new file mode 100644
index 0000000000..71e2a6c742
--- /dev/null
+++ b/spec/rubyspec/core/argf/readchar_spec.rb
@@ -0,0 +1,19 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/getc', __FILE__)
+
+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
+ lambda { while @argf.readchar; end }.should raise_error(EOFError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/readline_spec.rb b/spec/rubyspec/core/argf/readline_spec.rb
new file mode 100644
index 0000000000..d31cfce415
--- /dev/null
+++ b/spec/rubyspec/core/argf/readline_spec.rb
@@ -0,0 +1,23 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/gets', __FILE__)
+
+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
+ lambda { while @argf.readline; end }.should raise_error(EOFError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/readlines_spec.rb b/spec/rubyspec/core/argf/readlines_spec.rb
new file mode 100644
index 0000000000..8e68429aa8
--- /dev/null
+++ b/spec/rubyspec/core/argf/readlines_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/readlines', __FILE__)
+
+describe "ARGF.readlines" do
+ it_behaves_like :argf_readlines, :readlines
+end
diff --git a/spec/rubyspec/core/argf/readpartial_spec.rb b/spec/rubyspec/core/argf/readpartial_spec.rb
new file mode 100644
index 0000000000..61c330182c
--- /dev/null
+++ b/spec/rubyspec/core/argf/readpartial_spec.rb
@@ -0,0 +1,77 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/read', __FILE__)
+
+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
+ lambda { @argf.readpartial }.should raise_error(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
+
+ ruby_version_is "2.3" do
+ 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)
+ lambda { @argf.readpartial(1) }.should raise_error(EOFError)
+ lambda { @argf.readpartial(1) }.should raise_error(EOFError)
+ end
+ 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}", escape: true)
+ stdin.should == @stdin + "EOFError"
+ end
+end
diff --git a/spec/rubyspec/core/argf/rewind_spec.rb b/spec/rubyspec/core/argf/rewind_spec.rb
new file mode 100644
index 0000000000..d6abc3a856
--- /dev/null
+++ b/spec/rubyspec/core/argf/rewind_spec.rb
@@ -0,0 +1,39 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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
+ lambda { @argf.rewind }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/seek_spec.rb b/spec/rubyspec/core/argf/seek_spec.rb
new file mode 100644
index 0000000000..97dacb6cfc
--- /dev/null
+++ b/spec/rubyspec/core/argf/seek_spec.rb
@@ -0,0 +1,63 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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
+ lambda { @argf.seek }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/set_encoding_spec.rb b/spec/rubyspec/core/argf/set_encoding_spec.rb
new file mode 100644
index 0000000000..16d49a8c44
--- /dev/null
+++ b/spec/rubyspec/core/argf/set_encoding_spec.rb
@@ -0,0 +1,28 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+# These specs need to be run to a separate process as there is no way to reset ARGF encoding
+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
+ enc = ruby_exe('ARGF.set_encoding(Encoding::UTF_8); print ARGF.gets.encoding', args: [@file])
+ enc.should == "UTF-8"
+ end
+
+ it "sets the external encoding when passed an encoding name" do
+ enc = ruby_exe('ARGF.set_encoding("utf-8"); print ARGF.gets.encoding', args: [@file])
+ enc.should == "UTF-8"
+ end
+
+ it "sets the external, internal encoding when passed two encoding instances" do
+ enc = ruby_exe('ARGF.set_encoding(Encoding::UTF_8, Encoding::EUC_JP); print ARGF.gets.encoding', args: [@file])
+ enc.should == "EUC-JP"
+ end
+
+ it "sets the external, internal encoding when passed 'ext:int' String" do
+ enc = ruby_exe('ARGF.set_encoding("utf-8:euc-jp"); print ARGF.gets.encoding', args: [@file])
+ enc.should == "EUC-JP"
+ end
+end
diff --git a/spec/rubyspec/core/argf/shared/each_byte.rb b/spec/rubyspec/core/argf/shared/each_byte.rb
new file mode 100644
index 0000000000..6b1dc1dae2
--- /dev/null
+++ b/spec/rubyspec/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 be_an_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 be_an_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/rubyspec/core/argf/shared/each_char.rb b/spec/rubyspec/core/argf/shared/each_char.rb
new file mode 100644
index 0000000000..9e333ecc5b
--- /dev/null
+++ b/spec/rubyspec/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 be_an_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 be_an_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/rubyspec/core/argf/shared/each_codepoint.rb b/spec/rubyspec/core/argf/shared/each_codepoint.rb
new file mode 100644
index 0000000000..e2a2dfff46
--- /dev/null
+++ b/spec/rubyspec/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 be_an_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 be_an_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/rubyspec/core/argf/shared/each_line.rb b/spec/rubyspec/core/argf/shared/each_line.rb
new file mode 100644
index 0000000000..c0ef77dc54
--- /dev/null
+++ b/spec/rubyspec/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 be_an_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/rubyspec/core/argf/shared/eof.rb b/spec/rubyspec/core/argf/shared/eof.rb
new file mode 100644
index 0000000000..bba18ede50
--- /dev/null
+++ b/spec/rubyspec/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
+ lambda { @argf.send(@method) }.should raise_error(IOError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/shared/filename.rb b/spec/rubyspec/core/argf/shared/filename.rb
new file mode 100644
index 0000000000..f47c673dc0
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/shared/fileno.rb b/spec/rubyspec/core/argf/shared/fileno.rb
new file mode 100644
index 0000000000..891e250ad9
--- /dev/null
+++ b/spec/rubyspec/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 == [Fixnum, Fixnum, Fixnum, Fixnum]
+ end
+ end
+
+ it "raises an ArgumentError when called on a closed stream" do
+ argf [@file1] do
+ @argf.read
+ lambda { @argf.send(@method) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/shared/getc.rb b/spec/rubyspec/core/argf/shared/getc.rb
new file mode 100644
index 0000000000..8be39c60b6
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/shared/gets.rb b/spec/rubyspec/core/argf/shared/gets.rb
new file mode 100644
index 0000000000..160d24c27b
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/shared/pos.rb b/spec/rubyspec/core/argf/shared/pos.rb
new file mode 100644
index 0000000000..f7184f3d7c
--- /dev/null
+++ b/spec/rubyspec/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
+ lambda { @argf.send(@method) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/shared/read.rb b/spec/rubyspec/core/argf/shared/read.rb
new file mode 100644
index 0000000000..fe903983c0
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/shared/readlines.rb b/spec/rubyspec/core/argf/shared/readlines.rb
new file mode 100644
index 0000000000..505fa94acb
--- /dev/null
+++ b/spec/rubyspec/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/rubyspec/core/argf/skip_spec.rb b/spec/rubyspec/core/argf/skip_spec.rb
new file mode 100644
index 0000000000..5f5e9eb79a
--- /dev/null
+++ b/spec/rubyspec/core/argf/skip_spec.rb
@@ -0,0 +1,42 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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
+ lambda { ARGF.class.new(@file1_name).skip }.should_not raise_error
+ end
+end
diff --git a/spec/rubyspec/core/argf/tell_spec.rb b/spec/rubyspec/core/argf/tell_spec.rb
new file mode 100644
index 0000000000..bcd824f087
--- /dev/null
+++ b/spec/rubyspec/core/argf/tell_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/pos', __FILE__)
+
+describe "ARGF.tell" do
+ it_behaves_like :argf_pos, :tell
+end
diff --git a/spec/rubyspec/core/argf/to_a_spec.rb b/spec/rubyspec/core/argf/to_a_spec.rb
new file mode 100644
index 0000000000..75b5c10c9b
--- /dev/null
+++ b/spec/rubyspec/core/argf/to_a_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/readlines', __FILE__)
+
+describe "ARGF.to_a" do
+ it_behaves_like :argf_readlines, :to_a
+end
diff --git a/spec/rubyspec/core/argf/to_i_spec.rb b/spec/rubyspec/core/argf/to_i_spec.rb
new file mode 100644
index 0000000000..27359014af
--- /dev/null
+++ b/spec/rubyspec/core/argf/to_i_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/fileno', __FILE__)
+
+describe "ARGF.to_i" do
+ it_behaves_like :argf_fileno, :to_i
+end
diff --git a/spec/rubyspec/core/argf/to_io_spec.rb b/spec/rubyspec/core/argf/to_io_spec.rb
new file mode 100644
index 0000000000..0575c35f25
--- /dev/null
+++ b/spec/rubyspec/core/argf/to_io_spec.rb
@@ -0,0 +1,23 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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 be_kind_of(IO) }
+ result[0].should == result[1]
+ result[2].should == result[3]
+ end
+ end
+end
diff --git a/spec/rubyspec/core/argf/to_s_spec.rb b/spec/rubyspec/core/argf/to_s_spec.rb
new file mode 100644
index 0000000000..0128049c3f
--- /dev/null
+++ b/spec/rubyspec/core/argf/to_s_spec.rb
@@ -0,0 +1,14 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+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