diff options
author | Jeremy Evans <code@jeremyevans.net> | 2020-10-24 11:52:30 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2020-11-20 16:30:23 -0800 |
commit | 58325daae3beefda13ed100782cd19a89cc68771 (patch) | |
tree | fd1857904c1c86d9c7c21f6038535f3beeafc4bb /spec/ruby/core/string/split_spec.rb | |
parent | 4f5d14eb8cb7fba1c583d516d597c5e28d7a5540 (diff) |
Make String methods return String instances when called on a subclass instance
This modifies the following String methods to return String instances
instead of subclass instances:
* String#*
* String#capitalize
* String#center
* String#chomp
* String#chop
* String#delete
* String#delete_prefix
* String#delete_suffix
* String#downcase
* String#dump
* String#each/#each_line
* String#gsub
* String#ljust
* String#lstrip
* String#partition
* String#reverse
* String#rjust
* String#rpartition
* String#rstrip
* String#scrub
* String#slice!
* String#slice/#[]
* String#split
* String#squeeze
* String#strip
* String#sub
* String#succ/#next
* String#swapcase
* String#tr
* String#tr_s
* String#upcase
This also fixes a bug in String#swapcase where it would return the
receiver instead of a copy of the receiver if the receiver was the
empty string.
Some string methods were left to return subclass instances:
* String#+@
* String#-@
Both of these methods will return the receiver (subclass instance)
in some cases, so it is best to keep the returned class consistent.
Fixes [#10845]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3701
Diffstat (limited to 'spec/ruby/core/string/split_spec.rb')
-rw-r--r-- | spec/ruby/core/string/split_spec.rb | 120 |
1 files changed, 86 insertions, 34 deletions
diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb index 7ac8d7815c..c5441e3a49 100644 --- a/spec/ruby/core/string/split_spec.rb +++ b/spec/ruby/core/string/split_spec.rb @@ -159,28 +159,48 @@ describe "String#split with String" do "foo".split("bar", 3).should == ["foo"] end - it "returns subclass instances based on self" do - ["", "x.y.z.", " x y "].each do |str| - ["", ".", " "].each do |pat| - [-1, 0, 1, 2].each do |limit| - StringSpecs::MyString.new(str).split(pat, limit).each do |x| - x.should be_an_instance_of(StringSpecs::MyString) - end + ruby_version_is ''...'3.0' do + it "returns subclass instances based on self" do + ["", "x.y.z.", " x y "].each do |str| + ["", ".", " "].each do |pat| + [-1, 0, 1, 2].each do |limit| + StringSpecs::MyString.new(str).split(pat, limit).each do |x| + x.should be_an_instance_of(StringSpecs::MyString) + end - str.split(StringSpecs::MyString.new(pat), limit).each do |x| - x.should be_an_instance_of(String) + str.split(StringSpecs::MyString.new(pat), limit).each do |x| + x.should be_an_instance_of(String) + end end end end end + + it "does not call constructor on created subclass instances" do + # can't call should_not_receive on an object that doesn't yet exist + # so failure here is signalled by exception, not expectation failure + + s = StringSpecs::StringWithRaisingConstructor.new('silly:string') + s.split(':').first.should == 'silly' + end end - it "does not call constructor on created subclass instances" do - # can't call should_not_receive on an object that doesn't yet exist - # so failure here is signalled by exception, not expectation failure + ruby_version_is '3.0' do + it "returns String instances based on self" do + ["", "x.y.z.", " x y "].each do |str| + ["", ".", " "].each do |pat| + [-1, 0, 1, 2].each do |limit| + StringSpecs::MyString.new(str).split(pat, limit).each do |x| + x.should be_an_instance_of(String) + end - s = StringSpecs::StringWithRaisingConstructor.new('silly:string') - s.split(':').first.should == 'silly' + str.split(StringSpecs::MyString.new(pat), limit).each do |x| + x.should be_an_instance_of(String) + end + end + end + end + end end ruby_version_is ''...'2.7' do @@ -355,24 +375,40 @@ describe "String#split with Regexp" do "foo".split(/bar/, 3).should == ["foo"] end - it "returns subclass instances based on self" do - ["", "x:y:z:", " x y "].each do |str| - [//, /:/, /\s+/].each do |pat| - [-1, 0, 1, 2].each do |limit| - StringSpecs::MyString.new(str).split(pat, limit).each do |x| - x.should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances based on self" do + ["", "x:y:z:", " x y "].each do |str| + [//, /:/, /\s+/].each do |pat| + [-1, 0, 1, 2].each do |limit| + StringSpecs::MyString.new(str).split(pat, limit).each do |x| + x.should be_an_instance_of(StringSpecs::MyString) + end end end end end - end - it "does not call constructor on created subclass instances" do - # can't call should_not_receive on an object that doesn't yet exist - # so failure here is signalled by exception, not expectation failure + it "does not call constructor on created subclass instances" do + # can't call should_not_receive on an object that doesn't yet exist + # so failure here is signalled by exception, not expectation failure + + s = StringSpecs::StringWithRaisingConstructor.new('silly:string') + s.split(/:/).first.should == 'silly' + end + end - s = StringSpecs::StringWithRaisingConstructor.new('silly:string') - s.split(/:/).first.should == 'silly' + ruby_version_is '3.0' do + it "returns String instances based on self" do + ["", "x:y:z:", " x y "].each do |str| + [//, /:/, /\s+/].each do |pat| + [-1, 0, 1, 2].each do |limit| + StringSpecs::MyString.new(str).split(pat, limit).each do |x| + x.should be_an_instance_of(String) + end + end + end + end + end end ruby_version_is ''...'2.7' do @@ -493,16 +529,32 @@ describe "String#split with Regexp" do end describe "for a String subclass" do - it "yields instances of the same subclass" do - a = [] - StringSpecs::MyString.new("a|b").split("|") { |str| a << str } - first, last = a + ruby_version_is ''...'3.0' do + it "yields instances of the same subclass" do + a = [] + StringSpecs::MyString.new("a|b").split("|") { |str| a << str } + first, last = a + + first.should be_an_instance_of(StringSpecs::MyString) + first.should == "a" - first.should be_an_instance_of(StringSpecs::MyString) - first.should == "a" + last.should be_an_instance_of(StringSpecs::MyString) + last.should == "b" + end + end + + ruby_version_is '3.0' do + it "yields instances of String" do + a = [] + StringSpecs::MyString.new("a|b").split("|") { |str| a << str } + first, last = a - last.should be_an_instance_of(StringSpecs::MyString) - last.should == "b" + first.should be_an_instance_of(String) + first.should == "a" + + last.should be_an_instance_of(String) + last.should == "b" + end end end end |