1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/ruby/core/io/gets_spec.rb
Jeremy Evans ffd0820ab3 Deprecate taint/trust and related methods, and make the methods no-ops
This removes the related tests, and puts the related specs behind
version guards.  This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
2019-11-18 01:00:25 +02:00

327 lines
8.7 KiB
Ruby

# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/gets_ascii'
describe "IO#gets" do
it_behaves_like :io_gets_ascii, :gets
end
describe "IO#gets" do
before :each do
@io = IOSpecs.io_fixture "lines.txt"
@count = 0
end
after :each do
@io.close if @io
end
it "assigns the returned line to $_" do
IOSpecs.lines.each do |line|
@io.gets
$_.should == line
end
end
it "returns nil if called at the end of the stream" do
IOSpecs.lines.length.times { @io.gets }
@io.gets.should == nil
end
it "raises IOError on closed stream" do
-> { IOSpecs.closed_io.gets }.should raise_error(IOError)
end
describe "with no separator" do
it "returns the next line of string that is separated by $/" do
IOSpecs.lines.each { |line| line.should == @io.gets }
end
ruby_version_is ''...'2.7' do
it "returns tainted strings" do
while line = @io.gets
line.tainted?.should == true
end
end
end
it "updates lineno with each invocation" do
while @io.gets
@io.lineno.should == @count += 1
end
end
it "updates $. with each invocation" do
while @io.gets
$..should == @count += 1
end
end
end
describe "with nil separator" do
it "returns the entire contents" do
@io.gets(nil).should == IOSpecs.lines.join("")
end
ruby_version_is ''...'2.7' do
it "returns tainted strings" do
while line = @io.gets(nil)
line.tainted?.should == true
end
end
end
it "updates lineno with each invocation" do
while @io.gets(nil)
@io.lineno.should == @count += 1
end
end
it "updates $. with each invocation" do
while @io.gets(nil)
$..should == @count += 1
end
end
end
describe "with an empty String separator" do
# Two successive newlines in the input separate paragraphs.
# When there are more than two successive newlines, only two are kept.
it "returns the next paragraph" do
@io.gets("").should == IOSpecs.lines[0,3].join("")
@io.gets("").should == IOSpecs.lines[4,3].join("")
@io.gets("").should == IOSpecs.lines[7,2].join("")
end
it "reads until the beginning of the next paragraph" do
# There are three newlines between the first and second paragraph
@io.gets("")
@io.gets.should == IOSpecs.lines[4]
end
ruby_version_is ''...'2.7' do
it "returns tainted strings" do
while line = @io.gets("")
line.tainted?.should == true
end
end
end
it "updates lineno with each invocation" do
while @io.gets("")
@io.lineno.should == @count += 1
end
end
it "updates $. with each invocation" do
while @io.gets("")
$..should == @count += 1
end
end
end
describe "with an arbitrary String separator" do
it "reads up to and including the separator" do
@io.gets("la linea").should == "Voici la ligne une.\nQui \303\250 la linea"
end
ruby_version_is ''...'2.7' do
it "returns tainted strings" do
while line = @io.gets("la")
line.tainted?.should == true
end
end
end
it "updates lineno with each invocation" do
while (@io.gets("la"))
@io.lineno.should == @count += 1
end
end
it "updates $. with each invocation" do
while @io.gets("la")
$..should == @count += 1
end
end
end
describe "when passed chomp" do
it "returns the first line without a trailing newline character" do
@io.gets(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
end
end
end
describe "IO#gets" do
before :each do
@name = tmp("io_gets")
end
after :each do
rm_r @name
end
it "raises an IOError if the stream is opened for append only" do
-> { File.open(@name, "a:utf-8") { |f| f.gets } }.should raise_error(IOError)
end
it "raises an IOError if the stream is opened for writing only" do
-> { File.open(@name, "w:utf-8") { |f| f.gets } }.should raise_error(IOError)
end
end
describe "IO#gets" do
before :each do
@name = tmp("io_gets")
touch(@name) { |f| f.write "one\n\ntwo\n\nthree\nfour\n" }
@io = new_io @name, "r:utf-8"
end
after :each do
@io.close if @io
rm_r @name
end
it "calls #to_int to convert a single object argument to an Integer limit" do
obj = mock("io gets limit")
obj.should_receive(:to_int).and_return(6)
@io.gets(obj).should == "one\n"
end
it "calls #to_int to convert the second object argument to an Integer limit" do
obj = mock("io gets limit")
obj.should_receive(:to_int).and_return(2)
@io.gets(nil, obj).should == "on"
end
it "calls #to_str to convert the first argument to a String when passed a limit" do
obj = mock("io gets separator")
obj.should_receive(:to_str).and_return($/)
@io.gets(obj, 5).should == "one\n"
end
it "reads to the default separator when passed a single argument greater than the number of bytes to the separator" do
@io.gets(6).should == "one\n"
end
it "reads limit bytes when passed a single argument less than the number of bytes to the default separator" do
@io.gets(3).should == "one"
end
it "reads limit bytes when passed nil and a limit" do
@io.gets(nil, 6).should == "one\n\nt"
end
it "reads all bytes when the limit is higher than the available bytes" do
@io.gets(nil, 100).should == "one\n\ntwo\n\nthree\nfour\n"
end
it "reads until the next paragraph when passed '' and a limit greater than the next paragraph" do
@io.gets("", 6).should == "one\n\n"
end
it "reads limit bytes when passed '' and a limit less than the next paragraph" do
@io.gets("", 3).should == "one"
end
it "reads all bytes when pass a separator and reading more than all bytes" do
@io.gets("\t", 100).should == "one\n\ntwo\n\nthree\nfour\n"
end
end
describe "IO#gets" do
before :each do
@name = tmp("io_gets")
# create data "朝日" + "\xE3\x81" * 100 to avoid utf-8 conflicts
data = "朝日" + ([227,129].pack('C*') * 100).force_encoding('utf-8')
touch(@name) { |f| f.write data }
@io = new_io @name, "r:utf-8"
end
after :each do
@io.close if @io
rm_r @name
end
it "reads limit bytes and extra bytes when limit is reached not at character boundary" do
[@io.gets(1), @io.gets(1)].should == ["", ""]
end
it "read limit bytes and extra bytes with maximum of 16" do
# create str "朝日\xE3" + "\x81\xE3" * 8 to avoid utf-8 conflicts
str = "朝日" + ([227] + [129,227] * 8).pack('C*').force_encoding('utf-8')
@io.gets(7).should == str
end
end
describe "IO#gets" do
before :each do
@external = Encoding.default_external
@internal = Encoding.default_internal
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = nil
@name = tmp("io_gets")
touch(@name) { |f| f.write "line" }
end
after :each do
@io.close if @io
rm_r @name
Encoding.default_external = @external
Encoding.default_internal = @internal
end
it "uses the default external encoding" do
@io = new_io @name, 'r'
@io.gets.encoding.should == Encoding::UTF_8
end
it "uses the IO object's external encoding, when set" do
@io = new_io @name, 'r'
@io.set_encoding Encoding::US_ASCII
@io.gets.encoding.should == Encoding::US_ASCII
end
it "transcodes into the default internal encoding" do
Encoding.default_internal = Encoding::US_ASCII
@io = new_io @name, 'r'
@io.gets.encoding.should == Encoding::US_ASCII
end
it "transcodes into the IO object's internal encoding, when set" do
Encoding.default_internal = Encoding::US_ASCII
@io = new_io @name, 'r'
@io.set_encoding Encoding::UTF_8, Encoding::UTF_16
@io.gets.encoding.should == Encoding::UTF_16
end
it "overwrites the default external encoding with the IO object's own external encoding" do
Encoding.default_external = Encoding::BINARY
Encoding.default_internal = Encoding::UTF_8
@io = new_io @name, 'r'
@io.set_encoding Encoding::IBM866
@io.gets.encoding.should == Encoding::UTF_8
end
it "ignores the internal encoding if the default external encoding is BINARY" do
Encoding.default_external = Encoding::BINARY
Encoding.default_internal = Encoding::UTF_8
@io = new_io @name, 'r'
@io.gets.encoding.should == Encoding::BINARY
end
it "transcodes to internal encoding if the IO object's external encoding is BINARY" do
Encoding.default_external = Encoding::BINARY
Encoding.default_internal = Encoding::UTF_8
@io = new_io @name, 'r'
@io.set_encoding Encoding::BINARY, Encoding::UTF_8
@io.gets.encoding.should == Encoding::UTF_8
end
end