1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Move spec/rubyspec to spec/ruby for consistency

* Other ruby implementations use the spec/ruby directory.
  [Misc #13792] [ruby-core:82287]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-09-20 20:18:52 +00:00
parent 75bfc6440d
commit 1d15d5f080
4370 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,126 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../../../fixtures/basicobject/method_missing', __FILE__)
describe :method_missing_defined_module, shared: true do
describe "for a Module with #method_missing defined" do
it "is not called when a defined method is called" do
@object.method_public.should == :module_public_method
end
it "is called when a not defined method is called" do
@object.not_defined_method.should == :module_method_missing
end
it "is called when a protected method is called" do
@object.method_protected.should == :module_method_missing
end
it "is called when a private method is called" do
@object.method_private.should == :module_method_missing
end
end
end
describe :method_missing_module, shared: true do
describe "for a Module" do
it "raises a NoMethodError when an undefined method is called" do
lambda { @object.no_such_method }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a protected method is called" do
lambda { @object.method_protected }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a private method is called" do
lambda { @object.method_private }.should raise_error(NoMethodError)
end
end
end
describe :method_missing_defined_class, shared: true do
describe "for a Class with #method_missing defined" do
it "is not called when a defined method is called" do
@object.method_public.should == :class_public_method
end
it "is called when an undefined method is called" do
@object.no_such_method.should == :class_method_missing
end
it "is called when an protected method is called" do
@object.method_protected.should == :class_method_missing
end
it "is called when an private method is called" do
@object.method_private.should == :class_method_missing
end
end
end
describe :method_missing_class, shared: true do
describe "for a Class" do
it "raises a NoMethodError when an undefined method is called" do
lambda { @object.no_such_method }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a protected method is called" do
lambda { @object.method_protected }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a private method is called" do
lambda { @object.method_private }.should raise_error(NoMethodError)
end
end
end
describe :method_missing_defined_instance, shared: true do
describe "for an instance with #method_missing defined" do
before :each do
@instance = @object.new
end
it "is not called when a defined method is called" do
@instance.method_public.should == :instance_public_method
end
it "is called when an undefined method is called" do
@instance.no_such_method.should == :instance_method_missing
end
it "is called when an protected method is called" do
@instance.method_protected.should == :instance_method_missing
end
it "is called when an private method is called" do
@instance.method_private.should == :instance_method_missing
end
end
end
describe :method_missing_instance, shared: true do
describe "for an instance" do
it "raises a NoMethodError when an undefined method is called" do
lambda { @object.new.no_such_method }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a protected method is called" do
lambda { @object.new.method_protected }.should raise_error(NoMethodError)
end
it "raises a NoMethodError when a private method is called" do
lambda { @object.new.method_private }.should raise_error(NoMethodError)
end
ruby_version_is "2.3" do
it 'sets the receiver of the raised NoMethodError' do
obj = @object.new
begin
obj.method_private
rescue NoMethodError => error
(error.receiver == obj).should == true
end
end
end
end
end

View file

@ -0,0 +1,110 @@
module SendSpecs
end
describe :basicobject_send, shared: true do
it "invokes the named method" do
class SendSpecs::Foo
def bar
'done'
end
end
SendSpecs::Foo.new.send(@method, :bar).should == 'done'
end
it "accepts a String method name" do
class SendSpecs::Foo
def bar
'done'
end
end
SendSpecs::Foo.new.send(@method, 'bar').should == 'done'
end
it "invokes a class method if called on a class" do
class SendSpecs::Foo
def self.bar
'done'
end
end
SendSpecs::Foo.send(@method, :bar).should == 'done'
end
it "raises a NameError if the corresponding method can't be found" do
class SendSpecs::Foo
def bar
'done'
end
end
lambda { SendSpecs::Foo.new.send(@method, :syegsywhwua) }.should raise_error(NameError)
end
it "raises a NameError if the corresponding singleton method can't be found" do
class SendSpecs::Foo
def self.bar
'done'
end
end
lambda { SendSpecs::Foo.send(@method, :baz) }.should raise_error(NameError)
end
it "raises an ArgumentError if no arguments are given" do
class SendSpecs::Foo; end
lambda { SendSpecs::Foo.new.send @method }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if called with more arguments than available parameters" do
class SendSpecs::Foo
def bar; end
end
lambda { SendSpecs::Foo.new.send(@method, :bar, :arg) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if called with fewer arguments than required parameters" do
class SendSpecs::Foo
def foo(arg); end
end
lambda { SendSpecs::Foo.new.send(@method, :foo) }.should raise_error(ArgumentError)
end
it "succeeds if passed an arbitrary number of arguments as a splat parameter" do
class SendSpecs::Foo
def baz(*args) args end
end
begin
SendSpecs::Foo.new.send(@method, :baz).should == []
SendSpecs::Foo.new.send(@method, :baz, :quux).should == [:quux]
SendSpecs::Foo.new.send(@method, :baz, :quux, :foo).should == [:quux, :foo]
rescue
fail
end
end
it "succeeds when passing 1 or more arguments as a required and a splat parameter" do
class SendSpecs::Foo
def baz(first, *rest) [first, *rest] end
end
SendSpecs::Foo.new.send(@method, :baz, :quux).should == [:quux]
SendSpecs::Foo.new.send(@method, :baz, :quux, :foo).should == [:quux, :foo]
end
it "succeeds when passing 0 arguments to a method with one parameter with a default" do
class SendSpecs::Foo
def foo(first = true) first end
end
begin
SendSpecs::Foo.new.send(@method, :foo).should == true
SendSpecs::Foo.new.send(@method, :foo, :arg).should == :arg
rescue
fail
end
end
it "has a negative arity" do
method(@method).arity.should < 0
end
end

View file

@ -0,0 +1,133 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :kernel_Complex, shared: true do
describe "when passed [Complex, Complex]" do
it "returns a new Complex number based on the two given numbers" do
Complex(Complex(3, 4), Complex(5, 6)).should == Complex(3 - 6, 4 + 5)
Complex(Complex(1.5, 2), Complex(-5, 6.3)).should == Complex(1.5 - 6.3, 2 - 5)
end
end
describe "when passed [Complex]" do
it "returns the passed Complex number" do
Complex(Complex(1, 2)).should == Complex(1, 2)
Complex(Complex(-3.4, bignum_value)).should == Complex(-3.4, bignum_value)
end
end
describe "when passed [Integer, Integer]" do
it "returns a new Complex number" do
Complex(1, 2).should be_an_instance_of(Complex)
Complex(1, 2).real.should == 1
Complex(1, 2).imag.should == 2
Complex(-3, -5).should be_an_instance_of(Complex)
Complex(-3, -5).real.should == -3
Complex(-3, -5).imag.should == -5
Complex(3.5, -4.5).should be_an_instance_of(Complex)
Complex(3.5, -4.5).real.should == 3.5
Complex(3.5, -4.5).imag.should == -4.5
Complex(bignum_value, 30).should be_an_instance_of(Complex)
Complex(bignum_value, 30).real.should == bignum_value
Complex(bignum_value, 30).imag.should == 30
end
end
describe "when passed [Integer]" do
it "returns a new Complex number with 0 as the imaginary component" do
# Guard against the Mathn library
conflicts_with :Prime do
Complex(1).should be_an_instance_of(Complex)
Complex(1).imag.should == 0
Complex(1).real.should == 1
Complex(-3).should be_an_instance_of(Complex)
Complex(-3).imag.should == 0
Complex(-3).real.should == -3
Complex(-4.5).should be_an_instance_of(Complex)
Complex(-4.5).imag.should == 0
Complex(-4.5).real.should == -4.5
Complex(bignum_value).should be_an_instance_of(Complex)
Complex(bignum_value).imag.should == 0
Complex(bignum_value).real.should == bignum_value
end
end
end
describe "when passed a String" do
it "needs to be reviewed for spec completeness"
end
describe "when passed an Objectc which responds to #to_c" do
it "returns the passed argument" do
obj = Object.new; def obj.to_c; 1i end
Complex(obj).should == Complex(0, 1)
end
end
describe "when passed a Numeric which responds to #real? with false" do
it "returns the passed argument" do
n = mock_numeric("unreal")
n.should_receive(:real?).and_return(false)
Complex(n).should equal(n)
end
end
describe "when passed a Numeric which responds to #real? with true" do
it "returns a Complex with the passed argument as the real component and 0 as the imaginary component" do
n = mock_numeric("real")
n.should_receive(:real?).any_number_of_times.and_return(true)
result = Complex(n)
result.real.should equal(n)
result.imag.should equal(0)
end
end
describe "when passed Numerics n1 and n2 and at least one responds to #real? with false" do
[[false, false], [false, true], [true, false]].each do |r1, r2|
it "returns n1 + n2 * Complex(0, 1)" do
n1 = mock_numeric("n1")
n2 = mock_numeric("n2")
n3 = mock_numeric("n3")
n4 = mock_numeric("n4")
n1.should_receive(:real?).any_number_of_times.and_return(r1)
n2.should_receive(:real?).any_number_of_times.and_return(r2)
n2.should_receive(:*).with(Complex(0, 1)).and_return(n3)
n1.should_receive(:+).with(n3).and_return(n4)
Complex(n1, n2).should equal(n4)
end
end
end
describe "when passed two Numerics and both respond to #real? with true" do
it "returns a Complex with the passed arguments as real and imaginary components respectively" do
n1 = mock_numeric("n1")
n2 = mock_numeric("n2")
n1.should_receive(:real?).any_number_of_times.and_return(true)
n2.should_receive(:real?).any_number_of_times.and_return(true)
result = Complex(n1, n2)
result.real.should equal(n1)
result.imag.should equal(n2)
end
end
describe "when passed a single non-Numeric" do
it "coerces the passed argument using #to_c" do
n = mock("n")
c = Complex(0, 0)
n.should_receive(:to_c).and_return(c)
Complex(n).should equal(c)
end
end
describe "when passed a non-Numeric second argument" do
it "raises TypeError" do
lambda { Complex.send(@method, :sym, :sym) }.should raise_error(TypeError)
lambda { Complex.send(@method, 0, :sym) }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,12 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_abs, shared: true do
it "returns the modulus: |a + bi| = sqrt((a ^ 2) + (b ^ 2))" do
Complex(0, 0).send(@method).should == 0
Complex(3, 4).send(@method).should == 5 # well-known integer case
Complex(-3, 4).send(@method).should == 5
Complex(1, -1).send(@method).should be_close(Math.sqrt(2), TOLERANCE)
Complex(6.5, 0).send(@method).should be_close(6.5, TOLERANCE)
Complex(0, -7.2).send(@method).should be_close(7.2, TOLERANCE)
end
end

View file

@ -0,0 +1,12 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_abs2, shared: true do
it "returns the sum of the squares of the real and imaginary parts" do
Complex(1, -2).abs2.should == 1 + 4
Complex(-0.1, 0.2).abs2.should be_close(0.01 + 0.04, TOLERANCE)
# Guard against Mathn library
conflicts_with :Prime do
Complex(0).abs2.should == 0
end
end
end

View file

@ -0,0 +1,9 @@
describe :complex_arg, shared: true do
it "returns the argument -- i.e., the angle from (1, 0) in the complex plane" do
two_pi = 2 * Math::PI
(Complex(1, 0).send(@method) % two_pi).should be_close(0, TOLERANCE)
(Complex(0, 2).send(@method) % two_pi).should be_close(Math::PI * 0.5, TOLERANCE)
(Complex(-100, 0).send(@method) % two_pi).should be_close(Math::PI, TOLERANCE)
(Complex(0, -75.3).send(@method) % two_pi).should be_close(Math::PI * 1.5, TOLERANCE)
end
end

View file

@ -0,0 +1,70 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_coerce, shared: true do
before :each do
@one = Complex(1)
end
it "returns an array containing other and self as Complex when other is an Integer" do
result = @one.coerce(2)
result.should == [2, 1]
result.first.should be_kind_of(Complex)
result.last.should be_kind_of(Complex)
end
it "returns an array containing other and self as Complex when other is a Float" do
result = @one.coerce(20.5)
result.should == [20.5, 1]
result.first.should be_kind_of(Complex)
result.last.should be_kind_of(Complex)
end
it "returns an array containing other and self as Complex when other is a Bignum" do
result = @one.coerce(4294967296)
result.should == [4294967296, 1]
result.first.should be_kind_of(Complex)
result.last.should be_kind_of(Complex)
end
it "returns an array containing other and self as Complex when other is a Rational" do
result = @one.coerce(Rational(5,6))
result.should == [Rational(5,6), 1]
result.first.should be_kind_of(Complex)
result.last.should be_kind_of(Complex)
end
it "returns an array containing other and self when other is a Complex" do
other = Complex(2)
result = @one.coerce(other)
result.should == [other, @one]
result.first.should equal(other)
result.last.should equal(@one)
end
it "returns an array containing other as Complex and self when other is a Numeric which responds to #real? with true" do
other = mock_numeric('other')
other.should_receive(:real?).any_number_of_times.and_return(true)
result = @one.coerce(other)
result.should == [other, @one]
result.first.should eql(Complex(other))
result.last.should equal(@one)
end
it "raises TypeError when other is a Numeric which responds to #real? with false" do
other = mock_numeric('other')
other.should_receive(:real?).any_number_of_times.and_return(false)
lambda { @one.coerce(other) }.should raise_error(TypeError)
end
it "raises a TypeError when other is a String" do
lambda { @one.coerce("20") }.should raise_error(TypeError)
end
it "raises a TypeError when other is nil" do
lambda { @one.coerce(nil) }.should raise_error(TypeError)
end
it "raises a TypeError when other is false" do
lambda { @one.coerce(false) }.should raise_error(TypeError)
end
end

View file

@ -0,0 +1,8 @@
describe :complex_conjugate, shared: true do
it "returns the complex conjugate: conj a + bi = a - bi" do
Complex(3, 5).send(@method).should == Complex(3, -5)
Complex(3, -5).send(@method).should == Complex(3, 5)
Complex(-3.0, 5.2).send(@method).should be_close(Complex(-3.0, -5.2), TOLERANCE)
Complex(3.0, -5.2).send(@method).should be_close(Complex(3.0, 5.2), TOLERANCE)
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_I, shared: true do
it "is Complex(0, 1)" do
Complex::I.should eql(Complex(0, 1))
end
end

View file

@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_denominator, shared: true do
it "returns the least common multiple denominator of the real and imaginary parts" do
Complex(3, 4).denominator.should == 1
Complex(3, bignum_value).denominator.should == 1
Complex(3, Rational(3,4)).denominator.should == 4
Complex(Rational(4,8), Rational(3,4)).denominator.should == 4
Complex(Rational(3,8), Rational(3,4)).denominator.should == 8
end
end

View file

@ -0,0 +1,84 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_divide, shared: true do
describe "with Complex" do
it "divides according to the usual rule for complex numbers" do
a = Complex((1 * 10) - (2 * 20), (1 * 20) + (2 * 10))
b = Complex(1, 2)
a.send(@method, b).should == Complex(10, 20)
c = Complex((1.5 * 100.2) - (2.1 * -30.3), (1.5 * -30.3) + (2.1 * 100.2))
d = Complex(1.5, 2.1)
# remember the floating-point arithmetic
c.send(@method, d).should be_close(Complex(100.2, -30.3), TOLERANCE)
end
end
describe "with Fixnum" do
it "divides both parts of the Complex number" do
Complex(20, 40).send(@method, 2).should == Complex(10, 20)
Complex(30, 30).send(@method, 10).should == Complex(3, 3)
end
it "raises a ZeroDivisionError when given zero" do
lambda { Complex(20, 40).send(@method, 0) }.should raise_error(ZeroDivisionError)
end
it "produces Rational parts" do
Complex(5, 9).send(@method, 2).should eql(Complex(Rational(5,2), Rational(9,2)))
end
end
describe "with Bignum" do
it "divides both parts of the Complex number" do
Complex(20, 40).send(@method, 2).should == Complex(10, 20)
Complex(15, 16).send(@method, 2.0).should be_close(Complex(7.5, 8), TOLERANCE)
end
end
describe "with Float" do
it "divides both parts of the Complex number" do
Complex(3, 9).send(@method, 1.5).should == Complex(2, 6)
Complex(15, 16).send(@method, 2.0).should be_close(Complex(7.5, 8), TOLERANCE)
end
it "returns Complex(Infinity, Infinity) when given zero" do
Complex(20, 40).send(@method, 0.0).real.infinite?.should == 1
Complex(20, 40).send(@method, 0.0).imag.infinite?.should == 1
Complex(-20, 40).send(@method, 0.0).real.infinite?.should == -1
Complex(-20, 40).send(@method, 0.0).imag.infinite?.should == 1
end
end
describe "with Object" do
it "tries to coerce self into other" do
value = Complex(3, 9)
obj = mock("Object")
obj.should_receive(:coerce).with(value).and_return([4, 2])
value.send(@method, obj).should == 2
end
end
describe "with a Numeric which responds to #real? with true" do
it "returns Complex(real.quo(other), imag.quo(other))" do
other = mock_numeric('other')
real = mock_numeric('real')
imag = mock_numeric('imag')
other.should_receive(:real?).and_return(true)
real.should_receive(:quo).with(other).and_return(1)
imag.should_receive(:quo).with(other).and_return(2)
Complex(real, imag).send(@method, other).should == Complex(1, 2)
end
end
describe "with a Numeric which responds to #real? with false" do
it "coerces the passed argument to Complex and divides the resulting elements" do
complex = Complex(3, 0)
other = mock_numeric('other')
other.should_receive(:real?).any_number_of_times.and_return(false)
other.should_receive(:coerce).with(complex).and_return([5, 2])
complex.send(@method, other).should eql(Rational(5, 2))
end
end
end

View file

@ -0,0 +1,93 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_equal_value, shared: true do
describe "with Complex" do
it "returns true when self and other have numerical equality" do
Complex(1, 2).should == Complex(1, 2)
Complex(3, 9).should == Complex(3, 9)
Complex(-3, -9).should == Complex(-3, -9)
Complex(1, 2).should_not == Complex(3, 4)
Complex(3, 9).should_not == Complex(9, 3)
Complex(1.0, 2.0).should == Complex(1, 2)
Complex(3.0, 9.0).should_not == Complex(9.0, 3.0)
Complex(1.5, 2.5).should == Complex(1.5, 2.5)
Complex(1.5, 2.5).should == Complex(1.5, 2.5)
Complex(-1.5, 2.5).should == Complex(-1.5, 2.5)
Complex(1.5, 2.5).should_not == Complex(2.5, 1.5)
Complex(3.75, 2.5).should_not == Complex(1.5, 2.5)
Complex(bignum_value, 2.5).should == Complex(bignum_value, 2.5)
Complex(3.75, bignum_value).should_not == Complex(1.5, bignum_value)
Complex(nan_value).should_not == Complex(nan_value)
end
end
describe "with Numeric" do
it "returns true when self's imaginary part is 0 and the real part and other have numerical equality" do
Complex(3, 0).should == 3
Complex(-3, 0).should == -3
Complex(3.5, 0).should == 3.5
Complex(-3.5, 0).should == -3.5
Complex(bignum_value, 0).should == bignum_value
Complex(-bignum_value, 0).should == -bignum_value
Complex(3.0, 0).should == 3
Complex(-3.0, 0).should == -3
Complex(3, 0).should_not == 4
Complex(-3, 0).should_not == -4
Complex(3.5, 0).should_not == -4.5
Complex(-3.5, 0).should_not == 2.5
Complex(bignum_value, 0).should_not == bignum_value(10)
Complex(-bignum_value, 0).should_not == -bignum_value(20)
end
end
describe "with Object" do
# Fixnum#==, Float#== and Bignum#== only return booleans - Bug?
it "calls other#== with self" do
value = Complex(3, 0)
obj = mock("Object")
obj.should_receive(:==).with(value).and_return(:expected)
(value == obj).should_not be_false
end
end
describe "with a Numeric which responds to #real? with true" do
before do
@other = mock_numeric('other')
@other.should_receive(:real?).any_number_of_times.and_return(true)
end
it "returns real == other when the imaginary part is zero" do
real = mock_numeric('real')
real.should_receive(:==).with(@other).and_return(true)
(Complex(real, 0) == @other).should be_true
end
it "returns false when when the imaginary part is not zero" do
(Complex(3, 1) == @other).should be_false
end
end
describe "with a Numeric which responds to #real? with false" do
it "returns other == self" do
complex = Complex(3, 0)
other = mock_numeric('other')
other.should_receive(:real?).any_number_of_times.and_return(false)
other.should_receive(:==).with(complex).and_return(true)
(complex == other).should be_true
end
end
end

View file

@ -0,0 +1,61 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_exponent, shared: true do
describe "with Fixnum 0" do
it "returns Complex(1)" do
(Complex(3, 4) ** 0).should eql(Complex(1))
end
end
describe "with Float 0.0" do
it "returns Complex(1.0, 0.0)" do
(Complex(3, 4) ** 0.0).should eql(Complex(1.0, 0.0))
end
end
describe "with Complex" do
it "returns self raised to the given power" do
(Complex(2, 1) ** Complex(2, 1)).should be_close(Complex(-0.504824688978319, 3.10414407699553), TOLERANCE)
(Complex(2, 1) ** Complex(3, 4)).should be_close(Complex(-0.179174656916581, -1.74071656397662), TOLERANCE)
(Complex(2, 1) ** Complex(-2, -1)).should be_close(Complex(-0.051041070450869, -0.313849223270419), TOLERANCE)
(Complex(-2, -1) ** Complex(2, 1)).should be_close(Complex(-11.6819929610857, 71.8320439736158), TOLERANCE)
end
end
describe "with Integer" do
it "returns self raised to the given power" do
(Complex(2, 1) ** 2).should == Complex(3, 4)
(Complex(3, 4) ** 2).should == Complex(-7, 24)
(Complex(3, 4) ** -2).should be_close(Complex(-0.0112, -0.0384), TOLERANCE)
(Complex(2, 1) ** 2.5).should be_close(Complex(2.99179707178602, 6.85206901006896), TOLERANCE)
(Complex(3, 4) ** 2.5).should be_close(Complex(-38.0, 41.0), TOLERANCE)
(Complex(3, 4) ** -2.5).should be_close(Complex(-0.01216, -0.01312), TOLERANCE)
(Complex(1) ** 1).should == Complex(1)
# NOTE: Takes way too long...
#(Complex(2, 1) ** bignum_value)
end
end
describe "with Rational" do
it "returns self raised to the given power" do
(Complex(2, 1) ** Rational(3, 4)).should be_close(Complex(1.71913265276568, 0.623124744394697), TOLERANCE)
(Complex(2, 1) ** Rational(4, 3)).should be_close(Complex(2.3828547125173, 1.69466313833091), TOLERANCE)
(Complex(2, 1) ** Rational(-4, 3)).should be_close(Complex(0.278700377879388, -0.198209003071003), TOLERANCE)
end
end
describe "with Object" do
it "tries to coerce self into other" do
value = Complex(3, 9)
obj = mock("Object")
obj.should_receive(:coerce).with(value).and_return([2, 5])
(value ** obj).should == 2 ** 5
end
end
end

View file

@ -0,0 +1,38 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :float_arg, shared: true do
it "returns NaN if NaN" do
f = nan_value
f.send(@method).nan?.should be_true
end
it "returns self if NaN" do
f = nan_value
f.send(@method).should equal(f)
end
it "returns 0 if positive" do
1.0.send(@method).should == 0
end
it "returns 0 if +0.0" do
0.0.send(@method).should == 0
end
it "returns 0 if +Infinity" do
infinity_value.send(@method).should == 0
end
it "returns Pi if negative" do
(-1.0).send(@method).should == Math::PI
end
# This was established in r23960
it "returns Pi if -0.0" do
(-0.0).send(@method).should == Math::PI
end
it "returns Pi if -Infinity" do
(-infinity_value).send(@method).should == Math::PI
end
end

View file

@ -0,0 +1,16 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_hash, shared: true do
it "is static" do
Complex(1).hash.should == Complex(1).hash
Complex(1, 0).hash.should == Complex(1).hash
Complex(1, 1).hash.should == Complex(1, 1).hash
end
it "is different for different instances" do
Complex(1, 2).hash.should_not == Complex(1, 1).hash
Complex(2, 1).hash.should_not == Complex(1, 1).hash
Complex(1, 2).hash.should_not == Complex(2, 1).hash
end
end

View file

@ -0,0 +1,10 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_image, shared: true do
it "returns the imaginary part of self" do
Complex(1, 0).send(@method).should == 0
Complex(2, 1).send(@method).should == 1
Complex(6.7, 8.9).send(@method).should == 8.9
Complex(1, bignum_value).send(@method).should == bignum_value
end
end

View file

@ -0,0 +1,14 @@
describe :complex_inspect, shared: true do
it "returns (${real}+${image}i) for positive imaginary parts" do
Complex(1).inspect.should == "(1+0i)"
Complex(7).inspect.should == "(7+0i)"
Complex(-1, 4).inspect.should == "(-1+4i)"
Complex(-7, 6.7).inspect.should == "(-7+6.7i)"
end
it "returns (${real}-${image}i) for negative imaginary parts" do
Complex(0, -1).inspect.should == "(0-1i)"
Complex(-1, -4).inspect.should == "(-1-4i)"
Complex(-7, -6.7).inspect.should == "(-7-6.7i)"
end
end

View file

@ -0,0 +1,45 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_minus, shared: true do
describe "with Complex" do
it "subtracts both the real and imaginary components" do
(Complex(1, 2) - Complex(10, 20)).should == Complex(1 - 10, 2 - 20)
(Complex(1.5, 2.1) - Complex(100.2, -30.3)).should == Complex(1.5 - 100.2, 2.1 - (-30.3))
end
end
describe "with Integer" do
it "subtracts the real number from the real component of self" do
(Complex(1, 2) - 50).should == Complex(-49, 2)
(Complex(1, 2) - 50.5).should == Complex(-49.5, 2)
end
end
describe "with Object" do
it "tries to coerce self into other" do
value = Complex(3, 9)
obj = mock("Object")
obj.should_receive(:coerce).with(value).and_return([2, 5])
(value - obj).should == 2 - 5
end
end
describe "passed Numeric which responds to #real? with true" do
it "coerces the passed argument to the type of the real part and subtracts the resulting elements" do
n = mock_numeric('n')
n.should_receive(:real?).and_return(true)
n.should_receive(:coerce).with(1).and_return([1, 4])
(Complex(1, 2) - n).should == Complex(-3, 2)
end
end
describe "passed Numeric which responds to #real? with false" do
it "coerces the passed argument to Complex and subtracts the resulting elements" do
n = mock_numeric('n')
n.should_receive(:real?).and_return(false)
n.should_receive(:coerce).with(Complex(1, 2)).and_return([Complex(1, 2), Complex(3, 4)])
(Complex(1, 2) - n).should == Complex(-2, -2)
end
end
end

View file

@ -0,0 +1,49 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_multiply, shared: true do
describe "with Complex" do
it "multiplies according to the usual rule for complex numbers: (a + bi) * (c + di) = ac - bd + (ad + bc)i" do
(Complex(1, 2) * Complex(10, 20)).should == Complex((1 * 10) - (2 * 20), (1 * 20) + (2 * 10))
(Complex(1.5, 2.1) * Complex(100.2, -30.3)).should == Complex((1.5 * 100.2) - (2.1 * -30.3), (1.5 * -30.3) + (2.1 * 100.2))
end
end
describe "with Integer" do
it "multiplies both parts of self by the given Integer" do
(Complex(3, 2) * 50).should == Complex(150, 100)
(Complex(-3, 2) * 50.5).should == Complex(-151.5, 101)
end
end
describe "with Object" do
it "tries to coerce self into other" do
value = Complex(3, 9)
obj = mock("Object")
obj.should_receive(:coerce).with(value).and_return([2, 5])
(value * obj).should == 2 * 5
end
end
describe "with a Numeric which responds to #real? with true" do
it "multiples both parts of self by other" do
other = mock_numeric('other')
real = mock_numeric('real')
imag = mock_numeric('imag')
other.should_receive(:real?).and_return(true)
real.should_receive(:*).with(other).and_return(1)
imag.should_receive(:*).with(other).and_return(2)
(Complex(real, imag) * other).should == Complex(1, 2)
end
describe "with a Numeric which responds to #real? with false" do
it "coerces the passed argument to Complex and multiplies the resulting elements" do
complex = Complex(3, 0)
other = mock_numeric('other')
other.should_receive(:real?).any_number_of_times.and_return(false)
other.should_receive(:coerce).with(complex).and_return([5, 2])
(complex * other).should == 10
end
end
end
end

View file

@ -0,0 +1,19 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_numerator, shared: true do
it "returns self's numerator" do
Complex(2).numerator.should == Complex(2)
Complex(3, 4).numerator.should == Complex(3, 4)
Complex(Rational(3, 4), Rational(3, 4)).numerator.should == Complex(3, 3)
Complex(Rational(7, 4), Rational(8, 4)).numerator.should == Complex(7, 8)
Complex(Rational(7, 8), Rational(8, 4)).numerator.should == Complex(7, 16)
Complex(Rational(7, 4), Rational(8, 8)).numerator.should == Complex(7, 4)
# NOTE:
# Bug? - Fails with a MethodMissingError
# (undefined method `denominator' for 3.5:Float)
# Complex(3.5, 3.7).numerator
end
end

View file

@ -0,0 +1,38 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :numeric_arg, shared: true do
before :each do
@numbers = [
20,
Rational(3, 4),
bignum_value,
infinity_value
]
end
it "returns 0 if positive" do
@numbers.each do |number|
number.send(@method).should == 0
end
end
it "returns Pi if negative" do
@numbers.each do |number|
(0-number).send(@method).should == Math::PI
end
end
describe "with a Numeric subclass" do
it "returns 0 if self#<(0) returns false" do
numeric = mock_numeric('positive')
numeric.should_receive(:<).with(0).and_return(false)
numeric.send(@method).should == 0
end
it "returns Pi if self#<(0) returns true" do
numeric = mock_numeric('positive')
numeric.should_receive(:<).with(0).and_return(true)
numeric.send(@method).should == Math::PI
end
end
end

View file

@ -0,0 +1,20 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :numeric_conj, shared: true do
before :each do
@numbers = [
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
bignum_value,
infinity_value,
nan_value
]
end
it "returns self" do
@numbers.each do |number|
number.send(@method).should equal(number)
end
end
end

View file

@ -0,0 +1,26 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :numeric_imag, shared: true do
before :each do
@numbers = [
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
bignum_value, # Bignum
infinity_value,
nan_value
].map{|n| [n,-n]}.flatten
end
it "returns 0" do
@numbers.each do |number|
number.send(@method).should == 0
end
end
it "raises an ArgumentError if given any arguments" do
@numbers.each do |number|
lambda { number.send(@method, number) }.should raise_error(ArgumentError)
end
end
end

View file

@ -0,0 +1,50 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :numeric_polar, shared: true do
before :each do
@pos_numbers = [
1,
3898172610**9,
987.18273,
Float::MAX,
Rational(13,7),
infinity_value,
]
@neg_numbers = @pos_numbers.map {|n| -n}
@numbers = @pos_numbers + @neg_numbers
@numbers.push(0, 0.0)
end
it "returns a two-element Array" do
@numbers.each do |number|
number.polar.should be_an_instance_of(Array)
number.polar.size.should == 2
end
end
it "sets the first value to the absolute value of self" do
@numbers.each do |number|
number.polar.first.should == number.abs
end
end
it "sets the last value to 0 if self is positive" do
(@numbers - @neg_numbers).each do |number|
number.should >= 0
number.polar.last.should == 0
end
end
it "sets the last value to Pi if self is negative" do
@neg_numbers.each do |number|
number.should < 0
number.polar.last.should == Math::PI
end
end
it "returns [NaN, NaN] if self is NaN" do
nan_value.polar.size.should == 2
nan_value.polar.first.nan?.should be_true
nan_value.polar.last.nan?.should be_true
end
end

View file

@ -0,0 +1,30 @@
require File.expand_path('../../../../spec_helper', __FILE__)
describe :numeric_real, shared: true do
before :each do
@numbers = [
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
bignum_value, # Bignum
infinity_value,
nan_value
].map{|n| [n,-n]}.flatten
end
it "returns self" do
@numbers.each do |number|
if number.to_f.nan?
number.real.nan?.should be_true
else
number.real.should == number
end
end
end
it "raises an ArgumentError if given any arguments" do
@numbers.each do |number|
lambda { number.real(number) }.should raise_error(ArgumentError)
end
end
end

View file

@ -0,0 +1,45 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_plus, shared: true do
describe "with Complex" do
it "adds both the real and imaginary components" do
(Complex(1, 2) + Complex(10, 20)).should == Complex(1 + 10, 2 + 20)
(Complex(1.5, 2.1) + Complex(100.2, -30.3)).should == Complex(1.5 + 100.2, 2.1 + (-30.3))
end
end
describe "with Integer" do
it "adds the real number to the real component of self" do
(Complex(1, 2) + 50).should == Complex(51, 2)
(Complex(1, 2) + 50.5).should == Complex(51.5, 2)
end
end
describe "with Object" do
it "tries to coerce self into other" do
value = Complex(3, 9)
obj = mock("Object")
obj.should_receive(:coerce).with(value).and_return([2, 5])
(value + obj).should == 2 + 5
end
end
describe "passed Numeric which responds to #real? with true" do
it "coerces the passed argument to the type of the real part and adds the resulting elements" do
n = mock_numeric('n')
n.should_receive(:real?).and_return(true)
n.should_receive(:coerce).with(1).and_return([1, 4])
(Complex(1, 2) + n).should == Complex(5, 2)
end
end
describe "passed Numeric which responds to #real? with false" do
it "coerces the passed argument to Complex and adds the resulting elements" do
n = mock_numeric('n')
n.should_receive(:real?).and_return(false)
n.should_receive(:coerce).with(Complex(1, 2)).and_return([Complex(1, 2), Complex(3, 4)])
(Complex(1, 2) + n).should == Complex(4, 6)
end
end
end

View file

@ -0,0 +1,22 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_polar_class, shared: true do
it "returns a complex number in terms of radius and angle" do
Complex.polar(50, 60).should be_close(Complex(-47.6206490207578, -15.2405310551108), TOLERANCE)
Complex.polar(-10, -20).should be_close(Complex(-4.08082061813392, 9.12945250727628), TOLERANCE)
end
end
describe :complex_polar, shared: true do
it "returns the absolute value and the argument" do
a = Complex(3, 4)
a.polar.size.should == 2
a.polar.first.should == 5.0
a.polar.last.should be_close(0.927295218001612, TOLERANCE)
b = Complex(-3.5, 4.7)
b.polar.size.should == 2
b.polar.first.should be_close(5.86003412959345, TOLERANCE)
b.polar.last.should be_close(2.21088447955664, TOLERANCE)
end
end

View file

@ -0,0 +1,8 @@
describe :complex_real, shared: true do
it "returns the real part of self" do
Complex(1, 0).real.should == 1
Complex(2, 1).real.should == 2
Complex(6.7, 8.9).real.should == 6.7
Complex(bignum_value, 3).real.should == bignum_value
end
end

View file

@ -0,0 +1,96 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_rect, shared: true do
before :each do
@numbers = [
Complex(1),
Complex(0, 20),
Complex(0, 0),
Complex(0.0),
Complex(9999999**99),
Complex(-20),
Complex.polar(76, 10)
]
end
it "returns an Array" do
@numbers.each do |number|
number.send(@method).should be_an_instance_of(Array)
end
end
it "returns a two-element Array" do
@numbers.each do |number|
number.send(@method).size.should == 2
end
end
it "returns the real part of self as the first element" do
@numbers.each do |number|
number.send(@method).first.should == number.real
end
end
it "returns the imaginary part of self as the last element" do
@numbers.each do |number|
number.send(@method).last.should == number.imaginary
end
end
it "raises an ArgumentError if given any arguments" do
@numbers.each do |number|
lambda { number.send(@method, number) }.should raise_error(ArgumentError)
end
end
end
describe :complex_rect_class, shared: true do
describe "passed a Numeric n which responds to #real? with true" do
it "returns a Complex with real part n and imaginary part 0" do
n = mock_numeric('n')
n.should_receive(:real?).any_number_of_times.and_return(true)
result = Complex.send(@method, n)
result.real.should == n
result.imag.should == 0
end
end
describe "passed a Numeric which responds to #real? with false" do
it "raises TypeError" do
n = mock_numeric('n')
n.should_receive(:real?).any_number_of_times.and_return(false)
lambda { Complex.send(@method, n) }.should raise_error(TypeError)
end
end
describe "passed Numerics n1 and n2 and at least one responds to #real? with false" do
[[false, false], [false, true], [true, false]].each do |r1, r2|
it "raises TypeError" do
n1 = mock_numeric('n1')
n2 = mock_numeric('n2')
n1.should_receive(:real?).any_number_of_times.and_return(r1)
n2.should_receive(:real?).any_number_of_times.and_return(r2)
lambda { Complex.send(@method, n1, n2) }.should raise_error(TypeError)
end
end
end
describe "passed Numerics n1 and n2 and both respond to #real? with true" do
it "returns a Complex with real part n1 and imaginary part n2" do
n1 = mock_numeric('n1')
n2 = mock_numeric('n2')
n1.should_receive(:real?).any_number_of_times.and_return(true)
n2.should_receive(:real?).any_number_of_times.and_return(true)
result = Complex.send(@method, n1, n2)
result.real.should == n1
result.imag.should == n2
end
end
describe "passed a non-Numeric" do
it "raises TypeError" do
lambda { Complex.send(@method, :sym) }.should raise_error(TypeError)
lambda { Complex.send(@method, 0, :sym) }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,44 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :complex_to_s, shared: true do
describe "when self's real component is 0" do
it "returns both the real and imaginary component even when the real is 0" do
Complex(0, 5).to_s.should == "0+5i"
Complex(0, -3.2).to_s.should == "0-3.2i"
end
end
it "returns self as String" do
Complex(1, 5).to_s.should == "1+5i"
Complex(-2.5, 1.5).to_s.should == "-2.5+1.5i"
Complex(1, -5).to_s.should == "1-5i"
Complex(-2.5, -1.5).to_s.should == "-2.5-1.5i"
# Guard against the Mathn library
conflicts_with :Prime do
Complex(1, 0).to_s.should == "1+0i"
Complex(1, -0).to_s.should == "1+0i"
end
end
it "returns 1+0.0i for Complex(1, 0.0)" do
Complex(1, 0.0).to_s.should == "1+0.0i"
end
it "returns 1-0.0i for Complex(1, -0.0)" do
Complex(1, -0.0).to_s.should == "1-0.0i"
end
it "returns 1+Infinity*i for Complex(1, Infinity)" do
Complex(1, infinity_value).to_s.should == "1+Infinity*i"
end
it "returns 1-Infinity*i for Complex(1, -Infinity)" do
Complex(1, -infinity_value).to_s.should == "1-Infinity*i"
end
it "returns 1+NaN*i for Complex(1, NaN)" do
Complex(1, nan_value).to_s.should == "1+NaN*i"
end
end

View file

@ -0,0 +1,89 @@
# -*- encoding: us-ascii -*-
describe :enum_each, shared: true do
before :each do
object_each_with_arguments = Object.new
def object_each_with_arguments.each_with_arguments(arg, *args)
yield arg, *args
:method_returned
end
@enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2)
@enum_with_yielder = Enumerator.new {|y| y.yield :ok}
end
it "yields each element of self to the given block" do
acc = []
[1,2,3].to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "calls #each on the object given in the constructor by default" do
each = mock('each')
each.should_receive(:each)
each.to_enum.each {|e| e }
end
it "calls #each on the underlying object until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
each.to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "calls the method given in the constructor instead of #each" do
each = mock('peach')
each.should_receive(:peach)
each.to_enum(:peach).each {|e| e }
end
it "calls the method given in the constructor until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
each.to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "raises a NoMethodError if the object doesn't respond to #each" do
enum = Object.new.to_enum
lambda do
enum.each { |e| e }
end.should raise_error(NoMethodError)
end
it "returns self if not given arguments and not given a block" do
@enum_with_arguments.each.should equal(@enum_with_arguments)
@enum_with_yielder.each.should equal(@enum_with_yielder)
end
it "returns the same value from receiver.each if block is given" do
@enum_with_arguments.each {}.should equal(:method_returned)
end
it "passes given arguments at initialized to receiver.each" do
@enum_with_arguments.each.to_a.should == [[:arg0, :arg1, :arg2]]
end
it "requires multiple arguments" do
Enumerator.instance_method(:each).arity.should < 0
end
it "appends given arguments to receiver.each" do
@enum_with_arguments.each(:each0, :each1).to_a.should == [[:arg0, :arg1, :arg2, :each0, :each1]]
@enum_with_arguments.each(:each2, :each3).to_a.should == [[:arg0, :arg1, :arg2, :each2, :each3]]
end
it "returns the same value from receiver.each if block and arguments are given" do
@enum_with_arguments.each(:each1, :each2) {}.should equal(:method_returned)
end
it "returns new Enumerator if given arguments but not given a block" do
ret = @enum_with_arguments.each 1
ret.should be_an_instance_of(Enumerator)
ret.should_not equal(@enum_with_arguments)
end
end

View file

@ -0,0 +1,12 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../../../fixtures/enumerator/classes', __FILE__)
describe :enum_cons, shared: true do
it "returns an enumerator of the receiver with iteration of each_cons for each array of n concecutive elements" do
a = []
enum = EnumSpecs::Numerous.new.enum_cons(3)
enum.each {|x| a << x}
enum.should be_an_instance_of(Enumerator)
a.should == [[2, 5, 3], [5, 3, 6], [3, 6, 1], [6, 1, 4]]
end
end

View file

@ -0,0 +1,50 @@
describe :enum_for, shared: true do
it "is defined in Kernel" do
Kernel.method_defined?(@method).should be_true
end
it "returns a new enumerator" do
"abc".send(@method).should be_an_instance_of(Enumerator)
end
it "defaults the first argument to :each" do
enum = [1,2].send(@method)
enum.map { |v| v }.should == [1,2].each { |v| v }
end
it "exposes multi-arg yields as an array" do
o = Object.new
def o.each
yield :a
yield :b1, :b2
yield [:c]
yield :d1, :d2
yield :e1, :e2, :e3
end
enum = o.send(@method)
enum.next.should == :a
enum.next.should == [:b1, :b2]
enum.next.should == [:c]
enum.next.should == [:d1, :d2]
enum.next.should == [:e1, :e2, :e3]
end
it "uses the passed block's value to calculate the size of the enumerator" do
Object.new.enum_for { 100 }.size.should == 100
end
it "defers the evaluation of the passed block until #size is called" do
ScratchPad.record []
enum = Object.new.enum_for do
ScratchPad << :called
100
end
ScratchPad.recorded.should be_empty
enum.size
ScratchPad.recorded.should == [:called]
end
end

View file

@ -0,0 +1,42 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :enum_new, shared: true do
it "creates a new custom enumerator with the given object, iterator and arguments" do
enum = Enumerator.new(1, :upto, 3)
enum.should be_an_instance_of(Enumerator)
end
it "creates a new custom enumerator that responds to #each" do
enum = Enumerator.new(1, :upto, 3)
enum.respond_to?(:each).should == true
end
it "creates a new custom enumerator that runs correctly" do
Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
end
it "aliases the second argument to :each" do
Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
end
it "doesn't check for the presence of the iterator method" do
Enumerator.new(nil).should be_an_instance_of(Enumerator)
end
it "uses the latest define iterator method" do
class StrangeEach
def each
yield :foo
end
end
enum = Enumerator.new(StrangeEach.new)
enum.to_a.should == [:foo]
class StrangeEach
def each
yield :bar
end
end
enum.to_a.should == [:bar]
end
end

View file

@ -0,0 +1,28 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :enum_next, shared: true do
before :each do
@enum = 1.upto(3)
end
it "returns the next element of the enumeration" do
@enum.next.should == 1
@enum.next.should == 2
@enum.next.should == 3
end
it "raises a StopIteration exception at the end of the stream" do
3.times { @enum.next }
lambda { @enum.next }.should raise_error(StopIteration)
end
it "cannot be called again until the enumerator is rewound" do
3.times { @enum.next }
lambda { @enum.next }.should raise_error(StopIteration)
lambda { @enum.next }.should raise_error(StopIteration)
lambda { @enum.next }.should raise_error(StopIteration)
@enum.rewind
@enum.next.should == 1
end
end

View file

@ -0,0 +1,39 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :enum_rewind, shared: true do
before :each do
@enum = 1.upto(3)
end
it "resets the enumerator to its initial state" do
@enum.next.should == 1
@enum.next.should == 2
@enum.rewind
@enum.next.should == 1
end
it "returns self" do
@enum.rewind.should == @enum
end
it "has no effect on a new enumerator" do
@enum.rewind
@enum.next.should == 1
end
it "has no effect if called multiple, consecutive times" do
@enum.next.should == 1
@enum.rewind
@enum.rewind
@enum.next.should == 1
end
it "works with peek to reset the position" do
@enum.next
@enum.next
@enum.rewind
@enum.next
@enum.peek.should == 2
end
end

View file

@ -0,0 +1,32 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :enum_with_index, shared: true do
require File.expand_path('../../../fixtures/enumerator/classes', __FILE__)
before :each do
@enum = [1, 2, 3, 4].to_enum
end
it "passes each element and its index to block" do
@a = []
@enum.send(@method) { |o, i| @a << [o, i] }
@a.should == [[1, 0], [2, 1], [3, 2], [4, 3]]
end
it "returns the object being enumerated when given a block" do
[1, 2, 3, 4].should == @enum.send(@method) { |o, i| :glark }
end
it "binds splat arguments properly" do
acc = []
@enum.send(@method) { |*b| c,d = b; acc << c; acc << d }
[1, 0, 2, 1, 3, 2, 4, 3].should == acc
end
it "returns an enumerator if no block is supplied" do
ewi = @enum.send(@method)
ewi.should be_an_instance_of(Enumerator)
ewi.to_a.should == [[1, 0], [2, 1], [3, 2], [4, 3]]
end
end

View file

@ -0,0 +1,42 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :enum_with_object, shared: true do
before :each do
@enum = [:a, :b].to_enum
@memo = ''
@block_params = @enum.send(@method, @memo).to_a
end
it "receives an argument" do
@enum.method(@method).arity.should == 1
end
context "with block" do
it "returns the given object" do
ret = @enum.send(@method, @memo) do |elm, memo|
# nothing
end
ret.should equal(@memo)
end
context "the block parameter" do
it "passes each element to first parameter" do
@block_params[0][0].should equal(:a)
@block_params[1][0].should equal(:b)
end
it "passes the given object to last parameter" do
@block_params[0][1].should equal(@memo)
@block_params[1][1].should equal(@memo)
end
end
end
context "without block" do
it "returns new Enumerator" do
ret = @enum.send(@method, @memo)
ret.should be_an_instance_of(Enumerator)
ret.should_not equal(@enum)
end
end
end

View file

@ -0,0 +1,77 @@
describe :fiber_resume, shared: true do
it "can be invoked from the root Fiber" do
fiber = Fiber.new { :fiber }
fiber.send(@method).should == :fiber
end
it "raises a FiberError if invoked from a different Thread" do
fiber = Fiber.new { }
lambda do
Thread.new do
fiber.resume
end.join
end.should raise_error(FiberError)
fiber.resume
end
it "passes control to the beginning of the block on first invocation" do
invoked = false
fiber = Fiber.new { invoked = true }
fiber.send(@method)
invoked.should be_true
end
it "returns the last value encountered on first invocation" do
fiber = Fiber.new { 1+1; true }
fiber.send(@method).should be_true
end
it "runs until the end of the block" do
obj = mock('obj')
obj.should_receive(:do).once
fiber = Fiber.new { 1 + 2; a = "glark"; obj.do }
fiber.send(@method)
end
it "runs until Fiber.yield" do
obj = mock('obj')
obj.should_not_receive(:do)
fiber = Fiber.new { 1 + 2; Fiber.yield; obj.do }
fiber.send(@method)
end
it "resumes from the last call to Fiber.yield on subsequent invocations" do
fiber = Fiber.new { Fiber.yield :first; :second }
fiber.send(@method).should == :first
fiber.send(@method).should == :second
end
it "accepts any number of arguments" do
fiber = Fiber.new { |a| }
lambda { fiber.send(@method, *(1..10).to_a) }.should_not raise_error
end
it "sets the block parameters to its arguments on the first invocation" do
first = mock('first')
first.should_receive(:arg).with(:first).twice
fiber = Fiber.new { |arg| first.arg arg; Fiber.yield; first.arg arg; }
fiber.send(@method, :first)
fiber.send(@method, :second)
end
it "raises a FiberError if the Fiber is dead" do
fiber = Fiber.new { true }
fiber.send(@method)
lambda { fiber.send(@method) }.should raise_error(FiberError)
end
it "raises a LocalJumpError if the block includes a return statement" do
fiber = Fiber.new { return; }
lambda { fiber.send(@method) }.should raise_error(LocalJumpError)
end
it "raises a LocalJumpError if the block includes a break statement" do
fiber = Fiber.new { break; }
lambda { fiber.send(@method) }.should raise_error(LocalJumpError)
end
end

View file

@ -0,0 +1,9 @@
describe :file_blockdev, shared: true do
it "returns true/false depending if the named file is a block device" do
@object.send(@method, tmp("")).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(tmp(""))).should == false
end
end

