1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67112 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2019-02-21 15:38:59 +00:00
parent b8e389a0f3
commit da7976235f
75 changed files with 940 additions and 258 deletions

226
spec/ruby/.mspec.constants Normal file
View file

@ -0,0 +1,226 @@
Abbrev
Addrinfo
AliasObject
AliasObject2
AnonWithConstant
ArbitraryException
ArraySub
ArraySubPush
AryChild
Base64
BaseClass
BasicSocket
BeCloseToMatrixMatcher
BigDecimal
BigMath
BitwiseAndTest
BreakTest
BreakTest2
CAPI_SIZEOF_LONG
CApiModuleSpecsAutoload
CApiModuleSpecsModuleA
CGI
CMath
CODE_LOADING_DIR
CSAutoloadA
CSAutoloadB
CSAutoloadC
CSAutoloadD
CSV
ChainedNextTest
Channel
ChildClass
ClassIdUnderAutoload
ClassSpecDefineClass
ClassSpecsKeywordWithSemicolon
ClassSpecsKeywordWithoutSemicolon
ClassSpecsNumber
ClassUnderAutoload
CodingUS_ASCII
CodingUTF_8
ComparisonTest
ConstantSpecsIncludedModule
ConstantVisibility
Coverage
CustomArgumentError
DRb
DRbIdConv
DRbObject
DRbUndumped
Date
DateTime
DefSpecNested
DefSpecNestedB
DefSpecSingleton
DefSpecsLambdaVisibility
DefineMethodByProcClass
DefineMethodSpecClass
DefineSingletonMethodSpecClass
DescArray
DescObjectTest
Digest
DumpableDir
ERB
EnsureInClassExample
EnumerableSpecGrep
EnumerableSpecGrep2
EnumerableSpecIncludeP
EnumerableSpecIncludeP11
Etc
EvalBindingA
EvalBindingProcA
Exception2MessageMapper
ExceptionForMatrix
Fcntl
FileStat
FileUtils
Find
Forwardable
GetoptLong
HMACConstants
HashStringsASCII8BIT
HashStringsUSASCII
HashStringsUTF8
IPAddr
IPSocket
Importer
IncludeSpecsClass
IncludeSpecsMiddle
IncludeSpecsTop
IncludesMath
InvalidTostrTest
JSON
KSAutoloadA
KSAutoloadB
KSAutoloadBB
KSAutoloadCallsRequire
KSAutoloadD
Logger
MD5Constants
MY_INPUT4_FOR_ERB
Matrix
MatrixSub
MethodArity
Meths
MethsMore
Mixin
ModuleSpecsKeywordWithoutSemicolon
ModuleSpecsToplevel
ModuleSpecs_CS1
ModuleSpecs_CS2
ModuleSpecs_CS3
MyClass
MyClass0ForErb
MyClass1ForErb
MyClass1ForErb_
MyClass2ForErb
MyClass4ForErb
MyFiber
MyModule2ForErb
MyString
NamespaceTest
Net
OBJDIR
OBJECT_SPACE_TOP_LEVEL_CONSTANT
OFor
ObjectSpaceFixtures
ObjectSpecDup
ObjectSpecDupInitCopy
ObjectTest
Observable
Open3
OpenSSL
OpenStruct
OperatorImplementor
OptParse
OptionParser
OrAndXorTest
OtherCustomException
ParentClass
Pathname
Person
Prime
Private
ProcFromMethod
Psych
REXML
RUBY_SIGNALS
RbReadline
Readline
ReceiverClass
RegexpSpecsSubclass
RegexpSpecsSubclassTwo
RescueInClassExample
Resolv
SHA1Constants
SHA256Constants
SHA384Constants
SHA512Constants
SameName
ScanError
Scanf
SecondClass
SecureRandom
Set
Shellwords
SingleForwardable
Singleton
Socket
SocketError
SomeClass
SortedSet
SpecificExampleException
Specs
StrChild
StrangeEach
StringRefinement
StringScanner
StringSubclass
StructClasses
Syslog
TCPServer
TCPSocket
TSort
Tempfile
TestServer
Timeout
TimeoutError
UDPSocket
UNIXServer
UNIXSocket
UnaryMinusTest
UnicodeNormalize
UnloadableDumpableDir
UserArray
UserCustomConstructorString
UserDefined
UserDefinedImmediate
UserDefinedWithIvar
UserHash
UserHashInitParams
UserMarshal
UserMarshalWithClassName
UserMarshalWithIvar
UserObject
UserPreviouslyDefinedWithInitializedIvar
UserRegexp
UserString
ValidTostrTest
Vector
WEBrick
WIN32OLE
WIN32OLEQueryInterfaceError
WIN32OLERuntimeError
WIN32OLE_EVENT
WIN32OLE_METHOD
WIN32OLE_PARAM
WIN32OLE_RECORD
WIN32OLE_RUBYSPEC
WIN32OLE_TYPE
WIN32OLE_TYPELIB
WIN32OLE_VARIABLE
WIN32OLE_VARIANT
WeakRef
Win32
YAML
Zlib

View file

@ -13,7 +13,7 @@ matrix:
env: CHECK_LEAKS=true
- rvm: 2.5.3
env: CHECK_LEAKS=true
- rvm: 2.6.0
- rvm: 2.6.1
env: CHECK_LEAKS=true
- env: RUBOCOP=true
rvm: 2.4.5

View file

@ -98,6 +98,23 @@ In similar fashion, the following commands run the respective specs:
$ ../mspec/bin/mspec :library
$ ../mspec/bin/mspec :capi
### Sanity Checks When Running Specs
A number of checks for various kind of "leaks" (file descriptors, temporary files,
threads, subprocesses, `ENV`, `ARGV`, global encodings, top-level constants) can be
enabled with `CHECK_LEAKS=true`:
$ CHECK_LEAKS=true ../mspec/bin/mspec
New top-level constants should only be introduced when needed or follow the
pattern `<ClassBeingTested>Specs` such as `module StringSpecs`.
Other constants used for testing should be nested under such a module.
Exceptions to these rules are contained in the file `.mspec.constants`.
MSpec can automatically add new top-level constants in this file with:
$ CHECK_LEAKS=save mspec ../mspec/bin/mspec file
### Contributing and Writing Specs
See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) for documentation about contributing and writing specs (guards, matchers, etc).

View file

@ -27,6 +27,22 @@ describe "Array#each" do
b.should == [2, nil, 4]
end
it "yields elements added to the end of the array by the block" do
a = [2]
iterated = []
a.each { |x| iterated << x; x.times { a << 0 } }
iterated.should == [2, 0, 0]
end
it "does not yield elements deleted from the end of the array" do
a = [2, 3, 1]
iterated = []
a.each { |x| iterated << x; a.delete_at(2) if x == 3 }
iterated.should == [2, 3]
end
it_behaves_like :enumeratorize, :each
it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3]
end

View file

@ -9,14 +9,17 @@ ruby_version_is "2.6" do
it "returns a chain of self and provided enumerables" do
one = EnumerableSpecs::Numerous.new(1)
two = EnumerableSpecs::Numerous.new(2)
three = EnumerableSpecs::Numerous.new(3)
two = EnumerableSpecs::Numerous.new(2, 3)
three = EnumerableSpecs::Numerous.new(4, 5, 6)
chain = one.chain(two, three)
chain.should be_an_instance_of(Enumerator::Chain)
chain.each { |item| ScratchPad << item }
ScratchPad.recorded.should == [1, 2, 3]
ScratchPad.recorded.should == [1, 2, 3, 4, 5, 6]
end
it "returns an Enumerator::Chain if given a block" do
EnumerableSpecs::Numerous.new.chain.should be_an_instance_of(Enumerator::Chain)
end
end
end

View file

@ -68,4 +68,10 @@ describe "Enumerator::Lazy#chunk" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.chunk { |n| n.even? }.first(100).should ==
s.first(100).chunk { |n| n.even? }.to_a
end
end

View file

@ -0,0 +1,9 @@
require_relative '../../../spec_helper'
describe "Enumerator::Lazy#chunk_while" do
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.chunk_while { |a, b| false }.first(100).should ==
s.first(100).chunk_while { |a, b| false }.to_a
end
end

View file

@ -49,4 +49,10 @@ describe "Enumerator::Lazy#drop" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.drop(100).first(100).should ==
s.first(200).drop(100)
end
end

