diff options
Diffstat (limited to 'spec/ruby/core/io/copy_stream_spec.rb')
| -rw-r--r-- | spec/ruby/core/io/copy_stream_spec.rb | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/spec/ruby/core/io/copy_stream_spec.rb b/spec/ruby/core/io/copy_stream_spec.rb index 344746fac3..31383f9b0f 100644 --- a/spec/ruby/core/io/copy_stream_spec.rb +++ b/spec/ruby/core/io/copy_stream_spec.rb @@ -1,5 +1,5 @@ -require File.expand_path('../../../spec_helper', __FILE__) -require File.expand_path('../fixtures/classes', __FILE__) +require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe :io_copy_stream_to_file, shared: true do it "copies the entire IO contents to the file" do @@ -31,7 +31,7 @@ describe :io_copy_stream_to_file, shared: true do obj = mock("io_copy_stream_to") obj.should_receive(:to_path).and_return(1) - lambda { IO.copy_stream(@object.from, obj) }.should raise_error(TypeError) + -> { IO.copy_stream(@object.from, obj) }.should.raise(TypeError) end end @@ -69,14 +69,17 @@ describe :io_copy_stream_to_io, shared: true do end it "raises an IOError if the destination IO is not open for writing" do - @to_io.close - @to_io = new_io @to_name, "r" - lambda { IO.copy_stream @object.from, @to_io }.should raise_error(IOError) + to_io = new_io __FILE__, "r" + begin + -> { IO.copy_stream @object.from, to_io }.should.raise(IOError) + ensure + to_io.close + end end it "does not close the destination IO" do IO.copy_stream(@object.from, @to_io) - @to_io.closed?.should be_false + @to_io.closed?.should == false end it "copies only length bytes when specified" do @@ -109,7 +112,8 @@ describe "IO.copy_stream" do end after :each do - rm_r @to_name, @from_bigfile + rm_r @to_name if @to_name + rm_r @from_bigfile end describe "from an IO" do @@ -125,12 +129,12 @@ describe "IO.copy_stream" do it "raises an IOError if the source IO is not open for reading" do @from_io.close @from_io = new_io @from_bigfile, "a" - lambda { IO.copy_stream @from_io, @to_name }.should raise_error(IOError) + -> { IO.copy_stream @from_io, @to_name }.should.raise(IOError) end it "does not close the source IO" do IO.copy_stream(@from_io, @to_name) - @from_io.closed?.should be_false + @from_io.closed?.should == false end platform_is_not :windows do @@ -164,6 +168,25 @@ describe "IO.copy_stream" do it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream end + + describe "to a Tempfile" do + before :all do + require 'tempfile' + end + + before :each do + @to_io = Tempfile.new("rubyspec_copy_stream", encoding: Encoding::BINARY, mode: File::RDONLY) + @to_name = @to_io.path + end + + after :each do + @to_io.close! + @to_name = nil # do not rm_r it, already done by Tempfile#close! + end + + it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream + it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream + end end describe "from a file name" do @@ -183,7 +206,7 @@ describe "IO.copy_stream" do obj = mock("io_copy_stream_from") obj.should_receive(:to_path).and_return(1) - lambda { IO.copy_stream(obj, @to_name) }.should raise_error(TypeError) + -> { IO.copy_stream(obj, @to_name) }.should.raise(TypeError) end describe "to a file name" do @@ -217,12 +240,12 @@ describe "IO.copy_stream" do it "does not close the source IO" do IO.copy_stream(@from_io, @to_name) - @from_io.closed?.should be_false + @from_io.closed?.should == false end platform_is_not :windows do it "raises an error when an offset is specified" do - lambda { IO.copy_stream(@from_io, @to_name, 8, 4) }.should raise_error(Errno::ESPIPE) + -> { IO.copy_stream(@from_io, @to_name, 8, 4) }.should.raise(Errno::ESPIPE) end end @@ -278,5 +301,51 @@ describe "IO.copy_stream" do IO.copy_stream(@io, @to_name) end + it "does not call #read on the source or #write on the destination if zero length is given" do + from = mock("io_copy_stream_to_object_zero_length_read") + to = mock("io_copy_stream_to_object_zero_length_write") + from.should_not_receive(:read) + to.should_not_receive(:write) + IO.copy_stream(from, to, 0) + end + end + + describe "with a destination that does partial reads" do + before do + @from_out, @from_in = IO.pipe + @to_out, @to_in = IO.pipe + end + + after do + [@from_out, @from_in, @to_out, @to_in].each {|io| io.close rescue nil} + end + + it "calls #write repeatedly on the destination Object" do + @from_in.write "1234" + @from_in.close + + th = Thread.new do + IO.copy_stream(@from_out, @to_in) + end + + copied = "" + 4.times do + copied += @to_out.read(1) + end + + th.join + + copied.should == "1234" + end + + end +end + +describe "IO.copy_stream" do + it "does not use buffering when writing to STDOUT" do + IO.popen([*ruby_exe, fixture(__FILE__ , "copy_in_out.rb")], "r+") do |io| + io.write("bar") + io.read(3).should == "bar" + end end end |
