Skip to content

Commit

Permalink
Showing 127 changed files with 4,830 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/ruby/truffle/rubysl/README.md
Original file line number Diff line number Diff line change
@@ -5,3 +5,4 @@ was written by Brian Shirai, et al.
Commits for each library are:

* rubysl-strscan `efab0248119cbb10b2b0ce2561eae269e052cdfe`
* rubysl-stringio `4b2977296eceef83084146c73d9ddef8d7e8f1af`
25 changes: 25 additions & 0 deletions lib/ruby/truffle/rubysl/rubysl-stringio/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright (c) 2013, Brian Shirai
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the library nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "rubysl/stringio/version"
require "rubysl/stringio/stringio"

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module RubySL
module StringIO
VERSION = "2.0.0"
end
end
1 change: 1 addition & 0 deletions lib/ruby/truffle/rubysl/rubysl-stringio/lib/stringio.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require "rubysl/stringio"
1 change: 1 addition & 0 deletions spec/truffle/spec/rubysl/README.md
Original file line number Diff line number Diff line change
@@ -7,3 +7,4 @@ Commits for each library are:
* rubysl-erb `feeac7a63117185be74f94b88acdbf6824a1c76c`
* rubysl-set `f9f4f118523126fbafddc112c29529ac7bd5dedd`
* rubysl-strscan `efab0248119cbb10b2b0ce2561eae269e052cdfe`
* rubysl-stringio `4b2977296eceef83084146c73d9ddef8d7e8f1af`
25 changes: 25 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright (c) 2013, Brian Shirai
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the library nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 changes: 83 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/append_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#<< when passed [Object]" do
before(:each) do
@io = StringIO.new("example")
end

it "returns self" do
(@io << "just testing").should equal(@io)
end

it "writes the passed argument onto self" do
(@io << "just testing")
@io.string.should == "just testing"
(@io << " and more testing")
@io.string.should == "just testing and more testing"
end

it "writes the passed argument at the current position" do
@io.pos = 5
@io << "<test>"
@io.string.should == "examp<test>"
end

it "pads self with \\000 when the current position is after the end" do
@io.pos = 15
@io << "just testing"
@io.string.should == "example\000\000\000\000\000\000\000\000just testing"
end

it "taints self's String when the passed argument is tainted" do
(@io << "test".taint)
@io.string.tainted?.should be_true
end

it "does not taint self when the passed argument is tainted" do
(@io << "test".taint)
@io.tainted?.should be_false
end

it "updates self's position" do
@io << "test"
@io.pos.should eql(4)
end

it "tries to convert the passed argument to a String using #to_s" do
obj = mock("to_s")
obj.should_receive(:to_s).and_return("Test")

(@io << obj).string.should == "Testple"
end
end

describe "StringIO#<< when self is not writable" do
it "raises an IOError" do
io = StringIO.new("test", "r")
lambda { io << "test" }.should raise_error(IOError)

io = StringIO.new("test")
io.close_write
lambda { io << "test" }.should raise_error(IOError)
end
end

describe "StringIO#<< when in append mode" do
before(:each) do
@io = StringIO.new("example", "a")
end

it "appends the passed argument to the end of self, ignoring current position" do
(@io << ", just testing")
@io.string.should == "example, just testing"

@io.pos = 3
(@io << " and more testing")
@io.string.should == "example, just testing and more testing"
end

it "correctly updates self's position" do
@io << ", testing"
@io.pos.should eql(16)
end
end
8 changes: 8 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/binmode_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#binmode" do
it "returns self" do
io = StringIO.new("example")
io.binmode.should equal(io)
end
end
12 changes: 12 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/bytes_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'stringio'
require File.expand_path('../shared/each_byte', __FILE__)

ruby_version_is "1.8.7" do
describe "StringIO#bytes" do
it_behaves_like :stringio_each_byte, :bytes
end

describe "StringIO#bytes when self is not readable" do
it_behaves_like :stringio_each_byte_not_readable, :bytes
end
end
12 changes: 12 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/chars_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'stringio'
require File.expand_path('../shared/each_char', __FILE__)

ruby_version_is "1.8.7" do
describe "StringIO#chars" do
it_behaves_like :stringio_each_char, :chars
end

describe "StringIO#chars when self is not readable" do
it_behaves_like :stringio_each_char_not_readable, :chars
end
end
30 changes: 30 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/close_read_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#close_read" do
before(:each) do
@io = StringIO.new("example")
end

it "returns nil" do
@io.close_read.should be_nil
end

it "prevents further reading" do
@io.close_read
lambda { @io.read(1) }.should raise_error(IOError)
end

it "allows further writing" do
@io.close_read
@io.write("x").should == 1
end

it "raises an IOError when in write-only mode" do
io = StringIO.new("example", "w")
lambda { io.close_read }.should raise_error(IOError)

io = StringIO.new("example")
io.close_read
lambda { io.close_read }.should raise_error(IOError)
end
end
22 changes: 22 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/close_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#close" do
before(:each) do
@io = StringIOSpecs.build
end

it "returns nil" do
@io.close.should be_nil
end

it "prevents further reading and/or writing" do
@io.close
lambda { @io.read(1) }.should raise_error(IOError)
lambda { @io.write('x') }.should raise_error(IOError)
end

it "raises an IOError when self was already closed" do
@io.close
lambda { @io.close }.should raise_error(IOError)
end
end
30 changes: 30 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/close_write_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#close_write" do
before(:each) do
@io = StringIO.new("example")
end

it "returns nil" do
@io.close_write.should be_nil
end

it "prevents further writing" do
@io.close_write
lambda { @io.write('x') }.should raise_error(IOError)
end

it "allows further reading" do
@io.close_write
@io.read(1).should == 'e'
end

it "raises an IOError when in read-only mode" do
io = StringIO.new("example", "r")
lambda { io.close_write }.should raise_error(IOError)

io = StringIO.new("example")
io.close_write
lambda { io.close_write }.should raise_error(IOError)
end
end
11 changes: 11 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/closed_read_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#closed_read?" do
it "returns true if self is not readable" do
io = StringIO.new("example", "r+")
io.close_write
io.closed_read?.should be_false
io.close_read
io.closed_read?.should be_true
end
end
15 changes: 15 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/closed_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#closed?" do
it "returns true if self is completely closed" do
io = StringIO.new("example", "r+")
io.close_read
io.closed?.should be_false
io.close_write
io.closed?.should be_true

io = StringIO.new("example", "r+")
io.close
io.closed?.should be_true
end
end
11 changes: 11 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/closed_write_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#closed_write?" do
it "returns true if self is not writable" do
io = StringIO.new("example", "r+")
io.close_read
io.closed_write?.should be_false
io.close_write
io.closed_write?.should be_true
end
end
10 changes: 10 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/codepoints_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/codepoints', __FILE__)

# See redmine #1667
describe "StringIO#codepoints" do
ruby_version_is "1.9" do
it_behaves_like(:stringio_codepoints, :codepoints)
end
end
10 changes: 10 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/each_byte_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'stringio'
require File.expand_path('../shared/each_byte', __FILE__)

describe "StringIO#each_byte" do
it_behaves_like :stringio_each_byte, :each_byte
end

describe "StringIO#each_byte when self is not readable" do
it_behaves_like :stringio_each_byte_not_readable, :each_byte
end
12 changes: 12 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/each_char_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'stringio'
require File.expand_path('../shared/each_char', __FILE__)

ruby_version_is "1.8.7" do
describe "StringIO#each_char" do
it_behaves_like :stringio_each_char, :each_char
end

describe "StringIO#each_char when self is not readable" do
it_behaves_like :stringio_each_char_not_readable, :chars
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/codepoints', __FILE__)

# See redmine #1667
describe "StringIO#each_codepoint" do
ruby_version_is "1.9" do
it_behaves_like(:stringio_codepoints, :codepoints)
end
end

14 changes: 14 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/each_line_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/each', __FILE__)

describe "StringIO#each_line when passed a separator" do
it_behaves_like :stringio_each_separator, :each_line
end

describe "StringIO#each_line when passed no arguments" do
it_behaves_like :stringio_each_no_arguments, :each_line
end

describe "StringIO#each_line when self is not readable" do
it_behaves_like :stringio_each_not_readable, :each_line
end
14 changes: 14 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/each_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/each', __FILE__)

describe "StringIO#each when passed a separator" do
it_behaves_like :stringio_each_separator, :each
end

describe "StringIO#each when passed no arguments" do
it_behaves_like :stringio_each_no_arguments, :each
end

describe "StringIO#each when self is not readable" do
it_behaves_like :stringio_each_not_readable, :each
end
10 changes: 10 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/eof_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/eof', __FILE__)

describe "StringIO#eof?" do
it_behaves_like :stringio_eof, :eof?
end

describe "StringIO#eof" do
it_behaves_like :stringio_eof, :eof
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'stringio'