View file

@ -57,4 +57,10 @@ describe "Enumerator::Lazy#drop_while" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.drop_while { |n| n < 100 }.first(100).should ==
s.first(200).drop_while { |n| n < 100 }
end
end

View file

@ -27,4 +27,10 @@ describe "Enumerator::Lazy#force" do
ScratchPad.recorded.should == [:before_yield]
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.take(100).force.should ==
s.take(100)
end
end

View file

@ -79,4 +79,10 @@ describe "Enumerator::Lazy#grep" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.grep(Numeric).first(100).should ==
s.first(100).grep(Numeric)
end
end

View file

@ -81,4 +81,10 @@ describe "Enumerator::Lazy#grep_v" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.grep_v(String).first(100).should ==
s.first(100).grep_v(String)
end
end

View file

@ -6,6 +6,20 @@ describe "Enumerator::Lazy" do
it "is a subclass of Enumerator" do
Enumerator::Lazy.superclass.should equal(Enumerator)
end
it "defines lazy versions of a whitelist of Enumerator methods" do
lazy_methods = [
:chunk, :collect, :collect_concat, :drop, :drop_while, :enum_for,
:find_all, :flat_map, :force, :grep, :grep_v, :lazy, :map, :reject,
:select, :slice_after, :slice_before, :slice_when, :take, :take_while,
:to_enum, :zip
]
ruby_version_is "2.4" do
lazy_methods += [:chunk_while, :uniq]
end
Enumerator::Lazy.instance_methods(false).should include(*lazy_methods)
end
end
describe "Enumerator::Lazy#lazy" do

View file

@ -33,6 +33,18 @@ describe "Enumerator::Lazy#reject" do
end
end
it "lets exceptions raised in the block go through" do
lazy = 10.times.lazy.map do |i|
raise "foo"
end
lazy = lazy.reject(&:nil?)
-> {
lazy.first
}.should raise_error(RuntimeError, "foo")
end
it "calls the block with a gathered array when yield with multiple arguments" do
yields = []
@yieldsmixed.reject { |v| yields << v }.force
@ -57,4 +69,10 @@ describe "Enumerator::Lazy#reject" do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.reject { |n| false }.first(100).should ==
s.first(100).reject { |n| false }
end
end

View file

@ -53,4 +53,10 @@ describe :enumerator_lazy_collect, shared: true do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.send(@method) { |n| n }.first(100).should ==
s.first(100).send(@method) { |n| n }.to_a
end
end

View file

@ -69,4 +69,10 @@ describe :enumerator_lazy_collect_concat, shared: true do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.send(@method) { |n| [-n, +n] }.first(200).should ==
s.first(100).send(@method) { |n| [-n, +n] }.to_a
end
end

View file

@ -57,4 +57,10 @@ describe :enumerator_lazy_select, shared: true do
end
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.send(@method) { |n| true }.first(100).should ==
s.first(100).send(@method) { |n| true }
end
end

View file

@ -47,4 +47,10 @@ describe :enumerator_lazy_to_enum, shared: true do
@infinite.send(method, *args).should be_an_instance_of(Enumerator::Lazy)
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.send(@method, :with_index).first(100).should ==
s.first(100).to_enum.send(@method, :with_index).to_a
end
end

View file

@ -0,0 +1,9 @@
require_relative '../../../spec_helper'
describe "Enumerator::Lazy#slice_after" do
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.slice_after { |n| true }.first(100).should ==
s.first(100).slice_after { |n| true }.to_a
end
end

View file

@ -0,0 +1,9 @@
require_relative '../../../spec_helper'
describe "Enumerator::Lazy#slice_before" do
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.slice_before { |n| true }.first(100).should ==
s.first(100).slice_before { |n| true }.to_a
end
end

View file

@ -0,0 +1,9 @@
require_relative '../../../spec_helper'
describe "Enumerator::Lazy#slice_when" do
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.slice_when { |a, b| true }.first(100).should ==
s.first(100).slice_when { |a, b| true }.to_a
end
end

View file

@ -72,5 +72,11 @@ ruby_version_is '2.4' do
@lazy.uniq { |_, label| label.downcase }.force.should == [[0, 'foo'], [2, 'bar']]
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.uniq.first(100).should ==
s.first(100).uniq
end
end
end

View file

@ -71,4 +71,16 @@ describe "Enumerator::Lazy#zip" do
end
end
end
it "works with an infinite enumerable and an array" do
s = 0..Float::INFINITY
s.lazy.zip(0..1000).first(100).should ==
s.first(100).zip(0..100)
end
it "works with two infinite enumerables" do
s = 0..Float::INFINITY
s.lazy.zip(s).first(100).should ==
s.first(100).zip(s)
end
end

View file

@ -16,4 +16,29 @@ describe "Exception#cause" do
end
end
end
it "is set for user errors caused by internal errors" do
-> {
begin
1 / 0
rescue
raise "foo"
end
}.should raise_error(RuntimeError) { |e|
e.cause.should be_kind_of(ZeroDivisionError)
}
end
it "is set for internal errors caused by user errors" do
cause = RuntimeError.new "cause"
-> {
begin
raise cause
rescue
1 / 0
end
}.should raise_error(ZeroDivisionError) { |e|
e.cause.should equal(cause)
}
end
end

View file

@ -58,4 +58,17 @@ describe "Exception#dup" do
@obj.dup.backtrace.should == @obj.backtrace
end
it "does copy the cause" do
begin
raise StandardError, "the cause"
rescue StandardError => cause
begin
raise RuntimeError, "the consequence"
rescue RuntimeError => e
e.cause.should equal(cause)
e.dup.cause.should equal(cause)
end
end
end
end

View file

@ -33,6 +33,25 @@ ruby_version_is "2.5" do
e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m
e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m
end
it "shows the caller if the exception has no backtrace" do
e = RuntimeError.new("Some runtime error")
e.backtrace.should == nil
full_message = e.full_message(highlight: false, order: :top)
full_message.should include("#{__FILE__}:#{__LINE__-1}:in `")
full_message.should include("': Some runtime error (RuntimeError)\n")
end
it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
begin
line = __LINE__; raise "first line\nsecond line"
rescue => e
full_message = e.full_message(highlight: false, order: :top).lines
full_message[0].should include("#{__FILE__}:#{line}:in `")
full_message[0].should include(": first line (RuntimeError)\n")
full_message[1].should == "second line\n"
end
end
end
ruby_version_is "2.6" do

View file

@ -53,8 +53,9 @@ describe "File.split" do
end
it "coerces the argument with to_str if it is not a String type" do
class C; def to_str; "/rubinius/better/than/ruby"; end; end
File.split(C.new).should == ["/rubinius/better/than", "ruby"]
obj = mock("str")
obj.should_receive(:to_str).and_return("/one/two/three")
File.split(obj).should == ["/one/two", "three"]
end
it "accepts an object that has a #to_path method" do

View file

@ -81,6 +81,14 @@ describe "Integer#div" do
(10**50).div(-(10**40 + 1)).should == -10000000000
end
it "handles fixnum_min / -1" do
(fixnum_min / -1).should == -fixnum_min
(fixnum_min / -1).should > 0
int_min = -2147483648
(int_min / -1).should == 2147483648
end
it "calls #coerce and #div if argument responds to #coerce" do
x = mock("x")
y = mock("y")

View file

@ -11,8 +11,10 @@ describe "Integer#-@" do
end
it "negates self at Fixnum/Bignum boundaries" do
fixnum_max.send(:-@).should == (0 - fixnum_max)
fixnum_min.send(:-@).should == (0 - fixnum_min)
(-fixnum_max).should == (0 - fixnum_max)
(-fixnum_max).should < 0
(-fixnum_min).should == (0 - fixnum_min)
(-fixnum_min).should > 0
end
end

View file

@ -9,7 +9,7 @@ describe "IO#ioctl" do
end
platform_is :linux do
platform_is "86" do # x86 / x86_64
guard -> { RUBY_PLATFORM.include?("86") } do # x86 / x86_64
it "resizes an empty String to match the output size" do
File.open(__FILE__, 'r') do |f|
buffer = ''

View file

