diff options
Diffstat (limited to 'spec/ruby/shared')
109 files changed, 1579 insertions, 935 deletions
diff --git a/spec/ruby/shared/basicobject/method_missing.rb b/spec/ruby/shared/basicobject/method_missing.rb index 4871603dce..97ece14c03 100644 --- a/spec/ruby/shared/basicobject/method_missing.rb +++ b/spec/ruby/shared/basicobject/method_missing.rb @@ -1,5 +1,5 @@ -require_relative '../../spec_helper' -require_relative '../../fixtures/basicobject/method_missing' +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 @@ -24,15 +24,15 @@ end describe :method_missing_module, shared: true do describe "for a Module" do it "raises a NoMethodError when an undefined method is called" do - -> { @object.no_such_method }.should raise_error(NoMethodError) + lambda { @object.no_such_method }.should raise_error(NoMethodError) end it "raises a NoMethodError when a protected method is called" do - -> { @object.method_protected }.should raise_error(NoMethodError) + lambda { @object.method_protected }.should raise_error(NoMethodError) end it "raises a NoMethodError when a private method is called" do - -> { @object.method_private }.should raise_error(NoMethodError) + lambda { @object.method_private }.should raise_error(NoMethodError) end end end @@ -60,15 +60,15 @@ end describe :method_missing_class, shared: true do describe "for a Class" do it "raises a NoMethodError when an undefined method is called" do - -> { @object.no_such_method }.should raise_error(NoMethodError) + lambda { @object.no_such_method }.should raise_error(NoMethodError) end it "raises a NoMethodError when a protected method is called" do - -> { @object.method_protected }.should raise_error(NoMethodError) + lambda { @object.method_protected }.should raise_error(NoMethodError) end it "raises a NoMethodError when a private method is called" do - -> { @object.method_private }.should raise_error(NoMethodError) + lambda { @object.method_private }.should raise_error(NoMethodError) end end end @@ -100,24 +100,26 @@ end describe :method_missing_instance, shared: true do describe "for an instance" do it "raises a NoMethodError when an undefined method is called" do - -> { @object.new.no_such_method }.should raise_error(NoMethodError) + lambda { @object.new.no_such_method }.should raise_error(NoMethodError) end it "raises a NoMethodError when a protected method is called" do - -> { @object.new.method_protected }.should raise_error(NoMethodError) + lambda { @object.new.method_protected }.should raise_error(NoMethodError) end it "raises a NoMethodError when a private method is called" do - -> { @object.new.method_private }.should raise_error(NoMethodError) + lambda { @object.new.method_private }.should raise_error(NoMethodError) end - it 'sets the receiver of the raised NoMethodError' do - obj = @object.new + 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 + begin + obj.method_private + rescue NoMethodError => error + (error.receiver == obj).should == true + end end end end diff --git a/spec/ruby/shared/basicobject/send.rb b/spec/ruby/shared/basicobject/send.rb index 625aaa2917..f8c63c5522 100644 --- a/spec/ruby/shared/basicobject/send.rb +++ b/spec/ruby/shared/basicobject/send.rb @@ -29,20 +29,13 @@ describe :basicobject_send, shared: true do SendSpecs::Foo.send(@method, :bar).should == 'done' end - it "raises a TypeError if the method name is not a string or symbol" do - -> { SendSpecs.send(@method, nil) }.should raise_error(TypeError, /not a symbol nor a string/) - -> { SendSpecs.send(@method, 42) }.should raise_error(TypeError, /not a symbol nor a string/) - -> { SendSpecs.send(@method, 3.14) }.should raise_error(TypeError, /not a symbol nor a string/) - -> { SendSpecs.send(@method, true) }.should raise_error(TypeError, /not a symbol nor a string/) - end - it "raises a NameError if the corresponding method can't be found" do class SendSpecs::Foo def bar 'done' end end - -> { SendSpecs::Foo.new.send(@method, :syegsywhwua) }.should raise_error(NameError) + 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 @@ -51,12 +44,12 @@ describe :basicobject_send, shared: true do 'done' end end - -> { SendSpecs::Foo.send(@method, :baz) }.should raise_error(NameError) + 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 - -> { SendSpecs::Foo.new.send @method }.should raise_error(ArgumentError) + lambda { SendSpecs::Foo.new.send @method }.should raise_error(ArgumentError) end it "raises an ArgumentError if called with more arguments than available parameters" do @@ -64,7 +57,7 @@ describe :basicobject_send, shared: true do def bar; end end - -> { SendSpecs::Foo.new.send(@method, :bar, :arg) }.should raise_error(ArgumentError) + 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 @@ -72,7 +65,7 @@ describe :basicobject_send, shared: true do def foo(arg); end end - -> { SendSpecs::Foo.new.send(@method, :foo) }.should raise_error(ArgumentError) + 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 @@ -114,15 +107,4 @@ describe :basicobject_send, shared: true do it "has a negative arity" do method(@method).arity.should < 0 end - - it "invokes module methods with super correctly" do - m1 = Module.new { def foo(ary); ary << :m1; end; } - m2 = Module.new { def foo(ary = []); super(ary); ary << :m2; end; } - c2 = Class.new do - include m1 - include m2 - end - - c2.new.send(@method, :foo, *[[]]).should == %i[m1 m2] - end end diff --git a/spec/ruby/shared/complex/Complex.rb b/spec/ruby/shared/complex/Complex.rb new file mode 100644 index 0000000000..5a9715b161 --- /dev/null +++ b/spec/ruby/shared/complex/Complex.rb @@ -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 diff --git a/spec/ruby/shared/complex/abs.rb b/spec/ruby/shared/complex/abs.rb new file mode 100644 index 0000000000..1f8d861f65 --- /dev/null +++ b/spec/ruby/shared/complex/abs.rb @@ -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 diff --git a/spec/ruby/shared/complex/abs2.rb b/spec/ruby/shared/complex/abs2.rb new file mode 100644 index 0000000000..f899a41a3e --- /dev/null +++ b/spec/ruby/shared/complex/abs2.rb @@ -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 diff --git a/spec/ruby/shared/complex/arg.rb b/spec/ruby/shared/complex/arg.rb new file mode 100644 index 0000000000..c81f197433 --- /dev/null +++ b/spec/ruby/shared/complex/arg.rb @@ -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 diff --git a/spec/ruby/shared/complex/coerce.rb b/spec/ruby/shared/complex/coerce.rb new file mode 100644 index 0000000000..b8a230dfb5 --- /dev/null +++ b/spec/ruby/shared/complex/coerce.rb @@ -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 diff --git a/spec/ruby/shared/complex/conjugate.rb b/spec/ruby/shared/complex/conjugate.rb new file mode 100644 index 0000000000..d1ae47bcb6 --- /dev/null +++ b/spec/ruby/shared/complex/conjugate.rb @@ -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 diff --git a/spec/ruby/shared/complex/constants.rb b/spec/ruby/shared/complex/constants.rb new file mode 100644 index 0000000000..e8bb5fc907 --- /dev/null +++ b/spec/ruby/shared/complex/constants.rb @@ -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 diff --git a/spec/ruby/shared/complex/denominator.rb b/spec/ruby/shared/complex/denominator.rb new file mode 100644 index 0000000000..6084cbf672 --- /dev/null +++ b/spec/ruby/shared/complex/denominator.rb @@ -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 diff --git a/spec/ruby/shared/complex/divide.rb b/spec/ruby/shared/complex/divide.rb new file mode 100644 index 0000000000..0bd88f197e --- /dev/null +++ b/spec/ruby/shared/complex/divide.rb @@ -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 diff --git a/spec/ruby/shared/complex/equal_value.rb b/spec/ruby/shared/complex/equal_value.rb new file mode 100644 index 0000000000..d944698878 --- /dev/null +++ b/spec/ruby/shared/complex/equal_value.rb @@ -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 diff --git a/spec/ruby/shared/complex/exponent.rb b/spec/ruby/shared/complex/exponent.rb new file mode 100644 index 0000000000..8261db872a --- /dev/null +++ b/spec/ruby/shared/complex/exponent.rb @@ -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 diff --git a/spec/ruby/shared/complex/float/arg.rb b/spec/ruby/shared/complex/float/arg.rb new file mode 100644 index 0000000000..ca29796610 --- /dev/null +++ b/spec/ruby/shared/complex/float/arg.rb @@ -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 diff --git a/spec/ruby/shared/complex/hash.rb b/spec/ruby/shared/complex/hash.rb new file mode 100644 index 0000000000..26ca59aeaf --- /dev/null +++ b/spec/ruby/shared/complex/hash.rb @@ -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 diff --git a/spec/ruby/shared/complex/image.rb b/spec/ruby/shared/complex/image.rb new file mode 100644 index 0000000000..5d45210b45 --- /dev/null +++ b/spec/ruby/shared/complex/image.rb @@ -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 diff --git a/spec/ruby/shared/complex/inspect.rb b/spec/ruby/shared/complex/inspect.rb new file mode 100644 index 0000000000..7c0c3d6b9c --- /dev/null +++ b/spec/ruby/shared/complex/inspect.rb @@ -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 diff --git a/spec/ruby/shared/complex/minus.rb b/spec/ruby/shared/complex/minus.rb new file mode 100644 index 0000000000..c28d08ad2e --- /dev/null +++ b/spec/ruby/shared/complex/minus.rb @@ -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 diff --git a/spec/ruby/shared/complex/multiply.rb b/spec/ruby/shared/complex/multiply.rb new file mode 100644 index 0000000000..4d94ef2ce3 --- /dev/null +++ b/spec/ruby/shared/complex/multiply.rb @@ -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 diff --git a/spec/ruby/shared/complex/numerator.rb b/spec/ruby/shared/complex/numerator.rb new file mode 100644 index 0000000000..b8384e4a93 --- /dev/null +++ b/spec/ruby/shared/complex/numerator.rb @@ -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 diff --git a/spec/ruby/shared/complex/numeric/arg.rb b/spec/ruby/shared/complex/numeric/arg.rb new file mode 100644 index 0000000000..b7eb1f2e2d --- /dev/null +++ b/spec/ruby/shared/complex/numeric/arg.rb @@ -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 diff --git a/spec/ruby/shared/complex/numeric/conj.rb b/spec/ruby/shared/complex/numeric/conj.rb new file mode 100644 index 0000000000..50cb060442 --- /dev/null +++ b/spec/ruby/shared/complex/numeric/conj.rb @@ -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 diff --git a/spec/ruby/shared/complex/numeric/imag.rb b/spec/ruby/shared/complex/numeric/imag.rb new file mode 100644 index 0000000000..caf54e2cf9 --- /dev/null +++ b/spec/ruby/shared/complex/numeric/imag.rb @@ -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 diff --git a/spec/ruby/shared/complex/numeric/polar.rb b/spec/ruby/shared/complex/numeric/polar.rb new file mode 100644 index 0000000000..952b65c1b6 --- /dev/null +++ b/spec/ruby/shared/complex/numeric/polar.rb @@ -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 diff --git a/spec/ruby/shared/complex/numeric/real.rb b/spec/ruby/shared/complex/numeric/real.rb new file mode 100644 index 0000000000..0dcf2e8381 --- /dev/null +++ b/spec/ruby/shared/complex/numeric/real.rb @@ -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 diff --git a/spec/ruby/shared/complex/plus.rb b/spec/ruby/shared/complex/plus.rb new file mode 100644 index 0000000000..47e362d886 --- /dev/null +++ b/spec/ruby/shared/complex/plus.rb @@ -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 diff --git a/spec/ruby/shared/complex/polar.rb b/spec/ruby/shared/complex/polar.rb new file mode 100644 index 0000000000..acc063d89f --- /dev/null +++ b/spec/ruby/shared/complex/polar.rb @@ -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 diff --git a/spec/ruby/shared/complex/real.rb b/spec/ruby/shared/complex/real.rb new file mode 100644 index 0000000000..ab8ed07a4d --- /dev/null +++ b/spec/ruby/shared/complex/real.rb @@ -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 diff --git a/spec/ruby/shared/complex/rect.rb b/spec/ruby/shared/complex/rect.rb new file mode 100644 index 0000000000..8a59d873eb --- /dev/null +++ b/spec/ruby/shared/complex/rect.rb @@ -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 diff --git a/spec/ruby/shared/complex/to_s.rb b/spec/ruby/shared/complex/to_s.rb new file mode 100644 index 0000000000..03f4f98b84 --- /dev/null +++ b/spec/ruby/shared/complex/to_s.rb @@ -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 diff --git a/spec/ruby/shared/enumerable/minmax.rb b/spec/ruby/shared/enumerable/minmax.rb deleted file mode 100644 index 8af2626d2a..0000000000 --- a/spec/ruby/shared/enumerable/minmax.rb +++ /dev/null @@ -1,24 +0,0 @@ -describe :enumerable_minmax, shared: true do - it "min should return the minimum element" do - @enum.minmax.should == [4, 10] - @strs.minmax.should == ["1010", "60"] - end - - it "returns the minimum when using a block rule" do - @enum.minmax {|a,b| b <=> a }.should == [10, 4] - @strs.minmax {|a,b| a.length <=> b.length }.should == ["2", "55555"] - end - - it "returns [nil, nil] for an empty Enumerable" do - @empty_enum.minmax.should == [nil, nil] - end - - it "raises a NoMethodError for elements without #<=>" do - -> { @incomparable_enum.minmax }.should raise_error(NoMethodError) - end - - it "raises an ArgumentError when elements are incompatible" do - -> { @incompatible_enum.minmax }.should raise_error(ArgumentError) - -> { @enum.minmax{ |a, b| nil } }.should raise_error(ArgumentError) - end -end diff --git a/spec/ruby/shared/enumerator/each.rb b/spec/ruby/shared/enumerator/each.rb new file mode 100644 index 0000000000..bbab86fed7 --- /dev/null +++ b/spec/ruby/shared/enumerator/each.rb @@ -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 diff --git a/spec/ruby/shared/enumerator/enum_cons.rb b/spec/ruby/shared/enumerator/enum_cons.rb new file mode 100644 index 0000000000..59eed949d8 --- /dev/null +++ b/spec/ruby/shared/enumerator/enum_cons.rb @@ -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 diff --git a/spec/ruby/shared/enumerator/enum_for.rb b/spec/ruby/shared/enumerator/enum_for.rb index a67a76c461..9030ffbd7d 100644 --- a/spec/ruby/shared/enumerator/enum_for.rb +++ b/spec/ruby/shared/enumerator/enum_for.rb @@ -12,13 +12,6 @@ describe :enum_for, shared: true do enum.map { |v| v }.should == [1,2].each { |v| v } end - it "sets regexp matches in the caller" do - "wawa".send(@method, :scan, /./).map {|o| $& }.should == ["w", "a", "w", "a"] - a = [] - "wawa".send(@method, :scan, /./).each {|o| a << $& } - a.should == ["w", "a", "w", "a"] - end - it "exposes multi-arg yields as an array" do o = Object.new def o.each diff --git a/spec/ruby/shared/enumerator/new.rb b/spec/ruby/shared/enumerator/new.rb new file mode 100644 index 0000000000..23ace99816 --- /dev/null +++ b/spec/ruby/shared/enumerator/new.rb @@ -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 diff --git a/spec/ruby/shared/enumerator/next.rb b/spec/ruby/shared/enumerator/next.rb new file mode 100644 index 0000000000..d8ae6d9673 --- /dev/null +++ b/spec/ruby/shared/enumerator/next.rb @@ -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 diff --git a/spec/ruby/shared/enumerator/rewind.rb b/spec/ruby/shared/enumerator/rewind.rb new file mode 100644 index 0000000000..4d4139204c --- /dev/null +++ b/spec/ruby/shared/enumerator/rewind.rb @@ -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 diff --git a/spec/ruby/shared/enumerator/with_index.rb b/spec/ruby/shared/enumerator/with_index.rb index 89f40070e0..37048a7b52 100644 --- a/spec/ruby/shared/enumerator/with_index.rb +++ b/spec/ruby/shared/enumerator/with_index.rb @@ -1,22 +1,21 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :enum_with_index, shared: true do - require_relative '../../fixtures/enumerator/classes' + require File.expand_path('../../../fixtures/enumerator/classes', __FILE__) before :each do - @origin = [1, 2, 3, 4] - @enum = @origin.to_enum + @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]] + @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 - @enum.send(@method) { |o, i| :glark }.should equal(@origin) + [1, 2, 3, 4].should == @enum.send(@method) { |o, i| :glark } end it "binds splat arguments properly" do diff --git a/spec/ruby/shared/enumerator/with_object.rb b/spec/ruby/shared/enumerator/with_object.rb index c2e3a79366..1830736713 100644 --- a/spec/ruby/shared/enumerator/with_object.rb +++ b/spec/ruby/shared/enumerator/with_object.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :enum_with_object, shared: true do before :each do diff --git a/spec/ruby/shared/fiber/resume.rb b/spec/ruby/shared/fiber/resume.rb index f3477804ad..058ef4e15a 100644 --- a/spec/ruby/shared/fiber/resume.rb +++ b/spec/ruby/shared/fiber/resume.rb @@ -4,16 +4,19 @@ describe :fiber_resume, shared: true do fiber.send(@method).should == :fiber end + it "raises a FiberError if the Fiber tries to resume itself" do + fiber = Fiber.new { fiber.resume } + -> { fiber.resume }.should raise_error(FiberError, /double resume/) + end + it "raises a FiberError if invoked from a different Thread" do fiber = Fiber.new { 42 } Thread.new do -> { - fiber.send(@method) + fiber.resume }.should raise_error(FiberError) end.join - - # Check the Fiber can still be used - fiber.send(@method).should == 42 + fiber.resume.should == 42 end it "passes control to the beginning of the block on first invocation" do @@ -35,24 +38,45 @@ describe :fiber_resume, shared: true 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| } - -> { fiber.send(@method, *(1..10).to_a) }.should_not raise_error + 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) - -> { fiber.send(@method) }.should raise_error(FiberError) + 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; } - -> { fiber.send(@method) }.should raise_error(LocalJumpError) + 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; } - -> { fiber.send(@method) }.should raise_error(LocalJumpError) + lambda { fiber.send(@method) }.should raise_error(LocalJumpError) end end diff --git a/spec/ruby/shared/file/directory.rb b/spec/ruby/shared/file/directory.rb index 8ba933a601..67e939bf16 100644 --- a/spec/ruby/shared/file/directory.rb +++ b/spec/ruby/shared/file/directory.rb @@ -24,12 +24,12 @@ describe :file_directory, shared: true do end it "raises a TypeError when passed an Integer" do - -> { @object.send(@method, 1) }.should raise_error(TypeError) - -> { @object.send(@method, bignum_value) }.should raise_error(TypeError) + 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 - -> { @object.send(@method, nil) }.should raise_error(TypeError) + lambda { @object.send(@method, nil) }.should raise_error(TypeError) end end diff --git a/spec/ruby/shared/file/executable.rb b/spec/ruby/shared/file/executable.rb index 7b5c4c580c..5b21fb0d97 100644 --- a/spec/ruby/shared/file/executable.rb +++ b/spec/ruby/shared/file/executable.rb @@ -13,7 +13,7 @@ describe :file_executable, shared: true do rm_r @file1, @file2 end - platform_is_not :windows, :android do + 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 @@ -31,13 +31,13 @@ describe :file_executable, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { @object.send(@method) }.should raise_error(ArgumentError) + lambda { @object.send(@method) }.should raise_error(ArgumentError) end it "raises a TypeError if not passed a String type" do - -> { @object.send(@method, 1) }.should raise_error(TypeError) - -> { @object.send(@method, nil) }.should raise_error(TypeError) - -> { @object.send(@method, false) }.should raise_error(TypeError) + 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 diff --git a/spec/ruby/shared/file/executable_real.rb b/spec/ruby/shared/file/executable_real.rb index ce3d5ca176..2b1bf8f585 100644 --- a/spec/ruby/shared/file/executable_real.rb +++ b/spec/ruby/shared/file/executable_real.rb @@ -29,13 +29,13 @@ describe :file_executable_real, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { @object.send(@method) }.should raise_error(ArgumentError) + lambda { @object.send(@method) }.should raise_error(ArgumentError) end it "raises a TypeError if not passed a String type" do - -> { @object.send(@method, 1) }.should raise_error(TypeError) - -> { @object.send(@method, nil) }.should raise_error(TypeError) - -> { @object.send(@method, false) }.should raise_error(TypeError) + 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 diff --git a/spec/ruby/shared/file/exist.rb b/spec/ruby/shared/file/exist.rb index 3bd97711b4..1557f01a82 100644 --- a/spec/ruby/shared/file/exist.rb +++ b/spec/ruby/shared/file/exist.rb @@ -10,12 +10,12 @@ describe :file_exist, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { @object.send(@method) }.should raise_error(ArgumentError) - -> { @object.send(@method, __FILE__, __FILE__) }.should raise_error(ArgumentError) + 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 - -> { @object.send(@method, nil) }.should raise_error(TypeError) + lambda { @object.send(@method, nil) }.should raise_error(TypeError) end it "accepts an object that has a #to_path method" do diff --git a/spec/ruby/shared/file/file.rb b/spec/ruby/shared/file/file.rb index c1748a88b3..095bd63fff 100644 --- a/spec/ruby/shared/file/file.rb +++ b/spec/ruby/shared/file/file.rb @@ -34,12 +34,12 @@ describe :file_file, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { @object.send(@method) }.should raise_error(ArgumentError) - -> { @object.send(@method, @null, @file) }.should raise_error(ArgumentError) + 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 - -> { @object.send(@method, nil) }.should raise_error(TypeError) - -> { @object.send(@method, 1) }.should raise_error(TypeError) + lambda { @object.send(@method, nil) }.should raise_error(TypeError) + lambda { @object.send(@method, 1) }.should raise_error(TypeError) end end diff --git a/spec/ruby/shared/file/grpowned.rb b/spec/ruby/shared/file/grpowned.rb index 24e84c28e3..91a6483030 100644 --- a/spec/ruby/shared/file/grpowned.rb +++ b/spec/ruby/shared/file/grpowned.rb @@ -26,7 +26,8 @@ describe :file_grpowned, shared: true do @object.send(@method, @file).should == true else - skip "No supplementary groups" + # No supplementary groups + 1.should == 1 end end end diff --git a/spec/ruby/shared/file/identical.rb b/spec/ruby/shared/file/identical.rb index b7a2904839..e89cd309ea 100644 --- a/spec/ruby/shared/file/identical.rb +++ b/spec/ruby/shared/file/identical.rb @@ -9,11 +9,7 @@ describe :file_identical, shared: true do touch(@file2) { |f| f.puts "file2" } rm_r @link - begin - File.link(@file1, @link) - rescue Errno::EACCES - File.symlink(@file1, @link) - end + File.link(@file1, @link) end after :each do @@ -35,12 +31,12 @@ describe :file_identical, shared: true do end it "raises an ArgumentError if not passed two arguments" do - -> { @object.send(@method, @file1, @file2, @link) }.should raise_error(ArgumentError) - -> { @object.send(@method, @file1) }.should raise_error(ArgumentError) + 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 - -> { @object.send(@method, 1,1) }.should raise_error(TypeError) + lambda { @object.send(@method, 1,1) }.should raise_error(TypeError) end it "returns true if both named files are identical" do diff --git a/spec/ruby/shared/file/readable.rb b/spec/ruby/shared/file/readable.rb index eb2ca06812..74f58caaff 100644 --- a/spec/ruby/shared/file/readable.rb +++ b/spec/ruby/shared/file/readable.rb @@ -4,12 +4,9 @@ describe :file_readable, shared: true do platform_is :windows do @file2 = File.join(ENV["WINDIR"], "system32/drivers/etc/services").tr(File::SEPARATOR, File::ALT_SEPARATOR) end - platform_is_not :windows, :android do + platform_is_not :windows do @file2 = "/etc/passwd" end - platform_is :android do - @file2 = "/system/bin/sh" - end end after :each do diff --git a/spec/ruby/shared/file/size.rb b/spec/ruby/shared/file/size.rb index 880dfbb612..bb95190fc0 100644 --- a/spec/ruby/shared/file/size.rb +++ b/spec/ruby/shared/file/size.rb @@ -56,7 +56,7 @@ describe :file_size_raise_when_missing, shared: true do end it "raises an error if file_name doesn't exist" do - -> {@object.send(@method, @missing)}.should raise_error(Errno::ENOENT) + lambda {@object.send(@method, @missing)}.should raise_error(Errno::ENOENT) end end diff --git a/spec/ruby/shared/file/world_readable.rb b/spec/ruby/shared/file/world_readable.rb index 1dce7a580f..0fddf98b73 100644 --- a/spec/ruby/shared/file/world_readable.rb +++ b/spec/ruby/shared/file/world_readable.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :file_world_readable, shared: true do @@ -28,18 +28,18 @@ describe :file_world_readable, shared: true do end end - # We don't specify what the Integer is because it's system dependent - it "returns an Integer if the file is chmod 644" do + # 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(Integer) + @object.world_readable?(@file).should be_an_instance_of(Fixnum) end - it "returns an Integer if the file is a directory and chmod 644" do - dir = tmp(rand().to_s + '-ww') + it "returns a Fixnum if the file is a directory and chmod 644" do + dir = rand().to_s + '-ww' Dir.mkdir(dir) - Dir.should.exist?(dir) + Dir.exist?(dir).should be_true File.chmod(0644, dir) - @object.world_readable?(dir).should be_an_instance_of(Integer) + @object.world_readable?(dir).should be_an_instance_of(Fixnum) Dir.rmdir(dir) end diff --git a/spec/ruby/shared/file/world_writable.rb b/spec/ruby/shared/file/world_writable.rb index 7ed252dcf3..43ac23a997 100644 --- a/spec/ruby/shared/file/world_writable.rb +++ b/spec/ruby/shared/file/world_writable.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :file_world_writable, shared: true do @@ -27,18 +27,18 @@ describe :file_world_writable, shared: true do @object.world_writable?(@file).should be_nil end - # We don't specify what the Integer is because it's system dependent - it "returns an Integer if the file is chmod 777" do + # 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(Integer) + @object.world_writable?(@file).should be_an_instance_of(Fixnum) end - it "returns an Integer if the file is a directory and chmod 777" do - dir = tmp(rand().to_s + '-ww') + it "returns a Fixnum if the file is a directory and chmod 777" do + dir = rand().to_s + '-ww' Dir.mkdir(dir) - Dir.should.exist?(dir) + Dir.exist?(dir).should be_true File.chmod(0777, dir) - @object.world_writable?(dir).should be_an_instance_of(Integer) + @object.world_writable?(dir).should be_an_instance_of(Fixnum) Dir.rmdir(dir) end end diff --git a/spec/ruby/shared/file/writable.rb b/spec/ruby/shared/file/writable.rb index 4bb8aedce6..e8296928f3 100644 --- a/spec/ruby/shared/file/writable.rb +++ b/spec/ruby/shared/file/writable.rb @@ -8,10 +8,8 @@ describe :file_writable, shared: true do end it "returns true if named file is writable by the effective user id of the process, otherwise false" do - platform_is_not :windows, :android do - as_user do - @object.send(@method, "/etc/passwd").should == false - end + platform_is_not :windows do + @object.send(@method, "/etc/passwd").should == false end File.open(@file,'w') { @object.send(@method, @file).should == true } end diff --git a/spec/ruby/shared/file/writable_real.rb b/spec/ruby/shared/file/writable_real.rb index e9721fd379..3730befb7a 100644 --- a/spec/ruby/shared/file/writable_real.rb +++ b/spec/ruby/shared/file/writable_real.rb @@ -16,13 +16,13 @@ describe :file_writable_real, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { File.writable_real? }.should raise_error(ArgumentError) + lambda { File.writable_real? }.should raise_error(ArgumentError) end it "raises a TypeError if not passed a String type" do - -> { @object.send(@method, 1) }.should raise_error(TypeError) - -> { @object.send(@method, nil) }.should raise_error(TypeError) - -> { @object.send(@method, false) }.should raise_error(TypeError) + 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 diff --git a/spec/ruby/shared/file/zero.rb b/spec/ruby/shared/file/zero.rb index 6a9399a021..cf014d4722 100644 --- a/spec/ruby/shared/file/zero.rb +++ b/spec/ruby/shared/file/zero.rb @@ -40,13 +40,13 @@ describe :file_zero, shared: true do end it "raises an ArgumentError if not passed one argument" do - -> { File.zero? }.should raise_error(ArgumentError) + lambda { File.zero? }.should raise_error(ArgumentError) end it "raises a TypeError if not passed a String type" do - -> { @object.send(@method, nil) }.should raise_error(TypeError) - -> { @object.send(@method, true) }.should raise_error(TypeError) - -> { @object.send(@method, false) }.should raise_error(TypeError) + 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 diff --git a/spec/ruby/shared/hash/key_error.rb b/spec/ruby/shared/hash/key_error.rb deleted file mode 100644 index 54dcb89e91..0000000000 --- a/spec/ruby/shared/hash/key_error.rb +++ /dev/null @@ -1,23 +0,0 @@ -describe :key_error, shared: true do - it "raises a KeyError" do - -> { - @method.call(@object, 'foo') - }.should raise_error(KeyError) - end - - it "sets the Hash as the receiver of KeyError" do - -> { - @method.call(@object, 'foo') - }.should raise_error(KeyError) { |err| - err.receiver.should equal(@object) - } - end - - it "sets the unmatched key as the key of KeyError" do - -> { - @method.call(@object, 'foo') - }.should raise_error(KeyError) { |err| - err.key.to_s.should == 'foo' - } - end -end diff --git a/spec/ruby/shared/io/putc.rb b/spec/ruby/shared/io/putc.rb index e6012c0098..5f620f183f 100644 --- a/spec/ruby/shared/io/putc.rb +++ b/spec/ruby/shared/io/putc.rb @@ -1,4 +1,4 @@ -# -*- encoding: binary -*- +# -*- encoding: ascii-8bit -*- describe :io_putc, shared: true do after :each do @io.close if @io && !@io.closed? @@ -6,7 +6,7 @@ describe :io_putc, shared: true do rm_r @name end - describe "with an Integer argument" do + 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 @@ -40,18 +40,18 @@ describe :io_putc, shared: true do it "raises IOError on a closed stream" do @io.close - -> { @io_object.send(@method, "a") }.should raise_error(IOError) + lambda { @io_object.send(@method, "a") }.should raise_error(IOError) end it "raises a TypeError when passed nil" do - -> { @io_object.send(@method, nil) }.should raise_error(TypeError) + lambda { @io_object.send(@method, nil) }.should raise_error(TypeError) end it "raises a TypeError when passed false" do - -> { @io_object.send(@method, false) }.should raise_error(TypeError) + lambda { @io_object.send(@method, false) }.should raise_error(TypeError) end it "raises a TypeError when passed true" do - -> { @io_object.send(@method, true) }.should raise_error(TypeError) + lambda { @io_object.send(@method, true) }.should raise_error(TypeError) end end diff --git a/spec/ruby/shared/kernel/object_id.rb b/spec/ruby/shared/kernel/object_id.rb index 175f3fb749..7acdb27554 100644 --- a/spec/ruby/shared/kernel/object_id.rb +++ b/spec/ruby/shared/kernel/object_id.rb @@ -16,7 +16,7 @@ describe :object_id, shared: true do o1.__send__(@method).should_not == o2.__send__(@method) end - it "returns the same value for two Integers with the same value" do + it "returns the same value for two Fixnums with the same value" do o1 = 1 o2 = 1 o1.send(@method).should == o2.send(@method) @@ -46,7 +46,7 @@ describe :object_id, shared: true do o1.send(@method).should == o2.send(@method) end - it "returns a different value for two Integer literals" do + 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) @@ -64,14 +64,14 @@ describe :object_id, shared: true do o1.send(@method).should_not == o2.send(@method) end - it "returns a different value for two numbers near the 32 bit Integer limit" do + 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 Integer limit" do + it "returns a different value for two numbers near the 64 bit Fixnum limit" do o1 = -1 o2 = 2 ** 62 - 1 diff --git a/spec/ruby/shared/kernel/raise.rb b/spec/ruby/shared/kernel/raise.rb index f00a6ef294..70d638fff9 100644 --- a/spec/ruby/shared/kernel/raise.rb +++ b/spec/ruby/shared/kernel/raise.rb @@ -4,7 +4,7 @@ describe :kernel_raise, shared: true do end it "aborts execution" do - -> do + lambda do @object.raise Exception, "abort" ScratchPad.record :no_abort end.should raise_error(Exception, "abort") @@ -13,84 +13,55 @@ describe :kernel_raise, shared: true do end it "raises RuntimeError if no exception class is given" do - -> { @object.raise }.should raise_error(RuntimeError, "") + lambda { @object.raise }.should raise_error(RuntimeError) end it "raises a given Exception instance" do error = RuntimeError.new - -> { @object.raise(error) }.should raise_error(error) + lambda { @object.raise(error) }.should raise_error(error) end it "raises a RuntimeError if string given" do - -> { @object.raise("a bad thing") }.should raise_error(RuntimeError) - end - - it "passes no arguments to the constructor when given only an exception class" do - klass = Class.new(Exception) do - def initialize - end - end - -> { @object.raise(klass) }.should raise_error(klass) { |e| e.message.should == klass.to_s } + lambda { @object.raise("a bad thing") }.should raise_error(RuntimeError) end it "raises a TypeError when passed a non-Exception object" do - -> { @object.raise(Object.new) }.should raise_error(TypeError) + lambda { @object.raise(Object.new) }.should raise_error(TypeError) end it "raises a TypeError when passed true" do - -> { @object.raise(true) }.should raise_error(TypeError) + lambda { @object.raise(true) }.should raise_error(TypeError) end it "raises a TypeError when passed false" do - -> { @object.raise(false) }.should raise_error(TypeError) + lambda { @object.raise(false) }.should raise_error(TypeError) end it "raises a TypeError when passed nil" do - -> { @object.raise(nil) }.should raise_error(TypeError) + lambda { @object.raise(nil) }.should raise_error(TypeError) end - it "re-raises a previously rescued exception without overwriting the backtrace" do - # This spec is written using #backtrace and matching the line number - # from the string, as backtrace_locations is a more advanced - # method that is not always supported by implementations. - # - initial_raise_line = nil - raise_again_line = nil - raised_again = nil - - if defined?(FiberSpecs::NewFiberToRaise) and @object == FiberSpecs::NewFiberToRaise - fiber = Fiber.new do - begin - initial_raise_line = __LINE__; Fiber.yield - rescue => raised - begin - raise_again_line = __LINE__; Fiber.yield raised - rescue => raised_again - raised_again - end - end - end - fiber.resume - raised = fiber.raise 'raised' - raised_again = fiber.raise raised - else + it "re-raises the rescued exception" do + lambda do begin - initial_raise_line = __LINE__; @object.raise 'raised' - rescue => raised + raise Exception, "outer" + ScratchPad.record :no_abort + rescue begin - raise_again_line = __LINE__; @object.raise raised - rescue => raised_again - raised_again + raise StandardError, "inner" + rescue end + + @object.raise + ScratchPad.record :no_reraise end - end + end.should raise_error(Exception, "outer") - raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:") - raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:") + ScratchPad.recorded.should be_nil end it "allows Exception, message, and backtrace parameters" do - -> do + lambda do @object.raise(ArgumentError, "message", caller) end.should raise_error(ArgumentError, "message") end diff --git a/spec/ruby/shared/math/atanh.rb b/spec/ruby/shared/math/atanh.rb index 3fb64153a0..1d1a6ebd74 100644 --- a/spec/ruby/shared/math/atanh.rb +++ b/spec/ruby/shared/math/atanh.rb @@ -11,11 +11,11 @@ describe :math_atanh_base, shared: true do end it "raises a TypeError if the argument is nil" do - -> { @object.send(@method, nil) }.should raise_error(TypeError) + lambda { @object.send(@method, nil) }.should raise_error(TypeError) end it "raises a TypeError if the argument is not a Numeric" do - -> { @object.send(@method, "test") }.should raise_error(TypeError) + lambda { @object.send(@method, "test") }.should raise_error(TypeError) end it "returns Infinity if x == 1.0" do @@ -35,10 +35,10 @@ end describe :math_atanh_no_complex, shared: true do it "raises a Math::DomainError for arguments greater than 1.0" do - -> { @object.send(@method, 1.0 + Float::EPSILON) }.should raise_error(Math::DomainError) + 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 - -> { @object.send(@method, -1.0 - Float::EPSILON) }.should raise_error(Math::DomainError) + lambda { @object.send(@method, -1.0 - Float::EPSILON) }.should raise_error(Math::DomainError) end end diff --git a/spec/ruby/shared/process/abort.rb b/spec/ruby/shared/process/abort.rb index 935637e1c2..1a25aeffc2 100644 --- a/spec/ruby/shared/process/abort.rb +++ b/spec/ruby/shared/process/abort.rb @@ -8,29 +8,29 @@ describe :process_abort, shared: true do end it "raises a SystemExit exception" do - -> { @object.abort }.should raise_error(SystemExit) + lambda { @object.abort }.should raise_error(SystemExit) end it "sets the exception message to the given message" do - -> { @object.abort "message" }.should raise_error { |e| e.message.should == "message" } + lambda { @object.abort "message" }.should raise_error { |e| e.message.should == "message" } end it "sets the exception status code of 1" do - -> { @object.abort }.should raise_error { |e| e.status.should == 1 } + lambda { @object.abort }.should raise_error { |e| e.status.should == 1 } end it "prints the specified message to STDERR" do - -> { @object.abort "a message" }.should raise_error(SystemExit) + 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") - -> { @object.abort str }.should raise_error(SystemExit, "message") + lambda { @object.abort str }.should raise_error(SystemExit, "message") end it "raises TypeError when given a non-String object" do - -> { @object.abort 123 }.should raise_error(TypeError) + lambda { @object.abort 123 }.should raise_error(TypeError) end end diff --git a/spec/ruby/shared/process/exit.rb b/spec/ruby/shared/process/exit.rb index e633afc73a..7d567c8195 100644 --- a/spec/ruby/shared/process/exit.rb +++ b/spec/ruby/shared/process/exit.rb @@ -1,13 +1,13 @@ describe :process_exit, shared: true do it "raises a SystemExit with status 0" do - -> { @object.exit }.should raise_error(SystemExit) { |e| + 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| - -> { @object.exit(value) }.should raise_error(SystemExit) { |e| + lambda { @object.exit(value) }.should raise_error(SystemExit) { |e| e.status.should == value } end @@ -15,7 +15,7 @@ describe :process_exit, shared: true do it "raises a SystemExit with the specified boolean status" do { true => 0, false => 1 }.each do |value, status| - -> { @object.exit(value) }.should raise_error(SystemExit) { |e| + lambda { @object.exit(value) }.should raise_error(SystemExit) { |e| e.status.should == status } end @@ -24,24 +24,24 @@ describe :process_exit, shared: true do 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) - -> { @object.exit(obj) }.should raise_error(SystemExit) { |e| + 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| - -> { @object.exit(value) }.should raise_error(SystemExit) { |e| + 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 - -> { @object.exit(Object.new) }.should raise_error(TypeError) - -> { @object.exit('0') }.should raise_error(TypeError) - -> { @object.exit([0]) }.should raise_error(TypeError) - -> { @object.exit(nil) }.should raise_error(TypeError) + 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 @@ -69,7 +69,7 @@ describe :process_exit, shared: true do ScratchPad.recorded.should == [:in_thread, :in_main] # the thread also keeps the exception as its value - -> { t.value }.should raise_error(SystemExit) + lambda { t.value }.should raise_error(SystemExit) end end @@ -91,24 +91,4 @@ describe :process_exit!, shared: true do out.should == "" $?.exitstatus.should == 21 end - - it "skips at_exit handlers" do - out = ruby_exe("at_exit { STDERR.puts 'at_exit' }; #{@object}.send(:exit!, 21)", args: '2>&1') - out.should == "" - $?.exitstatus.should == 21 - end - - it "overrides the original exception and exit status when called from #at_exit" do - code = <<-RUBY - at_exit do - STDERR.puts 'in at_exit' - STDERR.puts "$! is \#{$!.class}:\#{$!.message}" - #{@object}.send(:exit!, 21) - end - raise 'original error' - RUBY - out = ruby_exe(code, args: '2>&1') - out.should == "in at_exit\n$! is RuntimeError:original error\n" - $?.exitstatus.should == 21 - end end diff --git a/spec/ruby/shared/process/fork.rb b/spec/ruby/shared/process/fork.rb index 11e18d7b1c..c2c2aee9bf 100644 --- a/spec/ruby/shared/process/fork.rb +++ b/spec/ruby/shared/process/fork.rb @@ -8,7 +8,7 @@ describe :process_fork, shared: true do end it "raises a NotImplementedError when called" do - -> { @object.fork }.should raise_error(NotImplementedError) + lambda { @object.fork }.should raise_error(NotImplementedError) end end @@ -60,7 +60,7 @@ describe :process_fork, shared: true do else Process.waitpid(child_id) end - File.should.exist?(@file) + File.exist?(@file).should == true end it "runs a block in a child process" do @@ -69,7 +69,7 @@ describe :process_fork, shared: true do Process.exit! } Process.waitpid(pid) - File.should.exist?(@file) + File.exist?(@file).should == true end it "marks threads from the parent as killed" do diff --git a/spec/ruby/shared/queue/clear.rb b/spec/ruby/shared/queue/clear.rb deleted file mode 100644 index 5db5a5b497..0000000000 --- a/spec/ruby/shared/queue/clear.rb +++ /dev/null @@ -1,12 +0,0 @@ -describe :queue_clear, shared: true do - it "removes all objects from the queue" do - queue = @object.call - queue << Object.new - queue << 1 - queue.empty?.should be_false - queue.clear - queue.empty?.should be_true - end - - # TODO: test for atomicity of Queue#clear -end diff --git a/spec/ruby/shared/queue/close.rb b/spec/ruby/shared/queue/close.rb deleted file mode 100644 index 0e7c69acba..0000000000 --- a/spec/ruby/shared/queue/close.rb +++ /dev/null @@ -1,14 +0,0 @@ -describe :queue_close, shared: true do - it "may be called multiple times" do - q = @object.call - q.close - q.closed?.should be_true - q.close # no effect - q.closed?.should be_true - end - - it "returns self" do - q = @object.call - q.close.should == q - end -end diff --git a/spec/ruby/shared/queue/closed.rb b/spec/ruby/shared/queue/closed.rb deleted file mode 100644 index b3cea0c524..0000000000 --- a/spec/ruby/shared/queue/closed.rb +++ /dev/null @@ -1,12 +0,0 @@ -describe :queue_closed?, shared: true do - it "returns false initially" do - queue = @object.call - queue.closed?.should be_false - end - - it "returns true when the queue is closed" do - queue = @object.call - queue.close - queue.closed?.should be_true - end -end diff --git a/spec/ruby/shared/queue/deque.rb b/spec/ruby/shared/queue/deque.rb deleted file mode 100644 index 8b755dd9b7..0000000000 --- a/spec/ruby/shared/queue/deque.rb +++ /dev/null @@ -1,85 +0,0 @@ -describe :queue_deq, shared: true do - it "removes an item from the queue" do - q = @object.call - q << Object.new - q.size.should == 1 - q.send @method - q.size.should == 0 - end - - it "returns items in the order they were added" do - q = @object.call - q << 1 - q << 2 - q.send(@method).should == 1 - q.send(@method).should == 2 - end - - it "blocks the thread until there are items in the queue" do - q = @object.call - v = 0 - - th = Thread.new do - q.send(@method) - v = 1 - end - - v.should == 0 - q << Object.new - th.join - v.should == 1 - end - - it "removes an item from a closed queue" do - q = @object.call - q << 1 - q.close - q.send(@method).should == 1 - end - - it "returns nil for a closed empty queue" do - q = @object.call - q.close - q.send(@method).should == nil - end - - it "returns nil for an empty queue that becomes closed" do - q = @object.call - - t = Thread.new { - q.send(@method).should == nil - } - - Thread.pass until t.status == "sleep" && q.num_waiting == 1 - q.close - t.join - end - - describe "in non-blocking mode" do - it "removes an item from the queue" do - q = @object.call - q << Object.new - q.size.should == 1 - q.send(@method, true) - q.size.should == 0 - end - - it "raises a ThreadError if the queue is empty" do - q = @object.call - -> { q.send(@method, true) }.should raise_error(ThreadError) - end - - it "removes an item from a closed queue" do - q = @object.call - q << 1 - q.close - q.send(@method, true).should == 1 - end - - it "raises a ThreadError for a closed empty queue" do - q = @object.call - q.close - -> { q.send(@method, true) }.should raise_error(ThreadError) - end - end -end diff --git a/spec/ruby/shared/queue/empty.rb b/spec/ruby/shared/queue/empty.rb deleted file mode 100644 index 4acd831d48..0000000000 --- a/spec/ruby/shared/queue/empty.rb +++ /dev/null @@ -1,12 +0,0 @@ -describe :queue_empty?, shared: true do - it "returns true on an empty Queue" do - queue = @object.call - queue.empty?.should be_true - end - - it "returns false when Queue is not empty" do - queue = @object.call - queue << Object.new - queue.empty?.should be_false - end -end diff --git a/spec/ruby/shared/queue/enque.rb b/spec/ruby/shared/queue/enque.rb deleted file mode 100644 index 8aba02e544..0000000000 --- a/spec/ruby/shared/queue/enque.rb +++ /dev/null @@ -1,18 +0,0 @@ -describe :queue_enq, shared: true do - it "adds an element to the Queue" do - q = @object.call - q.size.should == 0 - q.send @method, Object.new - q.size.should == 1 - q.send @method, Object.new - q.size.should == 2 - end - - it "is an error for a closed queue" do - q = @object.call - q.close - -> { - q.send @method, Object.new - }.should raise_error(ClosedQueueError) - end -end diff --git a/spec/ruby/shared/queue/length.rb b/spec/ruby/shared/queue/length.rb deleted file mode 100644 index a0143a4e19..0000000000 --- a/spec/ruby/shared/queue/length.rb +++ /dev/null @@ -1,9 +0,0 @@ -describe :queue_length, shared: true do - it "returns the number of elements" do - q = @object.call - q.send(@method).should == 0 - q << Object.new - q << Object.new - q.send(@method).should == 2 - end -end diff --git a/spec/ruby/shared/queue/num_waiting.rb b/spec/ruby/shared/queue/num_waiting.rb deleted file mode 100644 index b054951e45..0000000000 --- a/spec/ruby/shared/queue/num_waiting.rb +++ /dev/null @@ -1,16 +0,0 @@ -describe :queue_num_waiting, shared: true do - it "reports the number of threads waiting on the queue" do - q = @object.call - threads = [] - - 5.times do |i| - q.num_waiting.should == i - t = Thread.new { q.deq } - Thread.pass until q.num_waiting == i+1 - threads << t - end - - threads.each { q.enq Object.new } - threads.each {|t| t.join } - end -end diff --git a/spec/ruby/shared/rational/Rational.rb b/spec/ruby/shared/rational/Rational.rb index 2c36243dc3..0165fa769a 100644 --- a/spec/ruby/shared/rational/Rational.rb +++ b/spec/ruby/shared/rational/Rational.rb @@ -1,10 +1,10 @@ -require_relative '../../spec_helper' -require_relative '../../fixtures/rational' +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 - guard -> { !defined?(Math.rsqrt) } do + 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)) @@ -80,64 +80,24 @@ describe :kernel_Rational, shared: true do end it "raises a RangeError if the imaginary part is not 0" do - -> { Rational(Complex(1, 2)) }.should raise_error(RangeError) + lambda { Rational(Complex(1, 2)) }.should raise_error(RangeError) end end it "raises a TypeError if the first argument is nil" do - -> { Rational(nil) }.should raise_error(TypeError) + lambda { Rational(nil) }.should raise_error(TypeError) end it "raises a TypeError if the second argument is nil" do - -> { Rational(1, nil) }.should raise_error(TypeError) + lambda { Rational(1, nil) }.should raise_error(TypeError) end it "raises a TypeError if the first argument is a Symbol" do - -> { Rational(:sym) }.should raise_error(TypeError) + lambda { Rational(:sym) }.should raise_error(TypeError) end it "raises a TypeError if the second argument is a Symbol" do - -> { Rational(1, :sym) }.should raise_error(TypeError) - end - end - - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and [non-Numeric]" do - it "swallows an error" do - Rational(:sym, exception: false).should == nil - Rational("abc", exception: false).should == nil - end - end - - describe "and [non-Numeric, Numeric]" do - it "swallows an error" do - Rational(:sym, 1, exception: false).should == nil - Rational("abc", 1, exception: false).should == nil - end - end - - describe "and [anything, non-Numeric]" do - it "swallows an error" do - Rational(:sym, :sym, exception: false).should == nil - Rational("abc", :sym, exception: false).should == nil - end - end - - describe "and non-Numeric String arguments" do - it "swallows an error" do - Rational("a", "b", exception: false).should == nil - Rational("a", 0, exception: false).should == nil - Rational(0, "b", exception: false).should == nil - end - end - - describe "and nil arguments" do - it "swallows an error" do - Rational(nil, exception: false).should == nil - Rational(nil, nil, exception: false).should == nil - end - end + lambda { Rational(1, :sym) }.should raise_error(TypeError) end end end diff --git a/spec/ruby/shared/rational/abs.rb b/spec/ruby/shared/rational/abs.rb index 8beb20da7e..aa1bdc4363 100644 --- a/spec/ruby/shared/rational/abs.rb +++ b/spec/ruby/shared/rational/abs.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_abs, shared: true do it "returns self's absolute value" do diff --git a/spec/ruby/shared/rational/arithmetic_exception_in_coerce.rb b/spec/ruby/shared/rational/arithmetic_exception_in_coerce.rb deleted file mode 100644 index 0dff91d522..0000000000 --- a/spec/ruby/shared/rational/arithmetic_exception_in_coerce.rb +++ /dev/null @@ -1,11 +0,0 @@ -require_relative '../../fixtures/rational' - -describe :rational_arithmetic_exception_in_coerce, shared: true do - it "does not rescue exception raised in other#coerce" do - b = mock("numeric with failed #coerce") - b.should_receive(:coerce).and_raise(RationalSpecs::CoerceError) - - # e.g. Rational(3, 4) + b - -> { Rational(3, 4).send(@method, b) }.should raise_error(RationalSpecs::CoerceError) - end -end diff --git a/spec/ruby/shared/rational/ceil.rb b/spec/ruby/shared/rational/ceil.rb index f1cf60d2be..cbb4ed0d08 100644 --- a/spec/ruby/shared/rational/ceil.rb +++ b/spec/ruby/shared/rational/ceil.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_ceil, shared: true do before do diff --git a/spec/ruby/shared/rational/coerce.rb b/spec/ruby/shared/rational/coerce.rb index ccc8901ba0..8bdd19aa2a 100644 --- a/spec/ruby/shared/rational/coerce.rb +++ b/spec/ruby/shared/rational/coerce.rb @@ -1,6 +1,4 @@ -require_relative '../../spec_helper' - -require 'bigdecimal' +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 @@ -17,18 +15,7 @@ describe :rational_coerce, shared: true do result.last.is_a?(Rational).should be_true end - it "coerces to Rational, when given a Complex" do - Rational(3, 4).coerce(Complex(5)).should == [Rational(5, 1), Rational(3, 4)] - Rational(12, 4).coerce(Complex(5, 1)).should == [Complex(5, 1), Complex(3)] - 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 - - it "raises an error when passed a BigDecimal" do - -> { - Rational(500, 3).coerce(BigDecimal('166.666666666')) - }.should raise_error(TypeError, /BigDecimal can't be coerced into Rational/) - end end diff --git a/spec/ruby/shared/rational/comparison.rb b/spec/ruby/shared/rational/comparison.rb index 860462f579..c52363781f 100644 --- a/spec/ruby/shared/rational/comparison.rb +++ b/spec/ruby/shared/rational/comparison.rb @@ -1,5 +1,4 @@ -require_relative '../../spec_helper' -require_relative '../../fixtures/rational' +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 @@ -79,15 +78,6 @@ describe :rational_cmp_coerce, shared: true do end end -describe :rational_cmp_coerce_exception, shared: true do - it "does not rescue exception raised in other#coerce" do - b = mock("numeric with failed #coerce") - b.should_receive(:coerce).and_raise(RationalSpecs::CoerceError) - - -> { Rational(3, 4) <=> b }.should raise_error(RationalSpecs::CoerceError) - end -end - describe :rational_cmp_other, shared: true do it "returns nil" do (Rational <=> mock("Object")).should be_nil diff --git a/spec/ruby/shared/rational/denominator.rb b/spec/ruby/shared/rational/denominator.rb index 10d46aacb3..74e464465d 100644 --- a/spec/ruby/shared/rational/denominator.rb +++ b/spec/ruby/shared/rational/denominator.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_denominator, shared: true do it "returns the denominator" do diff --git a/spec/ruby/shared/rational/div.rb b/spec/ruby/shared/rational/div.rb index d5bd9e6644..23c11f5d12 100644 --- a/spec/ruby/shared/rational/div.rb +++ b/spec/ruby/shared/rational/div.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_div_rat, shared: true do it "performs integer division and returns the result" do @@ -7,11 +7,11 @@ describe :rational_div_rat, shared: true do end it "raises a ZeroDivisionError when the argument has a numerator of 0" do - -> { Rational(3, 4).div(Rational(0, 3)) }.should raise_error(ZeroDivisionError) + 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 - -> { Rational(3, 4).div(Rational(0.0, 3)) }.should raise_error(ZeroDivisionError) + lambda { Rational(3, 4).div(Rational(0.0, 3)) }.should raise_error(ZeroDivisionError) end end @@ -23,7 +23,7 @@ describe :rational_div_float, shared: true do end it "raises a ZeroDivisionError when the argument is 0.0" do - -> { Rational(3, 4).div(0.0) }.should raise_error(ZeroDivisionError) + lambda { Rational(3, 4).div(0.0) }.should raise_error(ZeroDivisionError) end end @@ -34,7 +34,7 @@ describe :rational_div_int, shared: true do end it "raises a ZeroDivisionError when the argument is 0" do - -> { Rational(3, 4).div(0) }.should raise_error(ZeroDivisionError) + lambda { Rational(3, 4).div(0) }.should raise_error(ZeroDivisionError) end end @@ -44,11 +44,11 @@ describe :rational_div, shared: true do end it "raises an ArgumentError if passed more than one argument" do - -> { Rational(3, 4).div(2,3) }.should raise_error(ArgumentError) + 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 - -> { Rational(3, 4).div([]) }.should raise_error(TypeError) + lambda { Rational(3, 4).div([]) }.should raise_error(TypeError) end end diff --git a/spec/ruby/shared/rational/divide.rb b/spec/ruby/shared/rational/divide.rb index 7d6d66390f..8c5bf666e6 100644 --- a/spec/ruby/shared/rational/divide.rb +++ b/spec/ruby/shared/rational/divide.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_divide_rat, shared: true do it "returns self divided by other as a Rational" do @@ -10,7 +10,7 @@ describe :rational_divide_rat, shared: true do end it "raises a ZeroDivisionError when passed a Rational with a numerator of 0" do - -> { Rational(3, 4).send(@method, Rational(0, 1)) }.should raise_error(ZeroDivisionError) + lambda { Rational(3, 4).send(@method, Rational(0, 1)) }.should raise_error(ZeroDivisionError) end end @@ -22,7 +22,7 @@ describe :rational_divide_int, shared: true do end it "raises a ZeroDivisionError when passed 0" do - -> { Rational(3, 4).send(@method, 0) }.should raise_error(ZeroDivisionError) + lambda { Rational(3, 4).send(@method, 0) }.should raise_error(ZeroDivisionError) end end diff --git a/spec/ruby/shared/rational/divmod.rb b/spec/ruby/shared/rational/divmod.rb index 5b319a95ff..607ae9d693 100644 --- a/spec/ruby/shared/rational/divmod.rb +++ b/spec/ruby/shared/rational/divmod.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +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 @@ -10,7 +10,7 @@ describe :rational_divmod_rat, shared: true do end it "raises a ZeroDivisonError when passed a Rational with a numerator of 0" do - -> { Rational(7, 4).divmod(Rational(0, 3)) }.should raise_error(ZeroDivisionError) + lambda { Rational(7, 4).divmod(Rational(0, 3)) }.should raise_error(ZeroDivisionError) end end @@ -23,7 +23,7 @@ describe :rational_divmod_int, shared: true do end it "raises a ZeroDivisionError when passed 0" do - -> { Rational(7, 4).divmod(0) }.should raise_error(ZeroDivisionError) + lambda { Rational(7, 4).divmod(0) }.should raise_error(ZeroDivisionError) end end @@ -37,6 +37,6 @@ describe :rational_divmod_float, shared: true do end it "raises a ZeroDivisionError when passed 0" do - -> { Rational(7, 4).divmod(0.0) }.should raise_error(ZeroDivisionError) + lambda { Rational(7, 4).divmod(0.0) }.should raise_error(ZeroDivisionError) end end diff --git a/spec/ruby/shared/rational/equal_value.rb b/spec/ruby/shared/rational/equal_value.rb index b2e7e09415..be4d5af598 100644 --- a/spec/ruby/shared/rational/equal_value.rb +++ b/spec/ruby/shared/rational/equal_value.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +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 diff --git a/spec/ruby/shared/rational/exponent.rb b/spec/ruby/shared/rational/exponent.rb index 0f6abcd634..7e7c5be7c1 100644 --- a/spec/ruby/shared/rational/exponent.rb +++ b/spec/ruby/shared/rational/exponent.rb @@ -1,9 +1,8 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_exponent, shared: true do describe "when passed Rational" do - # Guard against the Mathn library - guard -> { !defined?(Math.rsqrt) } 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)) @@ -46,8 +45,7 @@ describe :rational_exponent, shared: true do (Rational(3, -bignum_value) ** -4).should == Rational(7237005577332262213973186563042994240829374041602535252466099000494570602496, 81) end - # Guard against the Mathn library - guard -> { !defined?(Math.rsqrt) } do + 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)) @@ -59,14 +57,14 @@ describe :rational_exponent, shared: true do end end - describe "when passed Integer" do + 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 - -> { Rational(0) ** -bignum_value }.should raise_error(ZeroDivisionError) + lambda { Rational(0) ** -bignum_value }.should raise_error(ZeroDivisionError) end it "returns Rational(1) when self is Rational(1)" do @@ -117,9 +115,9 @@ describe :rational_exponent, shared: true do 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(0.0, -1.8371173070873836), TOLERANCE) - (Rational(3, -2) ** 1.5).should be_close(Complex(0.0, -1.8371173070873836), TOLERANCE) - (Rational(3, -2) ** -1.5).should be_close(Complex(0.0, 0.5443310539518174), 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(-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 @@ -153,19 +151,19 @@ describe :rational_exponent, shared: true do it "raises ZeroDivisionError for Rational(0, 1) passed a negative Integer" do [-1, -4, -9999].each do |exponent| - -> { Rational(0, 1) ** exponent }.should raise_error(ZeroDivisionError, "divided by 0") + 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| - -> { Rational(0, 1) ** exponent }.should raise_error(ZeroDivisionError, "divided by 0") + 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 - -> { Rational(0, 1) ** Rational(-3, 2) }.should raise_error(ZeroDivisionError, "divided by 0") + 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 diff --git a/spec/ruby/shared/rational/fdiv.rb b/spec/ruby/shared/rational/fdiv.rb index 6911ade8ac..22ca4b4ddc 100644 --- a/spec/ruby/shared/rational/fdiv.rb +++ b/spec/ruby/shared/rational/fdiv.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_fdiv, shared: true do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/shared/rational/floor.rb b/spec/ruby/shared/rational/floor.rb index ddf7fdbd17..5106e0b4d9 100644 --- a/spec/ruby/shared/rational/floor.rb +++ b/spec/ruby/shared/rational/floor.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_floor, shared: true do before do diff --git a/spec/ruby/shared/rational/hash.rb b/spec/ruby/shared/rational/hash.rb index 50f21cec20..a83ce49afb 100644 --- a/spec/ruby/shared/rational/hash.rb +++ b/spec/ruby/shared/rational/hash.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_hash, shared: true do # BUG: Rational(2, 3).hash == Rational(3, 2).hash diff --git a/spec/ruby/shared/rational/inspect.rb b/spec/ruby/shared/rational/inspect.rb index 19691a2f25..a641db8eb8 100644 --- a/spec/ruby/shared/rational/inspect.rb +++ b/spec/ruby/shared/rational/inspect.rb @@ -1,13 +1,11 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_inspect, shared: true 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)" - - # Guard against the Mathn library - guard -> { !defined?(Math.rsqrt) } 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 diff --git a/spec/ruby/shared/rational/marshal_dump.rb b/spec/ruby/shared/rational/marshal_dump.rb index 09782b45a5..673c6c8327 100644 --- a/spec/ruby/shared/rational/marshal_dump.rb +++ b/spec/ruby/shared/rational/marshal_dump.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_marshal_dump, shared: true do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/shared/rational/marshal_load.rb b/spec/ruby/shared/rational/marshal_load.rb index 20bdd6fdf4..7cf32ad1db 100644 --- a/spec/ruby/shared/rational/marshal_load.rb +++ b/spec/ruby/shared/rational/marshal_load.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_marshal_load, shared: true do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/shared/rational/minus.rb b/spec/ruby/shared/rational/minus.rb index 0a0946fdb9..e23430111e 100644 --- a/spec/ruby/shared/rational/minus.rb +++ b/spec/ruby/shared/rational/minus.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_minus_rat, shared: true do it "returns the result of subtracting other from self as a Rational" do diff --git a/spec/ruby/shared/rational/modulo.rb b/spec/ruby/shared/rational/modulo.rb index 9e4b0c49e6..ca69650f20 100644 --- a/spec/ruby/shared/rational/modulo.rb +++ b/spec/ruby/shared/rational/modulo.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +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 @@ -22,21 +22,21 @@ describe :rational_modulo, shared: true do 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 diff --git a/spec/ruby/shared/rational/multiply.rb b/spec/ruby/shared/rational/multiply.rb index 9c861cf79d..05a9cfc5c8 100644 --- a/spec/ruby/shared/rational/multiply.rb +++ b/spec/ruby/shared/rational/multiply.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_multiply_rat, shared: true do it "returns self divided by other as a Rational" do diff --git a/spec/ruby/shared/rational/numerator.rb b/spec/ruby/shared/rational/numerator.rb index 50d768168c..e4868ef43c 100644 --- a/spec/ruby/shared/rational/numerator.rb +++ b/spec/ruby/shared/rational/numerator.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_numerator, shared: true do it "returns the numerator" do diff --git a/spec/ruby/shared/rational/plus.rb b/spec/ruby/shared/rational/plus.rb index b126360ee4..e37c757c13 100644 --- a/spec/ruby/shared/rational/plus.rb +++ b/spec/ruby/shared/rational/plus.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_plus_rat, shared: true do it "returns the result of subtracting other from self as a Rational" do diff --git a/spec/ruby/shared/rational/quo.rb b/spec/ruby/shared/rational/quo.rb index 53b32fed2f..61bd3fad9d 100644 --- a/spec/ruby/shared/rational/quo.rb +++ b/spec/ruby/shared/rational/quo.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_quo, shared: true do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/shared/rational/remainder.rb b/spec/ruby/shared/rational/remainder.rb index dd907608db..64aeb55e6c 100644 --- a/spec/ruby/shared/rational/remainder.rb +++ b/spec/ruby/shared/rational/remainder.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_remainder, shared: true do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/shared/rational/round.rb b/spec/ruby/shared/rational/round.rb index 5b159ee3e6..c7a4cc6d07 100644 --- a/spec/ruby/shared/rational/round.rb +++ b/spec/ruby/shared/rational/round.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_round, shared: true do before do @@ -47,11 +47,8 @@ describe :rational_round, shared: true do it "returns a Rational" do @rational.round(1).should be_kind_of(Rational) @rational.round(2).should be_kind_of(Rational) - # Guard against the Mathn library - guard -> { !defined?(Math.rsqrt) } do - Rational(0, 1).round(1).should be_kind_of(Rational) - Rational(2, 1).round(1).should be_kind_of(Rational) - end + 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 @@ -72,35 +69,28 @@ describe :rational_round, shared: true do end end - describe "with half option" do - it "returns an Integer when precision is not passed" do - Rational(10, 4).round(half: nil).should == 3 - Rational(10, 4).round(half: :up).should == 3 - Rational(10, 4).round(half: :down).should == 2 - Rational(10, 4).round(half: :even).should == 2 - Rational(-10, 4).round(half: nil).should == -3 - Rational(-10, 4).round(half: :up).should == -3 - Rational(-10, 4).round(half: :down).should == -2 - Rational(-10, 4).round(half: :even).should == -2 - end - - it "returns a Rational when the precision is greater than 0" do - Rational(25, 100).round(1, half: nil).should == Rational(3, 10) - Rational(25, 100).round(1, half: :up).should == Rational(3, 10) - Rational(25, 100).round(1, half: :down).should == Rational(1, 5) - Rational(25, 100).round(1, half: :even).should == Rational(1, 5) - Rational(35, 100).round(1, half: nil).should == Rational(2, 5) - Rational(35, 100).round(1, half: :up).should == Rational(2, 5) - Rational(35, 100).round(1, half: :down).should == Rational(3, 10) - Rational(35, 100).round(1, half: :even).should == Rational(2, 5) - Rational(-25, 100).round(1, half: nil).should == Rational(-3, 10) - Rational(-25, 100).round(1, half: :up).should == Rational(-3, 10) - Rational(-25, 100).round(1, half: :down).should == Rational(-1, 5) - Rational(-25, 100).round(1, half: :even).should == Rational(-1, 5) - end + ruby_version_is "2.4" do + describe "with half option" do + it "returns an Integer when precision is not passed" do + Rational(10, 4).round(half: :up).should == 3 + Rational(10, 4).round(half: :down).should == 2 + Rational(10, 4).round(half: :even).should == 2 + Rational(-10, 4).round(half: :up).should == -3 + Rational(-10, 4).round(half: :down).should == -2 + Rational(-10, 4).round(half: :even).should == -2 + end - it "raise for a non-existent round mode" do - -> { Rational(10, 4).round(half: :nonsense) }.should raise_error(ArgumentError, "invalid rounding mode: nonsense") + it "returns a Rational when the precision is greater than 0" do + Rational(25, 100).round(1, half: :up).should == Rational(3, 10) + Rational(25, 100).round(1, half: :down).should == Rational(1, 5) + Rational(25, 100).round(1, half: :even).should == Rational(1, 5) + Rational(35, 100).round(1, half: :up).should == Rational(2, 5) + Rational(35, 100).round(1, half: :down).should == Rational(3, 10) + Rational(35, 100).round(1, half: :even).should == Rational(2, 5) + Rational(-25, 100).round(1, half: :up).should == Rational(-3, 10) + Rational(-25, 100).round(1, half: :down).should == Rational(-1, 5) + Rational(-25, 100).round(1, half: :even).should == Rational(-1, 5) + end end end end diff --git a/spec/ruby/shared/rational/to_f.rb b/spec/ruby/shared/rational/to_f.rb index 56e0b61d68..2c9afdddda 100644 --- a/spec/ruby/shared/rational/to_f.rb +++ b/spec/ruby/shared/rational/to_f.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_to_f, shared: true do it "returns self converted to a Float" do diff --git a/spec/ruby/shared/rational/to_i.rb b/spec/ruby/shared/rational/to_i.rb index 9be1183aa4..b0db78b3a8 100644 --- a/spec/ruby/shared/rational/to_i.rb +++ b/spec/ruby/shared/rational/to_i.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_to_i, shared: true do it "converts self to an Integer by truncation" do diff --git a/spec/ruby/shared/rational/to_r.rb b/spec/ruby/shared/rational/to_r.rb index 372c086850..646167614a 100644 --- a/spec/ruby/shared/rational/to_r.rb +++ b/spec/ruby/shared/rational/to_r.rb @@ -1,11 +1,13 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_to_r, shared: true do - it "returns self" do - a = Rational(3, 4) - a.to_r.should equal(a) + 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) + a = Rational(bignum_value, 4) + a.to_r.should equal(a) + end end end diff --git a/spec/ruby/shared/rational/to_s.rb b/spec/ruby/shared/rational/to_s.rb index e90c6e5e39..429a021908 100644 --- a/spec/ruby/shared/rational/to_s.rb +++ b/spec/ruby/shared/rational/to_s.rb @@ -1,12 +1,9 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_to_s, shared: true do it "returns a string representation of self" do - # Guard against the Mathn library - guard -> { !defined?(Math.rsqrt) } do - Rational(1, 1).to_s.should == "1/1" - Rational(2, 1).to_s.should == "2/1" - end + 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" diff --git a/spec/ruby/shared/rational/truncate.rb b/spec/ruby/shared/rational/truncate.rb index 761dd3113a..993c654c45 100644 --- a/spec/ruby/shared/rational/truncate.rb +++ b/spec/ruby/shared/rational/truncate.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe :rational_truncate, shared: true do before do diff --git a/spec/ruby/shared/sizedqueue/enque.rb b/spec/ruby/shared/sizedqueue/enque.rb deleted file mode 100644 index 6ef12349f8..0000000000 --- a/spec/ruby/shared/sizedqueue/enque.rb +++ /dev/null @@ -1,50 +0,0 @@ -describe :sizedqueue_enq, shared: true do - it "blocks if queued elements exceed size" do - q = @object.call(1) - - q.size.should == 0 - q.send(@method, :first_element) - q.size.should == 1 - - blocked_thread = Thread.new { q.send(@method, :second_element) } - sleep 0.01 until blocked_thread.stop? - - q.size.should == 1 - q.pop.should == :first_element - - blocked_thread.join - q.size.should == 1 - q.pop.should == :second_element - q.size.should == 0 - end - - it "raises a ThreadError if queued elements exceed size when not blocking" do - q = @object.call(2) - - non_blocking = true - add_to_queue = -> { q.send(@method, Object.new, non_blocking) } - - q.size.should == 0 - add_to_queue.call - q.size.should == 1 - add_to_queue.call - q.size.should == 2 - add_to_queue.should raise_error(ThreadError) - end - - it "interrupts enqueuing threads with ClosedQueueError when the queue is closed" do - q = @object.call(1) - q << 1 - - t = Thread.new { - -> { q.send(@method, 2) }.should raise_error(ClosedQueueError) - } - - Thread.pass until q.num_waiting == 1 - - q.close - - t.join - q.pop.should == 1 - end -end diff --git a/spec/ruby/shared/sizedqueue/max.rb b/spec/ruby/shared/sizedqueue/max.rb deleted file mode 100644 index ea10d24be0..0000000000 --- a/spec/ruby/shared/sizedqueue/max.rb +++ /dev/null @@ -1,47 +0,0 @@ -describe :sizedqueue_max, shared: true do - it "returns the size of the queue" do - q = @object.call(5) - q.max.should == 5 - end -end - -describe :sizedqueue_max=, shared: true do - it "sets the size of the queue" do - q = @object.call(5) - q.max.should == 5 - q.max = 10 - q.max.should == 10 - end - - it "does not remove items already in the queue beyond the maximum" do - q = @object.call(5) - q.enq 1 - q.enq 2 - q.enq 3 - q.max = 2 - (q.size > q.max).should be_true - q.deq.should == 1 - q.deq.should == 2 - q.deq.should == 3 - end - - it "raises a TypeError when given a non-numeric value" do - q = @object.call(5) - -> { q.max = "foo" }.should raise_error(TypeError) - -> { q.max = Object.new }.should raise_error(TypeError) - end - - it "raises an argument error when set to zero" do - q = @object.call(5) - q.max.should == 5 - -> { q.max = 0 }.should raise_error(ArgumentError) - q.max.should == 5 - end - - it "raises an argument error when set to a negative number" do - q = @object.call(5) - q.max.should == 5 - -> { q.max = -1 }.should raise_error(ArgumentError) - q.max.should == 5 - end -end diff --git a/spec/ruby/shared/sizedqueue/new.rb b/spec/ruby/shared/sizedqueue/new.rb deleted file mode 100644 index 713785fb50..0000000000 --- a/spec/ruby/shared/sizedqueue/new.rb +++ /dev/null @@ -1,18 +0,0 @@ -describe :sizedqueue_new, shared: true do - it "raises a TypeError when the given argument is not Numeric" do - -> { @object.call("foo") }.should raise_error(TypeError) - -> { @object.call(Object.new) }.should raise_error(TypeError) - end - - it "raises an argument error when no argument is given" do - -> { @object.call }.should raise_error(ArgumentError) - end - - it "raises an argument error when the given argument is zero" do - -> { @object.call(0) }.should raise_error(ArgumentError) - end - - it "raises an argument error when the given argument is negative" do - -> { @object.call(-1) }.should raise_error(ArgumentError) - end -end diff --git a/spec/ruby/shared/sizedqueue/num_waiting.rb b/spec/ruby/shared/sizedqueue/num_waiting.rb deleted file mode 100644 index 8c31e48ca5..0000000000 --- a/spec/ruby/shared/sizedqueue/num_waiting.rb +++ /dev/null @@ -1,12 +0,0 @@ -describe :sizedqueue_num_waiting, shared: true do - it "reports the number of threads waiting to push" do - q = @object.call(1) - q.push(1) - t = Thread.new { q.push(2) } - sleep 0.05 until t.stop? - q.num_waiting.should == 1 - - q.pop - t.join - end -end diff --git a/spec/ruby/shared/string/end_with.rb b/spec/ruby/shared/string/end_with.rb deleted file mode 100644 index 5f2a011235..0000000000 --- a/spec/ruby/shared/string/end_with.rb +++ /dev/null @@ -1,54 +0,0 @@ -describe :end_with, shared: true do - # the @method should either be :to_s or :to_sym - - it "returns true only if ends match" do - s = "hello".send(@method) - s.should.end_with?('o') - s.should.end_with?('llo') - end - - it 'returns false if the end does not match' do - s = 'hello'.send(@method) - s.should_not.end_with?('ll') - end - - it "returns true if the search string is empty" do - "hello".send(@method).should.end_with?("") - "".send(@method).should.end_with?("") - end - - it "returns true only if any ending match" do - "hello".send(@method).should.end_with?('x', 'y', 'llo', 'z') - end - - it "converts its argument using :to_str" do - s = "hello".send(@method) - find = mock('o') - find.should_receive(:to_str).and_return("o") - s.should.end_with?(find) - end - - it "ignores arguments not convertible to string" do - "hello".send(@method).should_not.end_with?() - -> { "hello".send(@method).end_with?(1) }.should raise_error(TypeError) - -> { "hello".send(@method).end_with?(["o"]) }.should raise_error(TypeError) - -> { "hello".send(@method).end_with?(1, nil, "o") }.should raise_error(TypeError) - end - - it "uses only the needed arguments" do - find = mock('h') - find.should_not_receive(:to_str) - "hello".send(@method).should.end_with?("o",find) - end - - it "works for multibyte strings" do - "céréale".send(@method).should.end_with?("réale") - end - - it "raises an Encoding::CompatibilityError if the encodings are incompatible" do - pat = "ア".encode Encoding::EUC_JP - -> do - "あれ".send(@method).end_with?(pat) - end.should raise_error(Encoding::CompatibilityError) - end -end diff --git a/spec/ruby/shared/string/start_with.rb b/spec/ruby/shared/string/start_with.rb deleted file mode 100644 index d8d6e13f6a..0000000000 --- a/spec/ruby/shared/string/start_with.rb +++ /dev/null @@ -1,72 +0,0 @@ -describe :start_with, shared: true do - # the @method should either be :to_s or :to_sym - - it "returns true only if beginning match" do - s = "hello".send(@method) - s.should.start_with?('h') - s.should.start_with?('hel') - s.should_not.start_with?('el') - end - - it "returns true only if any beginning match" do - "hello".send(@method).should.start_with?('x', 'y', 'he', 'z') - end - - it "returns true if the search string is empty" do - "hello".send(@method).should.start_with?("") - "".send(@method).should.start_with?("") - end - - it "converts its argument using :to_str" do - s = "hello".send(@method) - find = mock('h') - find.should_receive(:to_str).and_return("h") - s.should.start_with?(find) - end - - it "ignores arguments not convertible to string" do - "hello".send(@method).should_not.start_with?() - -> { "hello".send(@method).start_with?(1) }.should raise_error(TypeError) - -> { "hello".send(@method).start_with?(["h"]) }.should raise_error(TypeError) - -> { "hello".send(@method).start_with?(1, nil, "h") }.should raise_error(TypeError) - end - - it "uses only the needed arguments" do - find = mock('h') - find.should_not_receive(:to_str) - "hello".send(@method).should.start_with?("h",find) - end - - it "works for multibyte strings" do - "céréale".send(@method).should.start_with?("cér") - end - - it "supports regexps" do - regexp = /[h1]/ - "hello".send(@method).should.start_with?(regexp) - "1337".send(@method).should.start_with?(regexp) - "foxes are 1337".send(@method).should_not.start_with?(regexp) - "chunky\n12bacon".send(@method).should_not.start_with?(/12/) - end - - it "supports regexps with ^ and $ modifiers" do - regexp1 = /^\d{2}/ - regexp2 = /\d{2}$/ - "12test".send(@method).should.start_with?(regexp1) - "test12".send(@method).should_not.start_with?(regexp1) - "12test".send(@method).should_not.start_with?(regexp2) - "test12".send(@method).should_not.start_with?(regexp2) - end - - it "sets Regexp.last_match if it returns true" do - regexp = /test-(\d+)/ - "test-1337".send(@method).start_with?(regexp).should be_true - Regexp.last_match.should_not be_nil - Regexp.last_match[1].should == "1337" - $1.should == "1337" - - "test-asdf".send(@method).start_with?(regexp).should be_false - Regexp.last_match.should be_nil - $1.should be_nil - end -end diff --git a/spec/ruby/shared/string/times.rb b/spec/ruby/shared/string/times.rb index fcc9d00fd6..c44a76c9b7 100644 --- a/spec/ruby/shared/string/times.rb +++ b/spec/ruby/shared/string/times.rb @@ -18,63 +18,47 @@ describe :string_times, shared: true do end it "raises an ArgumentError when given integer is negative" do - -> { @object.call("cool", -3) }.should raise_error(ArgumentError) - -> { @object.call("cool", -3.14) }.should raise_error(ArgumentError) - -> { @object.call("cool", min_long) }.should raise_error(ArgumentError) + lambda { @object.call("cool", -3) }.should raise_error(ArgumentError) + lambda { @object.call("cool", -3.14) }.should raise_error(ArgumentError) end - it "raises a RangeError when given integer is an Integer" do - -> { @object.call("cool", 999999999999999999999) }.should raise_error(RangeError) - -> { @object.call("", 999999999999999999999) }.should raise_error(RangeError) + it "raises a RangeError when given integer is a Bignum" do + lambda { @object.call("cool", 999999999999999999999) }.should raise_error(RangeError) end - it "works with huge long values when string is empty" do - @object.call("", max_long).should == "" + it "returns subclass instances" do + @object.call(MyString.new("cool"), 0).should be_an_instance_of(MyString) + @object.call(MyString.new("cool"), 1).should be_an_instance_of(MyString) + @object.call(MyString.new("cool"), 2).should be_an_instance_of(MyString) end - ruby_version_is ''...'3.0' do - it "returns subclass instances" do - @object.call(MyString.new("cool"), 0).should be_an_instance_of(MyString) - @object.call(MyString.new("cool"), 1).should be_an_instance_of(MyString) - @object.call(MyString.new("cool"), 2).should be_an_instance_of(MyString) - end - end + it "always taints the result when self is tainted" do + ["", "OK", MyString.new(""), MyString.new("OK")].each do |str| + str.taint - ruby_version_is '3.0' do - it "returns String instances" do - @object.call(MyString.new("cool"), 0).should be_an_instance_of(String) - @object.call(MyString.new("cool"), 1).should be_an_instance_of(String) - @object.call(MyString.new("cool"), 2).should be_an_instance_of(String) - end - end - - ruby_version_is ''...'2.7' do - it "always taints the result when self is tainted" do - ["", "OK", MyString.new(""), MyString.new("OK")].each do |str| - str.taint - - [0, 1, 2].each do |arg| - @object.call(str, arg).should.tainted? - end + [0, 1, 2].each do |arg| + @object.call(str, arg).tainted?.should == true end end end - it "returns a String in the same encoding as self" do - str = "\xE3\x81\x82".force_encoding Encoding::UTF_8 - result = @object.call(str, 2) - result.encoding.should equal(Encoding::UTF_8) + with_feature :encoding do + it "returns a String in the same encoding as self" do + str = "\xE3\x81\x82".force_encoding Encoding::UTF_8 + result = @object.call(str, 2) + result.encoding.should equal(Encoding::UTF_8) + end end platform_is wordsize: 32 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do - -> { @object.call("abc", (2 ** 31) - 1) }.should raise_error(ArgumentError) + lambda { @object.call("abc", (2 ** 31) - 1) }.should raise_error(ArgumentError) end end platform_is wordsize: 64 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do - -> { @object.call("abc", (2 ** 63) - 1) }.should raise_error(ArgumentError) + lambda { @object.call("abc", (2 ** 63) - 1) }.should raise_error(ArgumentError) end end end diff --git a/spec/ruby/shared/time/strftime_for_date.rb b/spec/ruby/shared/time/strftime_for_date.rb index dbb124adc8..f126c5a323 100644 --- a/spec/ruby/shared/time/strftime_for_date.rb +++ b/spec/ruby/shared/time/strftime_for_date.rb @@ -264,10 +264,12 @@ describe :strftime_date, shared: true do @new_date[2001,3,22].strftime("%-m/%-d/%-y").should == "3/22/1" end - it "passes the format string's encoding to the result string" do - result = @new_date[2010,3,8].strftime("%d. März %Y") + with_feature :encoding do + it "passes the format string's encoding to the result string" do + result = @new_date[2010,3,8].strftime("%d. März %Y") - result.encoding.should == Encoding::UTF_8 - result.should == "08. März 2010" + result.encoding.should == Encoding::UTF_8 + result.should == "08. März 2010" + end end end |