ruby_version_is "1.9.2" do
describe "StringIO#external_encoding" do
it "gets the encoding of the underlying String" do
io = StringIO.new
io.set_encoding Encoding::UTF_8
io.external_encoding.should == Encoding::UTF_8
end
end
end
7 changes: 7 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/fcntl_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#fcntl" do
it "raises a NotImplementedError" do
lambda { StringIO.new("boom").fcntl }.should raise_error(NotImplementedError)
end
end
8 changes: 8 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/fileno_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/each', __FILE__)

describe "StringIO#fileno" do
it "returns nil" do
StringIO.new("nuffin").fileno.should be_nil
end
end
15 changes: 15 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/fixtures/classes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'stringio'

class StringSubclass < String; end

module StringIOSpecs
def self.build
str = <<-EOS
each
peach
pear
plum
EOS
StringIO.new(str)
end
end
8 changes: 8 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/flush_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#flush" do
it "returns self" do
io = StringIO.new("flush")
io.flush.should equal(io)
end
end
8 changes: 8 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/fsync_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#fsync" do
it "returns zero" do
io = StringIO.new("fsync")
io.fsync.should eql(0)
end
end
25 changes: 25 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/getbyte_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'stringio'
require File.expand_path('../shared/getc', __FILE__)

describe "StringIO#getbyte" do
it_behaves_like :stringio_getc, :getbyte

it "returns the 8-bit byte at the current position" do
io = StringIO.new("example")

io.send(@method).should == 101
io.send(@method).should == 120
io.send(@method).should == 97
end

it "retrieves bytes at a time rather than characters" do
io = StringIO.new("\xc3\x91")

io.getbyte.should == 0xc3
io.getbyte.should == 0x91
end
end

describe "StringIO#getbyte when self is not readable" do
it_behaves_like :stringio_getc_not_readable, :getbyte
end
30 changes: 30 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/getc_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- encoding: utf-8 -*-
require 'stringio'
require File.expand_path('../shared/getc', __FILE__)

describe "StringIO#getc" do
it_behaves_like :stringio_getc, :getc

it "returns the charactor at the current position" do
io = StringIO.new("example")

io.send(@method).should == ?e
io.send(@method).should == ?x
io.send(@method).should == ?a
end

with_feature :encoding do
it "increments #pos by the byte size of the character in multibyte strings" do
io = StringIO.new("föóbar")

io.send(@method); io.pos.should == 1 # "f" has byte size 1
io.send(@method); io.pos.should == 3 # "ö" has byte size 2
io.send(@method); io.pos.should == 5 # "ó" has byte size 2
io.send(@method); io.pos.should == 6 # "b" has byte size 1
end
end
end

describe "StringIO#getc when self is not readable" do
it_behaves_like :stringio_getc_not_readable, :getc
end
245 changes: 245 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/gets_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
require "stringio"

describe "StringIO#gets when passed [separator]" do
before(:each) do
@io = StringIO.new("this>is>an>example")
end

it "returns the data read till the next occurence of the passed separator" do
@io.gets(">").should == "this>"
@io.gets(">").should == "is>"
@io.gets(">").should == "an>"
@io.gets(">").should == "example"
end

it "sets $_ to the read content" do
@io.gets(">")
$_.should == "this>"
@io.gets(">")
$_.should == "is>"
@io.gets(">")
$_.should == "an>"
@io.gets(">")
$_.should == "example"
@io.gets(">")
$_.should be_nil
end

it "accepts string as separator" do
@io.gets("is>")
$_.should == "this>"
@io.gets("an>")
$_.should == "is>an>"
@io.gets("example")
$_.should == "example"
@io.gets("ple")
$_.should be_nil
end

it "updates self's lineno by one" do
@io.gets(">")
@io.lineno.should eql(1)

@io.gets(">")
@io.lineno.should eql(2)

@io.gets(">")
@io.lineno.should eql(3)
end

ruby_bug "", "1.8.8" do
it "returns the next paragraph when the passed separator is an empty String" do
io = StringIO.new("this is\n\nan example")
io.gets("").should == "this is\n\n"
io.gets("").should == "an example"
end
end

it "returns the remaining content starting at the current position when passed nil" do
io = StringIO.new("this is\n\nan example")
io.pos = 5
io.gets(nil).should == "is\n\nan example"
end

it "tries to convert the passed separator to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return(">")
@io.gets(obj).should == "this>"
end
end

describe "StringIO#gets when passed no argument" do
before(:each) do
@io = StringIO.new("this is\nan example\nfor StringIO#gets")
end

it "returns the data read till the next occurence of $/ or till eof" do
@io.gets.should == "this is\n"

begin
old_sep, $/ = $/, " "
@io.gets.should == "an "
@io.gets.should == "example\nfor "
@io.gets.should == "StringIO#gets"
ensure
$/ = old_sep
end
end

it "sets $_ to the read content" do
@io.gets
$_.should == "this is\n"
@io.gets
$_.should == "an example\n"
@io.gets
$_.should == "for StringIO#gets"
@io.gets
$_.should be_nil
end

it "updates self's position" do
@io.gets
@io.pos.should eql(8)

@io.gets
@io.pos.should eql(19)

@io.gets
@io.pos.should eql(36)
end

it "updates self's lineno" do
@io.gets
@io.lineno.should eql(1)

@io.gets
@io.lineno.should eql(2)

@io.gets
@io.lineno.should eql(3)
end

it "returns nil if self is at the end" do
@io.pos = 36
@io.gets.should be_nil
@io.gets.should be_nil
end
end

ruby_version_is "1.9" do
describe "StringIO#gets when passed [limit]" do
before(:each) do
@io = StringIO.new("this>is>an>example")
end

it "returns the data read until the limit is met" do
@io.gets(4).should == "this"
@io.gets(3).should == ">is"
@io.gets(5).should == ">an>e"
@io.gets(6).should == "xample"
end

it "sets $_ to the read content" do
@io.gets(4)
$_.should == "this"
@io.gets(3)
$_.should == ">is"
@io.gets(5)
$_.should == ">an>e"
@io.gets(6)
$_.should == "xample"
@io.gets(3)
$_.should be_nil
end

it "updates self's lineno by one" do
@io.gets(3)
@io.lineno.should eql(1)

@io.gets(3)
@io.lineno.should eql(2)

@io.gets(3)
@io.lineno.should eql(3)
end

it "tries to convert the passed limit to an Integer using #to_int" do
obj = mock('to_int')
obj.should_receive(:to_int).and_return(4)
@io.gets(obj).should == "this"
end

it "returns a blank string when passed a limit of 0" do
@io.gets(0).should == ""
end
end

describe "StringIO#gets when passed [separator] and [limit]" do
before(:each) do
@io = StringIO.new("this>is>an>example")
end

it "returns the data read until the limit is consumed or the separator is met" do
@io.gets('>', 8).should == "this>"
@io.gets('>', 2).should == "is"
@io.gets('>', 10).should == ">"
@io.gets('>', 6).should == "an>"
@io.gets('>', 5).should == "examp"
end

it "sets $_ to the read content" do
@io.gets('>', 8)
$_.should == "this>"
@io.gets('>', 2)
$_.should == "is"
@io.gets('>', 10)
$_.should == ">"
@io.gets('>', 6)
$_.should == "an>"
@io.gets('>', 5)
$_.should == "examp"
end

it "updates self's lineno by one" do
@io.gets('>', 3)
@io.lineno.should eql(1)

@io.gets('>', 3)
@io.lineno.should eql(2)

@io.gets('>', 3)
@io.lineno.should eql(3)
end

it "tries to convert the passed separator to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return('>')
@io.gets(obj, 5).should == "this>"
end

it "does not raise TypeError if passed separator is nil" do
@io.gets(nil, 5).should == "this>"
end

it "tries to convert the passed limit to an Integer using #to_int" do
obj = mock('to_int')
obj.should_receive(:to_int).and_return(5)
@io.gets('>', obj).should == "this>"
end

it "returns a String when both separator and limit are nil" do
@io.gets(nil, nil).should == "this>is>an>example"
end
end
end

describe "StringIO#gets when in write-only mode" do
it "raises an IOError" do
io = StringIO.new("xyz", "w")
lambda { io.gets }.should raise_error(IOError)

io = StringIO.new("xyz")
io.close_read
lambda { io.gets }.should raise_error(IOError)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
require 'stringio'

describe "StringIO#initialize_copy" do
before(:each) do
@io = StringIO.new("StringIO example")
@orig_io = StringIO.new("Original StringIO")
end

it "is private" do
StringIO.should have_private_instance_method(:initialize_copy)
end

it "returns self" do
@io.send(:initialize_copy, @orig_io).should equal(@io)
end

it "tries to convert the passed argument to a StringIO using #to_strio" do
obj = mock('to_strio')
obj.should_receive(:to_strio).and_return(StringIO.new("converted"))
@io.send(:initialize_copy, obj)
@io.string.should == "converted"
end