View file

@ -0,0 +1,9 @@
describe :file_chardev, shared: true do
it "returns true/false depending if the named file is a char device" do
@object.send(@method, tmp("")).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(tmp(""))).should == false
end
end

View file

@ -0,0 +1,66 @@
describe :file_directory, shared: true do
before :each do
@dir = tmp("file_directory")
@file = tmp("file_directory.txt")
mkdir_p @dir
touch @file
end
after :each do
rm_r @dir, @file
end
it "returns true if the argument is a directory" do
@object.send(@method, @dir).should be_true
end
it "returns false if the argument is not a directory" do
@object.send(@method, @file).should be_false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@dir)).should be_true
end
it "raises a TypeError when passed an Integer" do
lambda { @object.send(@method, 1) }.should raise_error(TypeError)
lambda { @object.send(@method, bignum_value) }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
end
end
describe :file_directory_io, shared: true do
before :each do
@dir = tmp("file_directory_io")
@file = tmp("file_directory_io.txt")
mkdir_p @dir
touch @file
end
after :each do
rm_r @dir, @file
end
it "returns false if the argument is an IO that's not a directory" do
@object.send(@method, STDIN).should be_false
end
platform_is_not :windows do
it "returns true if the argument is an IO that is a directory" do
File.open(@dir, "r") do |f|
@object.send(@method, f).should be_true
end
end
end
it "calls #to_io to convert a non-IO object" do
io = mock('FileDirectoryIO')
io.should_receive(:to_io).and_return(STDIN)
@object.send(@method, io).should be_false
end
end

