Skip to content

Commit

Permalink
Merge pull request jruby#8087 from eregon/update-specs
Browse files Browse the repository at this point in the history
Update specs
  • Loading branch information
eregon authored Feb 5, 2024
2 parents f431c1b + a910c8f commit de53d76
Show file tree
Hide file tree
Showing 275 changed files with 6,673 additions and 4,431 deletions.
58 changes: 58 additions & 0 deletions spec/mspec/lib/mspec/runner/actions/leakchecker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ def register
end

def start
disable_nss_modules
@checker = LeakChecker.new
end

Expand All @@ -316,4 +317,61 @@ def after(state)
end
end
end

private

# This function is intended to disable all NSS modules when ruby is compiled
# against glibc. NSS modules allow the system administrator to load custom
# shared objects into all processes using glibc, and use them to customise
# the behaviour of username, groupname, hostname, etc lookups. This is
# normally configured in the file /etc/nsswitch.conf.
# These modules often do things like open cache files or connect to system
# daemons like sssd or dbus, which of course means they have open file
# descriptors of their own. This can cause the leak-checking functionality
# in this file to report that such descriptors have been leaked, and fail
# the test suite.
# This function uses glibc's __nss_configure_lookup function to override any
# configuration in /etc/nsswitch.conf, and just use the built in files/dns
# name lookup functionality (which is of course perfectly sufficient for
# running ruby/spec).
def disable_nss_modules
begin
require 'fiddle'
rescue LoadError
# Make sure it's possible to run the test suite on a ruby implementation
# which does not (yet?) have Fiddle.
return
end

begin
libc = Fiddle.dlopen(nil)
# Older versions of fiddle don't have Fiddle::Type (and instead rely on Fiddle::TYPE_)
# Even older versions of fiddle don't have CONST_STRING,
string_type = defined?(Fiddle::TYPE_CONST_STRING) ? Fiddle::TYPE_CONST_STRING : Fiddle::TYPE_VOIDP
nss_configure_lookup = Fiddle::Function.new(
libc['__nss_configure_lookup'],
[string_type, string_type],
Fiddle::TYPE_INT
)
rescue Fiddle::DLError
# We're not running with glibc - no need to do this.
return
end

nss_configure_lookup.call 'passwd', 'files'
nss_configure_lookup.call 'shadow', 'files'
nss_configure_lookup.call 'group', 'files'
nss_configure_lookup.call 'hosts', 'files dns'
nss_configure_lookup.call 'services', 'files'
nss_configure_lookup.call 'netgroup', 'files'
nss_configure_lookup.call 'automount', 'files'
nss_configure_lookup.call 'aliases', 'files'
nss_configure_lookup.call 'ethers', 'files'
nss_configure_lookup.call 'gshadow', 'files'
nss_configure_lookup.call 'initgroups', 'files'
nss_configure_lookup.call 'networks', 'files dns'
nss_configure_lookup.call 'protocols', 'files'
nss_configure_lookup.call 'publickey', 'files'
nss_configure_lookup.call 'rpc', 'files'
end
end
6 changes: 3 additions & 3 deletions spec/ruby/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ Lint/InterpolationCheck:
Lint/LiteralAsCondition:
Enabled: false

Lint/RedundantRequireStatement:
Enabled: false

Lint/RedundantSplatExpansion:
Enabled: false

Expand Down Expand Up @@ -106,6 +103,9 @@ Lint/OutOfRangeRegexpRef:
Lint/InheritException:
Enabled: false

Lint/SafeNavigationChain:
Enabled: false

Lint/ElseLayout:
Exclude:
- 'language/if_spec.rb'
Expand Down
5 changes: 4 additions & 1 deletion spec/ruby/command_line/dash_r_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1", exit_status: 1)
$?.should_not.success?
out.should include("REQUIRED")
out.should include("syntax error")

# it's tempting not to rely on error message and rely only on exception class name,
# but CRuby before 3.2 doesn't print class name for syntax error
out.should include_any_of("syntax error", "SyntaxError")
end

it "does not require the file if the main script file does not exist" do
Expand Down
3 changes: 2 additions & 1 deletion spec/ruby/command_line/dash_v_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
it "prints version and ends" do
ruby_exe(nil, args: '-v').should include(RUBY_DESCRIPTION)
end unless (defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?) ||
(defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?)
(defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?) ||
(ENV['RUBY_MN_THREADS'] == '1')
end
end
10 changes: 8 additions & 2 deletions spec/ruby/command_line/syntax_error_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
describe "The interpreter" do
it "prints an error when given a file with invalid syntax" do
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), args: "2>&1", exit_status: 1)
out.should include "syntax error"