it "copies the passed StringIO's content to self" do
@io.send(:initialize_copy, @orig_io)
@io.string.should == "Original StringIO"
end

it "copies the passed StringIO's position to self" do
@orig_io.pos = 5
@io.send(:initialize_copy, @orig_io)
@io.pos.should eql(5)
end

it "taints self when the passed StringIO is tainted" do
@orig_io.taint
@io.send(:initialize_copy, @orig_io)
@io.tainted?.should be_true
end

it "copies the passed StringIO's mode to self" do
orig_io = StringIO.new("read-only", "r")
@io.send(:initialize_copy, orig_io)
@io.closed_read?.should be_false
@io.closed_write?.should be_true

orig_io = StringIO.new("write-only", "w")
@io.send(:initialize_copy, orig_io)
@io.closed_read?.should be_true
@io.closed_write?.should be_false

orig_io = StringIO.new("read-write", "r+")
@io.send(:initialize_copy, orig_io)
@io.closed_read?.should be_false
@io.closed_write?.should be_false

orig_io = StringIO.new("read-write", "w+")
@io.send(:initialize_copy, orig_io)
@io.closed_read?.should be_false
@io.closed_write?.should be_false
end

it "copies the passed StringIO's append mode" do
orig_io = StringIO.new("read-write", "a")
@io.send(:initialize_copy, orig_io)

@io.pos = 0
@io << " test"

@io.string.should == "read-write test"
end

it "does not truncate self's content when the copied StringIO was in truncate mode" do
orig_io = StringIO.new("original StringIO", "w+")
orig_io.write("not truncated") # make sure the content is not empty

@io.send(:initialize_copy, orig_io)
@io.string.should == "not truncated"
end

it "makes both StringIO objects to share position, eof status" do
@io.send(:initialize_copy, @orig_io)
@orig_io.pos.should == 0
@io.getc
@io.pos.should == 1
@orig_io.pos.should == 1
@orig_io.read(1).should == "r"
@io.read(1).should == "i"
@orig_io.pos.should == 3
@orig_io.pos.should == 3
@io.gets(nil)
@io.eof?.should == true
@orig_io.eof?.should == true
end
end
193 changes: 193 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/initialize_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
require 'stringio'

describe "StringIO#initialize when passed [Object, mode]" do
before(:each) do
@io = StringIO.allocate
end

it "uses the passed Object as the StringIO backend" do
@io.send(:initialize, str = "example", "r")
@io.string.should equal(str)
end

it "sets the mode based on the passed mode" do
io = StringIO.allocate
io.send(:initialize, "example", "r")
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.allocate
io.send(:initialize, "example", "rb")
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.allocate
io.send(:initialize, "example", "r+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "rb+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "w")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "wb")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "w+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "wb+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "a")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "ab")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "a+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", "ab+")
io.closed_read?.should be_false
io.closed_write?.should be_false
end

it "allows passing the mode as an Integer" do
io = StringIO.allocate
io.send(:initialize, "example", IO::RDONLY)
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.allocate
io.send(:initialize, "example", IO::RDWR)
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", IO::WRONLY)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", IO::WRONLY | IO::TRUNC)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", IO::RDWR | IO::TRUNC)
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", IO::WRONLY | IO::APPEND)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.allocate
io.send(:initialize, "example", IO::RDWR | IO::APPEND)
io.closed_read?.should be_false
io.closed_write?.should be_false
end

ruby_version_is "" ... "1.9" do
it "raises a TypeError when passed a frozen String in truncate mode as StringIO backend" do
io = StringIO.allocate
lambda { io.send(:initialize, "example".freeze, IO::TRUNC) }.should raise_error(TypeError)
end
end

ruby_version_is "1.9" do
it "raises a RuntimeError when passed a frozen String in truncate mode as StringIO backend" do
io = StringIO.allocate
lambda { io.send(:initialize, "example".freeze, IO::TRUNC) }.should raise_error(RuntimeError)
end
end

it "tries to convert the passed mode to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return("r")
@io.send(:initialize, "example", obj)

@io.closed_read?.should be_false
@io.closed_write?.should be_true
end

it "raises an Errno::EACCES error when passed a frozen string with a write-mode" do
(str = "example").freeze
lambda { @io.send(:initialize, str, "r+") }.should raise_error(Errno::EACCES)
lambda { @io.send(:initialize, str, "w") }.should raise_error(Errno::EACCES)
lambda { @io.send(:initialize, str, "a") }.should raise_error(Errno::EACCES)
end
end

describe "StringIO#initialize when passed [Object]" do
before(:each) do
@io = StringIO.allocate
end

it "uses the passed Object as the StringIO backend" do
@io.send(:initialize, str = "example")
@io.string.should equal(str)
end

it "sets the mode to read-write" do
@io.send(:initialize, "example")
@io.closed_read?.should be_false
@io.closed_write?.should be_false
end

it "tries to convert the passed Object to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return("example")
@io.send(:initialize, obj)
@io.string.should == "example"
end

it "automatically sets the mode to read-only when passed a frozen string" do
(str = "example").freeze
@io.send(:initialize, str)
@io.closed_read?.should be_false
@io.closed_write?.should be_true
end
end

describe "StringIO#initialize when passed no arguments" do
before(:each) do
@io = StringIO.allocate
end

it "is private" do
StringIO.should have_private_instance_method(:initialize)
end

it "sets the mode to read-write" do
@io.send(:initialize, "example")
@io.closed_read?.should be_false
@io.closed_write?.should be_false
end

it "uses an empty String as the StringIO backend" do
@io.send(:initialize)
@io.string.should == ""
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'stringio'

ruby_version_is "1.9.2" do
describe "StringIO#internal_encoding" do
it "returns nil" do
io = StringIO.new
io.set_encoding Encoding::UTF_8
io.internal_encoding.should == nil
end
end
end
6 changes: 6 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/isatty_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/isatty', __FILE__)

describe "StringIO#tty?" do
it_behaves_like :stringio_isatty, :isatty
end
6 changes: 6 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/length_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/length', __FILE__)

describe "StringIO#length" do
it_behaves_like :stringio_length, :length
end
29 changes: 29 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/lineno_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "stringio"

describe "StringIO#lineno" do
before(:each) do
@io = StringIO.new("this\nis\nan\nexample")
end

it "returns the number of lines read" do
@io.gets
@io.gets
@io.gets
@io.lineno.should eql(3)
end
end

describe "StringIO#lineno=" do
before(:each) do
@io = StringIO.new("this\nis\nan\nexample")
end

it "sets the current line number, but has no impact on the position" do
@io.lineno = 3
@io.pos.should eql(0)

@io.gets.should == "this\n"
@io.lineno.should eql(4)
@io.pos.should eql(5)
end
end
16 changes: 16 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/lines_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'stringio'
require File.expand_path('../shared/each', __FILE__)

ruby_version_is "1.8.7" do
describe "StringIO#lines when passed a separator" do
it_behaves_like :stringio_each_separator, :lines
end

describe "StringIO#lines when passed no arguments" do
it_behaves_like :stringio_each_no_arguments, :lines
end

describe "StringIO#lines when self is not readable" do
it_behaves_like :stringio_each_not_readable, :lines
end
end
215 changes: 215 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/open_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
require 'stringio'

describe "StringIO.open when passed [Object, mode]" do
it "uses the passed Object as the StringIO backend" do
io = StringIO.open(str = "example", "r")
io.string.should equal(str)
end

it "returns the blocks return value when yielding" do
ret = StringIO.open("example", "r") { :test }
ret.should equal(:test)
end

it "yields self to the passed block" do
io = nil
StringIO.open("example", "r") { |strio| io = strio }
io.should be_kind_of(StringIO)
end

it "closes self after yielding" do
io = nil
StringIO.open("example", "r") { |strio| io = strio }
io.closed?.should be_true
end

it "even closes self when an exception is raised while yielding" do
io = nil
begin
StringIO.open("example", "r") do |strio|
io = strio
raise "Error"
end
rescue
end
io.closed?.should be_true
end

it "sets self's string to nil after yielding" do
io = nil
StringIO.open("example", "r") { |strio| io = strio }
io.string.should be_nil
end

it "even sets self's string to nil when an exception is raised while yielding" do
io = nil
begin
StringIO.open("example", "r") do |strio|
io = strio
raise "Error"
end
rescue
end
io.string.should be_nil
end

it "sets the mode based on the passed mode" do
io = StringIO.open("example", "r")
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.open("example", "rb")
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.open("example", "r+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", "rb+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", "w")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", "wb")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", "w+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", "wb+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", "a")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", "ab")
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", "a+")
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", "ab+")
io.closed_read?.should be_false
io.closed_write?.should be_false
end

it "allows passing the mode as an Integer" do
io = StringIO.open("example", IO::RDONLY)
io.closed_read?.should be_false
io.closed_write?.should be_true

