summaryrefslogtreecommitdiff
path: root/spec/ruby/core/complex
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/complex')
-rw-r--r--spec/ruby/core/complex/abs2_spec.rb8
-rw-r--r--spec/ruby/core/complex/abs_spec.rb5
-rw-r--r--spec/ruby/core/complex/angle_spec.rb7
-rw-r--r--spec/ruby/core/complex/arg_spec.rb7
-rw-r--r--spec/ruby/core/complex/coerce_spec.rb69
-rw-r--r--spec/ruby/core/complex/comparison_spec.rb25
-rw-r--r--spec/ruby/core/complex/conj_spec.rb6
-rw-r--r--spec/ruby/core/complex/conjugate_spec.rb6
-rw-r--r--spec/ruby/core/complex/constants_spec.rb6
-rw-r--r--spec/ruby/core/complex/denominator_spec.rb12
-rw-r--r--spec/ruby/core/complex/divide_spec.rb3
-rw-r--r--spec/ruby/core/complex/eql_spec.rb2
-rw-r--r--spec/ruby/core/complex/equal_value_spec.rb92
-rw-r--r--spec/ruby/core/complex/exponent_spec.rb60
-rw-r--r--spec/ruby/core/complex/fdiv_spec.rb20
-rw-r--r--spec/ruby/core/complex/finite_spec.rb52
-rw-r--r--spec/ruby/core/complex/hash_spec.rb16
-rw-r--r--spec/ruby/core/complex/imag_spec.rb5
-rw-r--r--spec/ruby/core/complex/imaginary_spec.rb3
-rw-r--r--spec/ruby/core/complex/infinite_spec.rb50
-rw-r--r--spec/ruby/core/complex/inspect_spec.rb36
-rw-r--r--spec/ruby/core/complex/integer_spec.rb2
-rw-r--r--spec/ruby/core/complex/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/complex/marshal_dump_spec.rb2
-rw-r--r--spec/ruby/core/complex/minus_spec.rb44
-rw-r--r--spec/ruby/core/complex/multiply_spec.rb48
-rw-r--r--spec/ruby/core/complex/negative_spec.rb4
-rw-r--r--spec/ruby/core/complex/numerator_spec.rb18
-rw-r--r--spec/ruby/core/complex/phase_spec.rb4
-rw-r--r--spec/ruby/core/complex/plus_spec.rb44
-rw-r--r--spec/ruby/core/complex/polar_spec.rb37
-rw-r--r--spec/ruby/core/complex/positive_spec.rb4
-rw-r--r--spec/ruby/core/complex/quo_spec.rb3
-rw-r--r--spec/ruby/core/complex/rationalize_spec.rb10
-rw-r--r--spec/ruby/core/complex/real_spec.rb9
-rw-r--r--spec/ruby/core/complex/rect_spec.rb7
-rw-r--r--spec/ruby/core/complex/rectangular_spec.rb7
-rw-r--r--spec/ruby/core/complex/shared/abs.rb10
-rw-r--r--spec/ruby/core/complex/shared/arg.rb9
-rw-r--r--spec/ruby/core/complex/shared/conjugate.rb8
-rw-r--r--spec/ruby/core/complex/shared/divide.rb82
-rw-r--r--spec/ruby/core/complex/shared/image.rb8
-rw-r--r--spec/ruby/core/complex/shared/rect.rb94
-rw-r--r--spec/ruby/core/complex/to_c_spec.rb12
-rw-r--r--spec/ruby/core/complex/to_f_spec.rb8
-rw-r--r--spec/ruby/core/complex/to_i_spec.rb8
-rw-r--r--spec/ruby/core/complex/to_r_spec.rb18
-rw-r--r--spec/ruby/core/complex/to_s_spec.rb54
-rw-r--r--spec/ruby/core/complex/uminus_spec.rb2
49 files changed, 900 insertions, 151 deletions
diff --git a/spec/ruby/core/complex/abs2_spec.rb b/spec/ruby/core/complex/abs2_spec.rb
index debfade075..3e5c5fd225 100644
--- a/spec/ruby/core/complex/abs2_spec.rb
+++ b/spec/ruby/core/complex/abs2_spec.rb
@@ -1,5 +1,9 @@
-require File.expand_path('../../../shared/complex/abs2', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#abs2" do
- it_behaves_like(:complex_abs2, :abs2)
+ 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)
+ Complex(0).abs2.should == 0
+ end
end
diff --git a/spec/ruby/core/complex/abs_spec.rb b/spec/ruby/core/complex/abs_spec.rb
index a00d161ee9..43912c517f 100644
--- a/spec/ruby/core/complex/abs_spec.rb
+++ b/spec/ruby/core/complex/abs_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/abs', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/abs'
describe "Complex#abs" do
- it_behaves_like(:complex_abs, :abs)
+ it_behaves_like :complex_abs, :abs
end
diff --git a/spec/ruby/core/complex/angle_spec.rb b/spec/ruby/core/complex/angle_spec.rb
index f0c46bfd03..4aa176956f 100644
--- a/spec/ruby/core/complex/angle_spec.rb
+++ b/spec/ruby/core/complex/angle_spec.rb
@@ -1,7 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#angle" do
- it_behaves_like(:complex_arg, :angle)
+ it_behaves_like :complex_arg, :angle
end
diff --git a/spec/ruby/core/complex/arg_spec.rb b/spec/ruby/core/complex/arg_spec.rb
index 48f8a94cf5..009f19429f 100644
--- a/spec/ruby/core/complex/arg_spec.rb
+++ b/spec/ruby/core/complex/arg_spec.rb
@@ -1,7 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#arg" do
- it_behaves_like(:complex_arg, :arg)
+ it_behaves_like :complex_arg, :arg
end
diff --git a/spec/ruby/core/complex/coerce_spec.rb b/spec/ruby/core/complex/coerce_spec.rb
index 7c01170fde..a30a6c1d5f 100644
--- a/spec/ruby/core/complex/coerce_spec.rb
+++ b/spec/ruby/core/complex/coerce_spec.rb
@@ -1,5 +1,70 @@
-require File.expand_path('../../../shared/complex/coerce', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#coerce" do
- it_behaves_like(:complex_coerce, :coerce)
+ 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)
+ -> { @one.coerce(other) }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is a String" do
+ -> { @one.coerce("20") }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is nil" do
+ -> { @one.coerce(nil) }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is false" do
+ -> { @one.coerce(false) }.should raise_error(TypeError)
+ end
end
diff --git a/spec/ruby/core/complex/comparison_spec.rb b/spec/ruby/core/complex/comparison_spec.rb
new file mode 100644
index 0000000000..3a3142f234
--- /dev/null
+++ b/spec/ruby/core/complex/comparison_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../spec_helper'
+
+describe "Complex#<=>" do
+ it "returns nil if either self or argument has imaginary part" do
+ (Complex(5, 1) <=> Complex(2)).should be_nil
+ (Complex(1) <=> Complex(2, 1)).should be_nil
+ (5 <=> Complex(2, 1)).should be_nil
+ end
+
+ it "returns nil if argument is not numeric" do
+ (Complex(5, 1) <=> "cmp").should be_nil
+ (Complex(1) <=> "cmp").should be_nil
+ (Complex(1) <=> Object.new).should be_nil
+ end
+
+ it "returns 0, 1, or -1 if self and argument do not have imaginary part" do
+ (Complex(5) <=> Complex(2)).should == 1
+ (Complex(2) <=> Complex(3)).should == -1
+ (Complex(2) <=> Complex(2)).should == 0
+
+ (Complex(5) <=> 2).should == 1
+ (Complex(2) <=> 3).should == -1
+ (Complex(2) <=> 2).should == 0
+ end
+end
diff --git a/spec/ruby/core/complex/conj_spec.rb b/spec/ruby/core/complex/conj_spec.rb
index ad2c885b3b..5e3bc1acb8 100644
--- a/spec/ruby/core/complex/conj_spec.rb
+++ b/spec/ruby/core/complex/conj_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/conjugate', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/conjugate'
describe "Complex#conj" do
- it_behaves_like(:complex_conjugate, :conj)
+ it_behaves_like :complex_conjugate, :conj
end
diff --git a/spec/ruby/core/complex/conjugate_spec.rb b/spec/ruby/core/complex/conjugate_spec.rb
index 7fc2ddb430..f658bab4da 100644
--- a/spec/ruby/core/complex/conjugate_spec.rb
+++ b/spec/ruby/core/complex/conjugate_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/conjugate', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/conjugate'
describe "Complex#conjugate" do
- it_behaves_like(:complex_conjugate, :conjugate)
+ it_behaves_like :complex_conjugate, :conjugate
end
diff --git a/spec/ruby/core/complex/constants_spec.rb b/spec/ruby/core/complex/constants_spec.rb
index a8fcebbd31..50303de16c 100644
--- a/spec/ruby/core/complex/constants_spec.rb
+++ b/spec/ruby/core/complex/constants_spec.rb
@@ -1,5 +1,7 @@
-require File.expand_path('../../../shared/complex/constants', __FILE__)
+require_relative '../../spec_helper'
describe "Complex::I" do
- it_behaves_like :complex_I, :I
+ it "is Complex(0, 1)" do
+ Complex::I.should eql(Complex(0, 1))
+ end
end
diff --git a/spec/ruby/core/complex/denominator_spec.rb b/spec/ruby/core/complex/denominator_spec.rb
index 2568967968..c1a2003820 100644
--- a/spec/ruby/core/complex/denominator_spec.rb
+++ b/spec/ruby/core/complex/denominator_spec.rb
@@ -1,5 +1,13 @@
-require File.expand_path('../../../shared/complex/denominator', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#denominator" do
- it_behaves_like(:complex_denominator, :denominator)
+ 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/core/complex/divide_spec.rb b/spec/ruby/core/complex/divide_spec.rb
index 71614c76e1..bebf862312 100644
--- a/spec/ruby/core/complex/divide_spec.rb
+++ b/spec/ruby/core/complex/divide_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/divide', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/divide'
describe "Complex#/" do
it_behaves_like :complex_divide, :/
diff --git a/spec/ruby/core/complex/eql_spec.rb b/spec/ruby/core/complex/eql_spec.rb
index c8e432029f..9194efc074 100644
--- a/spec/ruby/core/complex/eql_spec.rb
+++ b/spec/ruby/core/complex/eql_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#eql?" do
it "returns false if other is not Complex" do
diff --git a/spec/ruby/core/complex/equal_value_spec.rb b/spec/ruby/core/complex/equal_value_spec.rb
index b3d93911bd..97c486d820 100644
--- a/spec/ruby/core/complex/equal_value_spec.rb
+++ b/spec/ruby/core/complex/equal_value_spec.rb
@@ -1,5 +1,93 @@
-require File.expand_path('../../../shared/complex/equal_value', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#==" do
- it_behaves_like :complex_equal_value, :==
+ 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
+ # Integer#== and Float#== 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 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/core/complex/exponent_spec.rb b/spec/ruby/core/complex/exponent_spec.rb
index 62f61a2bf3..86f827aece 100644
--- a/spec/ruby/core/complex/exponent_spec.rb
+++ b/spec/ruby/core/complex/exponent_spec.rb
@@ -1,5 +1,61 @@
-require File.expand_path('../../../shared/complex/exponent', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#**" do
- it_behaves_like :complex_exponent, :**
+ describe "with Integer 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/core/complex/fdiv_spec.rb b/spec/ruby/core/complex/fdiv_spec.rb
index 8211dfc9de..68f7d1b309 100644
--- a/spec/ruby/core/complex/fdiv_spec.rb
+++ b/spec/ruby/core/complex/fdiv_spec.rb
@@ -1,22 +1,22 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#fdiv" do
it "accepts a numeric argument" do
- lambda { Complex(20).fdiv(2) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(2.0) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(bignum_value) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(2) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(2.0) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(bignum_value) }.should_not raise_error(TypeError)
end
it "accepts a negative numeric argument" do
- lambda { Complex(20).fdiv(-2) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(-2.0) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(-bignum_value) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-2) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-2.0) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-bignum_value) }.should_not raise_error(TypeError)
end
it "raises a TypeError if passed a non-numeric argument" do
- lambda { Complex(20).fdiv([]) }.should raise_error(TypeError)
- lambda { Complex(20).fdiv(:sym) }.should raise_error(TypeError)
- lambda { Complex(20).fdiv('s') }.should raise_error(TypeError)
+ -> { Complex(20).fdiv([]) }.should raise_error(TypeError)
+ -> { Complex(20).fdiv(:sym) }.should raise_error(TypeError)
+ -> { Complex(20).fdiv('s') }.should raise_error(TypeError)
end
it "sets the real part to NaN if self's real part is NaN" do
diff --git a/spec/ruby/core/complex/finite_spec.rb b/spec/ruby/core/complex/finite_spec.rb
index e9ee19bef3..7d9f82404e 100644
--- a/spec/ruby/core/complex/finite_spec.rb
+++ b/spec/ruby/core/complex/finite_spec.rb
@@ -1,36 +1,32 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-ruby_version_is "2.4" do
- describe "Complex#finite?" do
- it "returns true if magnitude is finite" do
- (1+1i).finite?.should == true
- end
+describe "Complex#finite?" do
+ it "returns true if magnitude is finite" do
+ (1+1i).should.finite?
+ end
- it "returns false for positive infinity" do
- value = Complex(Float::INFINITY, 42)
- value.finite?.should == false
- end
+ it "returns false for positive infinity" do
+ value = Complex(Float::INFINITY, 42)
+ value.should_not.finite?
+ end
- it "returns false for positive complex with infinite imaginary" do
- value = Complex(1, Float::INFINITY)
- value.finite?.should == false
- end
+ it "returns false for positive complex with infinite imaginary" do
+ value = Complex(1, Float::INFINITY)
+ value.should_not.finite?
+ end
- it "returns false for negative infinity" do
- value = -Complex(Float::INFINITY, 42)
- value.finite?.should == false
- end
+ it "returns false for negative infinity" do
+ value = -Complex(Float::INFINITY, 42)
+ value.should_not.finite?
+ end
- it "returns false for negative complex with infinite imaginary" do
- value = -Complex(1, Float::INFINITY)
- value.finite?.should == false
- end
+ it "returns false for negative complex with infinite imaginary" do
+ value = -Complex(1, Float::INFINITY)
+ value.should_not.finite?
+ end
- ruby_bug "#14014", "2.4"..."2.5" do
- it "returns false for NaN" do
- value = Complex(Float::NAN, Float::NAN)
- value.finite?.should == false
- end
- end
+ it "returns false for NaN" do
+ value = Complex(Float::NAN, Float::NAN)
+ value.should_not.finite?
end
end
diff --git a/spec/ruby/core/complex/hash_spec.rb b/spec/ruby/core/complex/hash_spec.rb
index db4b3590df..cad283309d 100644
--- a/spec/ruby/core/complex/hash_spec.rb
+++ b/spec/ruby/core/complex/hash_spec.rb
@@ -1,6 +1,16 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/hash', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#hash" do
- it_behaves_like(:complex_hash, :hash)
+ 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/core/complex/imag_spec.rb b/spec/ruby/core/complex/imag_spec.rb
index 6aa8803f5d..2bafd1ab54 100644
--- a/spec/ruby/core/complex/imag_spec.rb
+++ b/spec/ruby/core/complex/imag_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/image', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/image'
describe "Complex#imag" do
- it_behaves_like(:complex_image, :imag)
+ it_behaves_like :complex_image, :imag
end
diff --git a/spec/ruby/core/complex/imaginary_spec.rb b/spec/ruby/core/complex/imaginary_spec.rb
index ecae19283b..a8a1bfea90 100644
--- a/spec/ruby/core/complex/imaginary_spec.rb
+++ b/spec/ruby/core/complex/imaginary_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/image', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/image'
describe "Complex#imaginary" do
it_behaves_like :complex_image, :imaginary
diff --git a/spec/ruby/core/complex/infinite_spec.rb b/spec/ruby/core/complex/infinite_spec.rb
index 79792c3169..9e48860dee 100644
--- a/spec/ruby/core/complex/infinite_spec.rb
+++ b/spec/ruby/core/complex/infinite_spec.rb
@@ -1,34 +1,32 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-ruby_version_is "2.4" do
- describe "Complex#infinite?" do
- it "returns nil if magnitude is finite" do
- (1+1i).infinite?.should == nil
- end
+describe "Complex#infinite?" do
+ it "returns nil if magnitude is finite" do
+ (1+1i).infinite?.should == nil
+ end
- it "returns 1 for positive infinity" do
- value = Complex(Float::INFINITY, 42).infinite?
- value.should == 1
- end
+ it "returns 1 for positive infinity" do
+ value = Complex(Float::INFINITY, 42).infinite?
+ value.should == 1
+ end
- it "returns 1 for positive complex with infinite imaginary" do
- value = Complex(1, Float::INFINITY).infinite?
- value.should == 1
- end
+ it "returns 1 for positive complex with infinite imaginary" do
+ value = Complex(1, Float::INFINITY).infinite?
+ value.should == 1
+ end
- it "returns -1 for negative infinity" do
- value = -Complex(Float::INFINITY, 42).infinite?
- value.should == -1
- end
+ it "returns -1 for negative infinity" do
+ value = -Complex(Float::INFINITY, 42).infinite?
+ value.should == -1
+ end
- it "returns -1 for negative complex with infinite imaginary" do
- value = -Complex(1, Float::INFINITY).infinite?
- value.should == -1
- end
+ it "returns -1 for negative complex with infinite imaginary" do
+ value = -Complex(1, Float::INFINITY).infinite?
+ value.should == -1
+ end
- it "returns nil for NaN" do
- value = Complex(0, Float::NAN).infinite?
- value.should == nil
- end
+ it "returns nil for NaN" do
+ value = Complex(0, Float::NAN).infinite?
+ value.should == nil
end
end
diff --git a/spec/ruby/core/complex/inspect_spec.rb b/spec/ruby/core/complex/inspect_spec.rb
index b766e7f730..045be94b22 100644
--- a/spec/ruby/core/complex/inspect_spec.rb
+++ b/spec/ruby/core/complex/inspect_spec.rb
@@ -1,5 +1,37 @@
-require File.expand_path('../../../shared/complex/inspect', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../numeric/fixtures/classes'
describe "Complex#inspect" do
- it_behaves_like(:complex_inspect, :inspect)
+ 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
+
+ it "calls #inspect on real and imaginary" do
+ real = NumericSpecs::Subclass.new
+ # + because of https://bugs.ruby-lang.org/issues/20337
+ real.should_receive(:inspect).and_return(+"1")
+ imaginary = NumericSpecs::Subclass.new
+ imaginary.should_receive(:inspect).and_return("2")
+ imaginary.should_receive(:<).any_number_of_times.and_return(false)
+ Complex(real, imaginary).inspect.should == "(1+2i)"
+ end
+
+ it "adds an `*' before the `i' if the last character of the imaginary part is not numeric" do
+ real = NumericSpecs::Subclass.new
+ # + because of https://bugs.ruby-lang.org/issues/20337
+ real.should_receive(:inspect).and_return(+"(1)")
+ imaginary = NumericSpecs::Subclass.new
+ imaginary.should_receive(:inspect).and_return("(2)")
+ imaginary.should_receive(:<).any_number_of_times.and_return(false)
+ Complex(real, imaginary).inspect.should == "((1)+(2)*i)"
+ end
end
diff --git a/spec/ruby/core/complex/integer_spec.rb b/spec/ruby/core/complex/integer_spec.rb
index 54b420e62c..0957accb70 100644
--- a/spec/ruby/core/complex/integer_spec.rb
+++ b/spec/ruby/core/complex/integer_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../../spec_helper'
+
describe "Complex#integer?" do
it "returns false for a Complex with no imaginary part" do
Complex(20).integer?.should be_false
diff --git a/spec/ruby/core/complex/magnitude_spec.rb b/spec/ruby/core/complex/magnitude_spec.rb
index e9175d763e..86f3b29868 100644
--- a/spec/ruby/core/complex/magnitude_spec.rb
+++ b/spec/ruby/core/complex/magnitude_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/abs', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/abs'
describe "Complex#magnitude" do
- it_behaves_like(:complex_abs, :magnitude)
+ it_behaves_like :complex_abs, :magnitude
end
diff --git a/spec/ruby/core/complex/marshal_dump_spec.rb b/spec/ruby/core/complex/marshal_dump_spec.rb
index 8d37929f54..116899b0ad 100644
--- a/spec/ruby/core/complex/marshal_dump_spec.rb
+++ b/spec/ruby/core/complex/marshal_dump_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#marshal_dump" do
it "is a private method" do
diff --git a/spec/ruby/core/complex/minus_spec.rb b/spec/ruby/core/complex/minus_spec.rb
index 2b7b8bb270..7c104ce784 100644
--- a/spec/ruby/core/complex/minus_spec.rb
+++ b/spec/ruby/core/complex/minus_spec.rb
@@ -1,5 +1,45 @@
-require File.expand_path('../../../shared/complex/minus', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#-" do
- it_behaves_like :complex_minus, :-
+ 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/core/complex/multiply_spec.rb b/spec/ruby/core/complex/multiply_spec.rb
index 7f600fc1ab..35bf7c8455 100644
--- a/spec/ruby/core/complex/multiply_spec.rb
+++ b/spec/ruby/core/complex/multiply_spec.rb
@@ -1,5 +1,49 @@
-require File.expand_path('../../../shared/complex/multiply', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#*" do
- it_behaves_like :complex_multiply, :*
+ 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/core/complex/negative_spec.rb b/spec/ruby/core/complex/negative_spec.rb
index 5b51933106..62ab89c04a 100644
--- a/spec/ruby/core/complex/negative_spec.rb
+++ b/spec/ruby/core/complex/negative_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#negative?" do
it "is undefined" do
c = Complex(1)
c.methods.should_not include(:negative?)
- lambda {
+ -> {
c.negative?
}.should raise_error(NoMethodError)
end
diff --git a/spec/ruby/core/complex/numerator_spec.rb b/spec/ruby/core/complex/numerator_spec.rb
index 8c0e8761bd..7ab66e6a61 100644
--- a/spec/ruby/core/complex/numerator_spec.rb
+++ b/spec/ruby/core/complex/numerator_spec.rb
@@ -1,5 +1,19 @@
-require File.expand_path('../../../shared/complex/numerator', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#numerator" do
- it_behaves_like(:complex_numerator, :numerator)
+ 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/core/complex/phase_spec.rb b/spec/ruby/core/complex/phase_spec.rb
index c17f922c7f..89574bf533 100644
--- a/spec/ruby/core/complex/phase_spec.rb
+++ b/spec/ruby/core/complex/phase_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#phase" do
it_behaves_like :complex_arg, :phase
diff --git a/spec/ruby/core/complex/plus_spec.rb b/spec/ruby/core/complex/plus_spec.rb
index 076582681f..2056ca786c 100644
--- a/spec/ruby/core/complex/plus_spec.rb
+++ b/spec/ruby/core/complex/plus_spec.rb
@@ -1,5 +1,45 @@
-require File.expand_path('../../../shared/complex/plus', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#+" do
- it_behaves_like :complex_plus, :+
+ 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/core/complex/polar_spec.rb b/spec/ruby/core/complex/polar_spec.rb
index d847e916ff..56335584ef 100644
--- a/spec/ruby/core/complex/polar_spec.rb
+++ b/spec/ruby/core/complex/polar_spec.rb
@@ -1,14 +1,41 @@
-require File.expand_path('../../../shared/complex/polar', __FILE__)
+require_relative '../../spec_helper'
describe "Complex.polar" do
- it_behaves_like(:complex_polar_class, :polar)
+ 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
it "raises a TypeError when given non real arguments" do
- lambda{ Complex.polar(nil) }.should raise_error(TypeError)
- lambda{ Complex.polar(nil, nil) }.should raise_error(TypeError)
+ ->{ Complex.polar(nil) }.should raise_error(TypeError)
+ ->{ Complex.polar(nil, nil) }.should raise_error(TypeError)
+ end
+
+ it "computes the real values of the real & imaginary parts from the polar form" do
+ a = Complex.polar(1.0+0.0i, Math::PI/2+0.0i)
+ a.real.should be_close(0.0, TOLERANCE)
+ a.imag.should be_close(1.0, TOLERANCE)
+ a.real.real?.should be_true
+ a.imag.real?.should be_true
+
+ b = Complex.polar(1+0.0i)
+ b.real.should be_close(1.0, TOLERANCE)
+ b.imag.should be_close(0.0, TOLERANCE)
+ b.real.real?.should be_true
+ b.imag.real?.should be_true
end
end
describe "Complex#polar" do
- it_behaves_like(:complex_polar, :polar)
+ 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/core/complex/positive_spec.rb b/spec/ruby/core/complex/positive_spec.rb
index 88898d31cf..f1bad8608c 100644
--- a/spec/ruby/core/complex/positive_spec.rb
+++ b/spec/ruby/core/complex/positive_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#positive?" do
it "is undefined" do
c = Complex(1)
c.methods.should_not include(:positive?)
- lambda {
+ -> {
c.positive?
}.should raise_error(NoMethodError)
end
diff --git a/spec/ruby/core/complex/quo_spec.rb b/spec/ruby/core/complex/quo_spec.rb
index cb3f1203b4..ee6fd65c79 100644
--- a/spec/ruby/core/complex/quo_spec.rb
+++ b/spec/ruby/core/complex/quo_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/divide', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/divide'
describe "Complex#quo" do
it_behaves_like :complex_divide, :quo
diff --git a/spec/ruby/core/complex/rationalize_spec.rb b/spec/ruby/core/complex/rationalize_spec.rb
index 2dd1e9b122..043b8ddf2a 100644
--- a/spec/ruby/core/complex/rationalize_spec.rb
+++ b/spec/ruby/core/complex/rationalize_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#rationalize" do
it "raises RangeError if self has non-zero imaginary part" do
- lambda { Complex(1,5).rationalize }.should raise_error(RangeError)
+ -> { Complex(1,5).rationalize }.should raise_error(RangeError)
end
it "raises RangeError if self has 0.0 imaginary part" do
- lambda { Complex(1,0.0).rationalize }.should raise_error(RangeError)
+ -> { Complex(1,0.0).rationalize }.should raise_error(RangeError)
end
it "returns a Rational if self has zero imaginary part" do
@@ -23,7 +25,7 @@ describe "Complex#rationalize" do
end
it "raises ArgumentError when passed more than one argument" do
- lambda { Complex(1,0).rationalize(0.1, 0.1) }.should raise_error(ArgumentError)
- lambda { Complex(1,0).rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError)
+ -> { Complex(1,0).rationalize(0.1, 0.1) }.should raise_error(ArgumentError)
+ -> { Complex(1,0).rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/complex/real_spec.rb b/spec/ruby/core/complex/real_spec.rb
index 1293e02d3c..2ea791c005 100644
--- a/spec/ruby/core/complex/real_spec.rb
+++ b/spec/ruby/core/complex/real_spec.rb
@@ -1,7 +1,12 @@
-require File.expand_path('../../../shared/complex/real', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#real" do
- it_behaves_like(:complex_real, :real)
+ 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
describe "Complex#real?" do
diff --git a/spec/ruby/core/complex/rect_spec.rb b/spec/ruby/core/complex/rect_spec.rb
index cf2ff9e83b..9e95f3efc2 100644
--- a/spec/ruby/core/complex/rect_spec.rb
+++ b/spec/ruby/core/complex/rect_spec.rb
@@ -1,9 +1,10 @@
-require File.expand_path('../../../shared/complex/rect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/rect'
describe "Complex#rect" do
- it_behaves_like(:complex_rect, :rect)
+ it_behaves_like :complex_rect, :rect
end
describe "Complex.rect" do
- it_behaves_like(:complex_rect_class, :rect)
+ it_behaves_like :complex_rect_class, :rect
end
diff --git a/spec/ruby/core/complex/rectangular_spec.rb b/spec/ruby/core/complex/rectangular_spec.rb
index 0eb29c3500..d4b8ad9782 100644
--- a/spec/ruby/core/complex/rectangular_spec.rb
+++ b/spec/ruby/core/complex/rectangular_spec.rb
@@ -1,9 +1,10 @@
-require File.expand_path('../../../shared/complex/rect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/rect'
describe "Complex#rectangular" do
- it_behaves_like(:complex_rect, :rectangular)
+ it_behaves_like :complex_rect, :rectangular
end
describe "Complex.rectangular" do
- it_behaves_like(:complex_rect_class, :rectangular)
+ it_behaves_like :complex_rect_class, :rectangular
end
diff --git a/spec/ruby/core/complex/shared/abs.rb b/spec/ruby/core/complex/shared/abs.rb
new file mode 100644
index 0000000000..2299479341
--- /dev/null
+++ b/spec/ruby/core/complex/shared/abs.rb
@@ -0,0 +1,10 @@
+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/core/complex/shared/arg.rb b/spec/ruby/core/complex/shared/arg.rb
new file mode 100644
index 0000000000..c81f197433
--- /dev/null
+++ b/spec/ruby/core/complex/shared/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/core/complex/shared/conjugate.rb b/spec/ruby/core/complex/shared/conjugate.rb
new file mode 100644
index 0000000000..d1ae47bcb6
--- /dev/null
+++ b/spec/ruby/core/complex/shared/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/core/complex/shared/divide.rb b/spec/ruby/core/complex/shared/divide.rb
new file mode 100644
index 0000000000..a60802c74c
--- /dev/null
+++ b/spec/ruby/core/complex/shared/divide.rb
@@ -0,0 +1,82 @@
+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
+ -> { 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/core/complex/shared/image.rb b/spec/ruby/core/complex/shared/image.rb
new file mode 100644
index 0000000000..f839dbcaf9
--- /dev/null
+++ b/spec/ruby/core/complex/shared/image.rb
@@ -0,0 +1,8 @@
+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/core/complex/shared/rect.rb b/spec/ruby/core/complex/shared/rect.rb
new file mode 100644
index 0000000000..4ac294e771
--- /dev/null
+++ b/spec/ruby/core/complex/shared/rect.rb
@@ -0,0 +1,94 @@
+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|
+ -> { 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)
+ -> { 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)
+ -> { 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
+ -> { Complex.send(@method, :sym) }.should raise_error(TypeError)
+ -> { Complex.send(@method, 0, :sym) }.should raise_error(TypeError)
+ end
+ end
+end
diff --git a/spec/ruby/core/complex/to_c_spec.rb b/spec/ruby/core/complex/to_c_spec.rb
new file mode 100644
index 0000000000..5ce01d9d4e
--- /dev/null
+++ b/spec/ruby/core/complex/to_c_spec.rb
@@ -0,0 +1,12 @@
+require_relative '../../spec_helper'
+
+describe "Complex#to_c" do
+ it "returns self" do
+ value = Complex(1, 5)
+ value.to_c.should equal(value)
+ end
+
+ it 'returns the same value' do
+ Complex(1, 5).to_c.should == Complex(1, 5)
+ end
+end
diff --git a/spec/ruby/core/complex/to_f_spec.rb b/spec/ruby/core/complex/to_f_spec.rb
index 33342e61cc..b53471c1fc 100644
--- a/spec/ruby/core/complex/to_f_spec.rb
+++ b/spec/ruby/core/complex/to_f_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_f" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_f to the real part" do
real = mock_numeric('real')
real.should_receive(:to_f).and_return(:f)
@@ -29,13 +29,13 @@ describe "Complex#to_f" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_f }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_f }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
it "raises RangeError" do
- lambda { Complex(0, 0.0).to_f }.should raise_error(RangeError)
+ -> { Complex(0, 0.0).to_f }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/complex/to_i_spec.rb b/spec/ruby/core/complex/to_i_spec.rb
index ea8b199b2e..1e78f5ec0e 100644
--- a/spec/ruby/core/complex/to_i_spec.rb
+++ b/spec/ruby/core/complex/to_i_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_i" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_i to the real part" do
real = mock_numeric('real')
real.should_receive(:to_i).and_return(:i)
@@ -29,13 +29,13 @@ describe "Complex#to_i" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_i }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_i }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
it "raises RangeError" do
- lambda { Complex(0, 0.0).to_i }.should raise_error(RangeError)
+ -> { Complex(0, 0.0).to_i }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/complex/to_r_spec.rb b/spec/ruby/core/complex/to_r_spec.rb
index 92fcdd3862..788027a500 100644
--- a/spec/ruby/core/complex/to_r_spec.rb
+++ b/spec/ruby/core/complex/to_r_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_r" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_r to the real part" do
real = mock_numeric('real')
real.should_receive(:to_r).and_return(:r)
@@ -29,13 +29,21 @@ describe "Complex#to_r" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_r }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_r }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
- it "raises RangeError" do
- lambda { Complex(0, 0.0).to_r }.should raise_error(RangeError)
+ ruby_version_is ''...'3.4' do
+ it "raises RangeError" do
+ -> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
+ end
+ end
+
+ ruby_version_is '3.4' do
+ it "returns a Rational" do
+ Complex(0, 0.0).to_r.should == 0r
+ end
end
end
end
diff --git a/spec/ruby/core/complex/to_s_spec.rb b/spec/ruby/core/complex/to_s_spec.rb
index c398bb000e..ceccffe470 100644
--- a/spec/ruby/core/complex/to_s_spec.rb
+++ b/spec/ruby/core/complex/to_s_spec.rb
@@ -1,5 +1,55 @@
-require File.expand_path('../../../shared/complex/to_s', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../numeric/fixtures/classes'
describe "Complex#to_s" do
- it_behaves_like(:complex_to_s, :to_s)
+ 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
+ guard -> { !defined?(Math.rsqrt) } 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
+
+ it "treats real and imaginary parts as strings" do
+ real = NumericSpecs::Subclass.new
+ # + because of https://bugs.ruby-lang.org/issues/20337
+ real.should_receive(:to_s).and_return(+"1")
+ imaginary = NumericSpecs::Subclass.new
+ imaginary.should_receive(:to_s).and_return("2")
+ imaginary.should_receive(:<).any_number_of_times.and_return(false)
+ Complex(real, imaginary).to_s.should == "1+2i"
+ end
end
diff --git a/spec/ruby/core/complex/uminus_spec.rb b/spec/ruby/core/complex/uminus_spec.rb
index 1bf56e770b..c0184e11de 100644
--- a/spec/ruby/core/complex/uminus_spec.rb
+++ b/spec/ruby/core/complex/uminus_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#-@" do
it "sends #-@ to the real and imaginary parts and returns a Complex with the resulting respective parts" do