@ -46,10 +46,10 @@ describe "Kernel#extend" do
end
it "makes the class a kind_of? the argument" do
class C
c = Class.new do
extend KernelSpecs::M
end
(C.kind_of? KernelSpecs::M).should == true
(c.kind_of? KernelSpecs::M).should == true
end
it "raises an ArgumentError when no arguments given" do

View file

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel.fail" do
describe "Kernel#fail" do
it "is a private method" do
Kernel.should have_private_instance_method(:fail)
end
@ -11,17 +11,16 @@ describe "Kernel.fail" do
end
it "accepts an Object with an exception method returning an Exception" do
class Boring
def self.exception(msg)
StandardError.new msg
end
obj = Object.new
def obj.exception(msg)
StandardError.new msg
end
lambda { fail Boring, "..." }.should raise_error(StandardError)
lambda { fail obj, "..." }.should raise_error(StandardError, "...")
end
it "instantiates the specified exception class" do
class LittleBunnyFooFoo < RuntimeError; end
lambda { fail LittleBunnyFooFoo }.should raise_error(LittleBunnyFooFoo)
error_class = Class.new(RuntimeError)
lambda { fail error_class }.should raise_error(error_class)
end
it "uses the specified message" do
@ -38,6 +37,6 @@ describe "Kernel.fail" do
end
end
describe "Kernel#fail" do
describe "Kernel.fail" do
it "needs to be reviewed for spec completeness"
end

View file

@ -3,32 +3,32 @@ require_relative 'fixtures/classes'
describe "Kernel#instance_variable_set" do
it "sets the value of the specified instance variable" do
class Dog
dog = Class.new do
def initialize(p1, p2)
@a, @b = p1, p2
end
end
Dog.new('cat', 99).instance_variable_set(:@a, 'dog').should == "dog"
dog.new('cat', 99).instance_variable_set(:@a, 'dog').should == "dog"
end
it "sets the value of the instance variable when no instance variables exist yet" do
class NoVariables; end
NoVariables.new.instance_variable_set(:@a, "new").should == "new"
no_variables = Class.new
no_variables.new.instance_variable_set(:@a, "new").should == "new"
end
it "raises a NameError exception if the argument is not of form '@x'" do
class NoDog; end
lambda { NoDog.new.instance_variable_set(:c, "cat") }.should raise_error(NameError)
no_dog = Class.new
lambda { no_dog.new.instance_variable_set(:c, "cat") }.should raise_error(NameError)
end
it "raises a NameError exception if the argument is an invalid instance variable name" do
class DigitDog; end
lambda { DigitDog.new.instance_variable_set(:"@0", "cat") }.should raise_error(NameError)
digit_dog = Class.new
lambda { digit_dog.new.instance_variable_set(:"@0", "cat") }.should raise_error(NameError)
end
it "raises a NameError when the argument is '@'" do
class DogAt; end
lambda { DogAt.new.instance_variable_set(:"@", "cat") }.should raise_error(NameError)
dog_at = Class.new
lambda { dog_at.new.instance_variable_set(:"@", "cat") }.should raise_error(NameError)
end
it "raises a TypeError if the instance variable name is a Fixnum" do

View file

@ -77,6 +77,15 @@ describe "Kernel#warn" do
}.should output(nil, /\n/)
end
it "writes to_s representation if passed a non-string" do
obj = mock("obj")
obj.should_receive(:to_s).and_return("to_s called")
lambda {
$VERBOSE = true
warn(obj)
}.should output(nil, "to_s called\n")
end
ruby_version_is "2.5" do
describe ":uplevel keyword argument" do
before :each do

View file

@ -475,6 +475,24 @@ describe "Marshal.dump" do
obj.set_backtrace(["foo/bar.rb:10"])
Marshal.dump(obj).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt[\x06\"\x12foo/bar.rb:10"
end
it "dumps the cause for the exception" do
exc = nil
begin
raise StandardError, "the cause"
rescue StandardError => cause
begin
raise RuntimeError, "the consequence"
rescue RuntimeError => e
e.cause.should equal(cause)
exc = e
end
end
reloaded = Marshal.load(Marshal.dump(exc))
reloaded.cause.should be_an_instance_of(StandardError)
reloaded.cause.message.should == "the cause"
end
end
it "dumps subsequent appearances of a symbol as a link" do

View file

@ -423,12 +423,12 @@ describe "Module#autoload" do
ModuleSpecs::Autoload::U::V::X.should == :autoload_uvx
end
it "loads the file that defines subclass XX::YY < YY and YY is a top level constant" do
it "loads the file that defines subclass XX::CS_CONST_AUTOLOAD < CS_CONST_AUTOLOAD and CS_CONST_AUTOLOAD is a top level constant" do
module ModuleSpecs::Autoload::XX
autoload :YY, fixture(__FILE__, "autoload_subclass.rb")
autoload :CS_CONST_AUTOLOAD, fixture(__FILE__, "autoload_subclass.rb")
end
ModuleSpecs::Autoload::XX::YY.superclass.should == YY
ModuleSpecs::Autoload::XX::CS_CONST_AUTOLOAD.superclass.should == CS_CONST_AUTOLOAD
end
describe "after autoloading searches for the constant like the original lookup" do

View file

@ -1,10 +1,10 @@
class YY
class CS_CONST_AUTOLOAD
end
module ModuleSpecs
module Autoload
module XX
class YY < YY
class CS_CONST_AUTOLOAD < CS_CONST_AUTOLOAD
end
end
end

View file

@ -77,19 +77,19 @@ describe "Module#remove_method" do
end
it "raises a NameError when attempting to remove method further up the inheritance tree" do
lambda {
class Third < ModuleSpecs::Second
Class.new(ModuleSpecs::Second) do
-> {
remove_method :method_to_remove
end
}.should raise_error(NameError)
}.should raise_error(NameError)
end
end
it "raises a NameError when attempting to remove a missing method" do
lambda {
class Third < ModuleSpecs::Second
Class.new(ModuleSpecs::Second) do
-> {
remove_method :blah
end
}.should raise_error(NameError)
}.should raise_error(NameError)
end
end
describe "on frozen instance" do

View file

@ -16,6 +16,14 @@ describe :numeric_step, :shared => true do
ScratchPad.recorded.should eql [1, 2, 3, 4, 5]
end
it "defaults to an infinite limit with a step size of 1 for Integers" do
1.step.first(5).should == [1, 2, 3, 4, 5]
end
it "defaults to an infinite limit with a step size of 1.0 for Floats" do
1.0.step.first(5).should == [1.0, 2.0, 3.0, 4.0, 5.0]
end
describe "when self, stop and step are Fixnums" do
it "yields only Fixnums" do
1.send(@method, *@step_args.call(5, 1)) { |x| x.should be_an_instance_of(Fixnum) }

View file

@ -60,6 +60,11 @@ describe "Numeric#step" do
enum.size.should == Float::INFINITY
end
end
it "defaults to an infinite size" do
enum = 1.step
enum.size.should == Float::INFINITY
end
end
describe "type" do

View file

@ -102,6 +102,15 @@ describe "Range#step" do
ScratchPad.recorded.should eql([1.0, 2.8, 4.6, 6.4, 1.0, 2.3, 3.6,
4.9, 6.2, 7.5, 8.8, 10.1, 11.4, 12.7])
end
it "handles infinite values at either end" do
(-Float::INFINITY..0.0).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY])
ScratchPad.record []
(0.0..Float::INFINITY).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([0.0, 2.0, 4.0])
end
end
describe "and Integer, Float values" do
@ -203,6 +212,15 @@ describe "Range#step" do
(1.0...55.6).step(18.2) { |x| ScratchPad << x }
ScratchPad.recorded.should eql([1.0, 2.8, 4.6, 1.0, 19.2, 37.4])
end
it "handles infinite values at either end" do
(-Float::INFINITY...0.0).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY])
ScratchPad.record []
(0.0...Float::INFINITY).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([0.0, 2.0, 4.0])
end
end
describe "and Integer, Float values" do

View file

