diff options
Diffstat (limited to 'spec/ruby/core/string/shared/each_line.rb')
| -rw-r--r-- | spec/ruby/core/string/shared/each_line.rb | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/spec/ruby/core/string/shared/each_line.rb b/spec/ruby/core/string/shared/each_line.rb index dee741e270..127db876ad 100644 --- a/spec/ruby/core/string/shared/each_line.rb +++ b/spec/ruby/core/string/shared/each_line.rb @@ -27,10 +27,17 @@ describe :string_each_line, shared: true do c.should == ["hello\n", "\n", "\n", "world"] end - it "taints substrings that are passed to the block if self is tainted" do - "one\ntwo\r\nthree".taint.send(@method) { |s| s.tainted?.should == true } + it "splits strings containing multibyte characters" do + s = <<~EOS + foo + 🤡🤡🤡🤡🤡🤡🤡 + bar + baz + EOS - "x.y.".send(@method, ".".taint) { |s| s.tainted?.should == false } + b = [] + s.send(@method) { |part| b << part } + b.should == ["foo\n", "🤡🤡🤡🤡🤡🤡🤡\n", "bar\n", "baz\n"] end it "passes self as a whole to the block if the separator is nil" do @@ -39,31 +46,37 @@ describe :string_each_line, shared: true do a.should == ["one\ntwo\r\nthree"] end - ruby_version_is ''...'2.5' do - it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do + context "when passed '' (paragraph mode, broken by 2 or more successive newlines)" do + it "replaces multiple newlines with only two ones" do a = [] "hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s } - a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n"] + a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"] a = [] "hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s } - a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n", "dog"] + a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"] end - end -quarantine! do # Currently fails on Travis - ruby_version_is '2.5' do - it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do + it 'handles \r\n-style newlines' do a = [] - "hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s } - a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"] + "hello\nworld\r\n\r\n\nand\nuniverse\n\r\n\n\n\n".send(@method, '') { |s| a << s } + a.should == ["hello\nworld\r\n\r\n", "and\nuniverse\n\r\n"] a = [] - "hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s } - a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"] + "hello\r\nworld\n\n\nand\nuniverse\n\n\n\r\n\r\ndog".send(@method, '') { |s| a << s } + a.should == ["hello\r\nworld\n\n", "and\nuniverse\n\n", "dog"] + end + + it "removes trailing newlines with `chomp: true`" do + a = [] + "hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '', chomp: true) { |s| a << s } + a.should == ["hello\nworld", "and\nuniverse"] + + a = [] + "hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '', chomp: true) { |s| a << s } + a.should == ["hello\nworld", "and\nuniverse", "dog"] end end -end describe "uses $/" do before :each do @@ -71,7 +84,7 @@ end end after :each do - $/ = @before_separator + suppress_warning {$/ = @before_separator} end it "as the separator when none is given" do @@ -83,10 +96,10 @@ end expected = [] str.send(@method, sep) { |x| expected << x } - $/ = sep + suppress_warning {$/ = sep} actual = [] - str.send(@method) { |x| actual << x } + suppress_warning {str.send(@method) { |x| actual << x }} actual.should == expected end @@ -94,15 +107,15 @@ end end end - it "yields subclass instances for subclasses" do + it "yields String instances for subclasses" do a = [] StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class } - a.should == [StringSpecs::MyString, StringSpecs::MyString] + a.should == [String, String] end it "returns self" do s = "hello\nworld" - (s.send(@method) {}).should equal(s) + (s.send(@method) {}).should.equal?(s) end it "tries to convert the separator to a string using to_str" do @@ -115,15 +128,21 @@ end end it "does not care if the string is modified while substituting" do - str = "hello\nworld." + str = +"hello\nworld." out = [] str.send(@method){|x| out << x; str[-1] = '!' }.should == "hello\nworld!" out.should == ["hello\n", "world."] end + it "returns Strings in the same encoding as self" do + "one\ntwo\r\nthree".encode("US-ASCII").send(@method) do |s| + s.encoding.should == Encoding::US_ASCII + end + end + it "raises a TypeError when the separator can't be converted to a string" do - lambda { "hello world".send(@method, false) {} }.should raise_error(TypeError) - lambda { "hello world".send(@method, mock('x')) {} }.should raise_error(TypeError) + -> { "hello world".send(@method, false) {} }.should.raise(TypeError) + -> { "hello world".send(@method, mock('x')) {} }.should.raise(TypeError) end it "accepts a string separator" do @@ -131,20 +150,49 @@ end end it "raises a TypeError when the separator is a symbol" do - lambda { "hello world".send(@method, :o).to_a }.should raise_error(TypeError) + -> { "hello world".send(@method, :o).to_a }.should.raise(TypeError) end - ruby_version_is '2.4' do - context "when `chomp` keyword argument is passed" do - it "removes new line characters" do - a = [] - "hello \nworld\n".send(@method, chomp: true) { |s| a << s } - a.should == ["hello ", "world"] + context "when `chomp` keyword argument is passed" do + it "removes new line characters when separator is not specified" do + a = [] + "hello \nworld\n".send(@method, chomp: true) { |s| a << s } + a.should == ["hello ", "world"] - a = [] - "hello \r\nworld\r\n".send(@method, chomp: true) { |s| a << s } - a.should == ["hello ", "world"] - end + a = [] + "hello \r\nworld\r\n".send(@method, chomp: true) { |s| a << s } + a.should == ["hello ", "world"] + end + + it "removes only specified separator" do + a = [] + "hello world".send(@method, ' ', chomp: true) { |s| a << s } + a.should == ["hello", "world"] + end + + # https://bugs.ruby-lang.org/issues/14257 + it "ignores new line characters when separator is specified" do + a = [] + "hello\n world\n".send(@method, ' ', chomp: true) { |s| a << s } + a.should == ["hello\n", "world\n"] + + a = [] + "hello\r\n world\r\n".send(@method, ' ', chomp: true) { |s| a << s } + a.should == ["hello\r\n", "world\r\n"] end end + + it "does not split lines for dummy UTF-16" do + "a\nb".encode(Encoding::UTF_16).lines.should == [ + "\xFE\xFF\x00\x61\x00\n\x00\x62".dup.force_encoding(Encoding::UTF_16) + ] + + str = "\x00\n\n\x00".dup.force_encoding(Encoding::UTF_16) + str.lines.should == [str] + end + + it "raises Encoding::ConverterNotFoundError for dummy UTF-7" do + str = "a\nb".dup.force_encoding(Encoding::UTF_7) + -> { str.lines }.should.raise(Encoding::ConverterNotFoundError) + end end |
