From 57aef4bc6440481ea1401f433c4322c4d5f3cd8d Mon Sep 17 00:00:00 2001
From: Laurent Julliard <laurent@moldus.org>
Date: Sat, 12 Jul 2008 19:04:19 +0200
Subject: [PATCH] Initial version of ARGF specs.

* All ARGF class methods are tested except the bimode method because
  it is almost imossible to test on 1.8.x (1.9.x improves on this)
* All tests pass OK on MRI 1.8.6 Linux Ubuntu.
* IMPORTANT NOTE to other committers: Do not modify the content
  of the fixture files as many tests depend on it
---
 1.8/core/argf/close_spec.rb       |   29 ++++++++
 1.8/core/argf/closed_spec.rb      |   35 +++++++++
 1.8/core/argf/each_byte_spec.rb   |   25 +++++++
 1.8/core/argf/each_line_spec.rb   |    7 ++
 1.8/core/argf/each_spec.rb        |    7 ++
 1.8/core/argf/eof_spec.rb         |   11 +++
 1.8/core/argf/file_spec.rb        |   30 ++++++++
 1.8/core/argf/filename_spec.rb    |    7 ++
 1.8/core/argf/fileno_spec.rb      |    7 ++
 1.8/core/argf/fixtures/classes.rb |   16 ++++
 1.8/core/argf/fixtures/file1.txt  |    2 +
 1.8/core/argf/fixtures/file2.txt  |    2 +
 1.8/core/argf/fixtures/stdin.txt  |    2 +
 1.8/core/argf/getc_spec.rb        |   33 +++++++++
 1.8/core/argf/gets_spec.rb        |  142 +++++++++++++++++++++++++++++++++++++
 1.8/core/argf/lineno_spec.rb      |   38 ++++++++++
 1.8/core/argf/path_spec.rb        |    7 ++
 1.8/core/argf/pos_spec.rb         |   42 +++++++++++
 1.8/core/argf/read_spec.rb        |  128 +++++++++++++++++++++++++++++++++
 1.8/core/argf/readchar_spec.rb    |   33 +++++++++
 1.8/core/argf/readline_spec.rb    |  129 +++++++++++++++++++++++++++++++++
 1.8/core/argf/readlines_spec.rb   |    7 ++
 1.8/core/argf/rewind_spec.rb      |   39 ++++++++++
 1.8/core/argf/seek_spec.rb        |   65 +++++++++++++++++
 1.8/core/argf/shared/each_line.rb |   26 +++++++
 1.8/core/argf/shared/eof.rb       |   37 ++++++++++
 1.8/core/argf/shared/filename.rb  |   47 ++++++++++++
 1.8/core/argf/shared/fileno.rb    |   37 ++++++++++
 1.8/core/argf/shared/pos.rb       |   39 ++++++++++
 1.8/core/argf/shared/readlines.rb |   33 +++++++++
 1.8/core/argf/skip_spec.rb        |   45 ++++++++++++
 1.8/core/argf/tell_spec.rb        |    7 ++
 1.8/core/argf/to_a_spec.rb        |    7 ++
 1.8/core/argf/to_i_spec.rb        |    7 ++
 1.8/core/argf/to_io_spec.rb       |   38 ++++++++++
 35 files changed, 1166 insertions(+), 0 deletions(-)
 create mode 100644 1.8/core/argf/close_spec.rb
 create mode 100644 1.8/core/argf/closed_spec.rb
 create mode 100644 1.8/core/argf/each_byte_spec.rb
 create mode 100644 1.8/core/argf/each_line_spec.rb
 create mode 100644 1.8/core/argf/each_spec.rb
 create mode 100644 1.8/core/argf/eof_spec.rb
 create mode 100644 1.8/core/argf/file_spec.rb
 create mode 100644 1.8/core/argf/filename_spec.rb
 create mode 100644 1.8/core/argf/fileno_spec.rb
 create mode 100644 1.8/core/argf/fixtures/classes.rb
 create mode 100644 1.8/core/argf/fixtures/file1.txt
 create mode 100644 1.8/core/argf/fixtures/file2.txt
 create mode 100644 1.8/core/argf/fixtures/stdin.txt
 create mode 100644 1.8/core/argf/getc_spec.rb
 create mode 100644 1.8/core/argf/gets_spec.rb
 create mode 100644 1.8/core/argf/lineno_spec.rb
 create mode 100644 1.8/core/argf/path_spec.rb
 create mode 100644 1.8/core/argf/pos_spec.rb
 create mode 100644 1.8/core/argf/read_spec.rb
 create mode 100644 1.8/core/argf/readchar_spec.rb
 create mode 100644 1.8/core/argf/readline_spec.rb
 create mode 100644 1.8/core/argf/readlines_spec.rb
 create mode 100644 1.8/core/argf/rewind_spec.rb
 create mode 100644 1.8/core/argf/seek_spec.rb
 create mode 100644 1.8/core/argf/shared/each_line.rb
 create mode 100644 1.8/core/argf/shared/eof.rb
 create mode 100644 1.8/core/argf/shared/filename.rb
 create mode 100644 1.8/core/argf/shared/fileno.rb
 create mode 100644 1.8/core/argf/shared/pos.rb
 create mode 100644 1.8/core/argf/shared/readlines.rb
 create mode 100644 1.8/core/argf/skip_spec.rb
 create mode 100644 1.8/core/argf/tell_spec.rb
 create mode 100644 1.8/core/argf/to_a_spec.rb
 create mode 100644 1.8/core/argf/to_i_spec.rb
 create mode 100644 1.8/core/argf/to_io_spec.rb

