1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2019-10-26 20:53:01 +02:00
parent 3eb0d50c0b
commit 664e96b1de
42 changed files with 484 additions and 117 deletions

View file

@ -77,6 +77,13 @@ Lint/NestedMethodDefinition:
- language/def_spec.rb - language/def_spec.rb
- language/fixtures/def.rb - language/fixtures/def.rb
Lint/ShadowingOuterLocalVariable:
Exclude:
- 'core/binding/local_variables_spec.rb'
- 'core/kernel/local_variables_spec.rb'
- 'language/block_spec.rb'
- 'language/proc_spec.rb'
Lint/UnreachableCode: Lint/UnreachableCode:
Exclude: Exclude:
- 'core/enumerator/lazy/fixtures/classes.rb' - 'core/enumerator/lazy/fixtures/classes.rb'

View file

@ -116,13 +116,6 @@ Lint/ShadowedArgument:
Exclude: Exclude:
- 'language/fixtures/super.rb' - 'language/fixtures/super.rb'
# Offense count: 10
Lint/ShadowingOuterLocalVariable:
Exclude:
- 'core/binding/local_variables_spec.rb'
- 'language/block_spec.rb'
- 'language/proc_spec.rb'
# Offense count: 2 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
Lint/StringConversionInInterpolation: Lint/StringConversionInInterpolation:

View file

@ -22,6 +22,12 @@ describe :enumerable_collect, shared: true do
multi.send(@method) {|e| e}.should == [1,3,6] multi.send(@method) {|e| e}.should == [1,3,6]
end end
it "only yields increasing values for a Range" do
(1..0).send(@method) { |x| x }.should == []
(1..1).send(@method) { |x| x }.should == [1]
(1..2).send(@method) { |x| x }.should == [1, 2]
end
it "returns an enumerator when no block given" do it "returns an enumerator when no block given" do
enum = EnumerableSpecs::Numerous.new.send(@method) enum = EnumerableSpecs::Numerous.new.send(@method)
enum.should be_an_instance_of(Enumerator) enum.should be_an_instance_of(Enumerator)

View file

@ -1,8 +1,12 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "ENV.assoc" do describe "ENV.assoc" do
before :each do
@foo = ENV["foo"]
end
after :each do after :each do
ENV.delete("foo") ENV["foo"] = @foo
end end
it "returns an array of the key and value of the environment variable with the given key" do it "returns an array of the key and value of the environment variable with the given key" do
@ -20,4 +24,8 @@ describe "ENV.assoc" do
k.should_receive(:to_str).and_return("foo") k.should_receive(:to_str).and_return("foo")
ENV.assoc(k).should == ["foo", "bar"] ENV.assoc(k).should == ["foo", "bar"]
end end
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.assoc(Object.new) }.should raise_error(TypeError)
end
end end

View file

@ -4,7 +4,7 @@ describe "ENV.clear" do
it "deletes all environment variables" do it "deletes all environment variables" do
orig = ENV.to_hash orig = ENV.to_hash
begin begin
ENV.clear ENV.clear.should equal(ENV)
# This used 'env' the helper before. That shells out to 'env' which # This used 'env' the helper before. That shells out to 'env' which
# itself sets up certain environment variables before it runs, because # itself sets up certain environment variables before it runs, because

View file

@ -2,14 +2,31 @@ require_relative '../../spec_helper'
require_relative '../enumerable/shared/enumeratorized' require_relative '../enumerable/shared/enumeratorized'
describe "ENV.delete_if" do describe "ENV.delete_if" do
before :each do
@foo = ENV["foo"]
@bar = ENV["bar"]
ENV["foo"] = "0"
ENV["bar"] = "1"
end
after :each do
ENV["foo"] = @foo
ENV["bar"] = @bar
end
it "deletes pairs if the block returns true" do it "deletes pairs if the block returns true" do
ENV["foo"] = "bar" ENV.delete_if { |k, v| ["foo", "bar"].include?(k) }
ENV.delete_if { |k, v| k == "foo" }
ENV["foo"].should == nil ENV["foo"].should == nil
ENV["bar"].should == nil
end
it "returns ENV when block given" do
ENV.delete_if { |k, v| ["foo", "bar"].include?(k) }.should equal(ENV)
end end
it "returns ENV even if nothing deleted" do it "returns ENV even if nothing deleted" do
ENV.delete_if { false }.should_not == nil ENV.delete_if { false }.should equal(ENV)
end end
it "returns an Enumerator if no block given" do it "returns an Enumerator if no block given" do
@ -17,10 +34,20 @@ describe "ENV.delete_if" do
end end
it "deletes pairs through enumerator" do it "deletes pairs through enumerator" do
ENV["foo"] = "bar"
enum = ENV.delete_if enum = ENV.delete_if
enum.each { |k, v| k == "foo" } enum.each { |k, v| ["foo", "bar"].include?(k) }
ENV["foo"].should == nil ENV["foo"].should == nil
ENV["bar"].should == nil
end
it "returns ENV from enumerator" do
enum = ENV.delete_if
enum.each { |k, v| ["foo", "bar"].include?(k) }.should equal(ENV)
end
it "returns ENV from enumerator even if nothing deleted" do
enum = ENV.delete_if
enum.each { false }.should equal(ENV)
end end
it_behaves_like :enumeratorized_with_origin_size, :delete_if, ENV it_behaves_like :enumeratorized_with_origin_size, :delete_if, ENV