io = StringIO.open("example", IO::RDWR)
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", IO::WRONLY)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", IO::WRONLY | IO::TRUNC)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", IO::RDWR | IO::TRUNC)
io.closed_read?.should be_false
io.closed_write?.should be_false

io = StringIO.open("example", IO::WRONLY | IO::APPEND)
io.closed_read?.should be_true
io.closed_write?.should be_false

io = StringIO.open("example", IO::RDWR | IO::APPEND)
io.closed_read?.should be_false
io.closed_write?.should be_false
end

ruby_version_is "" ... "1.9" do
it "raises a TypeError when passed a frozen String in truncate mode as StringIO backend" do
lambda { StringIO.open("example".freeze, IO::TRUNC) }.should raise_error(TypeError)
end
end

ruby_version_is "1.9" do
it "raises a RuntimeError when passed a frozen String in truncate mode as StringIO backend" do
lambda { StringIO.open("example".freeze, IO::TRUNC) }.should raise_error(RuntimeError)
end
end

it "tries to convert the passed mode to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return("r")
io = StringIO.open("example", obj)

io.closed_read?.should be_false
io.closed_write?.should be_true
end

it "raises an Errno::EACCES error when passed a frozen string with a write-mode" do
(str = "example").freeze
lambda { io = StringIO.open(str, "r+") }.should raise_error(Errno::EACCES)
lambda { io = StringIO.open(str, "w") }.should raise_error(Errno::EACCES)
lambda { io = StringIO.open(str, "a") }.should raise_error(Errno::EACCES)
end
end

describe "StringIO.open when passed [Object]" do
it "uses the passed Object as the StringIO backend" do
io = StringIO.open(str = "example")
io.string.should equal(str)
end

it "yields self to the passed block" do
io = nil
ret = StringIO.open("example") { |strio| io = strio }
io.should equal(ret)
end

it "sets the mode to read-write" do
io = StringIO.open("example")
io.closed_read?.should be_false
io.closed_write?.should be_false
end

it "tries to convert the passed Object to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return("example")
io = StringIO.open(obj)
io.string.should == "example"
end

it "automatically sets the mode to read-only when passed a frozen string" do
(str = "example").freeze
io = StringIO.open(str)
io.closed_read?.should be_false
io.closed_write?.should be_true
end
end

describe "StringIO.open when passed no arguments" do
it "yields self to the passed block" do
io = nil
ret = StringIO.open { |strio| io = strio }
io.should equal(ret)
end

it "sets the mode to read-write" do
io = StringIO.open
io.closed_read?.should be_false
io.closed_write?.should be_false
end

it "uses an empty String as the StringIO backend" do
StringIO.open.string.should == ""
end
end

15 changes: 15 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/path_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#path" do
ruby_version_is "" ... "1.9" do
it "returns nil" do
StringIO.new("path").path.should be_nil
end
end

ruby_version_is "1.9" do
it "is not defined" do
lambda { StringIO.new("path").path }.should raise_error(NoMethodError)
end
end
end
7 changes: 7 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/pid_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#pid" do
it "returns nil" do
StringIO.new("pid").pid.should be_nil
end
end
27 changes: 27 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/pos_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/tell', __FILE__)

describe "StringIO#pos" do
it_behaves_like :stringio_tell, :pos
end

describe "StringIO#pos=" do
before(:each) do
@io = StringIOSpecs.build
end

it "updates the current byte offset" do
@io.pos = 26
@io.read(1).should == "r"
end

it "raises an EINVAL if given a negative argument" do
lambda { @io.pos = -10 }.should raise_error(Errno::EINVAL)
end

it "updates the current byte offset after reaching EOF" do
@io.read
@io.pos = 26
@io.read(1).should == "r"
end
end
113 changes: 113 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/print_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#print" do
before(:each) do
@io = StringIO.new('example')
end

ruby_version_is "" ... "1.9" do
it "prints $_ when passed no arguments" do
$_ = nil
@io.print
@io.string.should == "nilmple"

$_ = "blah"
@io.print
@io.string.should == "nilblah"
end
end

ruby_version_is "1.9" do
it "prints $_ when passed no arguments" do
$_ = nil
@io.print
@io.string.should == "example"

$_ = "blah"
@io.print
@io.string.should == "blahple"
end
end

it "prints the passed arguments to self" do
@io.print(5, 6, 7, 8)
@io.string.should == "5678ple"
end

it "tries to convert the passed Object to a String using #to_s" do
obj = mock("to_s")
obj.should_receive(:to_s).and_return("to_s")
@io.print(obj)
@io.string.should == "to_sple"
end

it "returns nil" do
@io.print(1, 2, 3).should be_nil
end

it "pads self with \\000 when the current position is after the end" do
@io.pos = 10
@io.print(1, 2, 3)
@io.string.should == "example\000\000\000123"
end

it "honors the output record separator global" do
old_rs, $\ = $\, 'x'

begin
@io.print(5, 6, 7, 8)
@io.string.should == '5678xle'
ensure
$\ = old_rs
end
end

it "updates the current position" do
@io.print(1, 2, 3)
@io.pos.should eql(3)

@io.print(1, 2, 3)
@io.pos.should eql(6)
end

it "correctly updates the current position when honoring the output record separator global" do
old_rs, $\ = $\, 'x'

begin
@io.print(5, 6, 7, 8)
@io.pos.should eql(5)
ensure
$\ = old_rs
end
end
end

describe "StringIO#print when in append mode" do
before(:each) do
@io = StringIO.new("example", "a")
end

it "appends the passed argument to the end of self" do
@io.print(", just testing")
@io.string.should == "example, just testing"

@io.print(" and more testing")
@io.string.should == "example, just testing and more testing"
end

it "correctly updates self's position" do
@io.print(", testing")
@io.pos.should eql(16)
end
end

describe "StringIO#print when self is not writable" do
it "raises an IOError" do
io = StringIO.new("test", "r")
lambda { io.print("test") }.should raise_error(IOError)

io = StringIO.new("test")
io.close_write
lambda { io.print("test") }.should raise_error(IOError)
end
end
60 changes: 60 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/printf_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#printf" do
before(:each) do
@io = StringIO.new('example')
end

it "returns nil" do
@io.printf("%d %04x", 123, 123).should be_nil
end

it "pads self with \\000 when the current position is after the end" do
@io.pos = 10
@io.printf("%d", 123)
@io.string.should == "example\000\000\000123"
end

it "performs format conversion" do
@io.printf("%d %04x", 123, 123)
@io.string.should == "123 007b"
end

it "updates the current position" do
@io.printf("%d %04x", 123, 123)
@io.pos.should eql(8)

@io.printf("%d %04x", 123, 123)
@io.pos.should eql(16)
end
end

describe "StringIO#printf when in append mode" do
before(:each) do
@io = StringIO.new("example", "a")
end

it "appends the passed argument to the end of self" do
@io.printf("%d %04x", 123, 123)
@io.string.should == "example123 007b"

@io.printf("%d %04x", 123, 123)
@io.string.should == "example123 007b123 007b"
end

it "correctly updates self's position" do
@io.printf("%d %04x", 123, 123)
@io.pos.should eql(15)
end
end

describe "StringIO#printf when self is not writable" do
it "raises an IOError" do
io = StringIO.new("test", "r")
lambda { io.printf("test") }.should raise_error(IOError)

io = StringIO.new("test")
io.close_write
lambda { io.printf("test") }.should raise_error(IOError)
end
end
104 changes: 104 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/putc_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- encoding: utf-8 -*-

require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#putc when passed [String]" do
before(:each) do
@io = StringIO.new('example')
end

it "overwrites the character at the current position" do
@io.putc("t")
@io.string.should == "txample"

@io.pos = 3
@io.putc("t")
@io.string.should == "txatple"
end

it "only writes the first character from the passed String" do
@io.putc("test")
@io.string.should == "txample"
end

it "returns the passed String" do
str = "test"
@io.putc(str).should equal(str)
end

it "correctly updates the current position" do
@io.putc("t")
@io.pos.should == 1

@io.putc("test")
@io.pos.should == 2

@io.putc("t")
@io.pos.should == 3
end


with_feature :encoding do

before :each do
@enc_io = StringIO.new("ëllø")
end

it "writes a byte into the io" do
@enc_io.putc("t")
@enc_io.string.should == "t\xABllø"
end

end

end

describe "StringIO#putc when passed [Object]" do
before(:each) do
@io = StringIO.new('example')
end

it "it writes the passed Integer % 256 to self" do
@io.putc(333) # 333 % 256 == ?M
@io.string.should == "Mxample"

@io.putc(-450) # -450 % 256 == ?>
@io.string.should == "M>ample"
end

it "pads self with \\000 when the current position is after the end" do
@io.pos = 10
@io.putc(?A)
@io.string.should == "example\000\000\000A"
end