# it's tempting not to rely on error message and rely only on exception class name,
# but CRuby before 3.2 doesn't print class name for syntax error
out.should include_any_of("syntax error", "SyntaxError")
end

it "prints an error when given code via -e with invalid syntax" do
out = ruby_exe(nil, args: "-e 'a{' 2>&1", exit_status: 1)
out.should include "syntax error"

# it's tempting not to rely on error message and rely only on exception class name,
# but CRuby before 3.2 doesn't print class name for syntax error
out.should include_any_of("syntax error", "SyntaxError")
end
end
22 changes: 12 additions & 10 deletions spec/ruby/core/array/rassoc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,17 @@ def o.==(other); other == 'foobar'; end
[[1, :foobar, o], [2, o, 1], [3, mock('foo')]].rassoc(key).should == [2, o, 1]
end

it "does not call to_ary on non-array elements" do
s1 = [1, 2]
s2 = ArraySpecs::ArrayConvertible.new(2, 3)
a = [s1, s2]

s1.should_not_receive(:to_ary)
a.rassoc(2).should equal(s1)

s2.should_not_receive(:to_ary)
a.rassoc(3).should equal(nil)
ruby_version_is "3.3" do
it "calls to_ary on non-array elements" do
s1 = [1, 2]
s2 = ArraySpecs::ArrayConvertible.new(2, 3)
a = [s1, s2]

s1.should_not_receive(:to_ary)
a.rassoc(2).should equal(s1)

a.rassoc(3).should == [2, 3]
s2.called.should equal(:to_ary)
end
end
end
8 changes: 4 additions & 4 deletions spec/ruby/core/class/attached_object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
it "raises TypeError if the class is not a singleton class" do
a = Class.new

-> { a.attached_object }.should raise_error(TypeError)
-> { a.attached_object }.should raise_error(TypeError, /is not a singleton class/)
end