View file

@ -0,0 +1,48 @@
describe :file_executable, shared: true do
before :each do
@file1 = tmp('temp1.txt')
@file2 = tmp('temp2.txt')
touch @file1
touch @file2
File.chmod(0755, @file1)
end
after :each do
rm_r @file1, @file2
end
platform_is_not :windows do
it "returns true if named file is executable by the effective user id of the process, otherwise false" do
@object.send(@method, '/etc/passwd').should == false
@object.send(@method, @file1).should == true
@object.send(@method, @file2).should == false
end
it "returns true if the argument is an executable file" do
@object.send(@method, @file1).should == true
@object.send(@method, @file2).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file1)).should == true
end
end
it "raises an ArgumentError if not passed one argument" do
lambda { @object.send(@method) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, 1) }.should raise_error(TypeError)
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
lambda { @object.send(@method, false) }.should raise_error(TypeError)
end
end
describe :file_executable_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,46 @@
describe :file_executable_real, shared: true do
before :each do
@file1 = tmp('temp1.txt.exe')
@file2 = tmp('temp2.txt')
touch @file1
touch @file2
File.chmod(0755, @file1)
end
after :each do
rm_r @file1, @file2
end
platform_is_not :windows do
it "returns true if the file its an executable" do
@object.send(@method, @file1).should == true
@object.send(@method, @file2).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file1)).should == true
end
end
it "returns true if named file is readable by the real user id of the process, otherwise false" do
@object.send(@method, @file1).should == true
end
it "raises an ArgumentError if not passed one argument" do
lambda { @object.send(@method) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, 1) }.should raise_error(TypeError)
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
lambda { @object.send(@method, false) }.should raise_error(TypeError)
end
end
describe :file_executable_real_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,24 @@
describe :file_exist, shared: true do
it "returns true if the file exist" do
@object.send(@method, __FILE__).should == true
@object.send(@method, 'a_fake_file').should == false
end
it "returns true if the file exist using the alias exists?" do
@object.send(@method, __FILE__).should == true
@object.send(@method, 'a_fake_file').should == false
end
it "raises an ArgumentError if not passed one argument" do
lambda { @object.send(@method) }.should raise_error(ArgumentError)
lambda { @object.send(@method, __FILE__, __FILE__) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(__FILE__)).should == true
end
end