it "tries to convert the passed argument to an Integer using #to_int" do
obj = mock('to_int')
obj.should_receive(:to_int).and_return(116)
@io.putc(obj)
@io.string.should == "txample"
end

it "raises a TypeError when the passed argument can't be coerced to Integer" do
lambda { @io.putc(Object.new) }.should raise_error(TypeError)
end
end

describe "StringIO#putc when in append mode" do
it "appends to the end of self" do
io = StringIO.new("test", "a")
io.putc(?t)
io.string.should == "testt"
end
end

describe "StringIO#putc when self is not writable" do
it "raises an IOError" do
io = StringIO.new("test", "r")
lambda { io.putc(?a) }.should raise_error(IOError)

io = StringIO.new("test")
io.close_write
lambda { io.putc("t") }.should raise_error(IOError)
end
end
172 changes: 172 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/puts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# -*- encoding: utf-8 -*-

require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#puts when passed an Array" do
before(:each) do
@io = StringIO.new
end

it "writes each element of the passed Array to self, separated by a newline" do
@io.puts([1, 2, 3, 4])
@io.string.should == "1\n2\n3\n4\n"

@io.puts([1, 2], [3, 4])
@io.string.should == "1\n2\n3\n4\n1\n2\n3\n4\n"
end

it "flattens nested Arrays" do
@io.puts([1, [2, [3, [4]]]])
@io.string.should == "1\n2\n3\n4\n"
end

it "handles self-recursive arrays correctly" do
(ary = [5])
ary << ary
@io.puts(ary)
@io.string.should == "5\n[...]\n"
end

it "does not honor the global output record separator $\\" do
begin
old_rs, $\ = $\, "test"
@io.puts([1, 2, 3, 4])
@io.string.should == "1\n2\n3\n4\n"
ensure
$\ = old_rs
end
end

it "first tries to convert each Array element to an Array using #to_ary" do
obj = mock("Object")
obj.should_receive(:to_ary).and_return(["to_ary"])
@io.puts([obj])
@io.string.should == "to_ary\n"
end

it "then tries to convert each Array element to a String using #to_s" do
obj = mock("Object")
obj.should_receive(:to_s).and_return("to_s")
@io.puts([obj])
@io.string.should == "to_s\n"
end
end

describe "StringIO#puts when passed 1 or more objects" do
before(:each) do
@io = StringIO.new
end

it "does not honor the global output record separator $\\" do
begin
old_rs, $\ = $\, "test"
@io.puts(1, 2, 3, 4)
@io.string.should == "1\n2\n3\n4\n"
ensure
$\ = old_rs
end
end

it "does not put a \\n after each Objects that end in a newline" do
@io.puts("1\n", "2\n", "3\n")
@io.string.should == "1\n2\n3\n"
end

it "first tries to convert each Object to an Array using #to_ary" do
obj = mock("Object")
obj.should_receive(:to_ary).and_return(["to_ary"])
@io.puts(obj)
@io.string.should == "to_ary\n"
end

it "then tries to convert each Object to a String using #to_s" do
obj = mock("Object")
obj.should_receive(:to_s).and_return("to_s")
@io.puts(obj)
@io.string.should == "to_s\n"
end

it "prints a newline when passed an empty string" do
@io.puts ''
@io.string.should == "\n"
end

ruby_version_is ""..."1.9" do
it "prints a newline when passed nil" do
@io.puts nil
@io.string.should == "nil\n"
end
end

ruby_version_is "1.9" do
it "prints a newline when passed nil" do
@io.puts nil
@io.string.should == "\n"
end
end
end

describe "StringIO#puts when passed no arguments" do
before(:each) do
@io = StringIO.new
end

it "returns nil" do
@io.puts.should be_nil
end

it "prints a newline" do
@io.puts
@io.string.should == "\n"
end

it "does not honor the global output record separator $\\" do
begin
old_rs, $\ = $\, "test"
@io.puts
@io.string.should == "\n"
ensure
$\ = old_rs
end
end
end

describe "StringIO#puts when in append mode" do
before(:each) do
@io = StringIO.new("example", "a")
end

it "appends the passed argument to the end of self" do
@io.puts(", just testing")
@io.string.should == "example, just testing\n"

@io.puts(" and more testing")
@io.string.should == "example, just testing\n and more testing\n"
end

it "correctly updates self's position" do
@io.puts(", testing")
@io.pos.should eql(17)
end
end

describe "StringIO#puts when self is not writable" do
it "raises an IOError" do
io = StringIO.new("test", "r")
lambda { io.puts }.should raise_error(IOError)

io = StringIO.new("test")
io.close_write
lambda { io.puts }.should raise_error(IOError)
end
end

describe "StringIO#puts when passed an encoded string" do
it "stores the bytes unmodified" do
io = StringIO.new("")
io.puts "\x00\x01\x02"
io.puts "æåø"

io.string.should == "\x00\x01\x02\næåø\n"
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "stringio"
require File.expand_path('../shared/read', __FILE__)
require File.expand_path('../shared/sysread', __FILE__)

ruby_version_is "1.9" do
describe "StringIO#read_nonblock when passed length, buffer" do
it_behaves_like :stringio_read, :read_nonblock
end

describe "StringIO#read_nonblock when passed length" do
it_behaves_like :stringio_read_length, :read_nonblock
end

describe "StringIO#read_nonblock when passed no arguments" do
it_behaves_like :stringio_read_no_arguments, :read_nonblock
end

describe "StringIO#read_nonblock when self is not readable" do
it_behaves_like :stringio_read_not_readable, :read_nonblock
end

describe "StringIO#read_nonblock when passed nil" do
it_behaves_like :stringio_read_nil, :read_nonblock
end

describe "StringIO#read_nonblock when passed length" do
it_behaves_like :stringio_sysread_length, :read_nonblock
end
end
61 changes: 61 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/read_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# -*- encoding: utf-8 -*-
require "stringio"
require File.expand_path('../shared/read', __FILE__)

describe "StringIO#read when passed length, buffer" do
it_behaves_like :stringio_read, :read
end

describe "StringIO#read when passed length" do
it_behaves_like :stringio_read_length, :read

it "returns nil when passed length > 0 and no data remains" do
@io.send(@method, 8).should == "example"
@io.send(@method, 2).should be_nil
end

# This was filed as a bug in redmine#156 but since MRI refused to change the
# 1.8 behavior, it's now considered a version difference by RubySpec since
# it could have a significant impact on user code.
ruby_version_is ""..."1.9" do
it "returns nil when passed 0 and no data remains" do
@io.send(@method, 8).should == "example"
@io.send(@method, 0).should be_nil
end
end

ruby_version_is "1.9" do
it "returns an empty String when passed 0 and no data remains" do
@io.send(@method, 8).should == "example"
@io.send(@method, 0).should == ""
end

it "truncates the buffer when limit > 0 and no data remains" do
@io.send(@method)
@io.send(@method, 2, buffer = "abc").should be_nil
buffer.should == ""
end
end
end

describe "StringIO#read when passed no arguments" do
it_behaves_like :stringio_read_no_arguments, :read

it "returns an empty string if at EOF" do
@io.read.should == "example"
@io.read.should == ""
end
end

describe "StringIO#read when passed nil" do
it_behaves_like :stringio_read_nil, :read

it "returns an empty string if at EOF" do
@io.read(nil).should == "example"
@io.read(nil).should == ""
end
end

describe "StringIO#read when self is not readable" do
it_behaves_like :stringio_read_not_readable, :read
end
21 changes: 21 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/readbyte_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'stringio'
require File.expand_path('../shared/readchar', __FILE__)

ruby_version_is "1.8.7" do
describe "StringIO#readbyte" do
it_behaves_like :stringio_readchar, :readbyte

it "reads the next 8-bit byte from self's current position" do
io = StringIO.new("example")

io.send(@method).should == 101

io.pos = 4
io.send(@method).should == 112
end
end

describe "StringIO#readbyte when self is not readable" do
it_behaves_like :stringio_readchar_not_readable, :readbyte
end
end
19 changes: 19 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/readchar_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'stringio'
require File.expand_path('../shared/readchar', __FILE__)

describe "StringIO#readchar" do
it_behaves_like :stringio_readchar, :readchar

it "reads the next 8-bit byte from self's current position" do
io = StringIO.new("example")

io.send(@method).should == ?e

io.pos = 4
io.send(@method).should == ?p
end
end

describe "StringIO#readchar when self is not readable" do
it_behaves_like :stringio_readchar_not_readable, :readchar
end
127 changes: 127 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/readline_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
require File.expand_path('../fixtures/classes', __FILE__)


describe "StringIO#readline when passed [separator]" do
before(:each) do
@io = StringIO.new("this>is>an>example")
end

it "returns the data read till the next occurence of the passed separator" do
@io.readline(">").should == "this>"
@io.readline(">").should == "is>"
@io.readline(">").should == "an>"
@io.readline(">").should == "example"
end