diff --git a/1.8/core/argf/close_spec.rb b/1.8/core/argf/close_spec.rb
new file mode 100644
index 0000000..3d3529f
--- /dev/null
+++ b/1.8/core/argf/close_spec.rb
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.close" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "closes the current file and read the next one" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.close
+    ARGF.read.should == @contents_file2
+  end
+  
+  it "reads one line from the first file, closes it and read the next one" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.gets.should == @contents_file1.split($/).first+$/
+    ARGF.close
+    ARGF.read.should == @contents_file2
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/closed_spec.rb b/1.8/core/argf/closed_spec.rb
new file mode 100644
index 0000000..57b6a4b
--- /dev/null
+++ b/1.8/core/argf/closed_spec.rb
@@ -0,0 +1,35 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.closed?" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "says it is closed " do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    res = []
+    3.times do
+      res << ARGF.closed?
+      ARGF.gets
+      ARGF.gets
+    end
+    res << ARGF.closed?
+    ARGF.gets
+    res << ARGF.closed?
+
+    res.should == [false, false, false, false, true]
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/each_byte_spec.rb b/1.8/core/argf/each_byte_spec.rb
new file mode 100644
index 0000000..0d4fa58
--- /dev/null
+++ b/1.8/core/argf/each_byte_spec.rb
@@ -0,0 +1,25 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.each_byte" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "reads each byte of files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    byte_list = []
+    ARGF.each_byte { |b| byte_list << b }
+    byte_list.should == (@contents_file1 + @contents_file2 + @contents_stdin).split('').collect { |c| c[0]} # ord
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/each_line_spec.rb b/1.8/core/argf/each_line_spec.rb
new file mode 100644
index 0000000..4c8760b
--- /dev/null
+++ b/1.8/core/argf/each_line_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/each_line'
+
+describe "ARGF.each_line" do
+  it_behaves_like(:argf_each_line, :each_line)
+end
diff --git a/1.8/core/argf/each_spec.rb b/1.8/core/argf/each_spec.rb
new file mode 100644
index 0000000..449fce1
--- /dev/null
+++ b/1.8/core/argf/each_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/each_line'
+
+describe "ARGF.each" do
+  it_behaves_like(:argf_each_line, :each)
+end
diff --git a/1.8/core/argf/eof_spec.rb b/1.8/core/argf/eof_spec.rb
new file mode 100644
index 0000000..767bec5
--- /dev/null
+++ b/1.8/core/argf/eof_spec.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/eof'
+
+describe "ARGF.eof" do
+  it_behaves_like(:argf_eof, :eof)
+end
+
+describe "ARGF.eof?" do
+  it_behaves_like(:argf_eof, :eof?)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/file_spec.rb b/1.8/core/argf/file_spec.rb
new file mode 100644
index 0000000..972b21e
--- /dev/null
+++ b/1.8/core/argf/file_spec.rb
@@ -0,0 +1,30 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.file" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "returns the current file object on each file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    res = []
+    # returns first current file even when not yet open
+    begin
+      res << ARGF.file.path
+    end while ARGF.gets
+    # returns last current file even when closed
+    res << ARGF.file.path
+    res.should == %w{file1 file1 file1 file2 file2 file2}.collect { |bn| File.join(File.dirname(__FILE__), 'fixtures', bn+'.txt')}
+  end
+
+end
\ No newline at end of file
diff --git a/1.8/core/argf/filename_spec.rb b/1.8/core/argf/filename_spec.rb
new file mode 100644
index 0000000..0ff4c29
--- /dev/null
+++ b/1.8/core/argf/filename_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/filename'
+
+describe "ARGF.filename" do
+  it_behaves_like(:argf_filename, :filename)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/fileno_spec.rb b/1.8/core/argf/fileno_spec.rb
new file mode 100644
index 0000000..49ef53f
--- /dev/null
+++ b/1.8/core/argf/fileno_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/fileno'
+
+describe "ARGF.fileno" do
+  it_behaves_like(:argf_fileno, :fileno)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/fixtures/classes.rb b/1.8/core/argf/fixtures/classes.rb
new file mode 100644
index 0000000..69e3704
--- /dev/null
+++ b/1.8/core/argf/fixtures/classes.rb
@@ -0,0 +1,16 @@
+module ARGFSpecs
+  
+  def self.file_args(*args)
+    files = args.collect do |filename|
+      # if STDIN or abslute path then return as is
+      # else append the fixture path to the file
+      if filename == '-' || filename[0..0] == '/' 
+        filename
+      else
+        File.join(File.dirname(__FILE__),filename)
+      end
+    end
+    ARGV.concat(files)
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/fixtures/file1.txt b/1.8/core/argf/fixtures/file1.txt
new file mode 100644
index 0000000..1c89bfb
--- /dev/null
+++ b/1.8/core/argf/fixtures/file1.txt
@@ -0,0 +1,2 @@
+file1.1
+file1.2
diff --git a/1.8/core/argf/fixtures/file2.txt b/1.8/core/argf/fixtures/file2.txt
new file mode 100644
index 0000000..62e8dba
--- /dev/null
+++ b/1.8/core/argf/fixtures/file2.txt
@@ -0,0 +1,2 @@
+line2.1
+line2.2
diff --git a/1.8/core/argf/fixtures/stdin.txt b/1.8/core/argf/fixtures/stdin.txt
new file mode 100644
index 0000000..063cdcb
--- /dev/null
+++ b/1.8/core/argf/fixtures/stdin.txt
@@ -0,0 +1,2 @@
+stdin.1
+stdin.2
diff --git a/1.8/core/argf/getc_spec.rb b/1.8/core/argf/getc_spec.rb
new file mode 100644
index 0000000..747f45c
--- /dev/null
+++ b/1.8/core/argf/getc_spec.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.getc" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "reads each char of files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    stg = ""
+    while c = ARGF.getc
+      stg << c
+    end
+    stg.should == @contents_file1 + @contents_file2 + @contents_stdin
+  end
+  
+  it "returns nil when end of stream reached" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ARGF.read # read all files at once
+    ARGF.getc.should == nil
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/gets_spec.rb b/1.8/core/argf/gets_spec.rb
new file mode 100644
index 0000000..3dbc51d
--- /dev/null
+++ b/1.8/core/argf/gets_spec.rb
@@ -0,0 +1,142 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.gets" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ORIG_STDOUT = STDOUT
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+    STDOUT.reopen(ORIG_STDOUT) unless STDOUT == ORIG_STDOUT
+  end
+  
+  it "reads one line of a file" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.gets().should == @contents_file1.split($/).first+$/
+  end
+  
+  it "reads all lines of a file" do
+    ARGFSpecs.file_args('file1.txt')
+    number_of_lines = @contents_file1.split($/).size
+    all_lines = []
+    for i in 1..number_of_lines
+      all_lines << ARGF.gets()
+    end
+    all_lines.should == @contents_file1.split($/).collect { |l| l+$/ }
+  end
+  
+  it "reads all lines of stdin" do
+    ARGFSpecs.file_args('-')
+    number_of_lines = @contents_stdin.split($/).size
+    all_lines = []
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    for i in 1..number_of_lines
+      all_lines << ARGF.gets()
+    end
+    all_lines.should == @contents_stdin.split($/).collect { |l| l+$/ }
+  end
+  
+  it "reads all lines of two files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    number_of_lines = @contents_file1.split($/).size + @contents_file2.split($/).size
+    all_lines = []
+    for i in 1..number_of_lines
+      all_lines << ARGF.gets()
+    end
+    all_lines.should == (@contents_file1+ @contents_file2).split($/).collect { |l| l+$/ }
+  end
+  
+  it "returns nil when reaching end of files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    number_of_lines = @contents_file1.split($/).size + @contents_file2.split($/).size
+    for i in 1..number_of_lines
+      ARGF.gets()
+    end
+    ARGF.gets.should == nil
+  end
+  
+  it "sets $_ global variable with each line read" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    while line = ARGF.gets
+      $_.should == line
+    end
+  end
+  
+  # Note: this test will only work on platforms that is capable of doing
+  # safe rename. Unfortunately there is no method in 1.8.x to test that.
+  # This has been corrected in Ruby 1.9.x
+  it "modifies the files when in place edit mode is on" do
+    # create fixture files that can be altered
+    file1 = tmp('file1.txt'); file2 = tmp('file2.txt'); file3 = tmp('file3.txt')
+    File.open(file1,'w') { |fh| fh.write(@contents_file1) }
+    File.open(file2,'w') { |fh| fh.write(@contents_file2) }
+    File.open(file3,'w') { } # touch
+    ARGV.concat([file1, file2, file3])
+    $-i = ""  # activate in place edit mode no backup 
+    
+    modified_lines = []
+    while line = ARGF.gets
+      modified_line = line.chomp+'.new'+$/
+      modified_lines << modified_line
+      print modified_line
+    end
+    
+    # TODO: I could not find a way to test the changes on the last file
+    # its content seems to be written only when the ruby process terminates
+    # i tried various combination of flush, close on ARGF and STDOUT but could
+    # fix the problem. 
+    # Workaround: add a third empty file on the command line
+    contents_modified_files = File.read(file1) + File.read(file2)
+    contents_modified_files.should == modified_lines.join
+    
+    # cleanup the mess
+    [file1, file2, file3].each { |f| File.delete(f) if File.exists?(f) }
+    
+    # disable in place edit mode
+    $-i = nil
+  end
+  
+  
+  it "modifies and backups two files when in place edit mode is on" do
+    # create fixture files that can be altered
+    file1 = tmp('file1.txt'); file2 = tmp('file2.txt'); file3 = tmp('file3.txt')
+    File.open(file1,'w') { |fh| fh.write(@contents_file1) }
+    File.open(file2,'w') { |fh| fh.write(@contents_file2) }
+    File.open(file3,'w') { } # touch
+    ARGV.concat([file1, file2, file3])
+    $-i = ".bak"  # activate in place edit mode with backup
+    
+    modified_lines = []
+    
+    while line = ARGF.gets
+      modified_line = line.chomp+'.new'+$/
+      modified_lines << modified_line
+      print modified_line
+    end
+    
+    # TODO: I could not find a way to test the changes on the last file
+    # its content seems to be written only when the ruby process terminates
+    # i tried various combination of flush, close on ARGF and STDOUT but could
+    # fix the problem. 
+    # Workaround: add a third empty file on the command line
+    File.exists?(file1+$-i).should == true
+    File.exists?(file2+$-i).should == true
+    File.read(file1+$-i).should == @contents_file1
+    File.read(file2+$-i).should == @contents_file2
+    contents_modified_files = File.read(file1) + File.read(file2)
+    contents_modified_files.should == modified_lines.join
+    
+    # cleanup the mess
+    [file1, file2, file3, file1+$-i, file2+$-i, file3+$-i].each { |f| File.delete(f) if File.exists?(f)}
+    
+    # disable in place edit mode
+    $-i = nil
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/lineno_spec.rb b/1.8/core/argf/lineno_spec.rb
new file mode 100644
index 0000000..4e0cf47
--- /dev/null
+++ b/1.8/core/argf/lineno_spec.rb
@@ -0,0 +1,38 @@
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.lineno" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "returns the current line number on each file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', 'file1.txt', 'file2.txt')
+    res = []
+    
+    ARGF.gets; res << ARGF.lineno # 1
+    ARGF.gets; res << ARGF.lineno # 2
+    ARGF.gets; res << ARGF.lineno # 3
+    ARGF.gets; res << ARGF.lineno # 4
+    ARGF.rewind; res << ARGF.lineno # 4
+    ARGF.gets; res << ARGF.lineno # 3
+    ARGF.lineno = 1000; res << $.
+    ARGF.gets; res << $. # 1001
+    ARGF.gets; res << $. # 1002
+    $. = 2000
+    ARGF.gets; res << $. # 2001
+    ARGF.gets; res << $. # 2002
+    ARGF.read; res << $. # 2002 (beyond end of stream)
+
+    res.should == [1, 2, 3, 4, 4, 3, 1000, 1001, 1002, 2001, 2002, 2002]
+  end
+
+end
\ No newline at end of file
diff --git a/1.8/core/argf/path_spec.rb b/1.8/core/argf/path_spec.rb
new file mode 100644
index 0000000..6cd8c1f
--- /dev/null
+++ b/1.8/core/argf/path_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/filename'
+
+describe "ARGF.path" do
+  it_behaves_like(:argf_filename, :path)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/pos_spec.rb b/1.8/core/argf/pos_spec.rb
new file mode 100644
index 0000000..1fb574c
--- /dev/null
+++ b/1.8/core/argf/pos_spec.rb
@@ -0,0 +1,42 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/pos'
+
+describe "ARGF.pos" do
+  it_behaves_like(:argf_pos, :pos)
+end
+
+describe "ARGF.pos=" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+    
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "sets the correct position in files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    linef1_1, linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+    linef2_1, linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+
+    res =[]
+    ARGF.pos = linef1_1.size; res << ARGF.gets
+    ARGF.pos = 0; res << ARGF.gets
+    ARGF.gets # finish reading file1
+    ARGF.gets
+    ARGF.pos = 1; res << ARGF.gets
+    ARGF.pos = linef2_1.size + linef2_2.size - 1; res << ARGF.gets
+    ARGF.pos = 1000; res << ARGF.read
+
+    res.should == [linef1_2, linef1_1, linef2_1[1..-1], linef2_2[-1,1], ""]
+    
+  end
+  
+
+end
\ No newline at end of file
diff --git a/1.8/core/argf/read_spec.rb b/1.8/core/argf/read_spec.rb
new file mode 100644
index 0000000..5b62621
--- /dev/null
+++ b/1.8/core/argf/read_spec.rb
@@ -0,0 +1,128 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.read" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "reads the contents of a file" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.read().should == @contents_file1
+  end
+
+  it "treats first nil argument as no length limit" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.read(nil).should == @contents_file1
+  end
+  
+  it "treats second nil argument as no output buffer" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.read(nil, nil).should == @contents_file1
+  end
+  
+  it "treats second argument as an output buffer" do
+    ARGFSpecs.file_args('file1.txt')
+    buffer = ""
+    ARGF.read(nil, buffer)
+    buffer.should == @contents_file1
+  end
+  
+  it "reads a number of bytes from the first file" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.read(5).should == @contents_file1[0,5]
+  end
+  
+  it "reads from a single file consecutively" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.read(1).should == @contents_file1[0,1]
+    ARGF.read(2).should == @contents_file1[1,2]
+    ARGF.read(3).should == @contents_file1[3,3]
+  end
+  
+  it "reads the contents of two files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.read.should ==  @contents_file1 + @contents_file2
+  end
+  
+  it "reads the contents of one file and some characters from the second" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    len = @contents_file1.size + @contents_file2.size/2
+    ARGF.read(len).should ==  (@contents_file1 + @contents_file2)[0,len]
+  end
+  
+  it "reads across two files consecutively" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.read(@contents_file1.length-2 ).should == @contents_file1[0..-3]
+    ARGF.read(2+5).should == @contents_file1[-2..-1] + @contents_file2[0,5]
+  end
+  
+  it "reads the contents of stdin" do
+    ARGFSpecs.file_args('-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ARGF.read.should ==  @contents_stdin
+  end
+  
+  it "reads a number of bytes from stdin" do
+    ARGFSpecs.file_args('-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ARGF.read(10).should ==  @contents_stdin[0,10]
+  end
+  
+  it "reads a number of bytes from stdin" do
+    ARGFSpecs.file_args('-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ARGF.read(10).should ==  @contents_stdin[0,10]
+  end
+  
+  it "reads the contents of one file and stdin" do
+    ARGFSpecs.file_args('file1.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    ARGF.read.should ==  @contents_file1 + @contents_stdin
+  end
+  
+  it "reads the contents of the same file twice" do
+    ARGFSpecs.file_args('file1.txt', 'file1.txt')
+    ARGF.read.should ==  @contents_file1 + @contents_file1
+  end
+  
+  it "raises an IOError when contents read from stdin twice" do
+    ARGFSpecs.file_args('-', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    str = ""
+    lambda { str = ARGF.read }.should raise_error(IOError)
+    str.should ==  ""
+  end
+  
+  not_supported_on :windows do  
+    it "reads the contents of a special device file" do
+      ARGFSpecs.file_args('/dev/zero')
+      ARGF.read(100).should ==  "\000" * 100
+    end
+  end
+  
+  it "empties the files if in place edit mode is enabled and no output is generated" do
+    # create fixture files that can be altered
+    file1 = tmp('file1.txt'); file2 = tmp('file2.txt')
+    File.open(file1,'w') { |fh| fh.write(@contents_file1) }
+    File.open(file2,'w') { |fh| fh.write(@contents_file2) }
+    ARGV.concat([file1, file2])
+    $-i = ""  # activate in place edit mode
+    ARGF.read.should ==  @contents_file1 + @contents_file2
+    File.stat(file1).size.should == 0
+    File.stat(file2).size.should == 0
+    # cleanup the mess
+    [file1, file2, file1+$-i, file2+$-i].each { |f| File.delete(f) if File.exists?(f)}
+    # disable in place edit mode
+    $-i = nil
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/readchar_spec.rb b/1.8/core/argf/readchar_spec.rb
new file mode 100644
index 0000000..7bfbb3e
--- /dev/null
+++ b/1.8/core/argf/readchar_spec.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.readchar" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "reads each char of files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    total_len = @contents_file1.size + @contents_file2.size + @contents_stdin.size
+    stg = ""
+    for i in 1..total_len
+        stg << ARGF.readchar
+    end
+    stg.should == @contents_file1 + @contents_file2 + @contents_stdin
+  end
+  
+  it "raises EOFError when end of stream reached" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    lambda { while c = ARGF.readchar;end }.should raise_error(EOFError)
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/readline_spec.rb b/1.8/core/argf/readline_spec.rb
new file mode 100644
index 0000000..fcc0126
--- /dev/null
+++ b/1.8/core/argf/readline_spec.rb
@@ -0,0 +1,129 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.readline" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+    @contents_stdin = File.read(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "reads one line of a file" do
+    ARGFSpecs.file_args('file1.txt')
+    ARGF.readline().should == @contents_file1.split($/).first+$/
+  end
+  
+  it "reads all lines of a file" do
+    ARGFSpecs.file_args('file1.txt')
+    number_of_lines = @contents_file1.split($/).size
+    all_lines = []
+    for i in 1..number_of_lines
+      all_lines << ARGF.readline()
+    end
+    all_lines.should == @contents_file1.split($/).collect { |l| l+$/ }
+  end
+  
+  it "reads all lines of stdin" do
+    ARGFSpecs.file_args('-')
+    number_of_lines = @contents_stdin.split($/).size
+    all_lines = []
+    STDIN.reopen(File.dirname(__FILE__) + '/fixtures/stdin.txt')
+    for i in 1..number_of_lines
+      all_lines << ARGF.readline()
+    end
+    all_lines.should == @contents_stdin.split($/).collect { |l| l+$/ }
+  end
+  
+  it "reads all lines of two files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    number_of_lines = @contents_file1.split($/).size + @contents_file2.split($/).size
+    all_lines = []
+    for i in 1..number_of_lines
+      all_lines << ARGF.readline()
+    end
+    all_lines.should == (@contents_file1+ @contents_file2).split($/).collect { |l| l+$/ }
+  end
+  
+  it "raises an EOFError when reaching end of files" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    lambda { while line = ARGF.readline;end }.should raise_error(EOFError)
+  end
+  
+  # Note: this test will only work on platforms that is capable of doing
+  # safe rename. Unfortunately there is no method in 1.8.X to test that.
+  # This has been corrected in Ruby 1.9.x
+  it "modifies the files when in place edit mode is on" do
+    # create fixture files that can be altered
+    file1 = tmp('file1.txt'); file2 = tmp('file2.txt'); file3 = tmp('file3.txt')
+    File.open(file1,'w') { |fh| fh.write(@contents_file1) }
+    File.open(file2,'w') { |fh| fh.write(@contents_file2) }
+    File.open(file3,'w') { } # touch
+    ARGV.concat([file1, file2, file3])
+    $-i = ""  # activate in place edit mode
+    
+    modified_lines = []
+    begin
+      while line = ARGF.readline
+        modified_line = line+'.new'+$/
+        modified_lines << modified_line
+        print modified_line
+      end
+    rescue EOFError
+      # TODO: I could not find a way to test the changes on the last file
+      # its content seems to be written only when the ruby process terminates
+      # i tried various combination of flush, close on ARGF and STDOUT but could
+      # fix the problem. 
+      # Workaround: add a third empty file on the command line
+      contents_modified_files = File.read(file1) + File.read(file2)
+      contents_modified_files.should == modified_lines.join
+    ensure
+      # cleanup the mess
+      [file1, file2, file3].each { |f| File.delete(f) if File.exists?(f)}
+      # disable in place edit mode
+      $-i = nil      
+    end
+  end
+  
+    it "modifies an backups two files when in place edit mode is on" do
+    # create fixture files that can be altered
+    file1 = tmp('file1.txt'); file2 = tmp('file2.txt'); file3 = tmp('file3.txt')
+    File.open(file1,'w') { |fh| fh.write(@contents_file1) }
+    File.open(file2,'w') { |fh| fh.write(@contents_file2) }
+    File.open(file3,'w') { } # touch
+    ARGV.concat([file1, file2, file3])
+    $-i = ".bak"  # activate in place edit mode with backup
+    
+    modified_lines = []
+    begin
+      while line = ARGF.readline
+        modified_line = line+'.new'+$/
+        modified_lines << modified_line
+        print modified_line
+      end
+    rescue EOFError
+      # TODO: I could not find a way to test the changes on the last file
+      # its content seems to be written only when the ruby process terminates
+      # i tried various combination of flush, close on ARGF and STDOUT but could
+      # fix the problem. 
+      # Workaround: add a third empty file on the command line
+      File.exists?(file1+$-i).should == true
+      File.exists?(file2+$-i).should == true
+      File.read(file1+$-i).should == @contents_file1
+      File.read(file2+$-i).should == @contents_file2
+      contents_modified_files = File.read(file1) + File.read(file2)
+      contents_modified_files.should == modified_lines.join
+    ensure
+      # cleanup the mess
+      [file1, file2, file3, file1+$-i, file2+$-i, file3+$-i].each { |f| File.delete(f) if File.exists?(f)}
+      # disable in place edit mode
+      $-i = nil
+    end
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/readlines_spec.rb b/1.8/core/argf/readlines_spec.rb
new file mode 100644
index 0000000..85b51ee
--- /dev/null
+++ b/1.8/core/argf/readlines_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/readlines'
+
+describe "ARGF.readlines" do
+  it_behaves_like(:argf_readlines, :readlines)
+end
diff --git a/1.8/core/argf/rewind_spec.rb b/1.8/core/argf/rewind_spec.rb
new file mode 100644
index 0000000..d28ef08
--- /dev/null
+++ b/1.8/core/argf/rewind_spec.rb
@@ -0,0 +1,39 @@
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.rewind" do
+  before :each do
+    ARGV.clear
+    @contents_file1 = File.read(File.dirname(__FILE__) + '/fixtures/file1.txt')    
+    @contents_file2 = File.read(File.dirname(__FILE__) + '/fixtures/file2.txt')
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+    
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "goes back to beginning of current file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    linef1_1, linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+    linef2_1, linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+
+    res =[]
+    ARGF.gets;
+    ARGF.rewind; res << ARGF.gets
+    ARGF.gets # finish reading file1
+    ARGF.gets
+    ARGF.rewind; res << ARGF.gets
+
+    res.should == [linef1_1, linef2_1]
+    
+  end
+  
+  it "raises ArgumentError when end of stream reached" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.read 
+    lambda { ARGF.rewind }.should raise_error(ArgumentError)
+  end
+
+end
\ No newline at end of file
diff --git a/1.8/core/argf/seek_spec.rb b/1.8/core/argf/seek_spec.rb
new file mode 100644
index 0000000..4a37ecf
--- /dev/null
+++ b/1.8/core/argf/seek_spec.rb
@@ -0,0 +1,65 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.seek" do
+  before :each do
+    ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/fixtures/file2.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+
+  it "sets the correct absolute position relative to beginning of file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    linef1_1, linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+    linef2_1, linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+
+    res =[]
+    ARGF.seek(2); res << ARGF.gets
+    ARGF.seek(linef1_1.size); res << ARGF.gets
+    ARGF.seek(0, IO::SEEK_END); res << ARGF.gets
+
+    res.should == [linef1_1[2..-1], linef1_2, linef2_1]
+  end
+  
+  it "sets the correct position relative to current position in file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    linef1_1, linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+    linef2_1, linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+
+    res =[]
+    ARGF.seek(0, IO::SEEK_CUR); res << ARGF.gets
+    ARGF.seek(-linef1_1.size+2, IO::SEEK_CUR); res << ARGF.gets
+    ARGF.seek(1, IO::SEEK_CUR); res << ARGF.gets
+    ARGF.seek(3, IO::SEEK_CUR); res << ARGF.gets # seek doesn't go beyond file limit
+    ARGF.seek(linef1_2.size, IO::SEEK_CUR); res << ARGF.gets 
+
+    res.should == [linef1_1, linef1_1[2..-1], linef1_2[1..-1], linef2_1, nil]
+  end
+  
+  it "sets the correct absolute position relative to end of file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    linef1_1, linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+    linef2_1, linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+
+    res =[]
+    ARGF.seek(-linef1_1.size-linef1_2.size, IO::SEEK_END); res << ARGF.gets
+    ARGF.seek(-6, IO::SEEK_END); res << ARGF.gets
+    ARGF.seek(-4, IO::SEEK_END); res << ARGF.gets
+    res << ARGF.gets
+    ARGF.seek(-6, IO::SEEK_END); res << ARGF.gets
+
+    res.should == [linef1_1, linef1_2[-6..-1], linef1_2[4..-1], linef2_1, linef2_2[-6..-1]]
+  end
+  
+  it "takes at least one argument (offset)" do
+    lambda { ARGF.seek() }.should raise_error(ArgumentError)
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/each_line.rb b/1.8/core/argf/shared/each_line.rb
new file mode 100644
index 0000000..d9f5706
--- /dev/null
+++ b/1.8/core/argf/shared/each_line.rb
@@ -0,0 +1,26 @@
+shared :argf_each_line do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @stdin = File.dirname(__FILE__) + '/../fixtures/stdin.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @contents_stdin = File.read(@stdin)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    it "reads each line of files" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+      STDIN.reopen(@stdin)
+      line_list = []
+      ARGF.send(cmd) { |b| line_list << b }
+      line_list.should == (@contents_file1 + @contents_file2 + @contents_stdin).split($/).collect { |l| l+$/} # ord
+    end
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/eof.rb b/1.8/core/argf/shared/eof.rb
new file mode 100644
index 0000000..b57cce1
--- /dev/null
+++ b/1.8/core/argf/shared/eof.rb
@@ -0,0 +1,37 @@
+shared :argf_eof do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @stdin = File.dirname(__FILE__) + '/../fixtures/stdin.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @contents_stdin = File.read(@stdin)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    # NOTE: this test assumes that fixtures files have two lines each
+    # SO DO NOT modify the fixture files!!!
+    it "returns true when reaching the end of a file" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+      STDIN.reopen(@stdin)
+      res = []
+      # should say false, true alternatively with 2 line files  
+      while ARGF.gets
+        res << ARGF.send(cmd)
+      end
+      res.should == [false, true, false, true, false, true]
+    end
+  
+    it "raises IOError when called on a closed stream" do
+      ARGFSpecs.file_args('file1.txt')
+      ARGF.read # read everything at once. Stream closed.
+      lambda { ARGF.send(cmd) }.should raise_error(IOError)
+    end
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/filename.rb b/1.8/core/argf/shared/filename.rb
new file mode 100644
index 0000000..21f0c4f
--- /dev/null
+++ b/1.8/core/argf/shared/filename.rb
@@ -0,0 +1,47 @@
+shared :argf_filename do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    # NOTE: this test assumes that fixtures files have two lines each
+    # SO DO NOT modify the fixture files!!!
+    it "returns the current file name on each file" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt')
+
+      res = []
+      # returns first current file even when not yet open
+      begin
+        res << ARGF.send(cmd)
+      end while ARGF.gets
+      # returns last current file even when closed
+      res << ARGF.send(cmd)
+      res.collect { |f| File.expand_path(f) }.should == 
+        [@file1, @file1, @file1, @file2, @file2, @file2].collect { |f| File.expand_path(f)}
+    end
+  
+    # NOTE: this test assumes that fixtures files have two lines each
+    # SO DO NOT modify the fixture files!!!
+    it "it sets the $FILENAME global variable with the current file name on each file" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt')
+      res = []
+      while ARGF.gets
+        res << $FILENAME
+      end 
+      # returns last current file even when closed
+      res << $FILENAME
+      res.collect { |f| File.expand_path(f) }.should == 
+        [@file1, @file1, @file2, @file2, @file2].collect { |f| File.expand_path(f)}
+    end
+  end
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/fileno.rb b/1.8/core/argf/shared/fileno.rb
new file mode 100644
index 0000000..7f91830
--- /dev/null
+++ b/1.8/core/argf/shared/fileno.rb
@@ -0,0 +1,37 @@
+shared :argf_fileno do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    # NOTE: this test assumes that fixtures files have two lines each
+    # SO DO NOT modify the fixture files!!!
+    it "returns the current file number on each file" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt')
+
+      res = []
+      # returns first current file even when not yet open
+      while ARGF.gets
+        res << ARGF.send(cmd)
+      end 
+      # returns last current file even when closed
+      res.collect {|d| d.class}.should == [Fixnum, Fixnum, Fixnum, Fixnum]
+    end
+  
+    it "raises ArgumentError (no stream) when called on a closed stream" do
+      ARGFSpecs.file_args('file1.txt')
+      ARGF.read # read everything at once. Stream closed.
+      lambda { ARGF.send(cmd) }.should raise_error(ArgumentError)
+    end
+  end
+
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/pos.rb b/1.8/core/argf/shared/pos.rb
new file mode 100644
index 0000000..1ce0d51
--- /dev/null
+++ b/1.8/core/argf/shared/pos.rb
@@ -0,0 +1,39 @@
+shared :argf_pos do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @stdin = File.dirname(__FILE__) + '/../fixtures/stdin.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @contents_stdin = File.read(@stdin)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    it "gives the correct position for each read operation" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt')
+      res = []
+      N1 = @contents_file1.size
+      N2 = @contents_file2.size
+      ARGF.read(2); res << ARGF.send(cmd)
+      ARGF.read(N1-2); res << ARGF.send(cmd)
+      ARGF.read(6); res << ARGF.send(cmd)
+      ARGF.rewind; res << ARGF.send(cmd)
+      ARGF.read(N2); res << ARGF.send(cmd)
+    
+      res.should == [2, N1, 6, 0, N2]
+    
+    end
+  
+    it "raises ArgumentError (no stream) when called on a closed stream" do
+      ARGFSpecs.file_args('file1.txt')
+      ARGF.read # read everything at once. Stream closed.
+      lambda { ARGF.send(cmd) }.should raise_error(ArgumentError)
+    end
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/shared/readlines.rb b/1.8/core/argf/shared/readlines.rb
new file mode 100644
index 0000000..df372b4
--- /dev/null
+++ b/1.8/core/argf/shared/readlines.rb
@@ -0,0 +1,33 @@
+shared :argf_readlines do |cmd|
+  describe "ARGF.#{cmd}" do
+    before :each do
+      ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/../fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/../fixtures/file2.txt'
+      @stdin = File.dirname(__FILE__) + '/../fixtures/stdin.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @contents_stdin = File.read(@stdin)
+    end
+
+    after :each do
+      # Close any open file (catch exception if already closed)
+      ARGF.close rescue nil
+    end
+  
+    it "reads all lines of all files" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+      STDIN.reopen(@stdin)
+      all_lines = (@contents_file1 + @contents_file2 + @contents_stdin).split($/).collect { |l| l+$/ }
+      ary = ARGF.send(cmd)
+      ary.should == all_lines
+    end
+  
+    it "returns nil when end of stream reached" do
+      ARGFSpecs.file_args('file1.txt', 'file2.txt', '-')
+      STDIN.reopen(@stdin)
+      ARGF.read # read all files at once
+      ARGF.send(cmd).should == nil
+    end
+  end
+end
\ No newline at end of file
diff --git a/1.8/core/argf/skip_spec.rb b/1.8/core/argf/skip_spec.rb
new file mode 100644
index 0000000..ffea7ea
--- /dev/null
+++ b/1.8/core/argf/skip_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.skip" do
+  before :each do
+    ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/fixtures/file2.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @linef1_1, @linef1_2 =  @contents_file1.split($/).collect { |l| l+$/ }
+      @linef2_1, @linef2_2 =  @contents_file2.split($/).collect { |l| l+$/ }
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  it "skips the current file" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    stg = ""
+    ARGF.read(1)
+    ARGF.skip; stg << ARGF.gets
+    stg.should == @linef2_1
+  end
+  
+  it "has no effect when called twice in a row" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    stg = ""
+    ARGF.read(1)
+    ARGF.skip
+    ARGF.skip; stg << ARGF.gets
+    stg.should == @linef2_1
+  end
+  
+    it "has no effect at end of stream" do
+    ARGFSpecs.file_args('file1.txt', 'file2.txt')
+    ARGF.read
+    ARGF.skip
+    ARGF.gets.should == nil
+  end
+  
+  
+end
\ No newline at end of file
diff --git a/1.8/core/argf/tell_spec.rb b/1.8/core/argf/tell_spec.rb
new file mode 100644
index 0000000..6e4e561
--- /dev/null
+++ b/1.8/core/argf/tell_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/pos'
+
+describe "ARGF.tell" do
+  it_behaves_like(:argf_pos, :tell)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/to_a_spec.rb b/1.8/core/argf/to_a_spec.rb
new file mode 100644
index 0000000..cd829bd
--- /dev/null
+++ b/1.8/core/argf/to_a_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/readlines'
+
+describe "ARGF.to_a" do
+  it_behaves_like(:argf_readlines, :to_a)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/to_i_spec.rb b/1.8/core/argf/to_i_spec.rb
new file mode 100644
index 0000000..c706d3a
--- /dev/null
+++ b/1.8/core/argf/to_i_spec.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/fileno'
+
+describe "ARGF.to_i" do
+  it_behaves_like(:argf_fileno, :to_i)
+end
\ No newline at end of file
diff --git a/1.8/core/argf/to_io_spec.rb b/1.8/core/argf/to_io_spec.rb
new file mode 100644
index 0000000..18be6b6
--- /dev/null
+++ b/1.8/core/argf/to_io_spec.rb
@@ -0,0 +1,38 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "ARGF.to_io" do
+  before :each do
+    ARGV.clear
+      @file1 = File.dirname(__FILE__) + '/fixtures/file1.txt'
+      @file2 = File.dirname(__FILE__) + '/fixtures/file2.txt'
+      @stdin = File.dirname(__FILE__) + '/fixtures/stdin.txt'
+      @contents_file1 = File.read(@file1)    
+      @contents_file2 = File.read(@file2)
+      @contents_stdin = File.read(@stdin)
+  end
+
+  after :each do
+    # Close any open file (catch exception if already closed)
+    ARGF.close rescue nil
+  end
+  
+  # NOTE: this test assumes that fixtures files have two lines each
+  # SO DO NOT modify the fixture files!!!
+  it "returns the IO of the current file" do
+    ARGFSpecs.file_args('file1.txt', '-', 'file2.txt')
+    STDIN.reopen(@stdin)
+    res = []
+    ARGF.gets; res << ARGF.to_io
+    ARGF.gets; res << ARGF.to_io
+    ARGF.gets; res << ARGF.to_io
+    ARGF.gets; res << ARGF.to_io
+    ARGF.gets; res << ARGF.to_io
+    ARGF.gets; res << ARGF.to_io
+    res.collect { |io| io.kind_of? IO }.should == [true] * 6
+    res[0].should == res[1]
+    res[2].should == res[3]
+    res[4].should == res[5]
+  end
+
+end
\ No newline at end of file
-- 
1.5.4.5