@ -1,5 +1,11 @@
# -*- encoding: binary -*-
describe :string_codepoints, shared: true do
it "returns self" do
s = "foo"
result = s.send(@method) {}
result.should equal s
end
it "raises an ArgumentError when self has an invalid encoding and a method is called on the returned Enumerator" do
s = "\xDF".force_encoding(Encoding::UTF_8)
s.valid_encoding?.should be_false
@ -20,13 +26,13 @@ describe :string_codepoints, shared: true do
lambda { s.send(@method) { } }.should raise_error(ArgumentError)
end
it "returns codepoints as Fixnums" do
it "yields codepoints as Fixnums" do
"glark\u{20}".send(@method).to_a.each do |codepoint|
codepoint.should be_an_instance_of(Fixnum)
end
end
it "returns one codepoint for each character" do
it "yields one codepoint for each character" do
s = "\u{9876}\u{28}\u{1987}"
s.send(@method).to_a.size.should == s.chars.to_a.size
end
@ -37,7 +43,7 @@ describe :string_codepoints, shared: true do
s.send(@method).to_a.should == [38937]
end
it "returns the codepoint corresponding to the character's position in the String's encoding" do
it "yields the codepoints corresponding to the character's position in the String's encoding" do
"\u{787}".send(@method).to_a.should == [1927]
end

View file

@ -413,15 +413,17 @@ describe "String#split with Regexp" do
end
describe "for a String subclass" do
a = []
StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
first, last = a
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"
last.should be_an_instance_of(StringSpecs::MyString)
last.should == "b"
end
end
end
end

View file

@ -3,12 +3,9 @@ require_relative 'fixtures/classes'
require_relative 'shared/inspect'
describe "Struct#inspect" do
it "returns a string representation of some kind" do
it "returns a string representation showing members and values" do
car = StructClasses::Car.new('Ford', 'Ranger')
car.inspect.should == '#<struct StructClasses::Car make="Ford", model="Ranger", year=nil>'
Whiskey = Struct.new(:name, :ounces)
Whiskey.new('Jack', 100).inspect.should == '#<struct Whiskey name="Jack", ounces=100>'
end
it_behaves_like :struct_inspect, :inspect

View file

@ -53,4 +53,31 @@ describe "Thread.new" do
ScratchPad.recorded.should == [:good, :in_thread]
end
it "releases Mutexes held by the Thread when the Thread finishes" do
m1 = Mutex.new
m2 = Mutex.new
t = Thread.new {
m1.lock
m1.locked?.should == true
m2.lock
m2.locked?.should == true
}
t.join
m1.locked?.should == false
m2.locked?.should == false
end
it "releases Mutexes held by the Thread when the Thread finishes, also with Mutex#synchronize" do
m = Mutex.new
t = Thread.new {
m.synchronize {
m.unlock
m.lock
}
m.lock
m.locked?.should == true
}
t.join
m.locked?.should == false
end
end

View file

@ -5,6 +5,12 @@ describe :time_gmt_offset, shared: true do
end
end
it "returns 0 when the date is UTC" do
with_timezone("AST", 3) do
Time.new.utc.send(@method).should == 0
end
end
platform_is_not :windows do
it "returns the correct offset for US Eastern time zone around daylight savings time change" do
# "2010-03-14 01:59:59 -0500" + 1 ==> "2010-03-14 03:00:00 -0400"

View file

@ -1,34 +1,37 @@
require_relative '../../spec_helper'
describe 'TracePoint#disable' do
def test; end
it 'returns true if trace was enabled' do
called = false
trace = TracePoint.new(:call) do |tp|
trace = TracePoint.new(:line) do |tp|
called = true
end
trace.enable
trace.disable.should be_true
begin
line_event = true
ensure
ret = trace.disable
ret.should == true
end
called.should == true
# Check the TracePoint is disabled
called = false
test
line_event = true
called.should == false
end
it 'returns false if trace was disabled' do
event_name, method_name = nil
trace = TracePoint.new(:call) do |tp|
event_name = tp.event
method_name = tp.method_id
called = false
trace = TracePoint.new(:line) do |tp|
called = true
end
trace.disable.should be_false
event_name, method_name = nil
test
method_name.equal?(:test).should be_false
event_name.should equal(nil)
line_event = true
trace.disable.should == false
line_event = true
called.should == false
end
it 'is disabled within a block & is enabled outside the block' do
@ -37,19 +40,19 @@ describe 'TracePoint#disable' do
trace.enable
begin
trace.disable { enabled = trace.enabled? }
enabled.should be_false
trace.enabled?.should be_true
enabled.should == false
trace.enabled?.should == true
ensure
trace.disable
end
end
it 'is disabled within a block & also returns false when its called with a block' do
it 'returns the return value of the block' do
trace = TracePoint.new(:line) {}
trace.enable
begin
trace.disable { trace.enabled? }.should == false
trace.enabled?.should equal(true)
trace.disable { 42 }.should == 42
trace.enabled?.should == true
ensure
trace.disable
end
@ -57,14 +60,13 @@ describe 'TracePoint#disable' do
ruby_bug "#14057", ""..."2.5" do
it 'can accept param within a block but it should not yield arguments' do
event_name = nil
trace = TracePoint.new(:line) {}
trace.enable
begin
trace.disable do |*args|
args.should == []
end
trace.enabled?.should be_true
trace.enabled?.should == true
ensure
trace.disable
end

View file

@ -1,53 +1,49 @@
require_relative '../../spec_helper'
describe 'TracePoint#enable' do
def test; end
# def test; end
describe 'without a block' do
it 'returns true if trace was enabled' do
event_name = nil
trace = TracePoint.new(:call) do |tp|
event_name = tp.event
called = false
trace = TracePoint.new(:line) do |tp|
called = true
end
test
event_name.should == nil
line_event = true
called.should == false
trace.enable
begin
test
event_name.should equal(:call)
line_event = true
called.should == true
ensure
trace.disable
end
end
it 'returns false if trace was disabled' do
event_name, method_name = nil, nil
trace = TracePoint.new(:call) do |tp|
event_name = tp.event
method_name = tp.method_id
called = false
trace = TracePoint.new(:line) do |tp|
called = true
end
trace.enable.should be_false
trace.enable.should == false
begin
event_name.should equal(:call)
test
method_name.equal?(:test).should be_true
line_event = true
called.should == true
ensure
trace.disable
end
event_name, method_name = nil
test
method_name.equal?(:test).should be_false
event_name.should equal(nil)
called = false
line_event = true
called.should == false
trace.enable.should be_false
trace.enable.should == false
begin
event_name.should equal(:call)
test
method_name.equal?(:test).should be_true
line_event = true
called.should == true
ensure
trace.disable
end
@ -70,7 +66,7 @@ describe 'TracePoint#enable' do
event_name.should equal(:line)
args.should == []
end
trace.enabled?.should be_false
trace.enabled?.should == false
end
end
@ -86,17 +82,19 @@ describe 'TracePoint#enable' do
end
end
it 'returns value returned by the block' do
it 'returns the return value of the block' do
trace = TracePoint.new(:line) {}
trace.enable { true; 'test' }.should == 'test'
trace.enable { 42 }.should == 42
end
it 'disables the trace object outside the block' do
event_name = nil
trace = TracePoint.new(:line) { |tp|event_name = tp.event }
trace.enable { '2 + 2' }
event_name.should equal(:line)
trace.enabled?.should be_false
called = false
trace = TracePoint.new(:line) { called = true }
trace.enable {
line_event = true
}
called.should == true
trace.enabled?.should == false
end
end

View file

@ -2,13 +2,13 @@ require_relative '../../spec_helper'
describe 'TracePoint#enabled?' do
it 'returns true when current status of the trace is enable' do
trace = TracePoint.new(:call) {}
trace = TracePoint.new(:line) {}
trace.enable do
trace.enabled?.should be_true
trace.enabled?.should == true
end
end
it 'returns false when current status of the trace is disabled' do
TracePoint.new(:call) {}.enabled?.should be_false
TracePoint.new(:line) {}.enabled?.should == false
end
end

View file

@ -1,8 +1,28 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe 'TracePoint#inspect' do
it 'returns a string containing a human-readable TracePoint status' do
TracePoint.new(:call) {}.inspect.should ==
TracePoint.new(:line) {}.inspect.should ==
'#<TracePoint:disabled>'
end
it 'returns a String showing the event, path and line' do
inspect = nil
line = __LINE__
TracePoint.new(:line) { |tp| inspect = tp.inspect }.enable do
inspect.should == "#<TracePoint:line@#{__FILE__}:#{line+2}>"
end
end
it 'returns a String showing the event, path and line for a :class event' do
inspect = nil
line = __LINE__
TracePoint.new(:class) { |tp| inspect = tp.inspect }.enable do
class TracePointSpec::C
end
end
inspect.should == "#<TracePoint:class@#{__FILE__}:#{line+2}>"
end
end