View file

@ -1,8 +1,11 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "ENV.delete" do describe "ENV.delete" do
before :each do
@saved_foo = ENV["foo"]
end
after :each do after :each do
ENV.delete("foo") ENV["foo"] = @saved_foo
end end
it "removes the variable from the environment" do it "removes the variable from the environment" do
@ -16,9 +19,18 @@ describe "ENV.delete" do
ENV.delete("foo").should == "bar" ENV.delete("foo").should == "bar"
end end
it "returns nil if the named environment variable does not exist and no block given" do
ENV.delete("foo")
ENV.delete("foo").should == nil
end
it "yields the name to the given block if the named environment variable does not exist" do it "yields the name to the given block if the named environment variable does not exist" do
ENV.delete("foo") ENV.delete("foo")
ENV.delete("foo") { |name| ScratchPad.record name } ENV.delete("foo") { |name| ScratchPad.record name }
ScratchPad.recorded.should == "foo" ScratchPad.recorded.should == "foo"
end end
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.delete(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
end end

View file

@ -19,7 +19,9 @@ describe "ENV.each_key" do
end end
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.each_key.should be_an_instance_of(Enumerator) enum = ENV.each_key
enum.should be_an_instance_of(Enumerator)
enum.to_a.should == ENV.keys
end end
it "returns keys in the locale encoding" do it "returns keys in the locale encoding" do

View file

@ -19,7 +19,9 @@ describe "ENV.each_value" do
end end
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.each_value.should be_an_instance_of(Enumerator) enum = ENV.each_value
enum.should be_an_instance_of(Enumerator)
enum.to_a.should == ENV.values
end end
it "uses the locale encoding" do it "uses the locale encoding" do

View file

@ -19,6 +19,17 @@ describe "ENV.[]" do
ENV[@variable].frozen?.should == true ENV[@variable].frozen?.should == true
end end
it "coerces a non-string name with #to_str" do
ENV[@variable] = "bar"
k = mock('key')
k.should_receive(:to_str).and_return(@variable)
ENV[k].should == "bar"
end
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV[Object.new] }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
platform_is :windows do platform_is :windows do
it "looks up values case-insensitively" do it "looks up values case-insensitively" do
ENV[@variable] = "bar" ENV[@variable] = "bar"

View file

@ -2,14 +2,20 @@ require_relative '../../spec_helper'
require_relative '../../shared/hash/key_error' require_relative '../../shared/hash/key_error'
describe "ENV.fetch" do describe "ENV.fetch" do
before :each do
@foo_saved = ENV.delete("foo")
end
after :each do
ENV["foo"] = @saved_foo
end
it "returns a value" do it "returns a value" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.fetch("foo").should == "bar" ENV.fetch("foo").should == "bar"
ENV.delete "foo"
end end
it "raises a TypeError if the key is not a String" do it "raises a TypeError if the key is not a String" do
-> { ENV.fetch :should_never_be_set }.should raise_error(TypeError) -> { ENV.fetch Object.new }.should raise_error(TypeError, "no implicit conversion of Object into String")
end end
context "when the key is not found" do context "when the key is not found" do
@ -23,20 +29,34 @@ describe "ENV.fetch" do
end end
it "provides the given default parameter" do it "provides the given default parameter" do
ENV.fetch("should_never_be_set", "default").should == "default" ENV.fetch("foo", "default").should == "default"
end
it "does not insist that the default be a String" do
ENV.fetch("foo", :default).should == :default
end end
it "provides a default value from a block" do it "provides a default value from a block" do
ENV.fetch("should_never_be_set") { |k| "wanted #{k}" }.should == "wanted should_never_be_set" ENV.fetch("foo") { |k| "wanted #{k}" }.should == "wanted foo"
end
it "does not insist that the block return a String" do
ENV.fetch("foo") { |k| k.to_sym }.should == :foo
end end
it "warns on block and default parameter given" do it "warns on block and default parameter given" do
-> do -> do
ENV.fetch("should_never_be_set", "default") { 1 }.should == 1 ENV.fetch("foo", "default") { "bar" }.should == "bar"
end.should complain(/block supersedes default value argument/) end.should complain(/block supersedes default value argument/)
end end
it "does not evaluate the block when key found" do
ENV["foo"] = "bar"
ENV.fetch("foo") { fail "should not get here"}.should == "bar"
end
it "uses the locale encoding" do it "uses the locale encoding" do
ENV.fetch(ENV.keys.first).encoding.should == Encoding.find('locale') ENV["foo"] = "bar"
ENV.fetch("foo").encoding.should == Encoding.find('locale')
end end
end end

View file

