diff options
Diffstat (limited to 'spec/ruby/core')
22 files changed, 606 insertions, 26 deletions
diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb new file mode 100644 index 0000000000..a80e685996 --- /dev/null +++ b/spec/ruby/core/dir/children_spec.rb @@ -0,0 +1,72 @@ +# encoding: utf-8 + +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/common', __FILE__) + +ruby_version_is "2.5" do + describe "Dir.children" do + before :all do + DirSpecs.create_mock_dirs + end + + before :each do + @internal = Encoding.default_internal + end + + after :all do + DirSpecs.delete_mock_dirs + end + + after :each do + Encoding.default_internal = @internal + end + + it "returns an Array of filenames in an existing directory including dotfiles" do + a = Dir.children(DirSpecs.mock_dir).sort + + a.should == DirSpecs.expected_paths - %w[. ..] + + a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested").sort + a.should == %w|.dotfile.ext directory| + end + + it "calls #to_path on non-String arguments" do + p = mock('path') + p.should_receive(:to_path).and_return(DirSpecs.mock_dir) + Dir.children(p) + end + + it "accepts an options Hash" do + a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort + a.should == %w|.dotfile.ext directory| + end + + it "returns children encoded with the filesystem encoding by default" do + # This spec depends on the locale not being US-ASCII because if it is, the + # children that are not ascii_only? will be ASCII-8BIT encoded. + children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort + encoding = Encoding.find("filesystem") + encoding = Encoding::ASCII_8BIT if encoding == Encoding::US_ASCII + platform_is_not :windows do + children.should include("こんにちは.txt".force_encoding(encoding)) + end + children.first.encoding.should equal(Encoding.find("filesystem")) + end + + it "returns children encoded with the specified encoding" do + dir = File.join(DirSpecs.mock_dir, 'special') + children = Dir.children(dir, encoding: "euc-jp").sort + children.first.encoding.should equal(Encoding::EUC_JP) + end + + it "returns children transcoded to the default internal encoding" do + Encoding.default_internal = Encoding::EUC_KR + children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort + children.first.encoding.should equal(Encoding::EUC_KR) + end + + it "raises a SystemCallError if called with a nonexistent diretory" do + lambda { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError) + end + end +end diff --git a/spec/ruby/core/dir/each_child_spec.rb b/spec/ruby/core/dir/each_child_spec.rb new file mode 100644 index 0000000000..70f6f63333 --- /dev/null +++ b/spec/ruby/core/dir/each_child_spec.rb @@ -0,0 +1,53 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/common', __FILE__) + +ruby_version_is "2.5" do + describe "Dir.each_child" do + before :all do + DirSpecs.create_mock_dirs + end + + after :all do + DirSpecs.delete_mock_dirs + end + + it "yields all names in an existing directory to the provided block" do + a, b = [], [] + + Dir.each_child(DirSpecs.mock_dir) {|f| a << f} + Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested") {|f| b << f} + + a.sort.should == DirSpecs.expected_paths - %w[. ..] + b.sort.should == %w|.dotfile.ext directory| + end + + it "returns nil when successful" do + Dir.each_child(DirSpecs.mock_dir) {|f| f}.should == nil + end + + it "calls #to_path on non-String arguments" do + p = mock('path') + p.should_receive(:to_path).and_return(DirSpecs.mock_dir) + Dir.each_child(p).to_a + end + + it "raises a SystemCallError if passed a nonexistent directory" do + lambda { Dir.each_child(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError) + end + + describe "when no block is given" do + it "returns an Enumerator" do + Dir.each_child(DirSpecs.mock_dir).should be_an_instance_of(Enumerator) + Dir.each_child(DirSpecs.mock_dir).to_a.sort.should == DirSpecs.expected_paths - %w[. ..] + end + + describe "returned Enumerator" do + describe "size" do + it "should return nil" do + Dir.each_child(DirSpecs.mock_dir).size.should == nil + end + end + end + end + end +end diff --git a/spec/ruby/core/encoding/locale_charmap_spec.rb b/spec/ruby/core/encoding/locale_charmap_spec.rb index 12b93c2562..a9f0cd5ee0 100644 --- a/spec/ruby/core/encoding/locale_charmap_spec.rb +++ b/spec/ruby/core/encoding/locale_charmap_spec.rb @@ -16,7 +16,7 @@ with_feature :encoding do end end - platform_is :freebsd, :darwin do + platform_is :freebsd, :openbsd, :darwin do it "returns a value based on the LC_ALL environment variable" do old_lc_all = ENV['LC_ALL'] ENV['LC_ALL'] = 'C' @@ -25,7 +25,7 @@ with_feature :encoding do end end - platform_is :netbsd, :openbsd do + platform_is :netbsd do it "returns a value based on the LC_ALL environment variable" do old_lc_all = ENV['LC_ALL'] ENV['LC_ALL'] = 'C' diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb index bfde584260..9e40315baa 100644 --- a/spec/ruby/core/enumerable/all_spec.rb +++ b/spec/ruby/core/enumerable/all_spec.rb @@ -54,10 +54,20 @@ describe "Enumerable#all?" do end it "gathers whole arrays as elements when each yields multiple" do + # This spec doesn't spec what it says it does multi = EnumerableSpecs::YieldsMultiWithFalse.new multi.all?.should be_true end + ruby_version_is "2.5" do + describe "given a pattern argument" do + # This spec should be replaced by more extensive ones + it "returns true iff all match that pattern" do + @enum.all?(Integer).should == true + @enum2.all?(NilClass).should == false + end + end + end end describe "with block" do @@ -116,6 +126,5 @@ describe "Enumerable#all?" do multi.all? {|e, i| yielded << [e, i] } yielded.should == [[1, 2], [3, 4], [6, 7]] end - end end diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb index 0646c13b34..89472d6ee1 100644 --- a/spec/ruby/core/enumerable/none_spec.rb +++ b/spec/ruby/core/enumerable/none_spec.rb @@ -13,9 +13,20 @@ describe "Enumerable#none?" do end it "gathers whole arrays as elements when each yields multiple" do + # This spec doesn't spec what it says it does multi = EnumerableSpecs::YieldsMultiWithFalse.new multi.none?.should be_false end + + ruby_version_is "2.5" do + describe "given a pattern argument" do + # This spec should be replaced by more extensive ones + it "returns true iff none match that pattern" do + EnumerableSpecs::Numerous.new.none?(Float).should == true + [nil, false, true].none?(NilClass).should == false + end + end + end end describe "Enumerable#none? with a block" do diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb index 818d4663a4..5f118e3323 100644 --- a/spec/ruby/core/enumerable/one_spec.rb +++ b/spec/ruby/core/enumerable/one_spec.rb @@ -16,6 +16,7 @@ describe "Enumerable#one?" do end it "gathers initial args as elements when each yields multiple" do + # This spec doesn't spec what it says it does multi = EnumerableSpecs::YieldsMulti.new multi.one? {|e| e == 1 }.should be_true end @@ -26,6 +27,16 @@ describe "Enumerable#one?" do multi.one? {|e, i| yielded << [e, i] } yielded.should == [[1, 2], [3, 4]] end + + ruby_version_is "2.5" do + describe "given a pattern argument" do + # This spec should be replaced by more extensive ones + it "returns true iff none match that pattern" do + EnumerableSpecs::Numerous.new.one?(Integer).should == false + [nil, false, true].one?(NilClass).should == true + end + end + end end describe "when not passed a block" do diff --git a/spec/ruby/core/file/chown_spec.rb b/spec/ruby/core/file/chown_spec.rb index a0b46e9e39..6266e12bfd 100644 --- a/spec/ruby/core/file/chown_spec.rb +++ b/spec/ruby/core/file/chown_spec.rb @@ -91,17 +91,17 @@ describe "File#chown" do as_superuser do platform_is :windows do it "does not modify the owner id of the file" do - File.chown 0, nil, @fname - File.stat(@fname).uid.should == 0 - File.chown 501, nil, @fname - File.stat(@fname).uid.should == 0 + @file.chown 0, nil + @file.stat.uid.should == 0 + @file.chown 501, nil + @file.stat.uid.should == 0 end it "does not modify the group id of the file" do - File.chown nil, 0, @fname - File.stat(@fname).gid.should == 0 - File.chown nil, 501, @fname - File.stat(@fname).gid.should == 0 + @file.chown nil, 0 + @file.stat.gid.should == 0 + @file.chown nil, 501 + @file.stat.gid.should == 0 end end diff --git a/spec/ruby/core/file/shared/read.rb b/spec/ruby/core/file/shared/read.rb index 916a6222bf..e37523c244 100644 --- a/spec/ruby/core/file/shared/read.rb +++ b/spec/ruby/core/file/shared/read.rb @@ -1,13 +1,13 @@ require File.expand_path('../../../dir/fixtures/common', __FILE__) describe :file_read_directory, shared: true do - platform_is :darwin, :linux, :windows do + platform_is :darwin, :linux, :openbsd, :windows do it "raises an Errno::EISDIR when passed a path that is a directory" do lambda { @object.send(@method, ".") }.should raise_error(Errno::EISDIR) end end - platform_is :bsd do + platform_is :freebsd, :netbsd do it "does not raises any exception when passed a path that is a directory" do lambda { @object.send(@method, ".") }.should_not raise_error end diff --git a/spec/ruby/core/file/stat/inspect_spec.rb b/spec/ruby/core/file/stat/inspect_spec.rb index dd2ad21da3..ec99ab16a8 100644 --- a/spec/ruby/core/file/stat/inspect_spec.rb +++ b/spec/ruby/core/file/stat/inspect_spec.rb @@ -16,7 +16,7 @@ describe "File::Stat#inspect" do expected = "#<File::Stat dev=0x#{st.dev.to_s(16)}, ino=#{st.ino}, mode=#{sprintf("%07o", st.mode)}, nlink=#{st.nlink}" expected << ", uid=#{st.uid}, gid=#{st.gid}, rdev=0x#{st.rdev.to_s(16)}, size=#{st.size}, blksize=#{st.blksize.inspect}" expected << ", blocks=#{st.blocks.inspect}, atime=#{st.atime}, mtime=#{st.mtime}, ctime=#{st.ctime}" - platform_is :bsd, :darwin do + platform_is :netbsd, :freebsd, :darwin do # Windows has File.birthtime but it's not here since already shown by ctime. expected << ", birthtime=#{st.birthtime}" end diff --git a/spec/ruby/core/hash/slice_spec.rb b/spec/ruby/core/hash/slice_spec.rb new file mode 100644 index 0000000000..15c9c815ff --- /dev/null +++ b/spec/ruby/core/hash/slice_spec.rb @@ -0,0 +1,36 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +ruby_version_is "2.5" do + describe "Hash#slice" do + before :each do + @hash = { a: 1, b: 2, c: 3 } + end + + it "returns new hash" do + ret = @hash.slice + ret.should_not equal(@hash) + ret.should be_an_instance_of(Hash) + end + + it "returns the requested subset" do + @hash.slice(:c, :a).should == { c: 3, a: 1 } + end + + it "returns a hash ordered in the order of the requested keys" do + @hash.slice(:c, :a).keys.should == [:c, :a] + end + + it "returns only the keys of the original hash" do + @hash.slice(:a, :chunky_bacon).should == { a: 1 } + end + + it "returns a Hash instance, even on subclasses" do + klass = Class.new(Hash) + h = klass.new + h[:foo] = 42 + r = h.slice(:foo) + r.should == {foo: 42} + r.class.should == Hash + end + end +end diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb new file mode 100644 index 0000000000..379638bd4b --- /dev/null +++ b/spec/ruby/core/hash/transform_keys_spec.rb @@ -0,0 +1,110 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +ruby_version_is "2.5" do + describe "Hash#transform_keys" do + before :each do + @hash = { a: 1, b: 2, c: 3 } + end + + it "returns new hash" do + ret = @hash.transform_keys(&:succ) + ret.should_not equal(@hash) + ret.should be_an_instance_of(Hash) + end + + it "sets the result as transformed keys with the given block" do + @hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 } + end + + it "keeps last pair if new keys conflict" do + @hash.transform_keys { |_| :a }.should == { a: 3 } + end + + it "makes both hashes to share values" do + value = [1, 2, 3] + new_hash = { a: value }.transform_keys(&:upcase) + new_hash[:A].should equal(value) + end + + context "when no block is given" do + it "returns a sized Enumerator" do + enumerator = @hash.transform_keys + enumerator.should be_an_instance_of(Enumerator) + enumerator.size.should == @hash.size + enumerator.each(&:succ).should == { b: 1, c: 2, d: 3 } + end + end + + it "returns a Hash instance, even on subclasses" do + klass = Class.new(Hash) + h = klass.new + h[:foo] = 42 + r = h.transform_keys{|v| :"x#{v}"} + r.keys.should == [:xfoo] + r.class.should == Hash + end + end + + describe "Hash#transform_keys!" do + before :each do + @hash = { a: 1, b: 2, c: 3, d: 4 } + @initial_pairs = @hash.dup + end + + it "returns self" do + @hash.transform_keys!(&:succ).should equal(@hash) + end + + it "updates self as transformed values with the given block" do + @hash.transform_keys!(&:to_s) + @hash.should == { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 } + end + + it "does not prevent conflicts between new keys and old ones" do + @hash.transform_keys!(&:succ) + @hash.should == { e: 1 } + end + + it "partially modifies the contents if we broke from the block" do + @hash.transform_keys! do |v| + break if v == :c + v.succ + end + @hash.should == { c: 1, d: 4 } + end + + it "keeps later pair if new keys conflict" do + @hash.transform_keys! { |_| :a }.should == { a: 4 } + end + + context "when no block is given" do + it "returns a sized Enumerator" do + enumerator = @hash.transform_keys! + enumerator.should be_an_instance_of(Enumerator) + enumerator.size.should == @hash.size + enumerator.each(&:upcase).should == { A: 1, B: 2, C: 3, D: 4 } + end + end + + describe "on frozen instance" do + before :each do + @hash.freeze + end + + it "raises a RuntimeError on an empty hash" do + ->{ {}.freeze.transform_keys!(&:upcase) }.should raise_error(RuntimeError) + end + + it "keeps pairs and raises a RuntimeError" do + ->{ @hash.transform_keys!(&:upcase) }.should raise_error(RuntimeError) + @hash.should == @initial_pairs + end + + context "when no block is given" do + it "does not raise an exception" do + @hash.transform_keys!.should be_an_instance_of(Enumerator) + end + end + end + end +end diff --git a/spec/ruby/core/hash/transform_values_spec.rb b/spec/ruby/core/hash/transform_values_spec.rb index 0c9e43d621..a9098a9f2d 100644 --- a/spec/ruby/core/hash/transform_values_spec.rb +++ b/spec/ruby/core/hash/transform_values_spec.rb @@ -16,6 +16,13 @@ ruby_version_is "2.4" do @hash.transform_values(&:succ).should == { a: 2, b: 3, c: 4 } end + it "makes both hashes to share keys" do + key = [1, 2, 3] + new_hash = { key => 1 }.transform_values(&:succ) + new_hash[key].should == 2 + new_hash.keys[0].should equal(key) + end + context "when no block is given" do it "returns a sized Enumerator" do enumerator = @hash.transform_values @@ -47,7 +54,7 @@ ruby_version_is "2.4" do it "updates self as transformed values with the given block" do @hash.transform_values!(&:succ) - @hash.should == { a: 2, b: 3, c: 4 } + @hash.should == { a: 2, b: 3, c: 4 } end it "partially modifies the contents if we broke from the block" do diff --git a/spec/ruby/core/kernel/autoload_spec.rb b/spec/ruby/core/kernel/autoload_spec.rb index b9715eea66..b2aab5a895 100644 --- a/spec/ruby/core/kernel/autoload_spec.rb +++ b/spec/ruby/core/kernel/autoload_spec.rb @@ -57,7 +57,7 @@ describe "Kernel#autoload" do describe "when Object is frozen" do it "raises a FrozenError before defining the constant" do - ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "FrozenError - nil" + ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "#{frozen_error_class} - nil" end end end diff --git a/spec/ruby/core/module/included_modules_spec.rb b/spec/ruby/core/module/included_modules_spec.rb index 91e1298eef..ff2dc434dd 100644 --- a/spec/ruby/core/module/included_modules_spec.rb +++ b/spec/ruby/core/module/included_modules_spec.rb @@ -4,9 +4,9 @@ require File.expand_path('../fixtures/classes', __FILE__) describe "Module#included_modules" do it "returns a list of modules included in self" do ModuleSpecs.included_modules.should == [] - ModuleSpecs::Child.included_modules.should include(ModuleSpecs::Super, ModuleSpecs::Basic, Kernel) + ModuleSpecs::Child.included_modules.should include(ModuleSpecs::Super, ModuleSpecs::Basic, Kernel) ModuleSpecs::Parent.included_modules.should include(Kernel) ModuleSpecs::Basic.included_modules.should == [] - ModuleSpecs::Super.included_modules.should include(ModuleSpecs::Basic) + ModuleSpecs::Super.included_modules.should include(ModuleSpecs::Basic) end end diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index b54d83075f..ca7db0c2b6 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -320,7 +320,7 @@ describe "Module#refine" do result.should == "foo from subclass" end - context "for methods accesses indirectly" do + context "for methods accessed indirectly" do ruby_version_is "" ... "2.4" do it "is not honored by Kernel#send" do refinement = Module.new do @@ -425,6 +425,46 @@ describe "Module#refine" do end end + ruby_version_is "" ... "2.5" do + it "is not honored by string interpolation" do + refinement = Module.new do + refine Integer do + def to_s + "foo" + end + end + end + + result = nil + Module.new do + using refinement + result = "#{1}" + end + + result.should == "1" + end + end + + ruby_version_is "2.5" do + it "is honored by string interpolation" do + refinement = Module.new do + refine Integer do + def to_s + "foo" + end + end + end + + result = nil + Module.new do + using refinement + result = "#{1}" + end + + result.should == "foo" + end + end + it "is honored by Kernel#binding" do refinement = Module.new do refine String do diff --git a/spec/ruby/core/process/setsid_spec.rb b/spec/ruby/core/process/setsid_spec.rb index abb75f8225..5f060ef218 100644 --- a/spec/ruby/core/process/setsid_spec.rb +++ b/spec/ruby/core/process/setsid_spec.rb @@ -22,7 +22,7 @@ describe "Process.setsid" do read2.close pgid_child = Integer(read.gets) read.close - platform_is_not :aix do + platform_is_not :aix, :openbsd do # AIX does not allow Process.getsid(pid) # if pid is in a different session. pgid = Process.getsid(pid) diff --git a/spec/ruby/core/process/spawn_spec.rb b/spec/ruby/core/process/spawn_spec.rb index 330ec8fcd8..9e34713757 100644 --- a/spec/ruby/core/process/spawn_spec.rb +++ b/spec/ruby/core/process/spawn_spec.rb @@ -595,8 +595,10 @@ describe "Process.spawn" do end end - it "raises an Errno::EACCES when passed a directory" do - lambda { Process.spawn File.dirname(__FILE__) }.should raise_error(Errno::EACCES) + it "raises an Errno::EACCES or Errno::EISDIR when passed a directory" do + lambda { Process.spawn File.dirname(__FILE__) }.should raise_error(SystemCallError) { |e| + [Errno::EACCES, Errno::EISDIR].should include(e.class) + } end it "raises an ArgumentError when passed a string key in options" do diff --git a/spec/ruby/core/string/delete_prefix_spec.rb b/spec/ruby/core/string/delete_prefix_spec.rb new file mode 100644 index 0000000000..94d486eace --- /dev/null +++ b/spec/ruby/core/string/delete_prefix_spec.rb @@ -0,0 +1,81 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes.rb', __FILE__) + +ruby_version_is '2.5' do + describe "String#delete_prefix" do + it "returns a copy of the string, with the given prefix removed" do + 'hello'.delete_prefix('hell').should == 'o' + 'hello'.delete_prefix('hello').should == '' + end + + it "returns a copy of the string, when the prefix isn't found" do + s = 'hello' + r = s.delete_prefix('hello!') + r.should_not equal s + r.should == s + r = s.delete_prefix('ell') + r.should_not equal s + r.should == s + r = s.delete_prefix('') + r.should_not equal s + r.should == s + end + + it "taints resulting strings when other is tainted" do + 'hello'.taint.delete_prefix('hell').tainted?.should == true + 'hello'.taint.delete_prefix('').tainted?.should == true + end + + it "doesn't set $~" do + $~ = nil + + 'hello'.delete_prefix('hell') + $~.should == nil + end + + it "calls to_str on its argument" do + o = mock('x') + o.should_receive(:to_str).and_return 'hell' + 'hello'.delete_prefix(o).should == 'o' + end + + it "returns a subclass instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString) + end + end + + describe "String#delete_prefix!" do + it "removes the found prefix" do + s = 'hello' + s.delete_prefix!('hell').should equal(s) + s.should == 'o' + end + + it "returns nil if no change is made" do + s = 'hello' + s.delete_prefix!('ell').should == nil + s.delete_prefix!('').should == nil + end + + it "doesn't set $~" do + $~ = nil + + 'hello'.delete_prefix!('hell') + $~.should == nil + end + + it "calls to_str on its argument" do + o = mock('x') + o.should_receive(:to_str).and_return 'hell' + 'hello'.delete_prefix!(o).should == 'o' + end + + it "raises a RuntimeError when self is frozen" do + lambda { 'hello'.freeze.delete_prefix!('hell') }.should raise_error(RuntimeError) + lambda { 'hello'.freeze.delete_prefix!('') }.should raise_error(RuntimeError) + lambda { ''.freeze.delete_prefix!('') }.should raise_error(RuntimeError) + end + end +end diff --git a/spec/ruby/core/string/delete_suffix_spec.rb b/spec/ruby/core/string/delete_suffix_spec.rb new file mode 100644 index 0000000000..49689a8da1 --- /dev/null +++ b/spec/ruby/core/string/delete_suffix_spec.rb @@ -0,0 +1,81 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes.rb', __FILE__) + +ruby_version_is '2.5' do + describe "String#delete_suffix" do + it "returns a copy of the string, with the given suffix removed" do + 'hello'.delete_suffix('ello').should == 'h' + 'hello'.delete_suffix('hello').should == '' + end + + it "returns a copy of the string, when the suffix isn't found" do + s = 'hello' + r = s.delete_suffix('!hello') + r.should_not equal s + r.should == s + r = s.delete_suffix('ell') + r.should_not equal s + r.should == s + r = s.delete_suffix('') + r.should_not equal s + r.should == s + end + + it "taints resulting strings when other is tainted" do + 'hello'.taint.delete_suffix('ello').tainted?.should == true + 'hello'.taint.delete_suffix('').tainted?.should == true + end + + it "doesn't set $~" do + $~ = nil + + 'hello'.delete_suffix('ello') + $~.should == nil + end + + it "calls to_str on its argument" do + o = mock('x') + o.should_receive(:to_str).and_return 'ello' + 'hello'.delete_suffix(o).should == 'h' + end + + it "returns a subclass instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString) + end + end + + describe "String#delete_suffix!" do + it "removes the found prefix" do + s = 'hello' + s.delete_suffix!('ello').should equal(s) + s.should == 'h' + end + + it "returns nil if no change is made" do + s = 'hello' + s.delete_suffix!('ell').should == nil + s.delete_suffix!('').should == nil + end + + it "doesn't set $~" do + $~ = nil + + 'hello'.delete_suffix!('ello') + $~.should == nil + end + + it "calls to_str on its argument" do + o = mock('x') + o.should_receive(:to_str).and_return 'ello' + 'hello'.delete_suffix!(o).should == 'h' + end + + it "raises a RuntimeError when self is frozen" do + lambda { 'hello'.freeze.delete_suffix!('ello') }.should raise_error(RuntimeError) + lambda { 'hello'.freeze.delete_suffix!('') }.should raise_error(RuntimeError) + lambda { ''.freeze.delete_suffix!('') }.should raise_error(RuntimeError) + end + end +end diff --git a/spec/ruby/core/string/start_with_spec.rb b/spec/ruby/core/string/start_with_spec.rb index b85081037d..1b27fdaed7 100644 --- a/spec/ruby/core/string/start_with_spec.rb +++ b/spec/ruby/core/string/start_with_spec.rb @@ -28,9 +28,9 @@ describe "String#start_with?" do it "ignores arguments not convertible to string" do "hello".start_with?().should be_false - lambda { "hello".start_with?(1) }.should raise_error(TypeError) - lambda { "hello".start_with?(["h"]) }.should raise_error(TypeError) - lambda { "hello".start_with?(1, nil, "h").should }.should raise_error(TypeError) + lambda { "hello".start_with?(1) }.should raise_error(TypeError) + lambda { "hello".start_with?(["h"]) }.should raise_error(TypeError) + lambda { "hello".start_with?(1, nil, "h") }.should raise_error(TypeError) end it "uses only the needed arguments" do diff --git a/spec/ruby/core/struct/new_spec.rb b/spec/ruby/core/struct/new_spec.rb index db168ba279..f43e764cb8 100644 --- a/spec/ruby/core/struct/new_spec.rb +++ b/spec/ruby/core/struct/new_spec.rb @@ -60,7 +60,18 @@ describe "Struct.new" do lambda { Struct.new(:animal, nil) }.should raise_error(TypeError) lambda { Struct.new(:animal, true) }.should raise_error(TypeError) lambda { Struct.new(:animal, ['chris', 'evan']) }.should raise_error(TypeError) - lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError) + end + + ruby_version_is ""..."2.5" do + it "raises a TypeError if an argument is a Hash" do + lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(TypeError) + end + end + + ruby_version_is "2.5" do + it "raises a ArgumentError if passed a Hash with an unknown key" do + lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError) + end end it "raises a TypeError if object is not a Symbol" do diff --git a/spec/ruby/core/time/at_spec.rb b/spec/ruby/core/time/at_spec.rb index 40c729316e..6883a8d074 100644 --- a/spec/ruby/core/time/at_spec.rb +++ b/spec/ruby/core/time/at_spec.rb @@ -142,4 +142,60 @@ describe "Time.at" do lambda { Time.at(Time.now, 500000) }.should raise_error(TypeError) end end + + ruby_version_is "2.5" do + describe "passed [Time, Numeric, format]" do + context ":nanosecond format" do + it "traits second argument as nanoseconds" do + Time.at(0, 123456789, :nanosecond).nsec.should == 123456789 + end + end + + context ":nsec format" do + it "traits second argument as nanoseconds" do + Time.at(0, 123456789, :nsec).nsec.should == 123456789 + end + end + + context ":microsecond format" do + it "traits second argument as microseconds" do + Time.at(0, 123456, :microsecond).nsec.should == 123456000 + end + end + + context ":usec format" do + it "traits second argument as microseconds" do + Time.at(0, 123456, :usec).nsec.should == 123456000 + end + end + + context ":millisecond format" do + it "traits second argument as milliseconds" do + Time.at(0, 123, :millisecond).nsec.should == 123000000 + end + end + + context "not supported format" do + it "raises ArgumentError" do + ->() { Time.at(0, 123456, 2) }.should raise_error(ArgumentError) + ->() { Time.at(0, 123456, nil) }.should raise_error(ArgumentError) + ->() { Time.at(0, 123456, :invalid) }.should raise_error(ArgumentError) + end + + it "does not try to convert format to Symbol with #to_sym" do + format = "usec" + format.should_not_receive(:to_sym) + -> () { Time.at(0, 123456, format) }.should raise_error(ArgumentError) + end + end + + it "supports Float second argument" do + Time.at(0, 123456789.500, :nanosecond).nsec.should == 123456789 + Time.at(0, 123456789.500, :nsec).nsec.should == 123456789 + Time.at(0, 123456.500, :microsecond).nsec.should == 123456500 + Time.at(0, 123456.500, :usec).nsec.should == 123456500 + Time.at(0, 123.500, :millisecond).nsec.should == 123500000 + end + end + end end |