View file

@ -3,7 +3,7 @@ require_relative 'fixtures/classes'
describe 'TracePoint.new' do
it 'returns a new TracePoint object, not enabled by default' do
TracePoint.new(:call) {}.enabled?.should be_false
TracePoint.new(:line) {}.enabled?.should be_false
end
it 'includes :line event when event is not specified' do
@ -23,12 +23,11 @@ describe 'TracePoint.new' do
it 'converts given event name as string into symbol using to_sym' do
event_name = nil
(o = mock('return')).should_receive(:to_sym).and_return(:return)
(o = mock('line')).should_receive(:to_sym).and_return(:line)
TracePoint.new(o) { |tp| event_name = tp.event}.enable do
event_name.should equal(nil)
TracePointSpec.test
event_name.should equal(:return)
TracePoint.new(o) { |tp| event_name = tp.event }.enable do
line_event = true
event_name.should == :line
end
end
@ -58,11 +57,11 @@ describe 'TracePoint.new' do
ruby_bug "#140740", ""..."2.5" do
it 'expects to be called with a block' do
-> { TracePoint.new(:line) }.should raise_error(ArgumentError)
-> { TracePoint.new(:line) }.should raise_error(ArgumentError, "must be called with a block")
end
end
it "raises a Argument error when the give argument doesn't match an event name" do
-> { TracePoint.new(:test) }.should raise_error(ArgumentError)
it "raises a Argument error when the given argument doesn't match an event name" do
-> { TracePoint.new(:test) }.should raise_error(ArgumentError, "unknown event: test")
end
end

View file

@ -11,7 +11,7 @@ describe 'TracePoint#path' do
it 'equals (eval) inside an eval for :end event' do
path = nil
TracePoint.new(:end) { |tp| path = tp.path }.enable do
eval("class A; end")
eval("module TracePointSpec; end")
path.should == '(eval)'
end
end

View file

@ -1,4 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe 'TracePoint#self' do
it 'return the trace object from event' do
@ -7,4 +8,13 @@ describe 'TracePoint#self' do
trace.equal?(self).should be_true
end
end
it 'return the class object from a class event' do
trace = nil
TracePoint.new(:class) { |tp| trace = tp.self }.enable do
class TracePointSpec::C
end
end
trace.should equal TracePointSpec::C
end
end

View file

@ -2,8 +2,8 @@ require_relative '../../spec_helper'
describe 'TracePoint.trace' do
it 'activates the trace automatically' do
trace = TracePoint.trace(:call) {}
trace.enabled?.should be_true
trace = TracePoint.trace(:line) {}
trace.enabled?.should == true
trace.disable
end
end

View file

@ -46,7 +46,7 @@ class MSpecScript
set :toplevel_constants_excludes, [
/\wSpecs?$/,
/^CS_CONST\d/,
/^CS_CONST/,
]
# Enable features

View file

@ -204,7 +204,7 @@ describe "The alias keyword" do
end
it "operates on methods with splat arguments defined in a superclass using text block for class eval" do
class Sub < AliasObject;end
subclass = Class.new(AliasObject)
AliasObject.class_eval <<-code
def test(*args)
4
@ -215,7 +215,7 @@ describe "The alias keyword" do
alias test_without_check test
alias test test_with_check
code
Sub.new.test("testing").should == 4
subclass.new.test("testing").should == 4
end
it "is not allowed against Fixnum or String instances" do

View file

@ -210,16 +210,16 @@ describe "A class definition" do
describe "within a block creates a new class in the lexical scope" do
it "for named classes at the toplevel" do
klass = Class.new do
class Howdy
class CS_CONST_CLASS_SPECS
end
def self.get_class_name
Howdy.name
CS_CONST_CLASS_SPECS.name
end
end
Howdy.name.should == 'Howdy'
klass.get_class_name.should == 'Howdy'
klass.get_class_name.should == 'CS_CONST_CLASS_SPECS'
::CS_CONST_CLASS_SPECS.name.should == 'CS_CONST_CLASS_SPECS'
end
it "for named classes in a module" do

View file

@ -1,4 +1,4 @@
module Super
module SuperSpecs
module S1
class A
def foo(a)

View file

@ -32,14 +32,13 @@ describe "The for expression" do
end
it "iterates over any object responding to 'each'" do
class XYZ
def each
(0..10).each { |i| yield i }
end
obj = Object.new
def obj.each
(0..10).each { |i| yield i }
end
j = 0
for i in XYZ.new
for i in obj
j += i
end
j.should == 55

View file

@ -13,6 +13,7 @@ describe "Heredoc string" do
foo bar#{@ip}
HERE
s.should == "foo barxxx\n"
s.encoding.should == Encoding::US_ASCII
end
it 'allow HEREDOC with <<"identifier", interpolated' do
@ -20,6 +21,7 @@ HERE
foo bar#{@ip}
HERE
s.should == "foo barxxx\n"
s.encoding.should == Encoding::US_ASCII
end
it "allows HEREDOC with <<'identifier', no interpolation" do
@ -27,6 +29,7 @@ HERE
foo bar#{@ip}
HERE
s.should == 'foo bar#{@ip}' + "\n"
s.encoding.should == Encoding::US_ASCII
end
it "allows HEREDOC with <<-identifier, allowing to indent identifier, interpolated" do
@ -35,6 +38,7 @@ HERE
HERE
s.should == " foo barxxx\n"
s.encoding.should == Encoding::US_ASCII
end
it 'allows HEREDOC with <<-"identifier", allowing to indent identifier, interpolated' do
@ -43,6 +47,7 @@ HERE
HERE
s.should == " foo barxxx\n"
s.encoding.should == Encoding::US_ASCII
end
it "allows HEREDOC with <<-'identifier', allowing to indent identifier, no interpolation" do
@ -51,6 +56,7 @@ HERE
HERE
s.should == ' foo bar#{@ip}' + "\n"
s.encoding.should == Encoding::US_ASCII
end
it "allows HEREDOC with <<~'identifier', allowing to indent identifier and content" do

View file

@ -413,7 +413,7 @@ describe "The return keyword" do
ruby_version_is ""..."2.5" do
it "is allowed" do
File.write(@filename, <<-END_OF_CODE)
class A
class ReturnSpecs::A
ScratchPad << "before return"
return
@ -429,7 +429,7 @@ describe "The return keyword" do
ruby_version_is "2.5" do
it "raises a SyntaxError" do
File.write(@filename, <<-END_OF_CODE)
class A
class ReturnSpecs::A
ScratchPad << "before return"
return
@ -445,7 +445,7 @@ describe "The return keyword" do
describe "within a block within a class" do
it "is allowed" do
File.write(@filename, <<-END_OF_CODE)
class A
class ReturnSpecs::A
ScratchPad << "before return"
1.times { return }
ScratchPad << "after return"

View file

@ -3,71 +3,71 @@ require_relative 'fixtures/super'
describe "The super keyword" do
it "calls the method on the calling class" do
Super::S1::A.new.foo([]).should == ["A#foo","A#bar"]
Super::S1::A.new.bar([]).should == ["A#bar"]
Super::S1::B.new.foo([]).should == ["B#foo","A#foo","B#bar","A#bar"]
Super::S1::B.new.bar([]).should == ["B#bar","A#bar"]
SuperSpecs::S1::A.new.foo([]).should == ["A#foo","A#bar"]
SuperSpecs::S1::A.new.bar([]).should == ["A#bar"]
SuperSpecs::S1::B.new.foo([]).should == ["B#foo","A#foo","B#bar","A#bar"]
SuperSpecs::S1::B.new.bar([]).should == ["B#bar","A#bar"]
end
it "searches the full inheritance chain" do
Super::S2::B.new.foo([]).should == ["B#foo","A#baz"]
Super::S2::B.new.baz([]).should == ["A#baz"]
Super::S2::C.new.foo([]).should == ["B#foo","C#baz","A#baz"]
Super::S2::C.new.baz([]).should == ["C#baz","A#baz"]
SuperSpecs::S2::B.new.foo([]).should == ["B#foo","A#baz"]
SuperSpecs::S2::B.new.baz([]).should == ["A#baz"]
SuperSpecs::S2::C.new.foo([]).should == ["B#foo","C#baz","A#baz"]
SuperSpecs::S2::C.new.baz([]).should == ["C#baz","A#baz"]
end
it "searches class methods" do
Super::S3::A.new.foo([]).should == ["A#foo"]
Super::S3::A.foo([]).should == ["A.foo"]
Super::S3::A.bar([]).should == ["A.bar","A.foo"]
Super::S3::B.new.foo([]).should == ["A#foo"]
Super::S3::B.foo([]).should == ["B.foo","A.foo"]
Super::S3::B.bar([]).should == ["B.bar","A.bar","B.foo","A.foo"]
SuperSpecs::S3::A.new.foo([]).should == ["A#foo"]
SuperSpecs::S3::A.foo([]).should == ["A.foo"]
SuperSpecs::S3::A.bar([]).should == ["A.bar","A.foo"]
SuperSpecs::S3::B.new.foo([]).should == ["A#foo"]
SuperSpecs::S3::B.foo([]).should == ["B.foo","A.foo"]
SuperSpecs::S3::B.bar([]).should == ["B.bar","A.bar","B.foo","A.foo"]
end
it "calls the method on the calling class including modules" do
Super::MS1::A.new.foo([]).should == ["ModA#foo","ModA#bar"]
Super::MS1::A.new.bar([]).should == ["ModA#bar"]
Super::MS1::B.new.foo([]).should == ["B#foo","ModA#foo","ModB#bar","ModA#bar"]
Super::MS1::B.new.bar([]).should == ["ModB#bar","ModA#bar"]
SuperSpecs::MS1::A.new.foo([]).should == ["ModA#foo","ModA#bar"]
SuperSpecs::MS1::A.new.bar([]).should == ["ModA#bar"]
SuperSpecs::MS1::B.new.foo([]).should == ["B#foo","ModA#foo","ModB#bar","ModA#bar"]
SuperSpecs::MS1::B.new.bar([]).should == ["ModB#bar","ModA#bar"]
end
it "searches the full inheritance chain including modules" do
Super::MS2::B.new.foo([]).should == ["ModB#foo","A#baz"]
Super::MS2::B.new.baz([]).should == ["A#baz"]
Super::MS2::C.new.baz([]).should == ["C#baz","A#baz"]
Super::MS2::C.new.foo([]).should == ["ModB#foo","C#baz","A#baz"]
SuperSpecs::MS2::B.new.foo([]).should == ["ModB#foo","A#baz"]
SuperSpecs::MS2::B.new.baz([]).should == ["A#baz"]
SuperSpecs::MS2::C.new.baz([]).should == ["C#baz","A#baz"]
SuperSpecs::MS2::C.new.foo([]).should == ["ModB#foo","C#baz","A#baz"]
end
it "can resolve to different methods in an included module method" do
Super::MultiSuperTargets::A.new.foo.should == :BaseA
Super::MultiSuperTargets::B.new.foo.should == :BaseB
SuperSpecs::MultiSuperTargets::A.new.foo.should == :BaseA
SuperSpecs::MultiSuperTargets::B.new.foo.should == :BaseB
end
it "searches class methods including modules" do
Super::MS3::A.new.foo([]).should == ["A#foo"]
Super::MS3::A.foo([]).should == ["ModA#foo"]
Super::MS3::A.bar([]).should == ["ModA#bar","ModA#foo"]
Super::MS3::B.new.foo([]).should == ["A#foo"]
Super::MS3::B.foo([]).should == ["B.foo","ModA#foo"]
Super::MS3::B.bar([]).should == ["B.bar","ModA#bar","B.foo","ModA#foo"]
SuperSpecs::MS3::A.new.foo([]).should == ["A#foo"]
SuperSpecs::MS3::A.foo([]).should == ["ModA#foo"]
SuperSpecs::MS3::A.bar([]).should == ["ModA#bar","ModA#foo"]
SuperSpecs::MS3::B.new.foo([]).should == ["A#foo"]
SuperSpecs::MS3::B.foo([]).should == ["B.foo","ModA#foo"]
SuperSpecs::MS3::B.bar([]).should == ["B.bar","ModA#bar","B.foo","ModA#foo"]
end
it "searches BasicObject from a module for methods defined there" do
Super::IncludesFromBasic.new.__send__(:foobar).should == 43
SuperSpecs::IncludesFromBasic.new.__send__(:foobar).should == 43
end
it "searches BasicObject through another module for methods defined there" do
Super::IncludesIntermediate.new.__send__(:foobar).should == 42
SuperSpecs::IncludesIntermediate.new.__send__(:foobar).should == 42
end
it "calls the correct method when the method visibility is modified" do
Super::MS4::A.new.example.should == 5
SuperSpecs::MS4::A.new.example.should == 5
end
it "calls the correct method when the superclass argument list is different from the subclass" do
Super::S4::A.new.foo([]).should == ["A#foo"]
Super::S4::B.new.foo([],"test").should == ["B#foo(a,test)", "A#foo"]
SuperSpecs::S4::A.new.foo([]).should == ["A#foo"]
SuperSpecs::S4::B.new.foo([],"test").should == ["B#foo(a,test)", "A#foo"]
end
it "raises an error error when super method does not exist" do
@ -103,15 +103,15 @@ describe "The super keyword" do
end
it "calls the superclass method when in a block" do
Super::S6.new.here.should == :good
SuperSpecs::S6.new.here.should == :good
end
it "calls the superclass method when initial method is defined_method'd" do
Super::S7.new.here.should == :good
SuperSpecs::S7.new.here.should == :good
end
it "can call through a define_method multiple times (caching check)" do
obj = Super::S7.new
obj = SuperSpecs::S7.new
2.times do
obj.here.should == :good
@ -155,20 +155,20 @@ describe "The super keyword" do
# Rubinius ticket github#157
it "calls method_missing when a superclass method is not found" do
Super::MM_B.new.is_a?(Hash).should == false
SuperSpecs::MM_B.new.is_a?(Hash).should == false
end
# Rubinius ticket github#180
it "respects the original module a method is aliased from" do
Super::Alias3.new.name3.should == [:alias2, :alias1]
SuperSpecs::Alias3.new.name3.should == [:alias2, :alias1]
end
it "sees the included version of a module a method is alias from" do
Super::AliasWithSuper::Trigger.foo.should == [:b, :a]
SuperSpecs::AliasWithSuper::Trigger.foo.should == [:b, :a]
end
it "find super from a singleton class" do
obj = Super::SingletonCase::Foo.new
obj = SuperSpecs::SingletonCase::Foo.new
def obj.foobar(array)
array << :singleton
super
@ -177,97 +177,97 @@ describe "The super keyword" do
end
it "finds super on other objects if a singleton class aliased the method" do
orig_obj = Super::SingletonAliasCase::Foo.new
orig_obj = SuperSpecs::SingletonAliasCase::Foo.new
orig_obj.alias_on_singleton
orig_obj.new_foobar([]).should == [:foo, :base]
Super::SingletonAliasCase::Foo.new.foobar([]).should == [:foo, :base]
SuperSpecs::SingletonAliasCase::Foo.new.foobar([]).should == [:foo, :base]
end
it "passes along modified rest args when they weren't originally empty" do
Super::RestArgsWithSuper::B.new.a("bar").should == ["bar", "foo"]
SuperSpecs::RestArgsWithSuper::B.new.a("bar").should == ["bar", "foo"]
end
it "passes along modified rest args when they were originally empty" do
Super::RestArgsWithSuper::B.new.a.should == ["foo"]
SuperSpecs::RestArgsWithSuper::B.new.a.should == ["foo"]
end
# https://bugs.ruby-lang.org/issues/14279
it "passes along reassigned rest args" do
Super::ZSuperWithRestReassigned::B.new.a("bar").should == ["foo"]
SuperSpecs::ZSuperWithRestReassigned::B.new.a("bar").should == ["foo"]
end
# https://bugs.ruby-lang.org/issues/14279
it "wraps into array and passes along reassigned rest args with non-array scalar value" do
Super::ZSuperWithRestReassignedWithScalar::B.new.a("bar").should == ["foo"]
SuperSpecs::ZSuperWithRestReassignedWithScalar::B.new.a("bar").should == ["foo"]
end
it "invokes methods from a chain of anonymous modules" do
Super::AnonymousModuleIncludedTwice.new.a([]).should == ["anon", "anon", "non-anon"]
SuperSpecs::AnonymousModuleIncludedTwice.new.a([]).should == ["anon", "anon", "non-anon"]
end
it "without explicit arguments can accept a block but still pass the original arguments" do
Super::ZSuperWithBlock::B.new.a.should == 14
SuperSpecs::ZSuperWithBlock::B.new.a.should == 14
end
it "passes along block via reference to method expecting a reference" do
Super::ZSuperWithBlock::B.new.b.should == [14, 15]
SuperSpecs::ZSuperWithBlock::B.new.b.should == [14, 15]
end
it "passes along a block via reference to a method that yields" do
Super::ZSuperWithBlock::B.new.c.should == 16
SuperSpecs::ZSuperWithBlock::B.new.c.should == 16
end
it "without explicit arguments passes optional arguments that have a default value" do
Super::ZSuperWithOptional::B.new.m(1, 2).should == 14
SuperSpecs::ZSuperWithOptional::B.new.m(1, 2).should == 14
end
it "without explicit arguments passes optional arguments that have a non-default value" do
Super::ZSuperWithOptional::B.new.m(1, 2, 3).should == 3
SuperSpecs::ZSuperWithOptional::B.new.m(1, 2, 3).should == 3
end
it "without explicit arguments passes optional arguments that have a default value but were modified" do
Super::ZSuperWithOptional::C.new.m(1, 2).should == 100
SuperSpecs::ZSuperWithOptional::C.new.m(1, 2).should == 100
end
it "without explicit arguments passes optional arguments that have a non-default value but were modified" do
Super::ZSuperWithOptional::C.new.m(1, 2, 3).should == 100
SuperSpecs::ZSuperWithOptional::C.new.m(1, 2, 3).should == 100
end
it "without explicit arguments passes rest arguments" do
Super::ZSuperWithRest::B.new.m(1, 2, 3).should == [1, 2, 3]
SuperSpecs::ZSuperWithRest::B.new.m(1, 2, 3).should == [1, 2, 3]
end
it "without explicit arguments passes rest arguments including any modifications" do
Super::ZSuperWithRest::B.new.m_modified(1, 2, 3).should == [1, 14, 3]
SuperSpecs::ZSuperWithRest::B.new.m_modified(1, 2, 3).should == [1, 14, 3]
end
it "without explicit arguments passes arguments and rest arguments" do
Super::ZSuperWithRestAndOthers::B.new.m(1, 2, 3, 4, 5).should == [3, 4, 5]
SuperSpecs::ZSuperWithRestAndOthers::B.new.m(1, 2, 3, 4, 5).should == [3, 4, 5]
end
it "without explicit arguments passes arguments and rest arguments including any modifications" do
Super::ZSuperWithRestAndOthers::B.new.m_modified(1, 2, 3, 4, 5).should == [3, 14, 5]
SuperSpecs::ZSuperWithRestAndOthers::B.new.m_modified(1, 2, 3, 4, 5).should == [3, 14, 5]
end
it "without explicit arguments that are '_'" do
Super::ZSuperWithUnderscores::B.new.m(1, 2).should == [1, 2]
SuperSpecs::ZSuperWithUnderscores::B.new.m(1, 2).should == [1, 2]
end
it "without explicit arguments that are '_' including any modifications" do
Super::ZSuperWithUnderscores::B.new.m_modified(1, 2).should == [14, 2]
SuperSpecs::ZSuperWithUnderscores::B.new.m_modified(1, 2).should == [14, 2]
end
describe 'when using keyword arguments' do
before :each do
@req = Super::Keywords::RequiredArguments.new
@opts = Super::Keywords::OptionalArguments.new
@etc = Super::Keywords::PlaceholderArguments.new
@req = SuperSpecs::Keywords::RequiredArguments.new
@opts = SuperSpecs::Keywords::OptionalArguments.new
@etc = SuperSpecs::Keywords::PlaceholderArguments.new
@req_and_opts = Super::Keywords::RequiredAndOptionalArguments.new
@req_and_etc = Super::Keywords::RequiredAndPlaceholderArguments.new
@opts_and_etc = Super::Keywords::OptionalAndPlaceholderArguments.new
@req_and_opts = SuperSpecs::Keywords::RequiredAndOptionalArguments.new
@req_and_etc = SuperSpecs::Keywords::RequiredAndPlaceholderArguments.new
@opts_and_etc = SuperSpecs::Keywords::OptionalAndPlaceholderArguments.new
@req_and_opts_and_etc = Super::Keywords::RequiredAndOptionalAndPlaceholderArguments.new
@req_and_opts_and_etc = SuperSpecs::Keywords::RequiredAndOptionalAndPlaceholderArguments.new
end
it 'does not pass any arguments to the parent when none are given' do
@ -303,15 +303,15 @@ describe "The super keyword" do
describe 'when using regular and keyword arguments' do
before :each do
@req = Super::RegularAndKeywords::RequiredArguments.new
@opts = Super::RegularAndKeywords::OptionalArguments.new
@etc = Super::RegularAndKeywords::PlaceholderArguments.new
@req = SuperSpecs::RegularAndKeywords::RequiredArguments.new
@opts = SuperSpecs::RegularAndKeywords::OptionalArguments.new
@etc = SuperSpecs::RegularAndKeywords::PlaceholderArguments.new
@req_and_opts = Super::RegularAndKeywords::RequiredAndOptionalArguments.new
@req_and_etc = Super::RegularAndKeywords::RequiredAndPlaceholderArguments.new
@opts_and_etc = Super::RegularAndKeywords::OptionalAndPlaceholderArguments.new
@req_and_opts = SuperSpecs::RegularAndKeywords::RequiredAndOptionalArguments.new
@req_and_etc = SuperSpecs::RegularAndKeywords::RequiredAndPlaceholderArguments.new
@opts_and_etc = SuperSpecs::RegularAndKeywords::OptionalAndPlaceholderArguments.new
@req_and_opts_and_etc = Super::RegularAndKeywords::RequiredAndOptionalAndPlaceholderArguments.new
@req_and_opts_and_etc = SuperSpecs::RegularAndKeywords::RequiredAndOptionalAndPlaceholderArguments.new
end
it 'passes only required regular arguments to the parent when no optional keyword arguments are given' do
@ -347,7 +347,7 @@ describe "The super keyword" do
describe 'when using splat and keyword arguments' do
before :each do
@all = Super::SplatAndKeywords::AllArguments.new
@all = SuperSpecs::SplatAndKeywords::AllArguments.new
end
it 'does not pass any arguments to the parent when none are given' do