it "raises TypeError for special singleton classes" do
-> { nil.singleton_class.attached_object }.should raise_error(TypeError)
-> { true.singleton_class.attached_object }.should raise_error(TypeError)
-> { false.singleton_class.attached_object }.should raise_error(TypeError)
-> { nil.singleton_class.attached_object }.should raise_error(TypeError, /`NilClass' is not a singleton class/)
-> { true.singleton_class.attached_object }.should raise_error(TypeError, /`TrueClass' is not a singleton class/)
-> { false.singleton_class.attached_object }.should raise_error(TypeError, /`FalseClass' is not a singleton class/)
end
end
end
1 change: 0 additions & 1 deletion spec/ruby/core/conditionvariable/broadcast_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
require 'thread'

describe "ConditionVariable#broadcast" do
it "releases all threads waiting in line for this resource" do
Expand Down
1 change: 0 additions & 1 deletion spec/ruby/core/conditionvariable/marshal_dump_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
require 'thread'

describe "ConditionVariable#marshal_dump" do
it "raises a TypeError" do
Expand Down
1 change: 0 additions & 1 deletion spec/ruby/core/conditionvariable/signal_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
require 'thread'

describe "ConditionVariable#signal" do
it "releases the first thread waiting in line for this resource" do
Expand Down
1 change: 0 additions & 1 deletion spec/ruby/core/conditionvariable/wait_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
require 'thread'

describe "ConditionVariable#wait" do
it "calls #sleep on the given object" do
Expand Down
7 changes: 7 additions & 0 deletions spec/ruby/core/data/initialize_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
data.unit.should == "km"
end

it "accepts String keyword arguments" do
data = DataSpecs::Measure.new("amount" => 42, "unit" => "km")

data.amount.should == 42
data.unit.should == "km"
end

it "raises ArgumentError if no arguments are given" do
-> {
DataSpecs::Measure.new
Expand Down
35 changes: 35 additions & 0 deletions spec/ruby/core/data/with_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

ruby_version_is "3.2" do
describe "Data#with" do
it "returns self if given no arguments" do
data = DataSpecs::Measure.new(amount: 42, unit: "km")
data = data.with.should.equal?(data)
end

it "accepts keyword arguments" do
data = DataSpecs::Measure.new(amount: 42, unit: "km")
data = data.with(amount: 4, unit: "m")

data.amount.should == 4
data.unit.should == "m"
end

it "accepts String keyword arguments" do
data = DataSpecs::Measure.new(amount: 42, unit: "km")
data = data.with("amount" => 4, "unit" => "m")

data.amount.should == 4
data.unit.should == "m"
end

it "raises ArgumentError if no keyword arguments are given" do
data = DataSpecs::Measure.new(amount: 42, unit: "km")

-> {
data.with(4, "m")
}.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 0)")
end
end
end
16 changes: 16 additions & 0 deletions spec/ruby/core/exception/frozen_error_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,19 @@ def o.x; end
end
end
end

describe "Modifying a frozen object" do
context "#inspect is redefined and modifies the object" do
it "returns ... instead of String representation of object" do
object = Object.new
def object.inspect; @a = 1 end
def object.modify; @a = 2 end

object.freeze

# CRuby's message contains multiple whitespaces before '...'.
# So handle both multiple and single whitespace.
-> { object.modify }.should raise_error(FrozenError, /can't modify frozen .*?: \s*.../)
end
end
end
3 changes: 3 additions & 0 deletions spec/ruby/core/file/atime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
else
File.atime(__FILE__).usec.should == 0
end
rescue Errno::ENOENT => e
# Native Windows don't have stat command.
skip e.message
end
end
end
Expand Down
3 changes: 3 additions & 0 deletions spec/ruby/core/file/ctime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
else
File.ctime(__FILE__).usec.should == 0
end
rescue Errno::ENOENT => e
# Windows don't have stat command.
skip e.message
end
end

Expand Down
3 changes: 3 additions & 0 deletions spec/ruby/core/file/mtime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
else
File.mtime(__FILE__).usec.should == 0
end
rescue Errno::ENOENT => e
# Windows don't have stat command.
skip e.message
end
end
end
Expand Down
18 changes: 16 additions & 2 deletions spec/ruby/core/hash/delete_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,35 @@
it "allows removing a key while iterating" do
h = { a: 1, b: 2 }
visited = []
h.each_pair { |k,v|
h.each_pair { |k, v|
visited << k
h.delete(k)
}
visited.should == [:a, :b]
h.should == {}
end

it "allows removing a key while iterating for big hashes" do
h = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10,
k: 11, l: 12, m: 13, n: 14, o: 15, p: 16, q: 17, r: 18, s: 19, t: 20,
u: 21, v: 22, w: 23, x: 24, y: 25, z: 26 }
visited = []
h.each_pair { |k, v|
visited << k
h.delete(k)
}
visited.should == [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, :l, :m,
:n, :o, :p, :q, :r, :s, :t, :u, :v, :w, :x, :y, :z]
h.should == {}
end

it "accepts keys with private #hash method" do
key = HashSpecs::KeyWithPrivateHash.new
{ key => 5 }.delete(key).should == 5
end

it "raises a FrozenError if called on a frozen instance" do
-> { HashSpecs.frozen_hash.delete("foo") }.should raise_error(FrozenError)
-> { HashSpecs.frozen_hash.delete("foo") }.should raise_error(FrozenError)
-> { HashSpecs.empty_frozen_hash.delete("foo") }.should raise_error(FrozenError)
end
end
2 changes: 1 addition & 1 deletion spec/ruby/core/hash/hash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
end

ruby_version_is "3.1" do
it "allows ommiting values" do
it "allows omitting values" do
a = 1
b = 2

Expand Down
30 changes: 30 additions & 0 deletions spec/ruby/core/hash/rehash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,36 @@ def k1.hash; 1; end
h.keys.should_not.include? [1]
end

it "iterates keys in insertion order" do
key = Class.new do
attr_reader :name

def initialize(name)
@name = name
end

def hash
123
end
end

a, b, c, d = key.new('a'), key.new('b'), key.new('c'), key.new('d')
h = { a => 1, b => 2, c => 3, d => 4 }
h.size.should == 4

key.class_exec do
def eql?(other)
true
end
end

h.rehash
h.size.should == 1
k, v = h.first
k.name.should == 'a'
v.should == 4
end

it "raises a FrozenError if called on a frozen instance" do
-> { HashSpecs.frozen_hash.rehash }.should raise_error(FrozenError)
-> { HashSpecs.empty_frozen_hash.rehash }.should raise_error(FrozenError)
Expand Down
Loading

0 comments on commit de53d76

Please sign in to comment.