diff options
Diffstat (limited to 'spec/ruby/core/comparable')
| -rw-r--r-- | spec/ruby/core/comparable/between_spec.rb | 25 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/clamp_spec.rb | 223 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/equal_value_spec.rb | 114 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/fixtures/classes.rb | 37 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/gt_spec.rb | 43 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/gte_spec.rb | 47 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/lt_spec.rb | 49 | ||||
| -rw-r--r-- | spec/ruby/core/comparable/lte_spec.rb | 46 |
8 files changed, 584 insertions, 0 deletions
diff --git a/spec/ruby/core/comparable/between_spec.rb b/spec/ruby/core/comparable/between_spec.rb new file mode 100644 index 0000000000..fd79bb9b4c --- /dev/null +++ b/spec/ruby/core/comparable/between_spec.rb @@ -0,0 +1,25 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Comparable#between?" do + it "returns true if self is greater than or equal to the first and less than or equal to the second argument" do + a = ComparableSpecs::Weird.new(-1) + b = ComparableSpecs::Weird.new(0) + c = ComparableSpecs::Weird.new(1) + d = ComparableSpecs::Weird.new(2) + + a.between?(a, a).should == true + a.between?(a, b).should == true + a.between?(a, c).should == true + a.between?(a, d).should == true + c.between?(c, d).should == true + d.between?(d, d).should == true + c.between?(a, d).should == true + + a.between?(b, b).should == false + a.between?(b, c).should == false + a.between?(b, d).should == false + c.between?(a, a).should == false + c.between?(a, b).should == false + end +end diff --git a/spec/ruby/core/comparable/clamp_spec.rb b/spec/ruby/core/comparable/clamp_spec.rb new file mode 100644 index 0000000000..eb1dc1ff98 --- /dev/null +++ b/spec/ruby/core/comparable/clamp_spec.rb @@ -0,0 +1,223 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe 'Comparable#clamp' do + it 'raises an Argument error unless the 2 parameters are correctly ordered' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(3) + + -> { c.clamp(two, one) }.should.raise(ArgumentError) + one.should_receive(:<=>).any_number_of_times.and_return(nil) + -> { c.clamp(one, two) }.should.raise(ArgumentError) + end + + it 'returns self if within the given parameters' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + three = ComparableSpecs::WithOnlyCompareDefined.new(3) + c = ComparableSpecs::Weird.new(2) + + c.clamp(one, two).should.equal?(c) + c.clamp(two, two).should.equal?(c) + c.clamp(one, three).should.equal?(c) + c.clamp(two, three).should.equal?(c) + end + + it 'returns the min parameter if less than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(0) + + c.clamp(one, two).should.equal?(one) + end + + it 'returns the max parameter if greater than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(3) + + c.clamp(one, two).should.equal?(two) + end + + context 'max is nil' do + it 'returns min if less than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(0) + c.clamp(one, nil).should.equal?(one) + end + + it 'always returns self if greater than min' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(2) + c.clamp(one, nil).should.equal?(c) + end + end + + context 'min is nil' do + it 'returns max if greater than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(2) + c.clamp(nil, one).should.equal?(one) + end + + it 'always returns self if less than max' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(0) + c.clamp(nil, one).should.equal?(c) + end + end + + it 'always returns self when min is nil and max is nil' do + c = ComparableSpecs::Weird.new(1) + c.clamp(nil, nil).should.equal?(c) + end + + it 'returns self if within the given range parameters' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + three = ComparableSpecs::WithOnlyCompareDefined.new(3) + c = ComparableSpecs::Weird.new(2) + + c.clamp(one..two).should.equal?(c) + c.clamp(two..two).should.equal?(c) + c.clamp(one..three).should.equal?(c) + c.clamp(two..three).should.equal?(c) + end + + it 'returns the minimum value of the range parameters if less than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(0) + + c.clamp(one..two).should.equal?(one) + end + + it 'returns the maximum value of the range parameters if greater than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(3) + + c.clamp(one..two).should.equal?(two) + end + + it 'raises an Argument error if the range parameter is exclusive' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(3) + + -> { c.clamp(one...two) }.should.raise(ArgumentError) + end + + context 'with nil as the max argument' do + it 'returns min argument if less than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + zero = ComparableSpecs::WithOnlyCompareDefined.new(0) + c = ComparableSpecs::Weird.new(0) + + c.clamp(one, nil).should.equal?(one) + c.clamp(zero, nil).should.equal?(c) + end + + it 'always returns self if greater than min argument' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(2) + + c.clamp(one, nil).should.equal?(c) + c.clamp(two, nil).should.equal?(c) + end + end + + context 'with endless range' do + it 'returns minimum value of the range parameters if less than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + zero = ComparableSpecs::WithOnlyCompareDefined.new(0) + c = ComparableSpecs::Weird.new(0) + + c.clamp(one..).should.equal?(one) + c.clamp(zero..).should.equal?(c) + end + + it 'always returns self if greater than minimum value of the range parameters' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + two = ComparableSpecs::WithOnlyCompareDefined.new(2) + c = ComparableSpecs::Weird.new(2) + + c.clamp(one..).should.equal?(c) + c.clamp(two..).should.equal?(c) + end + + it 'works with exclusive range' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(2) + + c.clamp(one...).should.equal?(c) + end + end + + context 'with nil as the min argument' do + it 'returns max argument if greater than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(2) + + c.clamp(nil, one).should.equal?(one) + end + + it 'always returns self if less than max argument' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + zero = ComparableSpecs::WithOnlyCompareDefined.new(0) + c = ComparableSpecs::Weird.new(0) + + c.clamp(nil, one).should.equal?(c) + c.clamp(nil, zero).should.equal?(c) + end + end + + context 'with beginless range' do + it 'returns maximum value of the range parameters if greater than it' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(2) + + c.clamp(..one).should.equal?(one) + end + + it 'always returns self if less than maximum value of the range parameters' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + zero = ComparableSpecs::WithOnlyCompareDefined.new(0) + c = ComparableSpecs::Weird.new(0) + + c.clamp(..one).should.equal?(c) + c.clamp(..zero).should.equal?(c) + end + + it 'raises an Argument error if the range parameter is exclusive' do + one = ComparableSpecs::WithOnlyCompareDefined.new(1) + c = ComparableSpecs::Weird.new(0) + + -> { c.clamp(...one) }.should.raise(ArgumentError) + end + end + + context 'with nil as the min and the max argument' do + it 'always returns self' do + c = ComparableSpecs::Weird.new(1) + + c.clamp(nil, nil).should.equal?(c) + end + end + + context 'with beginless-and-endless range' do + it 'always returns self' do + c = ComparableSpecs::Weird.new(1) + + c.clamp(nil..nil).should.equal?(c) + end + + it 'works with exclusive range' do + c = ComparableSpecs::Weird.new(2) + + c.clamp(nil...nil).should.equal?(c) + end + end +end diff --git a/spec/ruby/core/comparable/equal_value_spec.rb b/spec/ruby/core/comparable/equal_value_spec.rb new file mode 100644 index 0000000000..3af40d1c7e --- /dev/null +++ b/spec/ruby/core/comparable/equal_value_spec.rb @@ -0,0 +1,114 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Comparable#==" do + a = b = nil + before :each do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(10) + end + + it "returns true if other is the same as self" do + (a == a).should == true + (b == b).should == true + end + + it "calls #<=> on self with other and returns true if #<=> returns 0" do + a.should_receive(:<=>).once.and_return(0) + (a == b).should == true + end + + it "calls #<=> on self with other and returns true if #<=> returns 0.0" do + a.should_receive(:<=>).once.and_return(0.0) + (a == b).should == true + end + + it "returns false if calling #<=> on self returns a positive Integer" do + a.should_receive(:<=>).once.and_return(1) + (a == b).should == false + end + + it "returns false if calling #<=> on self returns a negative Integer" do + a.should_receive(:<=>).once.and_return(-1) + (a == b).should == false + end + + context "when #<=> returns nil" do + before :each do + a.should_receive(:<=>).once.and_return(nil) + end + + it "returns false" do + (a == b).should == false + end + end + + context "when #<=> returns nor nil neither an Integer" do + before :each do + a.should_receive(:<=>).once.and_return("abc") + end + + it "raises an ArgumentError" do + -> { (a == b) }.should.raise(ArgumentError) + end + end + + context "when #<=> raises an exception" do + context "if it is a StandardError" do + before :each do + a.should_receive(:<=>).once.and_raise(StandardError) + end + + it "lets it go through" do + -> { (a == b) }.should.raise(StandardError) + end + end + + context "if it is a subclass of StandardError" do + # TypeError < StandardError + before :each do + a.should_receive(:<=>).once.and_raise(TypeError) + end + + it "lets it go through" do + -> { (a == b) }.should.raise(TypeError) + end + end + + it "lets it go through if it is not a StandardError" do + a.should_receive(:<=>).once.and_raise(Exception) + -> { (a == b) }.should.raise(Exception) + end + end + + context "when #<=> is not defined" do + before :each do + @a = ComparableSpecs::WithoutCompareDefined.new + @b = ComparableSpecs::WithoutCompareDefined.new + end + + it "returns true for identical objects" do + @a.should == @a + end + + it "returns false and does not recurse infinitely" do + @a.should_not == @b + end + end + + context "when #<=> calls super" do + before :each do + @a = ComparableSpecs::CompareCallingSuper.new + @b = ComparableSpecs::CompareCallingSuper.new + end + + it "returns true for identical objects" do + @a.should == @a + end + + it "calls the defined #<=> only once for different objects" do + @a.should_not == @b + @a.calls.should == 1 + end + end +end diff --git a/spec/ruby/core/comparable/fixtures/classes.rb b/spec/ruby/core/comparable/fixtures/classes.rb new file mode 100644 index 0000000000..2bdabbf014 --- /dev/null +++ b/spec/ruby/core/comparable/fixtures/classes.rb @@ -0,0 +1,37 @@ +module ComparableSpecs + class WithOnlyCompareDefined + attr_reader :value + + def initialize(value) + @value = value + end + + def <=>(other) + return nil if other.nil? + self.value <=> other.value + end + end + + class Weird < WithOnlyCompareDefined + include Comparable + end + + class WithoutCompareDefined + include Comparable + end + + class CompareCallingSuper + include Comparable + + attr_reader :calls + + def initialize + @calls = 0 + end + + def <=>(other) + @calls += 1 + super(other) + end + end +end diff --git a/spec/ruby/core/comparable/gt_spec.rb b/spec/ruby/core/comparable/gt_spec.rb new file mode 100644 index 0000000000..cebb5464ad --- /dev/null +++ b/spec/ruby/core/comparable/gt_spec.rb @@ -0,0 +1,43 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Comparable#>" do + it "calls #<=> on self with other and returns true if #<=> returns any Integer greater than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(1) + (a > b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(0.1) + (a > b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(10000000) + (a > b).should == true + end + + it "returns false if calling #<=> on self returns 0 or any Integer less than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(10) + + a.should_receive(:<=>).any_number_of_times.and_return(0) + (a > b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(0.0) + (a > b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(-1.0) + (a > b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(-10000000) + (a > b).should == false + end + + it "raises an ArgumentError if calling #<=> on self returns nil" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(nil) + -> { (a > b) }.should.raise(ArgumentError) + end +end diff --git a/spec/ruby/core/comparable/gte_spec.rb b/spec/ruby/core/comparable/gte_spec.rb new file mode 100644 index 0000000000..16da81b3ea --- /dev/null +++ b/spec/ruby/core/comparable/gte_spec.rb @@ -0,0 +1,47 @@ +require_relative 'fixtures/classes' +require_relative '../../spec_helper' + +describe "Comparable#>=" do + it "calls #<=> on self with other and returns true if #<=> returns 0 or any Integer greater than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(0) + (a >= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(0.0) + (a >= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(1) + (a >= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(0.1) + (a >= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(10000000) + (a >= b).should == true + end + + it "returns false if calling #<=> on self returns any Integer less than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(10) + + + a.should_receive(:<=>).any_number_of_times.and_return(-0.1) + (a >= b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(-1.0) + (a >= b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(-10000000) + (a >= b).should == false + end + + it "raises an ArgumentError if calling #<=> on self returns nil" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(nil) + -> { (a >= b) }.should.raise(ArgumentError) + end +end diff --git a/spec/ruby/core/comparable/lt_spec.rb b/spec/ruby/core/comparable/lt_spec.rb new file mode 100644 index 0000000000..175646d0d7 --- /dev/null +++ b/spec/ruby/core/comparable/lt_spec.rb @@ -0,0 +1,49 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Comparable#<" do + it "calls #<=> on self with other and returns true if #<=> returns any Integer less than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(-1) + (a < b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(-0.1) + (a < b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(-10000000) + (a < b).should == true + end + + it "returns false if calling #<=> on self returns 0 or any Integer greater than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(10) + + a.should_receive(:<=>).any_number_of_times.and_return(0) + (a < b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(0.0) + (a < b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(1.0) + (a < b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(10000000) + (a < b).should == false + end + + it "raises an ArgumentError if calling #<=> on self returns nil" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(nil) + -> { (a < b) }.should.raise(ArgumentError) + end + + it "raises an argument error with a message containing the value" do + -> { ("foo" < 7) }.should.raise(ArgumentError) { |e| + e.message.should.include? "String with 7 failed" + } + end +end diff --git a/spec/ruby/core/comparable/lte_spec.rb b/spec/ruby/core/comparable/lte_spec.rb new file mode 100644 index 0000000000..8cbbd5ebb4 --- /dev/null +++ b/spec/ruby/core/comparable/lte_spec.rb @@ -0,0 +1,46 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Comparable#<=" do + it "calls #<=> on self with other and returns true if #<=> returns 0 or any Integer less than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(0) + (a <= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(0.0) + (a <= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(-1) + (a <= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(-0.1) + (a <= b).should == true + + a.should_receive(:<=>).any_number_of_times.and_return(-10000000) + (a <= b).should == true + end + + it "returns false if calling #<=> on self returns any Integer greater than 0" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(10) + + a.should_receive(:<=>).any_number_of_times.and_return(0.1) + (a <= b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(1.0) + (a <= b).should == false + + a.should_receive(:<=>).any_number_of_times.and_return(10000000) + (a <= b).should == false + end + + it "raises an ArgumentError if calling #<=> on self returns nil" do + a = ComparableSpecs::Weird.new(0) + b = ComparableSpecs::Weird.new(20) + + a.should_receive(:<=>).any_number_of_times.and_return(nil) + -> { (a <= b) }.should.raise(ArgumentError) + end +end |