View file

@ -1,6 +1,12 @@
require_relative '../../spec_helper'
require 'bigdecimal'
describe "BigDecimal" do
it "is not defined unless it is required" do
ruby_exe('puts Object.const_defined?(:BigDecimal)').should == "false\n"
end
end
describe "Kernel#BigDecimal" do
it "creates a new object of class BigDecimal" do

View file

@ -55,4 +55,12 @@ describe "BigDecimal#-" do
(@one_minus - @infinity).should == @infinity_minus
end
describe "with Object" do
it "tries to coerce the other operand to self" do
object = mock("Object")
object.should_receive(:coerce).with(@one).and_return([@one, BigDecimal("42")])
(@one - object).should == BigDecimal("-41")
end
end
end

View file

@ -44,4 +44,11 @@ describe "BigDecimal#+" do
(@infinity + @infinity_minus).nan?.should == true
end
describe "with Object" do
it "tries to coerce the other operand to self" do
object = mock("Object")
object.should_receive(:coerce).with(@one).and_return([@one, BigDecimal("42")])
(@one + object).should == BigDecimal("43")
end
end
end

View file

@ -2,14 +2,11 @@ require_relative '../../spec_helper'
require 'ipaddr'
describe "IPAddr Operator" do
IN6MASK32 = "ffff:ffff::"
IN6MASK128 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
before do
@in6_addr_any = IPAddr.new()
@a = IPAddr.new("3ffe:505:2::/48")
@b = IPAddr.new("0:0:0:1::")
@c = IPAddr.new(IN6MASK32)
@c = IPAddr.new("ffff:ffff::")
end
it "bitwises or" do
@ -48,7 +45,7 @@ describe "IPAddr Operator" do
it "inverts" do
a = ~@in6_addr_any
a.to_s.should == IN6MASK128
a.to_s.should == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
@in6_addr_any.to_s.should == "::"
end

View file

@ -3,7 +3,11 @@ require_relative '../../spec_helper'
describe "mathn" do
ruby_version_is "2.5" do
it "is no longer part of the standard library" do
-> { require "mathn" }.should raise_error(LoadError)
-> {
require "mathn"
}.should raise_error(LoadError) { |e|
e.path.should == 'mathn'
}
end
end
end

View file

@ -1,11 +1,23 @@
require_relative '../../spec_helper'
require 'rbconfig'
describe 'RbConfig::CONFIG values' do
it 'are all strings' do
describe 'RbConfig::CONFIG' do
it 'values are all strings' do
RbConfig::CONFIG.each do |k, v|
k.should be_kind_of String
v.should be_kind_of String
end
end
it "['rubylibdir'] returns the directory containing Ruby standard libraries" do
rubylibdir = RbConfig::CONFIG['rubylibdir']
File.directory?(rubylibdir).should == true
File.exist?("#{rubylibdir}/fileutils.rb").should == true
end
it "['archdir'] returns the directory containing standard libraries C extensions" do
archdir = RbConfig::CONFIG['archdir']
File.directory?(archdir).should == true
File.exist?("#{archdir}/etc.#{RbConfig::CONFIG['DLEXT']}").should == true
end
end

View file

@ -51,6 +51,14 @@ describe "StringIO#puts when passed an Array" do
@io.puts([obj])
@io.string.should == "to_s\n"
end
it "returns general object info if :to_s does not return a string" do
object = mock('hola')
object.should_receive(:to_s).and_return(false)
@io.puts(object).should == nil
@io.string.should == object.inspect.split(" ")[0] + ">\n"
end
end
describe "StringIO#puts when passed 1 or more objects" do

View file

@ -1,5 +1,7 @@
class FooBar
def initialize(name)
@name = name
module YAMLSpecs
class Example
def initialize(name)
@name = name
end
end
end

View file

@ -13,8 +13,7 @@ describe "Object#to_yaml" do
end
it "returns the YAML representation of a Class object" do
FooBar.new("baz").to_yaml.should match_yaml("--- !ruby/object:FooBar\nname: baz\n")
YAMLSpecs::Example.new("baz").to_yaml.should match_yaml("--- !ruby/object:YAMLSpecs::Example\nname: baz\n")
end
it "returns the YAML representation of a Date object" do

View file

@ -232,6 +232,11 @@ VALUE string_spec_rb_str_times(VALUE self, VALUE str, VALUE times) {
return rb_str_times(str, times);
}
VALUE string_spec_rb_str_modify_expand(VALUE self, VALUE str, VALUE size) {
rb_str_modify_expand(str, FIX2LONG(size));
return str;
}
VALUE string_spec_rb_str_resize(VALUE self, VALUE str, VALUE size) {
return rb_str_resize(str, FIX2INT(size));
}
@ -435,6 +440,7 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_tainted_str_new2", string_spec_rb_tainted_str_new2, 1);
rb_define_method(cls, "rb_str_plus", string_spec_rb_str_plus, 2);
rb_define_method(cls, "rb_str_times", string_spec_rb_str_times, 2);
rb_define_method(cls, "rb_str_modify_expand", string_spec_rb_str_modify_expand, 2);
rb_define_method(cls, "rb_str_resize", string_spec_rb_str_resize, 2);
rb_define_method(cls, "rb_str_resize_RSTRING_LEN", string_spec_rb_str_resize_RSTRING_LEN, 2);
rb_define_method(cls, "rb_str_set_len", string_spec_rb_str_set_len, 2);

View file

@ -558,10 +558,33 @@ describe "C-API String function" do
it_behaves_like :string_value_macro, :SafeStringValue
end
describe "rb_str_modify_expand" do
it "grows the capacity to bytesize + expand, not changing the bytesize" do
str = @s.rb_str_buf_new(256, "abcd")
@s.rb_str_capacity(str).should == 256
@s.rb_str_set_len(str, 3)
str.bytesize.should == 3
@s.RSTRING_LEN(str).should == 3
@s.rb_str_capacity(str).should == 256
@s.rb_str_modify_expand(str, 4)
str.bytesize.should == 3
@s.RSTRING_LEN(str).should == 3
@s.rb_str_capacity(str).should == 7
@s.rb_str_modify_expand(str, 1024)
str.bytesize.should == 3
@s.RSTRING_LEN(str).should == 3
@s.rb_str_capacity(str).should == 1027
end
end
describe "rb_str_resize" do
it "reduces the size of the string" do
str = @s.rb_str_resize("test", 2)
str.size.should == 2
str.bytesize.should == 2
@s.RSTRING_LEN(str).should == 2
str.should == "te"
end
@ -574,6 +597,7 @@ describe "C-API String function" do
expected = "test".force_encoding("US-ASCII")
str = @s.rb_str_resize(expected.dup, 12)
str.size.should == 12
str.bytesize.should == 12
@s.RSTRING_LEN(str).should == 12
str[0, 4].should == expected
end

View file

@ -1,55 +1,59 @@
require_relative '../spec_helper'
require 'tempfile'
require 'tmpdir'
describe "CVE-2018-6914 is resisted by" do
before :all do
@traversal_path = Array.new(Dir.pwd.split('/').count, '..').join('/') + Dir.pwd + '/'
@traversal_path.delete!(':') if /mswin|mingw/ =~ RUBY_PLATFORM
before :each do
@dir = tmp("CVE-2018-6914")
Dir.mkdir(@dir)
touch "#{@dir}/bar"
@traversal_path = Array.new(@dir.count('/'), '..').join('/') + @dir + '/'
@traversal_path.delete!(':') if platform_is(:windows)
@tempfile = nil
end
after :each do
@tempfile.close! if @tempfile
rm_r @dir
end
it "Tempfile.open by deleting separators" do
begin
expect = Dir.glob(@traversal_path + '*').count
t = Tempfile.open([@traversal_path, 'foo'])
actual = Dir.glob(@traversal_path + '*').count
actual.should == expect
ensure
t.close!
end
expect = Dir.glob(@traversal_path + '*').size
@tempfile = Tempfile.open([@traversal_path, 'foo'])
actual = Dir.glob(@traversal_path + '*').size
actual.should == expect
end
it "Tempfile.new by deleting separators" do
begin
expect = Dir.glob(@traversal_path + '*').count
t = Tempfile.new(@traversal_path + 'foo')
actual = Dir.glob(@traversal_path + '*').count
actual.should == expect
ensure
t.close!
end
expect = Dir.glob(@traversal_path + '*').size
@tempfile = Tempfile.new(@traversal_path + 'foo')
actual = Dir.glob(@traversal_path + '*').size
actual.should == expect
end
it "Tempfile.create by deleting separators" do
expect = Dir.glob(@traversal_path + '*').count
expect = Dir.glob(@traversal_path + '*').size
Tempfile.create(@traversal_path + 'foo') do
actual = Dir.glob(@traversal_path + '*').count
actual = Dir.glob(@traversal_path + '*').size
actual.should == expect
end
end
it "Dir.mktmpdir by deleting separators" do
expect = Dir.glob(@traversal_path + '*').count
expect = Dir.glob(@traversal_path + '*').size
Dir.mktmpdir(@traversal_path + 'foo') do
actual = Dir.glob(@traversal_path + '*').count
actual = Dir.glob(@traversal_path + '*').size
actual.should == expect
end
end
it "Dir.mktmpdir with an array by deleting separators" do
expect = Dir.glob(@traversal_path + '*').count
expect = Dir.glob(@traversal_path + '*').size
Dir.mktmpdir([@traversal_path, 'foo']) do
actual = Dir.glob(@traversal_path + '*').count
actual = Dir.glob(@traversal_path + '*').size
actual.should == expect
end
end

View file

@ -13,7 +13,7 @@ describe :kernel_raise, shared: true do
end
it "raises RuntimeError if no exception class is given" do
lambda { @object.raise }.should raise_error(RuntimeError)
lambda { @object.raise }.should raise_error(RuntimeError, "")
end
it "raises a given Exception instance" do