View file

@ -0,0 +1,45 @@
describe :file_file, shared: true do
before :each do
platform_is :windows do
@null = "NUL"
@dir = "C:\\"
end
platform_is_not :windows do
@null = "/dev/null"
@dir = "/bin"
end
@file = tmp("test.txt")
touch @file
end
after :each do
rm_r @file
end
it "returns true if the named file exists and is a regular file." do
@object.send(@method, @file).should == true
@object.send(@method, @dir).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file)).should == true
end
platform_is_not :windows do
it "returns true if the null device exists and is a regular file." do
@object.send(@method, @null).should == false # May fail on MS Windows
end
end
it "raises an ArgumentError if not passed one argument" do
lambda { @object.send(@method) }.should raise_error(ArgumentError)
lambda { @object.send(@method, @null, @file) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
lambda { @object.send(@method, 1) }.should raise_error(TypeError)
end
end

View file

@ -0,0 +1,40 @@
describe :file_grpowned, shared: true do
before :each do
@file = tmp('i_exist')
touch(@file) { |f| f.puts "file_content" }
File.chown(nil, Process.gid, @file) rescue nil
end
after :each do
rm_r @file
end
platform_is_not :windows do
it "returns true if the file exist" do
@object.send(@method, @file).should be_true
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file)).should be_true
end
it 'takes non primary groups into account' do
group = (Process.groups - [Process.egid]).first
if group
File.chown(nil, group, @file)
@object.send(@method, @file).should == true
else
# No supplementary groups
1.should == 1
end
end
end
platform_is :windows do
it "returns false if the file exist" do
@object.send(@method, @file).should be_false
end
end
end

View file

@ -0,0 +1,47 @@
describe :file_identical, shared: true do
before :each do
@file1 = tmp('file_identical.txt')
@file2 = tmp('file_identical2.txt')
@link = tmp('file_identical.lnk')
@non_exist = 'non_exist'
touch(@file1) { |f| f.puts "file1" }
touch(@file2) { |f| f.puts "file2" }
rm_r @link
File.link(@file1, @link)
end
after :each do
rm_r @link, @file1, @file2
end
it "returns true for a file and its link" do
@object.send(@method, @file1, @link).should == true
end
it "returns false if any of the files doesn't exist" do
@object.send(@method, @file1, @non_exist).should be_false
@object.send(@method, @non_exist, @file1).should be_false
@object.send(@method, @non_exist, @non_exist).should be_false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file1), mock_to_path(@link)).should == true
end
it "raises an ArgumentError if not passed two arguments" do
lambda { @object.send(@method, @file1, @file2, @link) }.should raise_error(ArgumentError)
lambda { @object.send(@method, @file1) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed String types" do
lambda { @object.send(@method, 1,1) }.should raise_error(TypeError)
end
it "returns true if both named files are identical" do
@object.send(@method, @file1, @file1).should be_true
@object.send(@method, @link, @link).should be_true
@object.send(@method, @file1, @file2).should be_false
end
end

View file

@ -0,0 +1,3 @@
describe :file_owned, shared: true do
it "accepts an object that has a #to_path method"
end

View file

@ -0,0 +1,3 @@
describe :file_pipe, shared: true do
it "accepts an object that has a #to_path method"
end

View file

@ -0,0 +1,30 @@
describe :file_readable, shared: true do
before :each do
@file = tmp('i_exist')
platform_is :windows do
@file2 = File.join(ENV["WINDIR"], "system32/drivers/etc/services").tr(File::SEPARATOR, File::ALT_SEPARATOR)
end
platform_is_not :windows do
@file2 = "/etc/passwd"
end
end
after :each do
rm_r @file
end
it "returns true if named file is readable by the effective user id of the process, otherwise false" do
@object.send(@method, @file2).should == true
File.open(@file,'w') { @object.send(@method, @file).should == true }
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file2)).should == true
end
end
describe :file_readable_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,23 @@
describe :file_readable_real, shared: true do
before :each do
@file = tmp('i_exist')
end
after :each do
rm_r @file
end
it "returns true if named file is readable by the real user id of the process, otherwise false" do
File.open(@file,'w') { @object.send(@method, @file).should == true }
end
it "accepts an object that has a #to_path method" do
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
end
end
describe :file_readable_real_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,2 @@
describe :file_setgid, shared: true do
end