@ -3,20 +3,30 @@ require_relative '../enumerable/shared/enumeratorized'
describe "ENV.keep_if" do describe "ENV.keep_if" do
before :each do before :each do
ENV["foo"] = "bar" @foo = ENV["foo"]
@bar = ENV["bar"]
ENV["foo"] = "0"
ENV["bar"] = "1"
end end
after :each do after :each do
ENV.delete "foo" ENV["foo"] = @foo
ENV["bar"] = @bar
end end
it "deletes pairs if the block returns false" do it "deletes pairs if the block returns false" do
ENV.keep_if { |k, v| k != "foo" } ENV.keep_if { |k, v| !["foo", "bar"].include?(k) }
ENV["foo"].should == nil ENV["foo"].should == nil
ENV["bar"].should == nil
end
it "returns ENV when block given" do
ENV.keep_if { |k, v| !["foo", "bar"].include?(k) }.should equal(ENV)
end end
it "returns ENV even if nothing deleted" do it "returns ENV even if nothing deleted" do
ENV.keep_if { true }.should_not == nil ENV.keep_if { true }.should equal(ENV)
end end
it "returns an Enumerator if no block given" do it "returns an Enumerator if no block given" do
@ -25,8 +35,19 @@ describe "ENV.keep_if" do
it "deletes pairs through enumerator" do it "deletes pairs through enumerator" do
enum = ENV.keep_if enum = ENV.keep_if
enum.each { |k, v| k != "foo" } enum.each { |k, v| !["foo", "bar"].include?(k) }
ENV["foo"].should == nil ENV["foo"].should == nil
ENV["bar"].should == nil
end
it "returns ENV from enumerator" do
enum = ENV.keep_if
enum.each { |k, v| !["foo", "bar"].include?(k) }.should equal(ENV)
end
it "returns ENV from enumerator even if nothing deleted" do
enum = ENV.keep_if
enum.each { true }.should equal(ENV)
end end
it_behaves_like :enumeratorized_with_origin_size, :keep_if, ENV it_behaves_like :enumeratorized_with_origin_size, :keep_if, ENV

View file

@ -1,8 +1,14 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "ENV.rassoc" do describe "ENV.rassoc" do
before :each do
@foo = ENV["foo"]
@baz = ENV["baz"]
end
after :each do after :each do
ENV.delete("foo") ENV["foo"] = @foo
ENV["baz"] = @baz
end end
it "returns an array of the key and value of the environment variable with the given value" do it "returns an array of the key and value of the environment variable with the given value" do
@ -10,6 +16,15 @@ describe "ENV.rassoc" do
ENV.rassoc("bar").should == ["foo", "bar"] ENV.rassoc("bar").should == ["foo", "bar"]
end end
it "returns a single array even if there are multiple such environment variables" do
ENV["foo"] = "bar"
ENV["baz"] = "bar"
[
["foo", "bar"],
["baz", "bar"],
].should include(ENV.rassoc("bar"))
end
it "returns nil if no environment variable with the given value exists" do it "returns nil if no environment variable with the given value exists" do
ENV.rassoc("bar").should == nil ENV.rassoc("bar").should == nil
end end
@ -20,4 +35,8 @@ describe "ENV.rassoc" do
v.should_receive(:to_str).and_return("bar") v.should_receive(:to_str).and_return("bar")
ENV.rassoc(v).should == ["foo", "bar"] ENV.rassoc(v).should == ["foo", "bar"]
end end
it "returns nil if the argument is not a String and does not respond to #to_str" do
ENV.rassoc(Object.new).should == nil
end
end end

View file

@ -2,6 +2,14 @@ require_relative '../../spec_helper'
require_relative '../enumerable/shared/enumeratorized' require_relative '../enumerable/shared/enumeratorized'
describe "ENV.reject!" do describe "ENV.reject!" do
before :each do
@foo = ENV["foo"]
end
after :each do
ENV["foo"] = @foo
end
it "rejects entries based on key" do it "rejects entries based on key" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.reject! { |k, v| k == "foo" } ENV.reject! { |k, v| k == "foo" }
@ -17,12 +25,16 @@ describe "ENV.reject!" do
it "returns itself or nil" do it "returns itself or nil" do
ENV.reject! { false }.should == nil ENV.reject! { false }.should == nil
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.reject! { |k, v| k == "foo" }.should == ENV ENV.reject! { |k, v| k == "foo" }.should equal(ENV)
ENV["foo"].should == nil ENV["foo"].should == nil
end end
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.reject!.should be_an_instance_of(Enumerator) ENV["foo"] = "bar"
enum = ENV.reject!
enum.should be_an_instance_of(Enumerator)
enum.each { |k, v| k == "foo" }.should equal(ENV)
ENV["foo"].should == nil
end end
it "doesn't raise if empty" do it "doesn't raise if empty" do
@ -39,6 +51,14 @@ describe "ENV.reject!" do
end end
describe "ENV.reject" do describe "ENV.reject" do
before :each do
@foo = ENV["foo"]
end
after :each do
ENV["foo"] = @foo
end
it "rejects entries based on key" do it "rejects entries based on key" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
e = ENV.reject { |k, v| k == "foo" } e = ENV.reject { |k, v| k == "foo" }
@ -60,7 +80,11 @@ describe "ENV.reject" do
end end
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.reject.should be_an_instance_of(Enumerator) ENV["foo"] = "bar"
enum = ENV.reject
enum.should be_an_instance_of(Enumerator)
enum.each { |k, v| k == "foo"}
ENV["foo"] = nil
end end
it "doesn't raise if empty" do it "doesn't raise if empty" do