ruby_bug "http://redmine.ruby-lang.org/issues/show/159", "1.8.7.17" do
it "sets $_ to the read content" do
@io.readline(">")
$_.should == "this>"
@io.readline(">")
$_.should == "is>"
@io.readline(">")
$_.should == "an>"
@io.readline(">")
$_.should == "example"
end
end

it "updates self's lineno by one" do
@io.readline(">")
@io.lineno.should eql(1)

@io.readline(">")
@io.lineno.should eql(2)

@io.readline(">")
@io.lineno.should eql(3)
end

ruby_bug "", "1.8.8" do
it "returns the next paragraph when the passed separator is an empty String" do
io = StringIO.new("this is\n\nan example")
io.readline("").should == "this is\n\n"
io.readline("").should == "an example"
end
end

it "returns the remaining content starting at the current position when passed nil" do
io = StringIO.new("this is\n\nan example")
io.pos = 5
io.readline(nil).should == "is\n\nan example"
end

it "tries to convert the passed separator to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return(">")
@io.readline(obj).should == "this>"
end
end

describe "StringIO#readline when passed no argument" do
before(:each) do
@io = StringIO.new("this is\nan example\nfor StringIO#readline")
end

it "returns the data read till the next occurence of $/ or till eof" do
@io.readline.should == "this is\n"

begin
old_sep, $/ = $/, " "
@io.readline.should == "an "
@io.readline.should == "example\nfor "
@io.readline.should == "StringIO#readline"
ensure
$/ = old_sep
end
end

ruby_bug "http://redmine.ruby-lang.org/issues/show/159", "1.8.7.17" do
it "sets $_ to the read content" do
@io.readline
$_.should == "this is\n"
@io.readline
$_.should == "an example\n"
@io.readline
$_.should == "for StringIO#readline"
end
end

it "updates self's position" do
@io.readline
@io.pos.should eql(8)

@io.readline
@io.pos.should eql(19)

@io.readline
@io.pos.should eql(40)
end

it "updates self's lineno" do
@io.readline
@io.lineno.should eql(1)

@io.readline
@io.lineno.should eql(2)

@io.readline
@io.lineno.should eql(3)
end

it "raises an IOError if self is at the end" do
@io.pos = 40
lambda { @io.readline }.should raise_error(IOError)
end
end

describe "StringIO#readline when in write-only mode" do
it "raises an IOError" do
io = StringIO.new("xyz", "w")
lambda { io.readline }.should raise_error(IOError)

io = StringIO.new("xyz")
io.close_read
lambda { io.readline }.should raise_error(IOError)
end
end
124 changes: 124 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/readlines_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#readlines when passed [separator]" do
before(:each) do
@io = StringIO.new("this>is>an>example")
end

it "returns an Array containing lines based on the passed separator" do
@io.readlines(">").should == ["this>", "is>", "an>", "example"]
end

it "updates self's position based on the number of read bytes" do
@io.readlines(">")
@io.pos.should eql(18)
end

it "updates self's lineno based on the number of read lines" do
@io.readlines(">")
@io.lineno.should eql(4)
end

it "does not change $_" do
$_ = "test"
@io.readlines(">")
$_.should == "test"
end

ruby_bug "", "1.8.8" do
it "returns an Array containing all paragraphs when the passed separator is an empty String" do
io = StringIO.new("this is\n\nan example")
io.readlines("").should == ["this is\n\n", "an example"]
end
end

it "returns the remaining content as one line starting at the current position when passed nil" do
io = StringIO.new("this is\n\nan example")
io.pos = 5
io.readlines(nil).should == ["is\n\nan example"]
end

it "tries to convert the passed separator to a String using #to_str" do
obj = mock('to_str')
obj.stub!(:to_str).and_return(">")
@io.readlines(obj).should == ["this>", "is>", "an>", "example"]
end
end

ruby_version_is "1.9" do
describe "StringIO#readlines" do
before :each do
@io = StringIO.new("ab\ncd")
ScratchPad.record []
end

it "returns at most limit characters when limit is positive" do
@io.readlines.should == ["ab\n", "cd"]
end

it "calls #to_int to convert the limit" do
limit = mock("stringio each limit")
limit.should_receive(:to_int).at_least(1).times.and_return(5)

@io.readlines(limit)
end

it "calls #to_int to convert the limit when passed separator and limit" do
limit = mock("stringio each limit")
limit.should_receive(:to_int).at_least(1).times.and_return(6)

@io.readlines($/, limit)
end

it "raises an ArgumentError when limit is 0" do
lambda { @io.readlines(0) }.should raise_error(ArgumentError)
end
end
end

describe "StringIO#readlines when passed no argument" do
before(:each) do
@io = StringIO.new("this is\nan example\nfor StringIO#readlines")
end

it "returns an Array containing lines based on $/" do
begin
old_sep, $/ = $/, " "
@io.readlines.should == ["this ", "is\nan ", "example\nfor ", "StringIO#readlines"]
ensure
$/ = old_sep
end
end

it "updates self's position based on the number of read bytes" do
@io.readlines
@io.pos.should eql(41)
end

it "updates self's lineno based on the number of read lines" do
@io.readlines
@io.lineno.should eql(3)
end

it "does not change $_" do
$_ = "test"
@io.readlines(">")
$_.should == "test"
end

it "returns an empty Array when self is at the end" do
@io.pos = 41
@io.readlines.should == []
end
end

describe "StringIO#readlines when in write-only mode" do
it "raises an IOError" do
io = StringIO.new("xyz", "w")
lambda { io.readlines }.should raise_error(IOError)

io = StringIO.new("xyz")
io.close_read
lambda { io.readlines }.should raise_error(IOError)
end
end
29 changes: 29 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/readpartial_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "stringio"
require File.expand_path('../shared/read', __FILE__)
require File.expand_path('../shared/sysread', __FILE__)

ruby_version_is "1.9" do
describe "StringIO#readpartial when passed length, buffer" do
it_behaves_like :stringio_read, :readpartial
end

describe "StringIO#readpartial when passed length" do
it_behaves_like :stringio_read_length, :readpartial
end

describe "StringIO#readpartial when passed no arguments" do
it_behaves_like :stringio_read_no_arguments, :readpartial
end

describe "StringIO#readpartial when self is not readable" do
it_behaves_like :stringio_read_not_readable, :readpartial
end

describe "StringIO#readpartial when passed nil" do
it_behaves_like :stringio_read_nil, :readpartial
end

describe "StringIO#readpartial when passed length" do
it_behaves_like :stringio_sysread_length, :readpartial
end
end
303 changes: 303 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/reopen_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#reopen when passed [Object, Integer]" do
before(:each) do
@io = StringIO.new("example")
end

it "reopens self with the passed Object in the passed mode" do
@io.reopen("reopened", IO::RDONLY)
@io.closed_read?.should be_false
@io.closed_write?.should be_true
@io.string.should == "reopened"

@io.reopen("reopened, twice", IO::WRONLY)
@io.closed_read?.should be_true
@io.closed_write?.should be_false
@io.string.should == "reopened, twice"

@io.reopen("reopened, another time", IO::RDWR)
@io.closed_read?.should be_false
@io.closed_write?.should be_false
@io.string.should == "reopened, another time"
end

# NOTE: WEIRD!
it "does not taint self when the passed Object was tainted" do
@io.reopen("reopened".taint, IO::RDONLY)
@io.tainted?.should be_false

@io.reopen("reopened".taint, IO::WRONLY)
@io.tainted?.should be_false
end

it "tries to convert the passed Object to a String using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return("to_str")
@io.reopen(obj, IO::RDWR)
@io.string.should == "to_str"
end

it "raises a TypeError when the passed Object can't be converted to a String" do
lambda { @io.reopen(Object.new, IO::RDWR) }.should raise_error(TypeError)
end

it "raises an Errno::EACCES when trying to reopen self with a frozen String in write-mode" do
lambda { @io.reopen("burn".freeze, IO::WRONLY) }.should raise_error(Errno::EACCES)
lambda { @io.reopen("burn".freeze, IO::WRONLY | IO::APPEND) }.should raise_error(Errno::EACCES)
end

ruby_version_is "" ... "1.9" do
it "raises a TypeError when trying to reopen self with a frozen String in truncate-mode" do
lambda { @io.reopen("burn".freeze, IO::RDONLY | IO::TRUNC) }.should raise_error(TypeError)
end
end

ruby_version_is "1.9" do
it "raises a RuntimeError when trying to reopen self with a frozen String in truncate-mode" do
lambda { @io.reopen("burn".freeze, IO::RDONLY | IO::TRUNC) }.should raise_error(RuntimeError)
end
end

it "does not raise IOError when passed a frozen String in read-mode" do
@io.reopen("burn".freeze, IO::RDONLY)
@io.string.should == "burn"
end
end

describe "StringIO#reopen when passed [Object, Object]" do
before(:each) do
@io = StringIO.new("example")
end

it "reopens self with the passed Object in the passed mode" do
@io.reopen("reopened", "r")
@io.closed_read?.should be_false
@io.closed_write?.should be_true
@io.string.should == "reopened"

@io.reopen("reopened, twice", "r+")
@io.closed_read?.should be_false
@io.closed_write?.should be_false
@io.string.should == "reopened, twice"

@io.reopen("reopened, another", "w+")
@io.closed_read?.should be_false
@io.closed_write?.should be_false
@io.string.should == ""

@io.reopen("reopened, another time", "r+")
@io.closed_read?.should be_false
@io.closed_write?.should be_false
@io.string.should == "reopened, another time"
end

it "truncates the passed String when opened in truncate mode" do
@io.reopen(str = "reopened", "w")
str.should == ""
end

# NOTE: WEIRD!
it "does not taint self when the passed Object was tainted" do
@io.reopen("reopened".taint, "r")
@io.tainted?.should be_false

@io.reopen("reopened".taint, "w")
@io.tainted?.should be_false
end

it "tries to convert the passed Object to a String using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return("to_str")
@io.reopen(obj, "r")
@io.string.should == "to_str"
end

it "raises a TypeError when the passed Object can't be converted to a String using #to_str" do
lambda { @io.reopen(Object.new, "r") }.should raise_error(TypeError)
end

ruby_bug "#", "1.8.7" do
it "resets self's position to 0" do
@io.read(5)
@io.reopen("reopened")
@io.pos.should eql(0)
end

it "resets self's line number to 0" do
@io.gets
@io.reopen("reopened")
@io.lineno.should eql(0)
end
end

it "tries to convert the passed mode Object to an Integer using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return("r")
@io.reopen("reopened", obj)
@io.closed_read?.should be_false
@io.closed_write?.should be_true
@io.string.should == "reopened"
end

it "raises an Errno::EACCES error when trying to reopen self with a frozen String in write-mode" do
lambda { @io.reopen("burn".freeze, 'w') }.should raise_error(Errno::EACCES)
lambda { @io.reopen("burn".freeze, 'w+') }.should raise_error(Errno::EACCES)
lambda { @io.reopen("burn".freeze, 'a') }.should raise_error(Errno::EACCES)
lambda { @io.reopen("burn".freeze, "r+") }.should raise_error(Errno::EACCES)
end

it "does not raise IOError if a frozen string is passed in read mode" do
@io.reopen("burn".freeze, "r")
@io.string.should == "burn"
end
end

describe "StringIO#reopen when passed [String]" do
before(:each) do
@io = StringIO.new("example")
end

it "reopens self with the passed String in read-write mode" do
@io.close

@io.reopen("reopened")

@io.closed_write?.should be_false
@io.closed_read?.should be_false

@io.string.should == "reopened"
end

# NOTE: WEIRD!
it "does not taint self when the passed Object was tainted" do
@io.reopen("reopened".taint)
@io.tainted?.should be_false
end

ruby_bug "#", "1.8.7" do
it "resets self's position to 0" do
@io.read(5)
@io.reopen("reopened")
@io.pos.should eql(0)
end

it "resets self's line number to 0" do
@io.gets
@io.reopen("reopened")
@io.lineno.should eql(0)
end
end
end

describe "StringIO#reopen when passed [Object]" do
before(:each) do
@io = StringIO.new("example")
end

it "raises a TypeError when passed an Object that can't be converted to a StringIO" do
lambda { @io.reopen(Object.new) }.should raise_error(TypeError)
end

it "does not try to convert the passed Object to a String using #to_str" do
obj = mock("not to_str")
obj.should_not_receive(:to_str)
lambda { @io.reopen(obj) }.should raise_error(TypeError)
end

it "tries to convert the passed Object to a StringIO using #to_strio" do
obj = mock("to_strio")
obj.should_receive(:to_strio).and_return(StringIO.new("to_strio"))
@io.reopen(obj)
@io.string.should == "to_strio"
end

# NOTE: WEIRD!
it "taints self when the passed Object was tainted" do
@io.reopen(StringIO.new("reopened").taint)
@io.tainted?.should be_true
end
end

describe "StringIO#reopen when passed no arguments" do
before(:each) do
@io = StringIO.new("example\nsecond line")
end

it "resets self's mode to read-write" do
@io.close
@io.reopen
@io.closed_read?.should be_false
@io.closed_write?.should be_false
end

ruby_bug "#", "1.8.7" do
it "resets self's position to 0" do
@io.read(5)
@io.reopen
@io.pos.should eql(0)
end

it "resets self's line number to 0" do
@io.gets
@io.reopen
@io.lineno.should eql(0)
end
end
end

# NOTE: Some reopen specs disabled due to MRI bugs. See:
# http://rubyforge.org/tracker/index.php?func=detail&aid=13919&group_id=426&atid=1698
# for details.
describe "StringIO#reopen" do
before(:each) do
@io = StringIO.new('hello','a')
end

# TODO: find out if this is really a bug
ruby_bug "#", "1.8.6.114" do
it "reopens a stream when given a String argument" do
@io.reopen('goodbye').should == @io
@io.string.should == 'goodbye'
@io << 'x'
@io.string.should == 'xoodbye'
end

it "reopens a stream in append mode when flagged as such" do
@io.reopen('goodbye', 'a').should == @io
@io.string.should == 'goodbye'
@io << 'x'
@io.string.should == 'goodbyex'
end

it "reopens and truncate when reopened in write mode" do
@io.reopen('goodbye', 'wb').should == @io
@io.string.should == ''
@io << 'x'
@io.string.should == 'x'
end

it "truncates the given string, not a copy" do
str = 'goodbye'
@io.reopen(str, 'w')
@io.string.should == ''
str.should == ''
end
end

it "taints self if the provided StringIO argument is tainted" do
new_io = StringIO.new("tainted")
new_io.taint
@io.reopen(new_io)
@io.tainted?.should == true
end

it "does not truncate the content even when the StringIO argument is in the truncate mode" do
orig_io = StringIO.new("Original StringIO", IO::RDWR|IO::TRUNC)
orig_io.write("BLAH") # make sure the content is not empty

@io.reopen(orig_io)
@io.string.should == "BLAH"
end

end
23 changes: 23 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/rewind_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#rewind" do
before(:each) do
@io = StringIO.new("hello\nworld")
@io.pos = 3
@io.lineno = 1
end

it "returns 0" do
@io.rewind.should eql(0)
end

it "resets the position" do
@io.rewind
@io.pos.should == 0
end

it "resets the line number" do
@io.rewind
@io.lineno.should == 0
end
end
75 changes: 75 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/seek_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require File.expand_path('../fixtures/classes', __FILE__)

describe "StringIO#seek" do
before(:each) do
@io = StringIO.new("12345678")
end

it "seeks from the current position when whence is IO::SEEK_CUR" do
@io.pos = 1
@io.seek(1, IO::SEEK_CUR)
@io.pos.should eql(2)

@io.seek(-1, IO::SEEK_CUR)
@io.pos.should eql(1)
end

it "seeks from the end of self when whence is IO::SEEK_END" do
@io.seek(3, IO::SEEK_END)
@io.pos.should eql(11) # Outside of the StringIO's content

@io.seek(-2, IO::SEEK_END)
@io.pos.should eql(6)
end

it "seeks to an absolute position when whence is IO::SEEK_SET" do
@io.seek(5, IO::SEEK_SET)
@io.pos.should == 5

@io.pos = 3
@io.seek(5, IO::SEEK_SET)
@io.pos.should == 5
end

it "raises an Errno::EINVAL error on negative amounts when whence is IO::SEEK_SET" do
lambda { @io.seek(-5, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
end

it "raises an Errno::EINVAL error on incorrect whence argument" do
lambda { @io.seek(0, 3) }.should raise_error(Errno::EINVAL)
lambda { @io.seek(0, -1) }.should raise_error(Errno::EINVAL)
lambda { @io.seek(0, 2**16) }.should raise_error(Errno::EINVAL)
lambda { @io.seek(0, -2**16) }.should raise_error(Errno::EINVAL)
end

it "tries to convert the passed Object to a String using #to_int" do
obj = mock("to_int")
obj.should_receive(:to_int).and_return(2)
@io.seek(obj)
@io.pos.should eql(2)
end

it "raises a TypeError when the passed Object can't be converted to an Integer" do
lambda { @io.seek(Object.new) }.should raise_error(TypeError)
end
end

describe "StringIO#seek when self is closed" do
before(:each) do
@io = StringIO.new("example")
@io.close
end

ruby_version_is "" ... "1.8.7" do
it "does not raise an IOError" do
@io.seek(5)
@io.pos.should eql(5)
end
end

ruby_version_is "1.8.7" do
it "raises an IOError" do
lambda { @io.seek(5) }.should raise_error(IOError)
end
end
end
38 changes: 38 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/set_encoding_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'stringio'

ruby_version_is "1.9.2" do
describe "StringIO#set_encoding" do
before :each do
@default_external = Encoding.default_external
Encoding.default_external = Encoding::UTF_8
end

after :each do
Encoding.default_external = @default_external
end

it "sets the encoding of the underlying String to the specified encoding" do
io = StringIO.new
io.set_encoding Encoding::UTF_8
io.string.encoding.should == Encoding::UTF_8
end

it "sets the encoding of the underlying String to the named encoding" do
io = StringIO.new
io.set_encoding "UTF-8"
io.string.encoding.should == Encoding::UTF_8
end

it "sets the encoding of the underlying String to the default external encoding when passed nil" do
Encoding.default_external = Encoding::UTF_8
io = StringIO.new
io.set_encoding nil
io.string.encoding.should == Encoding::UTF_8
end

it "returns self" do
io = StringIO.new
io.set_encoding(Encoding::UTF_8).should equal(io)
end
end
end
45 changes: 45 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/shared/codepoints.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- encoding: utf-8 -*-
describe :stringio_codepoints, :shared => true do
before(:each) do
@io = StringIO.new("∂φ/∂x = gaîté")
@enum = @io.send(@method)
end

it "returns an Enumerator" do
@enum.should be_an_instance_of(enumerator_class)
end

it "yields each codepoint code in turn" do
@enum.to_a.should == [8706, 966, 47, 8706, 120, 32, 61, 32, 103, 97, 238, 116, 233]
end

it "yields each codepoint starting from the current position" do
@io.pos = 15
@enum.to_a.should == [238, 116, 233]
end

it "raises an error if reading invalid sequence" do
@io.pos = 1 # inside of a multibyte sequence
lambda { @enum.first }.should raise_error(ArgumentError)
end

it "raises an IOError if not readable" do
@io.close_read
lambda { @enum.to_a }.should raise_error(IOError)

io = StringIO.new("xyz", "w")
lambda { io.send(@method).to_a }.should raise_error(IOError)
end


it "calls the given block" do
r = []
@io.send(@method){|c| r << c }
r.should == [8706, 966, 47, 8706, 120, 32, 61, 32, 103, 97, 238, 116, 233]
end

it "returns self" do
@io.send(@method) {|l| l }.should equal(@io)
end

end
162 changes: 162 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/shared/each.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
describe :stringio_each_separator, :shared => true do
before(:each) do
@io = StringIO.new("a b c d e\n1 2 3 4 5")
ScratchPad.record []
end

it "uses the passed argument as the line separator" do
seen = []
@io.send(@method, " ") {|s| seen << s}
seen.should == ["a ", "b ", "c ", "d ", "e\n1 ", "2 ", "3 ", "4 ", "5"]
end

it "does not change $_" do
$_ = "test"
@io.send(@method, " ") { |s| s}
$_.should == "test"
end

it "returns self" do
@io.send(@method) {|l| l }.should equal(@io)
end

ruby_version_is "1.9" do
it "returns at most limit characters when limit is positive" do
@io.send(@method, $/, 5) { |x| ScratchPad << x }
ScratchPad.recorded.should == ["a b c", " d e\n", "1 2 3", " 4 5"]
end

it "calls #to_str to convert a single argument to a String" do
sep = mock("stringio each sep")
sep.should_receive(:to_str).at_least(1).times.and_return($/)
sep.should_not_receive(:to_int)

@io.send(@method, sep) { |x| }
end

it "calls #to_int to convert a single argument if #to_str does not return a String" do
limit = mock("stringio each limit")
limit.should_receive(:to_str).at_least(1).times.and_return(nil)
limit.should_receive(:to_int).at_least(1).times.and_return(5)

@io.send(@method, limit) { |x| }
end

it "calls #to_int to convert the limit" do
limit = mock("stringio each limit")
limit.should_receive(:to_int).at_least(1).times.and_return(5)

@io.send(@method, limit) { |x| }
end

it "calls #to_int to convert the limit when passed separator and limit" do
limit = mock("stringio each limit")
limit.should_receive(:to_int).at_least(1).times.and_return(6)

@io.send(@method, $/, limit) { |x| }
end

it "raises an ArgumentError if length is 0 and #each is called on the Enumerator" do
enum = @io.send(@method, 0)
lambda { enum.each { } }.should raise_error(ArgumentError)
end

it "raises an ArgumentError if length is 0" do
lambda { @io.send(@method, 0) { } }.should raise_error(ArgumentError)
end
end

it "tries to convert the passed separator to a String using #to_str" do
obj = mock("to_str")
obj.stub!(:to_str).and_return(" ")

seen = []
@io.send(@method, obj) { |l| seen << l }
seen.should == ["a ", "b ", "c ", "d ", "e\n1 ", "2 ", "3 ", "4 ", "5"]
end

it "yields self's content starting from the current position when the passed separator is nil" do
seen = []
io = StringIO.new("1 2 1 2 1 2")
io.pos = 2
io.send(@method, nil) {|s| seen << s}
seen.should == ["2 1 2 1 2"]
end

ruby_bug "", "1.8.8" do
it "yields each paragraph when passed an empty String as separator" do
seen = []
io = StringIO.new("para1\n\npara2\n\n\npara3")
io.send(@method, "") {|s| seen << s}
seen.should == ["para1\n\n", "para2\n\n", "para3"]
end
end
end

describe :stringio_each_no_arguments, :shared => true do
before(:each) do
@io = StringIO.new("a b c d e\n1 2 3 4 5")
end

it "yields each line to the passed block" do
seen = []
@io.send(@method) {|s| seen << s }
seen.should == ["a b c d e\n", "1 2 3 4 5"]
end

it "yields each line starting from the current position" do
seen = []
@io.pos = 4
@io.send(@method) {|s| seen << s }
seen.should == ["c d e\n", "1 2 3 4 5"]
end

it "does not change $_" do
$_ = "test"
@io.send(@method) { |s| s}
$_.should == "test"
end

it "uses $/ as the default line separator" do
seen = []
begin
old_rs, $/ = $/, " "
@io.send(@method) {|s| seen << s }
seen.should eql(["a ", "b ", "c ", "d ", "e\n1 ", "2 ", "3 ", "4 ", "5"])
ensure
$/ = old_rs
end
end

it "returns self" do
@io.send(@method) {|l| l }.should equal(@io)
end

ruby_version_is "" ... "1.8.7" do
it "yields a LocalJumpError when passed no block" do
lambda { @io.send(@method) }.should raise_error(LocalJumpError)
end
end

ruby_version_is "1.8.7" do
it "returns an Enumerator when passed no block" do
enum = @io.send(@method)
enum.instance_of?(enumerator_class).should be_true

seen = []
enum.each { |b| seen << b }
seen.should == ["a b c d e\n", "1 2 3 4 5"]
end
end
end

describe :stringio_each_not_readable, :shared => true do
it "raises an IOError" do
io = StringIO.new("a b c d e", "w")
lambda { io.send(@method) { |b| b } }.should raise_error(IOError)

io = StringIO.new("a b c d e")
io.close_read
lambda { io.send(@method) { |b| b } }.should raise_error(IOError)
end
end
60 changes: 60 additions & 0 deletions spec/truffle/spec/rubysl/rubysl-stringio/spec/shared/each_byte.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
describe :stringio_each_byte, :shared => true do
before(:each) do
@io = StringIO.new("xyz")
end

it "yields each character code in turn" do
seen = []
@io.send(@method) { |b| seen << b }
seen.should == [120, 121, 122]
end

it "updates the position before each yield" do
seen = []
@io.send(@method) { |b| seen << @io.pos }
seen.should == [1, 2, 3]
end

it "does not yield if the current position is out of bounds" do
@io.pos = 1000
seen = nil
@io.send(@method) { |b| seen = b }
seen.should be_nil
end

ruby_version_is "" ... "1.8.7" do
it "returns nil" do
@io.send(@method) {}.should be_nil
end

it "yields a LocalJumpError when passed no block" do
lambda { @io.send(@method) }.should raise_error(LocalJumpError)
end
end

ruby_version_is "1.8.7" do
it "returns self" do
@io.send(@method) {}.should equal(@io)
end

it "returns an Enumerator when passed no block" do
enum = @io.send(@method)
enum.instance_of?(enumerator_class).should be_true

seen = []
enum.each { |b| seen << b }
seen.should == [120, 121, 122]
end
end
end

describe :stringio_each_byte_not_readable, :shared => true do
it "raises an IOError" do
io = StringIO.new("xyz", "w")
lambda { io.send(@method) { |b| b } }.should raise_error(IOError)

io = StringIO.new("xyz")
io.close_read
lambda { io.send(@method) { |b| b } }.should raise_error(IOError)
end
end
Loading

0 comments on commit e09e135

Please sign in to comment.