View file

@ -0,0 +1,2 @@
describe :file_setuid, shared: true do
end

View file

@ -0,0 +1,124 @@
describe :file_size, shared: true do
before :each do
@exists = tmp('i_exist')
touch(@exists) { |f| f.write 'rubinius' }
end
after :each do
rm_r @exists
end
it "returns the size of the file if it exists and is not empty" do
@object.send(@method, @exists).should == 8
end
it "accepts a String-like (to_str) parameter" do
obj = mock("file")
obj.should_receive(:to_str).and_return(@exists)
@object.send(@method, obj).should == 8
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@exists)).should == 8
end
end
describe :file_size_to_io, shared: true do
before :each do
@exists = tmp('i_exist')
touch(@exists) { |f| f.write 'rubinius' }
@file = File.open(@exists, 'r')
end
after :each do
@file.close unless @file.closed?
rm_r @exists
end
it "calls #to_io to convert the argument to an IO" do
obj = mock("io like")
obj.should_receive(:to_io).and_return(@file)
@object.send(@method, obj).should == 8
end
end
describe :file_size_raise_when_missing, shared: true do
before :each do
# TODO: missing_file
@missing = tmp("i_dont_exist")
rm_r @missing
end
after :each do
rm_r @missing
end
it "raises an error if file_name doesn't exist" do
lambda {@object.send(@method, @missing)}.should raise_error(Errno::ENOENT)
end
end
describe :file_size_nil_when_missing, shared: true do
before :each do
# TODO: missing_file
@missing = tmp("i_dont_exist")
rm_r @missing
end
after :each do
rm_r @missing
end
it "returns nil if file_name doesn't exist or has 0 size" do
@object.send(@method, @missing).should == nil
end
end
describe :file_size_0_when_empty, shared: true do
before :each do
@empty = tmp("i_am_empty")
touch @empty
end
after :each do
rm_r @empty
end
it "returns 0 if the file is empty" do
@object.send(@method, @empty).should == 0
end
end
describe :file_size_nil_when_empty, shared: true do
before :each do
@empty = tmp("i_am_empt")
touch @empty
end
after :each do
rm_r @empty
end
it "returns nil if file_name is empty" do
@object.send(@method, @empty).should == nil
end
end
describe :file_size_with_file_argument, shared: true do
before :each do
@exists = tmp('i_exist')
touch(@exists) { |f| f.write 'rubinius' }
end
after :each do
rm_r @exists
end
it "accepts a File argument" do
File.open(@exists) do |f|
@object.send(@method, f).should == 8
end
end
end

View file

@ -0,0 +1,3 @@
describe :file_socket, shared: true do
it "accepts an object that has a #to_path method"
end

View file

@ -0,0 +1,29 @@
describe :file_sticky, shared: true do
before :each do
@dir = tmp('sticky_dir')
Dir.rmdir(@dir) if File.exist?(@dir)
end
after :each do
Dir.rmdir(@dir) if File.exist?(@dir)
end
platform_is_not :windows, :darwin, :freebsd, :netbsd, :openbsd, :solaris, :aix do
it "returns true if the named file has the sticky bit, otherwise false" do
Dir.mkdir @dir, 01755
@object.send(@method, @dir).should == true
@object.send(@method, '/').should == false
end
end
it "accepts an object that has a #to_path method"
end
describe :file_sticky_missing, shared: true do
platform_is_not :windows do
it "returns false if the file dies not exist" do
@object.send(@method, 'fake_file').should == false
end
end
end

View file

@ -0,0 +1,46 @@
describe :file_symlink, shared: true do
before :each do
@file = tmp("test.txt")
@link = tmp("test.lnk")
rm_r @link
touch @file
end
after :each do
rm_r @link, @file
end
platform_is_not :windows do
it "returns true if the file is a link" do
File.symlink(@file, @link)
@object.send(@method, @link).should == true
end
it "accepts an object that has a #to_path method" do
File.symlink(@file, @link)
@object.send(@method, mock_to_path(@link)).should == true
end
end
end
describe :file_symlink_nonexistent, shared: true do
before :each do
@file = tmp("test.txt")
@link = tmp("test.lnk")
rm_r @link
touch @file
end
after :each do
rm_r @link
rm_r @file
end
platform_is_not :windows do
it "returns false if the file does not exist" do
@object.send(@method, "non_existent_link").should == false
end
end
end

View file

@ -0,0 +1,49 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :file_world_readable, shared: true do
before :each do
@file = tmp('world-readable')
touch @file
end
after :each do
rm_r @file
end
platform_is_not :windows do
it "returns nil if the file is chmod 600" do
File.chmod(0600, @file)
@object.world_readable?(@file).should be_nil
end
it "returns nil if the file is chmod 000" do
File.chmod(0000, @file)
@object.world_readable?(@file).should be_nil
end
it "returns nil if the file is chmod 700" do
File.chmod(0700, @file)
@object.world_readable?(@file).should be_nil
end
end
# We don't specify what the Fixnum is because it's system dependent
it "returns a Fixnum if the file is chmod 644" do
File.chmod(0644, @file)
@object.world_readable?(@file).should be_an_instance_of(Fixnum)
end
it "returns a Fixnum if the file is a directory and chmod 644" do
dir = rand().to_s + '-ww'
Dir.mkdir(dir)
Dir.exist?(dir).should be_true
File.chmod(0644, dir)
@object.world_readable?(dir).should be_an_instance_of(Fixnum)
Dir.rmdir(dir)
end
it "coerces the argument with #to_path" do
@object.world_readable?(mock_to_path(@file))
end
end

View file

@ -0,0 +1,49 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :file_world_writable, shared: true do
before :each do
@file = tmp('world-writable')
touch @file
end
after :each do
rm_r @file
end
platform_is_not :windows do
it "returns nil if the file is chmod 600" do
File.chmod(0600, @file)
@object.world_writable?(@file).should be_nil
end
it "returns nil if the file is chmod 000" do
File.chmod(0000, @file)
@object.world_writable?(@file).should be_nil
end
it "returns nil if the file is chmod 700" do
File.chmod(0700, @file)
@object.world_writable?(@file).should be_nil
end
# We don't specify what the Fixnum is because it's system dependent
it "returns a Fixnum if the file is chmod 777" do
File.chmod(0777, @file)
@object.world_writable?(@file).should be_an_instance_of(Fixnum)
end
it "returns a Fixnum if the file is a directory and chmod 777" do
dir = rand().to_s + '-ww'
Dir.mkdir(dir)
Dir.exist?(dir).should be_true
File.chmod(0777, dir)
@object.world_writable?(dir).should be_an_instance_of(Fixnum)
Dir.rmdir(dir)
end
end
it "coerces the argument with #to_path" do
@object.world_writable?(mock_to_path(@file))
end
end

View file

@ -0,0 +1,26 @@
describe :file_writable, shared: true do
before :each do
@file = tmp('i_exist')
end
after :each do
rm_r @file
end
it "returns true if named file is writable by the effective user id of the process, otherwise false" do
platform_is_not :windows do
@object.send(@method, "/etc/passwd").should == false
end
File.open(@file,'w') { @object.send(@method, @file).should == true }
end
it "accepts an object that has a #to_path method" do
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
end
end
describe :file_writable_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,33 @@
describe :file_writable_real, shared: true do
before :each do
@file = tmp('i_exist')
end
after :each do
rm_r @file
end
it "returns true if named file is writable by the real user id of the process, otherwise false" do
File.open(@file,'w') { @object.send(@method, @file).should == true }
end
it "accepts an object that has a #to_path method" do
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
end
it "raises an ArgumentError if not passed one argument" do
lambda { File.writable_real? }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, 1) }.should raise_error(TypeError)
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
lambda { @object.send(@method, false) }.should raise_error(TypeError)
end
end
describe :file_writable_real_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,76 @@
describe :file_zero, shared: true do
before :each do
@zero_file = tmp("test.txt")
@nonzero_file = tmp("test2.txt")
@dir = tmp("dir")
Dir.mkdir @dir
touch @zero_file
touch(@nonzero_file) { |f| f.puts "hello" }
end
after :each do
rm_r @zero_file, @nonzero_file
rm_r @dir
end
it "returns true if the file is empty" do
@object.send(@method, @zero_file).should == true
end
it "returns false if the file is not empty" do
@object.send(@method, @nonzero_file).should == false
end
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@zero_file)).should == true
end
platform_is :windows do
it "returns true for NUL" do
@object.send(@method, 'NUL').should == true
@object.send(@method, 'nul').should == true
end
end
platform_is_not :windows do
it "returns true for /dev/null" do
@object.send(@method, File.realpath('/dev/null')).should == true
end
end
it "raises an ArgumentError if not passed one argument" do
lambda { File.zero? }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed a String type" do
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
lambda { @object.send(@method, true) }.should raise_error(TypeError)
lambda { @object.send(@method, false) }.should raise_error(TypeError)
end
it "returns true inside a block opening a file if it is empty" do
File.open(@zero_file,'w') do
@object.send(@method, @zero_file).should == true
end
end
platform_is_not :windows do
it "returns false for a directory" do
@object.send(@method, @dir).should == false
end
end
platform_is :windows do
# see http://redmine.ruby-lang.org/issues/show/449 for background
it "returns true for a directory" do
@object.send(@method, @dir).should == true
end
end
end
describe :file_zero_missing, shared: true do
it "returns false if the file does not exist" do
@object.send(@method, 'fake_file').should == false
end
end

View file

@ -0,0 +1,57 @@
# -*- encoding: ascii-8bit -*-
describe :io_putc, shared: true do
after :each do
@io.close if @io && !@io.closed?
@io_object = nil
rm_r @name
end
describe "with a Fixnum argument" do
it "writes one character as a String" do
@io.should_receive(:write).with("A")
@io_object.send(@method, 65).should == 65
end
it "writes the low byte as a String" do
@io.should_receive(:write).with("A")
@io_object.send(@method, 0x2441).should == 0x2441
end
end
describe "with a String argument" do
it "writes one character" do
@io.should_receive(:write).with("B")
@io_object.send(@method, "B").should == "B"
end
it "writes the first character" do
@io.should_receive(:write).with("R")
@io_object.send(@method, "Ruby").should == "Ruby"
end
end
it "calls #to_int to convert an object to an Integer" do
obj = mock("kernel putc")
obj.should_receive(:to_int).and_return(65)
@io.should_receive(:write).with("A")
@io_object.send(@method, obj).should == obj
end
it "raises IOError on a closed stream" do
@io.close
lambda { @io_object.send(@method, "a") }.should raise_error(IOError)
end
it "raises a TypeError when passed nil" do
lambda { @io_object.send(@method, nil) }.should raise_error(TypeError)
end
it "raises a TypeError when passed false" do
lambda { @io_object.send(@method, false) }.should raise_error(TypeError)
end
it "raises a TypeError when passed true" do
lambda { @io_object.send(@method, true) }.should raise_error(TypeError)
end
end

View file

@ -0,0 +1,54 @@
# These examples hold for BasicObject#equal?, BasicObject#== and Kernel#eql?
describe :object_equal, shared: true do
it "returns true if other is identical to self" do
obj = Object.new
obj.__send__(@method, obj).should be_true
end
it "returns false if other is not identical to self" do
a = Object.new
b = Object.new
a.__send__(@method, b).should be_false
end
it "returns true only if self and other are the same object" do
o1 = mock('o1')
o2 = mock('o2')
o1.__send__(@method, o1).should == true
o2.__send__(@method, o2).should == true
o1.__send__(@method, o2).should == false
end
it "returns true for the same immediate object" do
o1 = 1
o2 = :hola
1.__send__(@method, o1).should == true
:hola.__send__(@method, o2).should == true
end
it "returns false for nil and any other object" do
o1 = mock('o1')
nil.__send__(@method, nil).should == true
o1.__send__(@method, nil).should == false
nil.__send__(@method, o1).should == false
end
it "returns false for objects of different classes" do
:hola.__send__(@method, 1).should == false
end
it "returns true only if self and other are the same boolean" do
true.__send__(@method, true).should == true
false.__send__(@method, false).should == true
true.__send__(@method, false).should == false
false.__send__(@method, true).should == false
end
it "returns true for integers of initially different ranges" do
big42 = (bignum_value * 42 / bignum_value)
42.__send__(@method, big42).should == true
long42 = (1 << 35) * 42 / (1 << 35)
42.__send__(@method, long42).should == true
end
end

View file

@ -0,0 +1,80 @@
# These examples hold for both BasicObject#__id__ and Kernel#object_id.
describe :object_id, shared: true do
it "returns an integer" do
o1 = @object.new
o1.__send__(@method).should be_kind_of(Integer)
end
it "returns the same value on all calls to id for a given object" do
o1 = @object.new
o1.__send__(@method).should == o1.__send__(@method)
end
it "returns different values for different objects" do
o1 = @object.new
o2 = @object.new
o1.__send__(@method).should_not == o2.__send__(@method)
end
it "returns the same value for two Fixnums with the same value" do
o1 = 1
o2 = 1
o1.send(@method).should == o2.send(@method)
end
it "returns the same value for two Symbol literals" do
o1 = :hello
o2 = :hello
o1.send(@method).should == o2.send(@method)
end
it "returns the same value for two true literals" do
o1 = true
o2 = true
o1.send(@method).should == o2.send(@method)
end
it "returns the same value for two false literals" do
o1 = false
o2 = false
o1.send(@method).should == o2.send(@method)
end
it "returns the same value for two nil literals" do
o1 = nil
o2 = nil
o1.send(@method).should == o2.send(@method)
end
it "returns a different value for two Bignum literals" do
o1 = 2e100.to_i
o2 = 2e100.to_i
o1.send(@method).should_not == o2.send(@method)
end
it "returns a different value for two String literals" do
o1 = "hello"
o2 = "hello"
o1.send(@method).should_not == o2.send(@method)
end
it "returns a different value for an object and its dup" do
o1 = mock("object")
o2 = o1.dup
o1.send(@method).should_not == o2.send(@method)
end
it "returns a different value for two numbers near the 32 bit Fixnum limit" do
o1 = -1
o2 = 2 ** 30 - 1
o1.send(@method).should_not == o2.send(@method)
end
it "returns a different value for two numbers near the 64 bit Fixnum limit" do
o1 = -1
o2 = 2 ** 62 - 1
o1.send(@method).should_not == o2.send(@method)
end
end

View file

@ -0,0 +1,68 @@
describe :kernel_raise, shared: true do
before :each do
ScratchPad.clear
end
it "aborts execution" do
lambda do
@object.raise Exception, "abort"
ScratchPad.record :no_abort
end.should raise_error(Exception, "abort")
ScratchPad.recorded.should be_nil
end
it "raises RuntimeError if no exception class is given" do
lambda { @object.raise }.should raise_error(RuntimeError)
end
it "raises a given Exception instance" do
error = RuntimeError.new
lambda { @object.raise(error) }.should raise_error(error)
end
it "raises a RuntimeError if string given" do
lambda { @object.raise("a bad thing") }.should raise_error(RuntimeError)
end
it "raises a TypeError when passed a non-Exception object" do
lambda { @object.raise(Object.new) }.should raise_error(TypeError)
end
it "raises a TypeError when passed true" do
lambda { @object.raise(true) }.should raise_error(TypeError)
end
it "raises a TypeError when passed false" do
lambda { @object.raise(false) }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { @object.raise(nil) }.should raise_error(TypeError)
end
it "re-raises the rescued exception" do
lambda do
begin
raise Exception, "outer"
ScratchPad.record :no_abort
rescue
begin
raise StandardError, "inner"
rescue
end
@object.raise
ScratchPad.record :no_reraise
end
end.should raise_error(Exception, "outer")
ScratchPad.recorded.should be_nil
end
it "allows Exception, message, and backtrace parameters" do
lambda do
@object.raise(ArgumentError, "message", caller)
end.should raise_error(ArgumentError, "message")
end
end

View file

@ -0,0 +1,44 @@
describe :math_atanh_base, shared: true do
it "returns a float" do
@object.send(@method, 0.5).should be_an_instance_of(Float)
end
it "returns the inverse hyperbolic tangent of the argument" do
@object.send(@method, 0.0).should == 0.0
@object.send(@method, -0.0).should == -0.0
@object.send(@method, 0.5).should be_close(0.549306144334055, TOLERANCE)
@object.send(@method, -0.2).should be_close(-0.202732554054082, TOLERANCE)
end
it "raises a TypeError if the argument is nil" do
lambda { @object.send(@method, nil) }.should raise_error(TypeError)
end
it "raises a TypeError if the argument is not a Numeric" do
lambda { @object.send(@method, "test") }.should raise_error(TypeError)
end
it "returns Infinity if x == 1.0" do
@object.send(@method, 1.0).should == Float::INFINITY
end
it "return -Infinity if x == -1.0" do
@object.send(@method, -1.0).should == -Float::INFINITY
end
end
describe :math_atanh_private, shared: true do
it "is a private instance method" do
Math.should have_private_instance_method(@method)
end
end
describe :math_atanh_no_complex, shared: true do
it "raises a Math::DomainError for arguments greater than 1.0" do
lambda { @object.send(@method, 1.0 + Float::EPSILON) }.should raise_error(Math::DomainError)
end
it "raises a Math::DomainError for arguments less than -1.0" do
lambda { @object.send(@method, -1.0 - Float::EPSILON) }.should raise_error(Math::DomainError)
end
end

View file

@ -0,0 +1,36 @@
describe :process_abort, shared: true do
before :each do
@stderr, $stderr = $stderr, IOStub.new
end
after :each do
$stderr = @stderr
end
it "raises a SystemExit exception" do
lambda { @object.abort }.should raise_error(SystemExit)
end
it "sets the exception message to the given message" do
lambda { @object.abort "message" }.should raise_error { |e| e.message.should == "message" }
end
it "sets the exception status code of 1" do
lambda { @object.abort }.should raise_error { |e| e.status.should == 1 }
end
it "prints the specified message to STDERR" do
lambda { @object.abort "a message" }.should raise_error(SystemExit)
$stderr.should =~ /a message/
end
it "coerces the argument with #to_str" do
str = mock('to_str')
str.should_receive(:to_str).any_number_of_times.and_return("message")
lambda { @object.abort str }.should raise_error(SystemExit, "message")
end
it "raises TypeError when given a non-String object" do
lambda { @object.abort 123 }.should raise_error(TypeError)
end
end

View file

@ -0,0 +1,94 @@
describe :process_exit, shared: true do
it "raises a SystemExit with status 0" do
lambda { @object.exit }.should raise_error(SystemExit) { |e|
e.status.should == 0
}
end
it "raises a SystemExit with the specified status" do
[-2**16, -2**8, -8, -1, 0, 1 , 8, 2**8, 2**16].each do |value|
lambda { @object.exit(value) }.should raise_error(SystemExit) { |e|
e.status.should == value
}
end
end
it "raises a SystemExit with the specified boolean status" do
{ true => 0, false => 1 }.each do |value, status|
lambda { @object.exit(value) }.should raise_error(SystemExit) { |e|
e.status.should == status
}
end
end
it "tries to convert the passed argument to an Integer using #to_int" do
obj = mock('5')
obj.should_receive(:to_int).and_return(5)
lambda { @object.exit(obj) }.should raise_error(SystemExit) { |e|
e.status.should == 5
}
end
it "converts the passed Float argument to an Integer" do
{ -2.2 => -2, -0.1 => 0, 5.5 => 5, 827.999 => 827 }.each do |value, status|
lambda { @object.exit(value) }.should raise_error(SystemExit) { |e|
e.status.should == status
}
end
end
it "raises TypeError if can't convert the argument to an Integer" do
lambda { @object.exit(Object.new) }.should raise_error(TypeError)
lambda { @object.exit('0') }.should raise_error(TypeError)
lambda { @object.exit([0]) }.should raise_error(TypeError)
lambda { @object.exit(nil) }.should raise_error(TypeError)
end
it "raises the SystemExit in the main thread if it reaches the top-level handler of another thread" do
ScratchPad.record []
ready = false
t = Thread.new {
Thread.pass until ready
begin
@object.exit 42
rescue SystemExit => e
ScratchPad << :in_thread
raise e
end
}
begin
ready = true
sleep
rescue SystemExit
ScratchPad << :in_main
end
ScratchPad.recorded.should == [:in_thread, :in_main]
# the thread also keeps the exception as its value
lambda { t.value }.should raise_error(SystemExit)
end
end
describe :process_exit!, shared: true do
it "exits with the given status" do
out = ruby_exe("#{@object}.send(:exit!, 21)", args: '2>&1')
out.should == ""
$?.exitstatus.should == 21
end
it "exits when called from a thread" do
out = ruby_exe("Thread.new { #{@object}.send(:exit!, 21) }.join; sleep", args: '2>&1')
out.should == ""
$?.exitstatus.should == 21
end
it "exits when called from a fiber" do
out = ruby_exe("Fiber.new { #{@object}.send(:exit!, 21) }.resume", args: '2>&1')
out.should == ""
$?.exitstatus.should == 21
end
end

View file

@ -0,0 +1,90 @@
describe :process_fork, shared: true do
platform_is :windows do
it "returns false from #respond_to?" do
# Workaround for Kernel::Method being public and losing the "non-respond_to? magic"
mod = @object.class.name == "KernelSpecs::Method" ? Object.new : @object
mod.respond_to?(:fork).should be_false
mod.respond_to?(:fork, true).should be_false
end
it "raises a NotImplementedError when called" do
lambda { @object.fork }.should raise_error(NotImplementedError)
end
end
platform_is_not :windows do
before :each do
@file = tmp('i_exist')
rm_r @file
end
after :each do
rm_r @file
end
it "returns status zero" do
pid = Process.fork { exit! 0 }
_, result = Process.wait2(pid)
result.exitstatus.should == 0
end
it "returns status zero" do
pid = Process.fork { exit 0 }
_, result = Process.wait2(pid)
result.exitstatus.should == 0
end
it "returns status zero" do
pid = Process.fork {}
_, result = Process.wait2(pid)
result.exitstatus.should == 0
end
it "returns status non-zero" do
pid = Process.fork { exit! 42 }
_, result = Process.wait2(pid)
result.exitstatus.should == 42
end
it "returns status non-zero" do
pid = Process.fork { exit 42 }
_, result = Process.wait2(pid)
result.exitstatus.should == 42
end
it "returns nil for the child process" do
child_id = @object.fork
if child_id == nil
touch(@file) { |f| f.write 'rubinius' }
Process.exit!
else
Process.waitpid(child_id)
end
File.exist?(@file).should == true
end
it "runs a block in a child process" do
pid = @object.fork {
touch(@file) { |f| f.write 'rubinius' }
Process.exit!
}
Process.waitpid(pid)
File.exist?(@file).should == true
end
it "marks threads from the parent as killed" do
t = Thread.new { sleep }
pid = @object.fork {
touch(@file) do |f|
f.write Thread.current.alive?
f.write t.alive?
end
Process.exit!
}
Process.waitpid(pid)
t.kill
t.join
File.read(@file).should == "truefalse"
end
end
end

View file

@ -0,0 +1,103 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../../../fixtures/rational', __FILE__)
describe :kernel_Rational, shared: true do
describe "passed Integer" do
# Guard against the Mathn library
conflicts_with :Prime do
it "returns a new Rational number with 1 as the denominator" do
Rational(1).should eql(Rational(1, 1))
Rational(-3).should eql(Rational(-3, 1))
Rational(bignum_value).should eql(Rational(bignum_value, 1))
end
end
end
describe "passed two integers" do
it "returns a new Rational number" do
rat = Rational(1, 2)
rat.numerator.should == 1
rat.denominator.should == 2
rat.should be_an_instance_of(Rational)
rat = Rational(-3, -5)
rat.numerator.should == 3
rat.denominator.should == 5
rat.should be_an_instance_of(Rational)
rat = Rational(bignum_value, 3)
rat.numerator.should == bignum_value
rat.denominator.should == 3
rat.should be_an_instance_of(Rational)
end
it "reduces the Rational" do
rat = Rational(2, 4)
rat.numerator.should == 1
rat.denominator.should == 2
rat = Rational(3, 9)
rat.numerator.should == 1
rat.denominator.should == 3
end
end
describe "when passed a String" do
it "converts the String to a Rational using the same method as String#to_r" do
r = Rational(13, 25)
s_r = ".52".to_r
r_s = Rational(".52")
r_s.should == r
r_s.should == s_r
end
it "scales the Rational value of the first argument by the Rational value of the second" do
Rational(".52", ".6").should == Rational(13, 15)
Rational(".52", "1.6").should == Rational(13, 40)
end
it "does not use the same method as Float#to_r" do
r = Rational(3, 5)
f_r = 0.6.to_r
r_s = Rational("0.6")
r_s.should == r
r_s.should_not == f_r
end
describe "when passed a Numeric" do
it "calls #to_r to convert the first argument to a Rational" do
num = RationalSpecs::SubNumeric.new(2)
Rational(num).should == Rational(2)
end
end
describe "when passed a Complex" do
it "returns a Rational from the real part if the imaginary part is 0" do
Rational(Complex(1, 0)).should == Rational(1)
end
it "raises a RangeError if the imaginary part is not 0" do
lambda { Rational(Complex(1, 2)) }.should raise_error(RangeError)
end
end
it "raises a TypeError if the first argument is nil" do
lambda { Rational(nil) }.should raise_error(TypeError)
end
it "raises a TypeError if the second argument is nil" do
lambda { Rational(1, nil) }.should raise_error(TypeError)
end
it "raises a TypeError if the first argument is a Symbol" do
lambda { Rational(:sym) }.should raise_error(TypeError)
end
it "raises a TypeError if the second argument is a Symbol" do
lambda { Rational(1, :sym) }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,11 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_abs, shared: true do
it "returns self's absolute value" do
Rational(3, 4).send(@method).should == Rational(3, 4)
Rational(-3, 4).send(@method).should == Rational(3, 4)
Rational(3, -4).send(@method).should == Rational(3, 4)
Rational(bignum_value, -bignum_value).send(@method).should == Rational(bignum_value, bignum_value)
end
end

View file

@ -0,0 +1,45 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_ceil, shared: true do
before do
@rational = Rational(2200, 7)
end
describe "with no arguments (precision = 0)" do
it "returns an Integer" do
@rational.ceil.should be_kind_of(Integer)
end
it "returns the truncated value toward positive infinity" do
@rational.ceil.should == 315
Rational(1, 2).ceil.should == 1
Rational(-1, 2).ceil.should == 0
end
end
describe "with a precision < 0" do
it "returns an Integer" do
@rational.ceil(-2).should be_kind_of(Integer)
@rational.ceil(-1).should be_kind_of(Integer)
end
it "moves the truncation point n decimal places left" do
@rational.ceil(-3).should == 1000
@rational.ceil(-2).should == 400
@rational.ceil(-1).should == 320
end
end
describe "with precision > 0" do
it "returns a Rational" do
@rational.ceil(1).should be_kind_of(Rational)
@rational.ceil(2).should be_kind_of(Rational)
end
it "moves the truncation point n decimal places right" do
@rational.ceil(1).should == Rational(3143, 10)
@rational.ceil(2).should == Rational(31429, 100)
@rational.ceil(3).should == Rational(157143, 500)
end
end
end

View file

@ -0,0 +1,21 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_coerce, shared: true do
it "returns the passed argument, self as Float, when given a Float" do
result = Rational(3, 4).coerce(1.0)
result.should == [1.0, 0.75]
result.first.is_a?(Float).should be_true
result.last.is_a?(Float).should be_true
end
it "returns the passed argument, self as Rational, when given an Integer" do
result = Rational(3, 4).coerce(10)
result.should == [Rational(10, 1), Rational(3, 4)]
result.first.is_a?(Rational).should be_true
result.last.is_a?(Rational).should be_true
end
it "returns [argument, self] when given a Rational" do
Rational(3, 7).coerce(Rational(9, 2)).should == [Rational(9, 2), Rational(3, 7)]
end
end

View file

@ -0,0 +1,85 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_cmp_rat, shared: true do
it "returns 1 when self is greater than the passed argument" do
(Rational(4, 4) <=> Rational(3, 4)).should equal(1)
(Rational(-3, 4) <=> Rational(-4, 4)).should equal(1)
end
it "returns 0 when self is equal to the passed argument" do
(Rational(4, 4) <=> Rational(4, 4)).should equal(0)
(Rational(-3, 4) <=> Rational(-3, 4)).should equal(0)
end
it "returns -1 when self is less than the passed argument" do
(Rational(3, 4) <=> Rational(4, 4)).should equal(-1)
(Rational(-4, 4) <=> Rational(-3, 4)).should equal(-1)
end
end
describe :rational_cmp_int, shared: true do
it "returns 1 when self is greater than the passed argument" do
(Rational(4, 4) <=> 0).should equal(1)
(Rational(4, 4) <=> -10).should equal(1)
(Rational(-3, 4) <=> -1).should equal(1)
end
it "returns 0 when self is equal to the passed argument" do
(Rational(4, 4) <=> 1).should equal(0)
(Rational(-8, 4) <=> -2).should equal(0)
end
it "returns -1 when self is less than the passed argument" do
(Rational(3, 4) <=> 1).should equal(-1)
(Rational(-4, 4) <=> 0).should equal(-1)
end
end
describe :rational_cmp_float, shared: true do
it "returns 1 when self is greater than the passed argument" do
(Rational(4, 4) <=> 0.5).should equal(1)
(Rational(4, 4) <=> -1.5).should equal(1)
(Rational(-3, 4) <=> -0.8).should equal(1)
end
it "returns 0 when self is equal to the passed argument" do
(Rational(4, 4) <=> 1.0).should equal(0)
(Rational(-6, 4) <=> -1.5).should equal(0)
end
it "returns -1 when self is less than the passed argument" do
(Rational(3, 4) <=> 1.2).should equal(-1)
(Rational(-4, 4) <=> 0.5).should equal(-1)
end
end
describe :rational_cmp_coerce, shared: true do
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational <=> obj
end
it "calls #<=> on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:<=>).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
(rational <=> obj).should == :result
end
end
describe :rational_cmp_other, shared: true do
it "returns nil" do
(Rational <=> mock("Object")).should be_nil
end
end

View file

@ -0,0 +1,14 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_denominator, shared: true do
it "returns the denominator" do
Rational(3, 4).denominator.should equal(4)
Rational(3, -4).denominator.should equal(4)
Rational(1, bignum_value).denominator.should == bignum_value
end
it "returns 1 if no denominator was given" do
Rational(80).denominator.should == 1
end
end

View file

@ -0,0 +1,54 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_div_rat, shared: true do
it "performs integer division and returns the result" do
Rational(2, 3).div(Rational(2, 3)).should == 1
Rational(-2, 9).div(Rational(-9, 2)).should == 0
end
it "raises a ZeroDivisionError when the argument has a numerator of 0" do
lambda { Rational(3, 4).div(Rational(0, 3)) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the argument has a numerator of 0.0" do
lambda { Rational(3, 4).div(Rational(0.0, 3)) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_div_float, shared: true do
it "performs integer division and returns the result" do
Rational(2, 3).div(30.333).should == 0
Rational(2, 9).div(Rational(-8.6)).should == -1
Rational(3.12).div(0.5).should == 6
end
it "raises a ZeroDivisionError when the argument is 0.0" do
lambda { Rational(3, 4).div(0.0) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_div_int, shared: true do
it "performs integer division and returns the result" do
Rational(2, 1).div(1).should == 2
Rational(25, 5).div(-50).should == -1
end
it "raises a ZeroDivisionError when the argument is 0" do
lambda { Rational(3, 4).div(0) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_div, shared: true do
it "returns an Integer" do
Rational(229, 21).div(82).should be_kind_of(Integer)
end
it "raises an ArgumentError if passed more than one argument" do
lambda { Rational(3, 4).div(2,3) }.should raise_error(ArgumentError)
end
# See http://redmine.ruby-lang.org/issues/show/1648
it "raises a TypeError if passed a non-numeric argument" do
lambda { Rational(3, 4).div([]) }.should raise_error(TypeError)
end
end

View file

@ -0,0 +1,71 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_divide_rat, shared: true do
it "returns self divided by other as a Rational" do
Rational(3, 4).send(@method, Rational(3, 4)).should eql(Rational(1, 1))
Rational(2, 4).send(@method, Rational(1, 4)).should eql(Rational(2, 1))
Rational(2, 4).send(@method, 2).should == Rational(1, 4)
Rational(6, 7).send(@method, -2).should == Rational(-3, 7)
end
it "raises a ZeroDivisionError when passed a Rational with a numerator of 0" do
lambda { Rational(3, 4).send(@method, Rational(0, 1)) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_divide_int, shared: true do
it "returns self divided by other as a Rational" do
Rational(3, 4).send(@method, 2).should eql(Rational(3, 8))
Rational(2, 4).send(@method, 2).should eql(Rational(1, 4))
Rational(6, 7).send(@method, -2).should eql(Rational(-3, 7))
end
it "raises a ZeroDivisionError when passed 0" do
lambda { Rational(3, 4).send(@method, 0) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_divide_float, shared: true do
it "returns self divided by other as a Float" do
Rational(3, 4).send(@method, 0.75).should eql(1.0)
Rational(3, 4).send(@method, 0.25).should eql(3.0)
Rational(3, 4).send(@method, 0.3).should eql(2.5)
Rational(-3, 4).send(@method, 0.3).should eql(-2.5)
Rational(3, -4).send(@method, 0.3).should eql(-2.5)
Rational(3, 4).send(@method, -0.3).should eql(-2.5)
end
it "returns infinity when passed 0" do
Rational(3, 4).send(@method, 0.0).infinite?.should eql(1)
Rational(-3, -4).send(@method, 0.0).infinite?.should eql(1)
Rational(-3, 4).send(@method, 0.0).infinite?.should eql(-1)
Rational(3, -4).send(@method, 0.0).infinite?.should eql(-1)
end
end
describe :rational_divide, shared: true do
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational.send(@method, obj)
end
it "calls #/ on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:/).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
rational.send(@method, obj).should == :result
end
end

View file

@ -0,0 +1,42 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_divmod_rat, shared: true do
it "returns the quotient as Integer and the remainder as Rational" do
Rational(7, 4).divmod(Rational(1, 2)).should eql([3, Rational(1, 4)])
Rational(7, 4).divmod(Rational(-1, 2)).should eql([-4, Rational(-1, 4)])
Rational(0, 4).divmod(Rational(4, 3)).should eql([0, Rational(0, 1)])
Rational(bignum_value, 4).divmod(Rational(4, 3)).should eql([1729382256910270464, Rational(0, 1)])
end
it "raises a ZeroDivisonError when passed a Rational with a numerator of 0" do
lambda { Rational(7, 4).divmod(Rational(0, 3)) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_divmod_int, shared: true do
it "returns the quotient as Integer and the remainder as Rational" do
Rational(7, 4).divmod(2).should eql([0, Rational(7, 4)])
Rational(7, 4).divmod(-2).should eql([-1, Rational(-1, 4)])
Rational(bignum_value, 4).divmod(3).should == [768614336404564650, Rational(2, 1)]
end
it "raises a ZeroDivisionError when passed 0" do
lambda { Rational(7, 4).divmod(0) }.should raise_error(ZeroDivisionError)
end
end
describe :rational_divmod_float, shared: true do
it "returns the quotient as Integer and the remainder as Float" do
Rational(7, 4).divmod(0.5).should eql([3, 0.25])
end
it "returns the quotient as Integer and the remainder as Float" do
Rational(7, 4).divmod(-0.5).should eql([-4, -0.25])
end
it "raises a ZeroDivisionError when passed 0" do
lambda { Rational(7, 4).divmod(0.0) }.should raise_error(ZeroDivisionError)
end
end

View file

@ -0,0 +1,39 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_equal_value_rat, shared: true do
it "returns true if self has the same numerator and denominator as the passed argument" do
(Rational(3, 4) == Rational(3, 4)).should be_true
(Rational(-3, -4) == Rational(3, 4)).should be_true
(Rational(-4, 5) == Rational(4, -5)).should be_true
(Rational(bignum_value, 3) == Rational(bignum_value, 3)).should be_true
(Rational(-bignum_value, 3) == Rational(bignum_value, -3)).should be_true
end
end
describe :rational_equal_value_int, shared: true do
it "returns true if self has the passed argument as numerator and a denominator of 1" do
# Rational(x, y) reduces x and y automatically
(Rational(4, 2) == 2).should be_true
(Rational(-4, 2) == -2).should be_true
(Rational(4, -2) == -2).should be_true
end
end
describe :rational_equal_value_float, shared: true do
it "converts self to a Float and compares it with the passed argument" do
(Rational(3, 4) == 0.75).should be_true
(Rational(4, 2) == 2.0).should be_true
(Rational(-4, 2) == -2.0).should be_true
(Rational(4, -2) == -2.0).should be_true
end
end
describe :rational_equal_value, shared: true do
it "returns the result of calling #== with self on the passed argument" do
obj = mock("Object")
obj.should_receive(:==).and_return(:result)
(Rational(3, 4) == obj).should_not be_false
end
end

View file

@ -0,0 +1,176 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_exponent, shared: true do
describe "when passed Rational" do
conflicts_with :Prime do
it "returns Rational(1) if the exponent is Rational(0)" do
(Rational(0) ** Rational(0)).should eql(Rational(1))
(Rational(1) ** Rational(0)).should eql(Rational(1))
(Rational(3, 4) ** Rational(0)).should eql(Rational(1))
(Rational(-1) ** Rational(0)).should eql(Rational(1))
(Rational(-3, 4) ** Rational(0)).should eql(Rational(1))
(Rational(bignum_value) ** Rational(0)).should eql(Rational(1))
(Rational(-bignum_value) ** Rational(0)).should eql(Rational(1))
end
it "returns self raised to the argument as a Rational if the exponent's denominator is 1" do
(Rational(3, 4) ** Rational(1, 1)).should eql(Rational(3, 4))
(Rational(3, 4) ** Rational(2, 1)).should eql(Rational(9, 16))
(Rational(3, 4) ** Rational(-1, 1)).should eql(Rational(4, 3))
(Rational(3, 4) ** Rational(-2, 1)).should eql(Rational(16, 9))
end
it "returns self raised to the argument as a Float if the exponent's denominator is not 1" do
(Rational(3, 4) ** Rational(4, 3)).should be_close(0.681420222312052, TOLERANCE)
(Rational(3, 4) ** Rational(-4, 3)).should be_close(1.46752322173095, TOLERANCE)
(Rational(3, 4) ** Rational(4, -3)).should be_close(1.46752322173095, TOLERANCE)
end
it "returns a complex number when self is negative and the passed argument is not 0" do
(Rational(-3, 4) ** Rational(-4, 3)).should be_close(Complex(-0.7337616108654732, 1.2709123906625817), TOLERANCE)
end
end
end
describe "when passed Integer" do
it "returns the Rational value of self raised to the passed argument" do
(Rational(3, 4) ** 4).should == Rational(81, 256)
(Rational(3, 4) ** -4).should == Rational(256, 81)
(Rational(-3, 4) ** -4).should == Rational(256, 81)
(Rational(3, -4) ** -4).should == Rational(256, 81)
(Rational(bignum_value, 4) ** 4).should == Rational(28269553036454149273332760011886696253239742350009903329945699220681916416, 1)
(Rational(3, bignum_value) ** -4).should == Rational(7237005577332262213973186563042994240829374041602535252466099000494570602496, 81)
(Rational(-bignum_value, 4) ** -4).should == Rational(1, 28269553036454149273332760011886696253239742350009903329945699220681916416)
(Rational(3, -bignum_value) ** -4).should == Rational(7237005577332262213973186563042994240829374041602535252466099000494570602496, 81)
end
conflicts_with :Prime do
it "returns Rational(1, 1) when the passed argument is 0" do
(Rational(3, 4) ** 0).should eql(Rational(1, 1))
(Rational(-3, 4) ** 0).should eql(Rational(1, 1))
(Rational(3, -4) ** 0).should eql(Rational(1, 1))
(Rational(bignum_value, 4) ** 0).should eql(Rational(1, 1))
(Rational(3, -bignum_value) ** 0).should eql(Rational(1, 1))
end
end
end
describe "when passed Bignum" do
# #5713
it "returns Rational(0) when self is Rational(0) and the exponent is positive" do
(Rational(0) ** bignum_value).should eql(Rational(0))
end
it "raises ZeroDivisionError when self is Rational(0) and the exponent is negative" do
lambda { Rational(0) ** -bignum_value }.should raise_error(ZeroDivisionError)
end
it "returns Rational(1) when self is Rational(1)" do
(Rational(1) ** bignum_value).should eql(Rational(1))
(Rational(1) ** -bignum_value).should eql(Rational(1))
end
it "returns Rational(1) when self is Rational(-1) and the exponent is positive and even" do
(Rational(-1) ** bignum_value(0)).should eql(Rational(1))
(Rational(-1) ** bignum_value(2)).should eql(Rational(1))
end
it "returns Rational(-1) when self is Rational(-1) and the exponent is positive and odd" do
(Rational(-1) ** bignum_value(1)).should eql(Rational(-1))
(Rational(-1) ** bignum_value(3)).should eql(Rational(-1))
end
it "returns positive Infinity when self is > 1" do
(Rational(2) ** bignum_value).infinite?.should == 1
(Rational(fixnum_max) ** bignum_value).infinite?.should == 1
end
it "returns 0.0 when self is > 1 and the exponent is negative" do
(Rational(2) ** -bignum_value).should eql(0.0)
(Rational(fixnum_max) ** -bignum_value).should eql(0.0)
end
# Fails on linux due to pow() bugs in glibc: http://sources.redhat.com/bugzilla/show_bug.cgi?id=3866
platform_is_not :linux do
it "returns positive Infinity when self < -1" do
(Rational(-2) ** bignum_value).infinite?.should == 1
(Rational(-2) ** (bignum_value + 1)).infinite?.should == 1
(Rational(fixnum_min) ** bignum_value).infinite?.should == 1
end
it "returns 0.0 when self is < -1 and the exponent is negative" do
(Rational(-2) ** -bignum_value).should eql(0.0)
(Rational(fixnum_min) ** -bignum_value).should eql(0.0)
end
end
end
describe "when passed Float" do
it "returns self converted to Float and raised to the passed argument" do
(Rational(3, 1) ** 3.0).should eql(27.0)
(Rational(3, 1) ** 1.5).should be_close(5.19615242270663, TOLERANCE)
(Rational(3, 1) ** -1.5).should be_close(0.192450089729875, TOLERANCE)
end
it "returns a complex number if self is negative and the passed argument is not 0" do
(Rational(-3, 2) ** 1.5).should be_close(Complex(-3.374618290464398e-16, -1.8371173070873836), TOLERANCE)
(Rational(3, -2) ** 1.5).should be_close(Complex(-3.374618290464398e-16, -1.8371173070873836), TOLERANCE)
(Rational(3, -2) ** -1.5).should be_close(Complex(-9.998869008783402e-17, 0.5443310539518174), TOLERANCE)
end
it "returns Complex(1.0) when the passed argument is 0.0" do
(Rational(3, 4) ** 0.0).should == Complex(1.0)
(Rational(-3, 4) ** 0.0).should == Complex(1.0)
(Rational(-3, 4) ** 0.0).should == Complex(1.0)
end
end
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational ** obj
end
it "calls #** on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:**).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
(rational ** obj).should == :result
end
it "raises ZeroDivisionError for Rational(0, 1) passed a negative Integer" do
[-1, -4, -9999].each do |exponent|
lambda { Rational(0, 1) ** exponent }.should raise_error(ZeroDivisionError, "divided by 0")
end
end
it "raises ZeroDivisionError for Rational(0, 1) passed a negative Rational with denominator 1" do
[Rational(-1, 1), Rational(-3, 1)].each do |exponent|
lambda { Rational(0, 1) ** exponent }.should raise_error(ZeroDivisionError, "divided by 0")
end
end
# #7513
it "raises ZeroDivisionError for Rational(0, 1) passed a negative Rational" do
lambda { Rational(0, 1) ** Rational(-3, 2) }.should raise_error(ZeroDivisionError, "divided by 0")
end
platform_is_not :solaris do # See https://github.com/ruby/spec/issues/134
it "returns Infinity for Rational(0, 1) passed a negative Float" do
[-1.0, -3.0, -3.14].each do |exponent|
(Rational(0, 1) ** exponent).infinite?.should == 1
end
end
end
end

View file

@ -0,0 +1,5 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_fdiv, shared: true do
it "needs to be reviewed for spec completeness"
end

View file

@ -0,0 +1,45 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_floor, shared: true do
before do
@rational = Rational(2200, 7)
end
describe "with no arguments (precision = 0)" do
it "returns an integer" do
@rational.floor.should be_kind_of(Integer)
end
it "returns the truncated value toward negative infinity" do
@rational.floor.should == 314
Rational(1, 2).floor.should == 0
Rational(-1, 2).floor.should == -1
end
end
describe "with a precision < 0" do
it "returns an integer" do
@rational.floor(-2).should be_kind_of(Integer)
@rational.floor(-1).should be_kind_of(Integer)
end
it "moves the truncation point n decimal places left" do
@rational.floor(-3).should == 0
@rational.floor(-2).should == 300
@rational.floor(-1).should == 310
end
end
describe "with a precision > 0" do
it "returns a Rational" do
@rational.floor(1).should be_kind_of(Rational)
@rational.floor(2).should be_kind_of(Rational)
end
it "moves the truncation point n decimal places right" do
@rational.floor(1).should == Rational(1571, 5)
@rational.floor(2).should == Rational(7857, 25)
@rational.floor(3).should == Rational(62857, 200)
end
end
end

View file

@ -0,0 +1,9 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_hash, shared: true do
# BUG: Rational(2, 3).hash == Rational(3, 2).hash
it "is static" do
Rational(2, 3).hash.should == Rational(2, 3).hash
Rational(2, 4).hash.should_not == Rational(2, 3).hash
end
end

View file

@ -0,0 +1,12 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_inspect, shared: true do
conflicts_with :Prime do
it "returns a string representation of self" do
Rational(3, 4).inspect.should == "(3/4)"
Rational(-5, 8).inspect.should == "(-5/8)"
Rational(-1, -2).inspect.should == "(1/2)"
Rational(bignum_value, 1).inspect.should == "(#{bignum_value}/1)"
end
end
end

View file

@ -0,0 +1,5 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_marshal_dump, shared: true do
it "needs to be reviewed for spec completeness"
end

View file

@ -0,0 +1,5 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_marshal_load, shared: true do
it "needs to be reviewed for spec completeness"
end

View file

@ -0,0 +1,48 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_minus_rat, shared: true do
it "returns the result of substracting other from self as a Rational" do
(Rational(3, 4) - Rational(0, 1)).should eql(Rational(3, 4))
(Rational(3, 4) - Rational(1, 4)).should eql(Rational(1, 2))
(Rational(3, 4) - Rational(2, 1)).should eql(Rational(-5, 4))
end
end
describe :rational_minus_int, shared: true do
it "returns the result of substracting other from self as a Rational" do
(Rational(3, 4) - 1).should eql(Rational(-1, 4))
(Rational(3, 4) - 2).should eql(Rational(-5, 4))
end
end
describe :rational_minus_float, shared: true do
it "returns the result of substracting other from self as a Float" do
(Rational(3, 4) - 0.2).should eql(0.55)
(Rational(3, 4) - 2.5).should eql(-1.75)
end
end
describe :rational_minus, shared: true do
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational - obj
end
it "calls #- on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:-).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
(rational - obj).should == :result
end
end

View file

@ -0,0 +1,43 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_modulo, shared: true do
it "returns the remainder when this value is divided by other" do
Rational(2, 3).send(@method, Rational(2, 3)).should == Rational(0, 1)
Rational(4, 3).send(@method, Rational(2, 3)).should == Rational(0, 1)
Rational(2, -3).send(@method, Rational(-2, 3)).should == Rational(0, 1)
Rational(0, -1).send(@method, -1).should == Rational(0, 1)
Rational(7, 4).send(@method, Rational(1, 2)).should == Rational(1, 4)
Rational(7, 4).send(@method, 1).should == Rational(3, 4)
Rational(7, 4).send(@method, Rational(1, 7)).should == Rational(1, 28)
Rational(3, 4).send(@method, -1).should == Rational(-1, 4)
Rational(1, -5).send(@method, -1).should == Rational(-1, 5)
end
it "returns a Float value when the argument is Float" do
Rational(7, 4).send(@method, 1.0).should be_kind_of(Float)
Rational(7, 4).send(@method, 1.0).should == 0.75
Rational(7, 4).send(@method, 0.26).should be_close(0.19, 0.0001)
end
it "raises ZeroDivisionError on zero denominator" do
lambda {
Rational(3, 5).send(@method, Rational(0, 1))
}.should raise_error(ZeroDivisionError)
lambda {
Rational(0, 1).send(@method, Rational(0, 1))
}.should raise_error(ZeroDivisionError)
lambda {
Rational(3, 5).send(@method, 0)
}.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the argument is 0.0" do
lambda {
Rational(3, 5).send(@method, 0.0)
}.should raise_error(ZeroDivisionError)
end
end

View file

@ -0,0 +1,62 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_multiply_rat, shared: true do
it "returns self divided by other as a Rational" do
(Rational(3, 4) * Rational(3, 4)).should eql(Rational(9, 16))
(Rational(2, 4) * Rational(1, 4)).should eql(Rational(1, 8))
(Rational(3, 4) * Rational(0, 1)).should eql(Rational(0, 4))
end
end
describe :rational_multiply_int, shared: true do
it "returns self divided by other as a Rational" do
(Rational(3, 4) * 2).should eql(Rational(3, 2))
(Rational(2, 4) * 2).should eql(Rational(1, 1))
(Rational(6, 7) * -2).should eql(Rational(-12, 7))
(Rational(3, 4) * 0).should eql(Rational(0, 4))
end
end
describe :rational_multiply_float, shared: true do
it "returns self divided by other as a Float" do
(Rational(3, 4) * 0.75).should eql(0.5625)
(Rational(3, 4) * 0.25).should eql(0.1875)
(Rational(3, 4) * 0.3).should be_close(0.225, TOLERANCE)
(Rational(-3, 4) * 0.3).should be_close(-0.225, TOLERANCE)
(Rational(3, -4) * 0.3).should be_close(-0.225, TOLERANCE)
(Rational(3, 4) * -0.3).should be_close(-0.225, TOLERANCE)
(Rational(3, 4) * 0.0).should eql(0.0)
(Rational(-3, -4) * 0.0).should eql(0.0)
(Rational(-3, 4) * 0.0).should eql(0.0)
(Rational(3, -4) * 0.0).should eql(0.0)
end
end
describe :rational_multiply, shared: true do
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational * obj
end
it "calls #* on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:*).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
(rational * obj).should == :result
end
end

View file

@ -0,0 +1,10 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_numerator, shared: true do
it "returns the numerator" do
Rational(3, 4).numerator.should equal(3)
Rational(3, -4).numerator.should equal(-3)
Rational(bignum_value, 1).numerator.should == bignum_value
end
end

View file

@ -0,0 +1,48 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_plus_rat, shared: true do
it "returns the result of substracting other from self as a Rational" do
(Rational(3, 4) + Rational(0, 1)).should eql(Rational(3, 4))
(Rational(3, 4) + Rational(1, 4)).should eql(Rational(1, 1))
(Rational(3, 4) + Rational(2, 1)).should eql(Rational(11, 4))
end
end
describe :rational_plus_int, shared: true do
it "returns the result of substracting other from self as a Rational" do
(Rational(3, 4) + 1).should eql(Rational(7, 4))
(Rational(3, 4) + 2).should eql(Rational(11, 4))
end
end
describe :rational_plus_float, shared: true do
it "returns the result of substracting other from self as a Float" do
(Rational(3, 4) + 0.2).should eql(0.95)
(Rational(3, 4) + 2.5).should eql(3.25)
end
end
describe :rational_plus, shared: true do
it "calls #coerce on the passed argument with self" do
rational = Rational(3, 4)
obj = mock("Object")
obj.should_receive(:coerce).with(rational).and_return([1, 2])
rational + obj
end
it "calls #+ on the coerced Rational with the coerced Object" do
rational = Rational(3, 4)
coerced_rational = mock("Coerced Rational")
coerced_rational.should_receive(:+).and_return(:result)
coerced_obj = mock("Coerced Object")
obj = mock("Object")
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
(rational + obj).should == :result
end
end

View file

@ -0,0 +1,5 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_quo, shared: true do
it "needs to be reviewed for spec completeness"
end

View file

@ -0,0 +1,5 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_remainder, shared: true do
it "needs to be reviewed for spec completeness"
end

View file

@ -0,0 +1,71 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_round, shared: true do
before do
@rational = Rational(2200, 7)
end
describe "with no arguments (precision = 0)" do
it "returns an integer" do
@rational.round.should be_kind_of(Integer)
Rational(0, 1).round(0).should be_kind_of(Integer)
Rational(124, 1).round(0).should be_kind_of(Integer)
end
it "returns the truncated value toward the nearest integer" do
@rational.round.should == 314
Rational(0, 1).round(0).should == 0
Rational(2, 1).round(0).should == 2
end
it "returns the rounded value toward the nearest integer" do
Rational(1, 2).round.should == 1
Rational(-1, 2).round.should == -1
Rational(3, 2).round.should == 2
Rational(-3, 2).round.should == -2
Rational(5, 2).round.should == 3
Rational(-5, 2).round.should == -3
end
end
describe "with a precision < 0" do
it "returns an integer" do
@rational.round(-2).should be_kind_of(Integer)
@rational.round(-1).should be_kind_of(Integer)
Rational(0, 1).round(-1).should be_kind_of(Integer)
Rational(2, 1).round(-1).should be_kind_of(Integer)
end
it "moves the truncation point n decimal places left" do
@rational.round(-3).should == 0
@rational.round(-2).should == 300
@rational.round(-1).should == 310
end
end
describe "with a precision > 0" do
it "returns a Rational" do
@rational.round(1).should be_kind_of(Rational)
@rational.round(2).should be_kind_of(Rational)
Rational(0, 1).round(1).should be_kind_of(Rational)
Rational(2, 1).round(1).should be_kind_of(Rational)
end
it "moves the truncation point n decimal places right" do
@rational.round(1).should == Rational(3143, 10)
@rational.round(2).should == Rational(31429, 100)
@rational.round(3).should == Rational(157143, 500)
Rational(0, 1).round(1).should == Rational(0, 1)
Rational(2, 1).round(1).should == Rational(2, 1)
end
it "doesn't alter the value if the precision is too great" do
Rational(3, 2).round(10).should == Rational(3, 2).round(20)
end
# #6605
it "doesn't fail when rounding to an absurdly large positive precision" do
Rational(3, 2).round(2_097_171).should == Rational(3, 2)
end
end
end

View file

@ -0,0 +1,10 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_to_f, shared: true do
it "returns self converted to a Float" do
Rational(3, 4).to_f.should eql(0.75)
Rational(3, -4).to_f.should eql(-0.75)
Rational(-1, 4).to_f.should eql(-0.25)
Rational(-1, -4).to_f.should eql(0.25)
end
end

View file

@ -0,0 +1,12 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_to_i, shared: true do
it "converts self to an Integer by truncation" do
Rational(7, 4).to_i.should eql(1)
Rational(11, 4).to_i.should eql(2)
end
it "converts self to an Integer by truncation" do
Rational(-7, 4).to_i.should eql(-1)
end
end

View file

@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_to_r, shared: true do
conflicts_with :Prime do
it "returns self" do
a = Rational(3, 4)
a.to_r.should equal(a)
a = Rational(bignum_value, 4)
a.to_r.should equal(a)
end
end
end

View file

@ -0,0 +1,11 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe :rational_to_s, shared: true do
it "returns a string representation of self" do
Rational(1, 1).to_s.should == "1/1"
Rational(2, 1).to_s.should == "2/1"
Rational(1, 2).to_s.should == "1/2"
Rational(-1, 3).to_s.should == "-1/3"
Rational(1, -3).to_s.should == "-1/3"
end
end

Some files were not shown because too many files have changed in this diff Show more