View file

@ -17,7 +17,11 @@ describe :env_each, shared: true do
end end
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.send(@method).should be_an_instance_of(Enumerator) enum = ENV.send(@method)
enum.should be_an_instance_of(Enumerator)
enum.each do |name, value|
ENV[name].should == value
end
end end
before :all do before :all do

View file

@ -1,11 +1,23 @@
describe :env_include, shared: true do describe :env_include, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do
ENV["foo"] = @saved_foo
end
it "returns true if ENV has the key" do it "returns true if ENV has the key" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.send(@method, "foo").should == true ENV.send(@method, "foo").should == true
ENV.delete "foo"
end end
it "returns false if ENV doesn't include the key" do it "returns false if ENV doesn't include the key" do
ENV.send(@method, "should_never_be_set").should == false ENV.delete("foo")
ENV.send(@method, "foo").should == false
end
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.send(@method, Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end end
end end

View file

@ -1,11 +1,23 @@
describe :env_key, shared: true do describe :env_key, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do
ENV["foo"] = @saved_foo
end
it "returns the index associated with the passed value" do it "returns the index associated with the passed value" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.send(@method, "bar").should == "foo" ENV.send(@method, "bar").should == "foo"
ENV.delete "foo"
end end
it "returns nil if the passed value is not found" do it "returns nil if the passed value is not found" do
ENV.send(@method, "should_never_be_set").should be_nil ENV.delete("foo")
ENV.send(@method, "foo").should be_nil
end
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.send(@method, Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end end
end end

View file

@ -1,16 +1,38 @@
describe :env_select, shared: true do describe :env_select, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do
ENV["foo"] = @saved_foo
end
it "returns a Hash of names and values for which block return true" do it "returns a Hash of names and values for which block return true" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
(ENV.send(@method) { |k, v| k == "foo" }).should == { "foo" => "bar" } (ENV.send(@method) { |k, v| k == "foo" }).should == { "foo" => "bar" }
ENV.delete "foo"
end end
it "returns an Enumerator when no block is given" do it "returns an Enumerator when no block is given" do
ENV.send(@method).should be_an_instance_of(Enumerator) enum = ENV.send(@method)
enum.should be_an_instance_of(Enumerator)
end
it "selects via the enumerator" do
enum = ENV.send(@method)
ENV["foo"] = "bar"
enum.each { |k, v| k == "foo" }.should == { "foo" => "bar"}
end end
end end
describe :env_select!, shared: true do describe :env_select!, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do
ENV["foo"] = @saved_foo
end
it "removes environment variables for which the block returns true" do it "removes environment variables for which the block returns true" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.send(@method) { |k, v| k != "foo" } ENV.send(@method) { |k, v| k != "foo" }
@ -29,4 +51,11 @@ describe :env_select!, shared: true do
it "returns an Enumerator if called without a block" do it "returns an Enumerator if called without a block" do
ENV.send(@method).should be_an_instance_of(Enumerator) ENV.send(@method).should be_an_instance_of(Enumerator)
end end
it "selects via the enumerator" do
enum = ENV.send(@method)
ENV["foo"] = "bar"
enum.each { |k, v| k != "foo" }
ENV["foo"].should == nil
end
end end

View file

@ -1,6 +1,10 @@
describe :env_store, shared: true do describe :env_store, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do after :each do
ENV.delete("foo") ENV["foo"] = @saved_foo
end end
it "sets the environment variable to the given value" do it "sets the environment variable to the given value" do
@ -34,11 +38,11 @@ describe :env_store, shared: true do
end end
it "raises TypeError when the key is not coercible to String" do it "raises TypeError when the key is not coercible to String" do
-> { ENV.send(@method, Object.new, "bar") }.should raise_error(TypeError) -> { ENV.send(@method, Object.new, "bar") }.should raise_error(TypeError, "no implicit conversion of Object into String")
end end
it "raises TypeError when the value is not coercible to String" do it "raises TypeError when the value is not coercible to String" do
-> { ENV.send(@method, "foo", Object.new) }.should raise_error(TypeError) -> { ENV.send(@method, "foo", Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end end
it "raises Errno::EINVAL when the key contains the '=' character" do it "raises Errno::EINVAL when the key contains the '=' character" do

View file

@ -1,21 +1,66 @@
describe :env_update, shared: true do describe :env_update, shared: true do
before :each do
@saved_foo = ENV["foo"]
@saved_bar = ENV["bar"]
end
after :each do
ENV["foo"] = @saved_foo
ENV["bar"] = @saved_bar
end
it "adds the parameter hash to ENV" do it "adds the parameter hash to ENV" do
ENV["foo"].should == nil ENV.send @method, {"foo" => "0", "bar" => "1"}
ENV.send @method, "foo" => "bar" ENV["foo"].should == "0"
ENV["foo"].should == "bar" ENV["bar"].should == "1"
ENV.delete "foo" end
it "returns ENV when no block given" do
ENV.send(@method, {"foo" => "0", "bar" => "1"}).should equal(ENV)
end end
it "yields key, the old value and the new value when replacing entries" do it "yields key, the old value and the new value when replacing entries" do
ENV.send @method, "foo" => "bar" ENV.send @method, {"foo" => "0", "bar" => "3"}
ENV["foo"].should == "bar" a = []
ENV.send(@method, "foo" => "boo") do |key, old, new| ENV.send @method, {"foo" => "1", "bar" => "4"} do |key, old, new|
key.should == "foo" a << [key, old, new]
old.should == "bar" (new.to_i + 1).to_s
new.should == "boo" end
"rab" ENV["foo"].should == "2"
ENV["bar"].should == "5"
a[0].should == ["foo", "0", "1"]
a[1].should == ["bar", "3", "4"]
end
it "returns ENV when block given" do
ENV.send(@method, {"foo" => "0", "bar" => "1"}){}.should equal(ENV)
end
it "raises TypeError when a name is not coercible to String" do
-> { ENV.send @method, Object.new => "0" }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
it "raises TypeError when a value is not coercible to String" do
-> { ENV.send @method, "foo" => Object.new }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
it "updates good data preceding an error" do
ENV["foo"] = "0"
begin
ENV.send @method, {"foo" => "2", Object.new => "1"}
rescue TypeError
ensure
ENV["foo"].should == "2"
end
end
it "does not update good data following an error" do
ENV["foo"] = "0"
begin
ENV.send @method, {Object.new => "1", "foo" => "2"}
rescue TypeError
ensure
ENV["foo"].should == "0"
end end
ENV["foo"].should == "rab"
ENV.delete "foo"
end end
end end

View file

@ -1,11 +1,22 @@
describe :env_value, shared: true do describe :env_value, shared: true do
before :each do
@saved_foo = ENV["foo"]
end
after :each do
ENV["foo"] = @saved_foo
end
it "returns true if ENV has the value" do it "returns true if ENV has the value" do
ENV["foo"] = "bar" ENV["foo"] = "bar"
ENV.send(@method, "bar").should == true ENV.send(@method, "bar").should == true
ENV["foo"] = nil
end end
it "returns false if ENV doesn't have the value" do it "returns false if ENV doesn't have the value" do
ENV.send(@method, "this_value_should_never_exist").should == false ENV.send(@method, "foo").should == false
end
it "returns nil if the argument is not a String and does not respond to #to_str" do
ENV.send(@method, Object.new).should == nil
end end
end end

29
spec/ruby/core/env/slice_spec.rb vendored Normal file
View file

@ -0,0 +1,29 @@
require_relative '../../spec_helper'
ruby_version_is "2.6" do
describe "ENV.slice" do
before :each do
@saved_foo = ENV["foo"]
@saved_bar = ENV["bar"]
ENV["foo"] = "0"
ENV["bar"] = "1"
end
after :each do
ENV["foo"] = @saved_foo
ENV["bar"] = @saved_bar
end
it "returns a hash of the given environment variable names and their values" do
ENV.slice("foo", "bar").should == {"foo" => "0", "bar" => "1"}
end
it "ignores each String that is not an environment variable name" do
ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"}
end
it "raises TypeError if any argument is not a String and does not respond to #to_str" do
-> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
end
end

View file

@ -6,6 +6,10 @@ describe "Exception#inspect" do
Exception.new.inspect.should == "#<Exception: Exception>" Exception.new.inspect.should == "#<Exception: Exception>"
end end
it "keeps message encoding" do
Exception.new('å').inspect.should == "#<Exception: å>"
end
it "includes #to_s when the result is non-empty" do it "includes #to_s when the result is non-empty" do
ExceptionSpecs::OverrideToS.new.inspect.should == "#<ExceptionSpecs::OverrideToS: this is from #to_s>" ExceptionSpecs::OverrideToS.new.inspect.should == "#<ExceptionSpecs::OverrideToS: this is from #to_s>"
end end

View file

@ -2,7 +2,7 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "File.extname" do describe "File.extname" do
it "returns the extension (the portion of file name in path after the period)." do it "returns the extension (the portion of file name in path after the period)" do
File.extname("foo.rb").should == ".rb" File.extname("foo.rb").should == ".rb"
File.extname("/foo/bar.rb").should == ".rb" File.extname("/foo/bar.rb").should == ".rb"
File.extname("/foo.rb/bar.c").should == ".c" File.extname("/foo.rb/bar.c").should == ".c"
@ -12,7 +12,7 @@ describe "File.extname" do
File.extname(".app.conf").should == ".conf" File.extname(".app.conf").should == ".conf"
end end
it "returns the extension (the portion of file name in path after the period).(edge cases)" do it "returns the extension for edge cases" do
File.extname("").should == "" File.extname("").should == ""
File.extname(".").should == "" File.extname(".").should == ""
File.extname("/").should == "" File.extname("/").should == ""
@ -20,15 +20,23 @@ describe "File.extname" do
File.extname("..").should == "" File.extname("..").should == ""
File.extname("...").should == "" File.extname("...").should == ""
File.extname("....").should == "" File.extname("....").should == ""
end
describe "for a filename ending with a dot" do
guard -> { platform_is :windows or ruby_version_is ""..."2.7" } do guard -> { platform_is :windows or ruby_version_is ""..."2.7" } do
it "returns ''" do
File.extname(".foo.").should == "" File.extname(".foo.").should == ""
File.extname("foo.").should == "" File.extname("foo.").should == ""
end end
end
guard -> { platform_is_not :windows and ruby_version_is "2.7" } do guard -> { platform_is_not :windows and ruby_version_is "2.7" } do
it "returns '.'" do
File.extname(".foo.").should == "." File.extname(".foo.").should == "."
File.extname("foo.").should == "." File.extname("foo.").should == "."
end end
end end
end
it "returns only the last extension of a file with several dots" do it "returns only the last extension of a file with several dots" do
File.extname("a.b.c.d.e").should == ".e" File.extname("a.b.c.d.e").should == ".e"

View file

@ -24,7 +24,7 @@ describe :io_new, shared: true do
end end
it "creates an IO instance when STDOUT is closed" do it "creates an IO instance when STDOUT is closed" do
verbose, $VERBOSE = $VERBOSE, nil suppress_warning do
stdout = STDOUT stdout = STDOUT
stdout_file = tmp("stdout.txt") stdout_file = tmp("stdout.txt")
@ -33,13 +33,13 @@ describe :io_new, shared: true do
@io.should be_an_instance_of(IO) @io.should be_an_instance_of(IO)
ensure ensure
STDOUT = stdout STDOUT = stdout
$VERBOSE = verbose
rm_r stdout_file rm_r stdout_file
end end
end end
end
it "creates an IO instance when STDERR is closed" do it "creates an IO instance when STDERR is closed" do
verbose, $VERBOSE = $VERBOSE, nil suppress_warning do
stderr = STDERR stderr = STDERR
stderr_file = tmp("stderr.txt") stderr_file = tmp("stderr.txt")
STDERR = new_io stderr_file STDERR = new_io stderr_file
@ -50,10 +50,10 @@ describe :io_new, shared: true do
@io.should be_an_instance_of(IO) @io.should be_an_instance_of(IO)
ensure ensure
STDERR = stderr STDERR = stderr
$VERBOSE = verbose
rm_r stderr_file rm_r stderr_file
end end
end end
end
it "calls #to_int on an object to convert to a Fixnum" do it "calls #to_int on an object to convert to a Fixnum" do
obj = mock("file descriptor") obj = mock("file descriptor")

View file

@ -341,5 +341,22 @@ CODE
value.encoding.should == Encoding::BINARY value.encoding.should == Encoding::BINARY
value.frozen?.should be_true value.frozen?.should be_true
end end
it "ignores the frozen_string_literal magic comment if it appears after a token and warns if $VERBOSE is true" do
code = <<CODE
some_token_before_magic_comment = :anything
# frozen_string_literal: true
class EvalSpecs
Vπstring_not_frozen = "not frozen"
end
CODE
-> { eval(code) }.should complain(/warning: `frozen_string_literal' is ignored after any tokens/, verbose: true)
EvalSpecs::Vπstring_not_frozen.frozen?.should be_false
EvalSpecs.send :remove_const, :Vπstring_not_frozen
-> { eval(code) }.should_not complain(verbose: false)
EvalSpecs::Vπstring_not_frozen.frozen?.should be_false
EvalSpecs.send :remove_const, :Vπstring_not_frozen
end
end end
end end

View file

@ -34,4 +34,15 @@ describe "Kernel#local_variables" do
ScratchPad.recorded.should include(:a, :b) ScratchPad.recorded.should include(:a, :b)
ScratchPad.recorded.length.should == 2 ScratchPad.recorded.length.should == 2
end end
it "includes only unique variable names" do
def local_var_method
a = 1
1.times do |;a|
return local_variables
end
end
local_var_method.should == [:a]
end
end end

View file

@ -10,4 +10,9 @@ describe "MatchData#regexp" do
m = 'haystack'.match(/hay/) m = 'haystack'.match(/hay/)
m.regexp.should == /hay/ m.regexp.should == /hay/
end end
it "returns a Regexp for the result of gsub(String)" do
'he[[o'.gsub('[', ']')
$~.regexp.should == /\[/
end
end end

View file

@ -11,4 +11,15 @@ describe "MatchData#string" do
str.should == "THX1138." str.should == "THX1138."
str.frozen?.should == true str.frozen?.should == true
end end
it "returns the same frozen string for every call" do
md = /(.)(.)(\d+)(\d)/.match("THX1138.")
md.string.should equal(md.string)
end
it "returns a frozen copy of the matched string for gsub(String)" do
'he[[o'.gsub!('[', ']')
$~.string.should == 'he[[o'
$~.string.frozen?.should == true
end
end end

View file

@ -24,12 +24,12 @@ describe "Mutex#sleep" do
it "pauses execution for approximately the duration requested" do it "pauses execution for approximately the duration requested" do
m = Mutex.new m = Mutex.new
m.lock m.lock
duration = 0.1 duration = 0.001
start = Process.clock_gettime(Process::CLOCK_MONOTONIC) start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
m.sleep duration m.sleep duration
now = Process.clock_gettime(Process::CLOCK_MONOTONIC) now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
(now - start).should > 0 (now - start).should >= 0
(now - start).should < 2.0 (now - start).should < (duration + TIME_TOLERANCE)
end end
it "unlocks the mutex while sleeping" do it "unlocks the mutex while sleeping" do
@ -46,7 +46,7 @@ describe "Mutex#sleep" do
it "relocks the mutex when woken" do it "relocks the mutex when woken" do
m = Mutex.new m = Mutex.new
m.lock m.lock
m.sleep(0.01) m.sleep(0.001)
m.locked?.should be_true m.locked?.should be_true
end end
@ -71,7 +71,7 @@ describe "Mutex#sleep" do
it "returns the rounded number of seconds asleep" do it "returns the rounded number of seconds asleep" do
m = Mutex.new m = Mutex.new
m.lock m.lock
m.sleep(0.01).should be_kind_of(Integer) m.sleep(0.001).should be_kind_of(Integer)
end end
it "wakes up when requesting sleep times near or equal to zero" do it "wakes up when requesting sleep times near or equal to zero" do

View file

@ -4,7 +4,6 @@ require_relative 'shared/rand'
describe "Random.rand" do describe "Random.rand" do
it_behaves_like :random_number, :rand, Random.new it_behaves_like :random_number, :rand, Random.new
it_behaves_like :random_number, :random_number, Random.new
it_behaves_like :random_number, :rand, Random it_behaves_like :random_number, :rand, Random
it "returns a Float >= 0 if no max argument is passed" do it "returns a Float >= 0 if no max argument is passed" do
@ -218,9 +217,3 @@ describe "Random#rand with Range" do
end.should raise_error(ArgumentError) end.should raise_error(ArgumentError)
end end
end end
ruby_version_is "2.6" do
describe "Random.random_number" do
it_behaves_like :random_number, :random_number, Random
end
end

View file

@ -0,0 +1,10 @@
require_relative '../../spec_helper'
require_relative 'shared/rand'
describe "Random.random_number" do
it_behaves_like :random_number, :random_number, Random.new
ruby_version_is "2.6" do
it_behaves_like :random_number, :random_number, Random
end
end

View file

@ -55,4 +55,8 @@ describe "Regexp#encoding" do
/foo/.encoding.should_not == Encoding::EUC_JP /foo/.encoding.should_not == Encoding::EUC_JP
Encoding.default_internal = old_internal Encoding.default_internal = old_internal
end end
it "allows otherwise invalid characters if NOENCODING is specified" do
Regexp.new('([\x00-\xFF])', Regexp::IGNORECASE | Regexp::NOENCODING).encoding.should == Encoding::BINARY
end
end end

View file

@ -1,15 +1,13 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "Thread.exclusive" do describe "Thread.exclusive" do
verbose = Object
before :each do before :each do
ScratchPad.clear ScratchPad.clear
verbose, $VERBOSE = $VERBOSE, nil $VERBOSE, @verbose = nil, $VERBOSE
end end
after :each do after :each do
$VERBOSE = verbose $VERBOSE = @verbose
end end
it "yields to the block" do it "yields to the block" do

View file

@ -147,31 +147,31 @@ describe "Time.at" do
ruby_version_is "2.5" do ruby_version_is "2.5" do
describe "passed [Time, Numeric, format]" do describe "passed [Time, Numeric, format]" do
context ":nanosecond format" do context ":nanosecond format" do
it "traits second argument as nanoseconds" do it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nanosecond).nsec.should == 123456789 Time.at(0, 123456789, :nanosecond).nsec.should == 123456789
end end
end end
context ":nsec format" do context ":nsec format" do
it "traits second argument as nanoseconds" do it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nsec).nsec.should == 123456789 Time.at(0, 123456789, :nsec).nsec.should == 123456789
end end
end end
context ":microsecond format" do context ":microsecond format" do
it "traits second argument as microseconds" do it "treats second argument as microseconds" do
Time.at(0, 123456, :microsecond).nsec.should == 123456000 Time.at(0, 123456, :microsecond).nsec.should == 123456000
end end
end end
context ":usec format" do context ":usec format" do
it "traits second argument as microseconds" do it "treats second argument as microseconds" do
Time.at(0, 123456, :usec).nsec.should == 123456000 Time.at(0, 123456, :usec).nsec.should == 123456000
end end
end end
context ":millisecond format" do context ":millisecond format" do
it "traits second argument as milliseconds" do it "treats second argument as milliseconds" do
Time.at(0, 123, :millisecond).nsec.should == 123000000 Time.at(0, 123, :millisecond).nsec.should == 123000000
end end
end end

View file

@ -11,7 +11,7 @@ describe "Gem.bin_path" do
ENV['BUNDLE_GEMFILE'] = @bundle_gemfile ENV['BUNDLE_GEMFILE'] = @bundle_gemfile
end end
guard_not -> { platform_is :windows } do platform_is_not :windows do
it "finds executables of default gems, which are the only files shipped for default gems" do it "finds executables of default gems, which are the only files shipped for default gems" do
# For instance, Gem.bin_path("bundler", "bundle") is used by rails new # For instance, Gem.bin_path("bundler", "bundle") is used by rails new

View file

@ -0,0 +1,8 @@
require_relative '../../spec_helper'
require_relative '../../core/random/shared/bytes'
require 'securerandom'
describe "SecureRandom.bytes" do
it_behaves_like :random_bytes, :bytes, SecureRandom
end

View file

@ -5,7 +5,6 @@ require 'securerandom'
describe "SecureRandom.random_bytes" do describe "SecureRandom.random_bytes" do
it_behaves_like :random_bytes, :random_bytes, SecureRandom it_behaves_like :random_bytes, :random_bytes, SecureRandom
it_behaves_like :random_bytes, :bytes, SecureRandom
it "generates a random binary string of length 16 if no argument is provided" do it "generates a random binary string of length 16 if no argument is provided" do
bytes = SecureRandom.random_bytes bytes = SecureRandom.random_bytes

View file

@ -40,7 +40,7 @@ describe "TCPServer.new" do
end end
it "binds to INADDR_ANY if the hostname is empty and the port is a string" do it "binds to INADDR_ANY if the hostname is empty and the port is a string" do
@server = TCPServer.new('', 0) @server = TCPServer.new('', '0')
addr = @server.addr addr = @server.addr
addr[0].should == 'AF_INET' addr[0].should == 'AF_INET'
addr[1].should be_kind_of(Integer) addr[1].should be_kind_of(Integer)

View file

@ -21,7 +21,7 @@ static int set_non_blocking(int fd) {
int flags = 1; int flags = 1;
return ioctl(fd, FIOBIO, &flags); return ioctl(fd, FIOBIO, &flags);
#else #else
# define SET_NON_BLOCKING_FAILS_ALWAYS 1 #define SET_NON_BLOCKING_FAILS_ALWAYS 1
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
#endif #endif
@ -115,13 +115,13 @@ VALUE io_spec_rb_io_taint_check(VALUE self, VALUE io) {
#define RB_IO_WAIT_READABLE_BUF 13 #define RB_IO_WAIT_READABLE_BUF 13
#if SET_NON_BLOCKING_FAILS_ALWAYS #ifdef SET_NON_BLOCKING_FAILS_ALWAYS
NORETURN(VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p)); NORETURN(VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p));
#endif #endif
VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
int fd = io_spec_get_fd(io); int fd = io_spec_get_fd(io);
#if !SET_NON_BLOCKING_FAILS_ALWAYS #ifndef SET_NON_BLOCKING_FAILS_ALWAYS
char buf[RB_IO_WAIT_READABLE_BUF]; char buf[RB_IO_WAIT_READABLE_BUF];
int ret, saved_errno; int ret, saved_errno;
#endif #endif
@ -129,7 +129,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
if (set_non_blocking(fd) == -1) if (set_non_blocking(fd) == -1)
rb_sys_fail("set_non_blocking failed"); rb_sys_fail("set_non_blocking failed");
#if !SET_NON_BLOCKING_FAILS_ALWAYS #ifndef SET_NON_BLOCKING_FAILS_ALWAYS
if(RTEST(read_p)) { if(RTEST(read_p)) {
if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) { if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
return Qnil; return Qnil;

View file

@ -97,7 +97,7 @@ VALUE kernel_spec_call_proc_with_catch_obj(RB_BLOCK_CALL_FUNC_ARGLIST(arg, data)
} }
VALUE kernel_spec_rb_catch_obj(VALUE self, VALUE obj, VALUE main_proc) { VALUE kernel_spec_rb_catch_obj(VALUE self, VALUE obj, VALUE main_proc) {
return rb_catch_obj(obj, kernel_spec_call_proc_with_catch, main_proc); return rb_catch_obj(obj, kernel_spec_call_proc_with_catch_obj, main_proc);
} }
VALUE kernel_spec_rb_eval_string(VALUE self, VALUE str) { VALUE kernel_spec_rb_eval_string(VALUE self, VALUE str) {

View file

@ -16,14 +16,15 @@ VALUE util_spec_rb_scan_args(VALUE self, VALUE argv, VALUE fmt, VALUE expected,
args[i] = rb_ary_entry(argv, i); args[i] = rb_ary_entry(argv, i);
} }
if (*RSTRING_PTR(fmt) == 'k') {
#ifdef RB_SCAN_ARGS_KEYWORDS #ifdef RB_SCAN_ARGS_KEYWORDS
if (*RSTRING_PTR(fmt) == 'k') {
result = rb_scan_args_kw(RB_SCAN_ARGS_KEYWORDS, argc, args, RSTRING_PTR(fmt)+1, &a1, &a2, &a3, &a4, &a5, &a6); result = rb_scan_args_kw(RB_SCAN_ARGS_KEYWORDS, argc, args, RSTRING_PTR(fmt)+1, &a1, &a2, &a3, &a4, &a5, &a6);
} else {
#endif #endif
}
else {
result = rb_scan_args(argc, args, RSTRING_PTR(fmt), &a1, &a2, &a3, &a4, &a5, &a6); result = rb_scan_args(argc, args, RSTRING_PTR(fmt), &a1, &a2, &a3, &a4, &a5, &a6);
#ifdef RB_SCAN_ARGS_KEYWORDS
} }
#endif
switch(NUM2INT(expected)) { switch(NUM2INT(expected)) {
case 6: case 6: