Permalink
Browse files

Add specs for subclass methods returning subclass instances

Previously, Date was hard coded in a few places, so that if you
did Class.new(Date).new + 1, you got an instance of Date back,
instead of an instance of the subclass. This adds specs for many
cases to ensure that the correct class is used.  In some cases,
these specs pass without code changes, in others the following
commit is required.

Problem pointed out by aquasync (ruby-ole gem author) as a comment
on issue #15.
  • Loading branch information...
1 parent ea3fa56 commit 3640f9cccc37a8338d0399fc5c3b98484b5e9d9b @jeremyevans committed Oct 18, 2010
@@ -17,6 +17,11 @@
d.should == Date.civil(2008, 4, 30)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.>>(-10).should be_kind_of(c)
+ end
+
it "should raise an error on non numeric parameters" do
lambda { Date.civil(2007,2,27) >> "hello" }.should raise_error(TypeError)
lambda { Date.civil(2007,2,27) >> Date.new }.should raise_error(TypeError)
View
@@ -14,6 +14,11 @@
d.should == Date.civil(2007, 2, 17)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.+(10).should be_kind_of(c)
+ end
+
it "should raise an error on non numeric parameters" do
lambda { Date.civil(2007,2,27) + "hello" }.should raise_error(TypeError)
lambda { Date.civil(2007,2,27) + Date.new }.should raise_error(TypeError)
View
@@ -67,6 +67,11 @@
proc{Date.civil(2008, 2, 30)}.should raise_error(ArgumentError)
proc{Date.civil(2009, 2, 29)}.should raise_error(ArgumentError)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.civil.should be_kind_of(c)
+ end
end
describe "Date.new" do
@@ -143,5 +148,4 @@
Date.valid_civil?(2008, -11, -10).should == true
end
end
-
end
@@ -91,6 +91,11 @@
proc{Date.commercial(2008, 54, 6)}.should raise_error(ArgumentError)
proc{Date.commercial(2009, 1, 8)}.should raise_error(ArgumentError)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.commercial.should be_kind_of(c)
+ end
end
ruby_version_is "" ... "1.9" do
@@ -9,6 +9,11 @@
Date.civil(1752, 9, 13).new_start(Date::ENGLAND).should == Date.civil(1752, 9, 13, Date::ENGLAND)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.new_start.should be_kind_of(c)
+ end
+
ruby_version_is "" ... "1.9" do
it "#newsg should be the same as new_start" do
Date.civil(1582, 10, 14, Date::ENGLAND).newsg.should == Date.civil(1582, 10, 14, Date::ENGLAND).new_start
@@ -45,6 +50,11 @@
Date.civil(1582, 10, 14).gregorian.should == Date.civil(1582, 10, 14, Date::GREGORIAN)
Date.civil(1752, 9, 14).gregorian.should == Date.civil(1752, 9, 14, Date::GREGORIAN)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.gregorian.should be_kind_of(c)
+ end
end
ruby_version_is "" ... "1.9" do
View
@@ -14,4 +14,10 @@
count.should == 17
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.downto(c.jd - 2) do |d|
+ d.should be_kind_of(c)
+ end.should be_kind_of(c)
+ end
end
View
@@ -24,6 +24,11 @@
proc{Date.jd(Date::JULIAN)}.should raise_error
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.should be_kind_of(c)
+ end
+
ruby_version_is "" ... "1.9" do
it ".new1 should be the same as jd" do
Date.new1(2454156).should == Date.jd(2454156)
@@ -43,6 +48,11 @@
Date.new!(2008, 1, 1).should == Date.jd(2008)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.new!.should be_kind_of(c)
+ end
+
it "should not accept more than 3 arguments" do
proc{Date.new!(2008, 1, 1, 1)}.should raise_error(ArgumentError)
end
@@ -16,6 +16,11 @@
d.should == Date.civil(2008, 2, 29)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.<<(-10).should be_kind_of(c)
+ end
+
it "should raise an error on non numeric parameters" do
lambda { Date.civil(2007,2,27) << "hello" }.should raise_error(TypeError)
lambda { Date.civil(2007,2,27) << Date.new }.should raise_error(TypeError)
View
@@ -14,6 +14,11 @@
d.should == Date.civil(2007, 5 ,2)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.-(10).should be_kind_of(c)
+ end
+
it "should be able to compute the different between two dates" do
(Date.civil(2007,2,27) - Date.civil(2007,2,27)).should == 0
(Date.civil(2007,2,27) - Date.civil(2007,2,26)).should == 1
@@ -13,6 +13,11 @@
it "should handle a negative argument by subtracting days" do
(Date.civil(2007,2,27).next_day(-2)).should == Date.civil(2007, 2, 25)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.next_day.should be_kind_of(c)
+ end
end
describe "Date#prev_day" do
@@ -27,6 +32,11 @@
it "should handle a negative argument by adding days" do
(Date.civil(2007,2,27).prev_day(-2)).should == Date.civil(2007, 3, 1)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.prev_day.should be_kind_of(c)
+ end
end
describe "Date#next_month" do
@@ -47,6 +57,11 @@
(Date.civil(2008,1,31).next_month).should == Date.civil(2008, 2, 29)
(Date.civil(2007,1,31).next_month(3)).should == Date.civil(2007, 4, 30)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.next_month.should be_kind_of(c)
+ end
end
describe "Date#prev_month" do
@@ -67,6 +82,11 @@
(Date.civil(2008,3,31).prev_month).should == Date.civil(2008, 2, 29)
(Date.civil(2007,3,31).prev_month(4)).should == Date.civil(2006, 11, 30)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.prev_month.should be_kind_of(c)
+ end
end
describe "Date#next_year" do
@@ -85,6 +105,11 @@
it "should handle adding a year where the new date is not a valid date" do
(Date.civil(2008,2,29).next_year).should == Date.civil(2009, 2, 28)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.next_year.should be_kind_of(c)
+ end
end
describe "Date#prev_year" do
@@ -103,6 +128,10 @@
it "should handle adding a year where the new date is not a valid date" do
(Date.civil(2008,2,29).prev_year).should == Date.civil(2007, 2, 28)
end
- end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.prev_year.should be_kind_of(c)
+ end
+ end
end
@@ -25,6 +25,11 @@
lambda { Date.ordinal(2008, 367) }.should raise_error(ArgumentError)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.ordinal.should be_kind_of(c)
+ end
+
ruby_version_is "" ... "1.9" do
it ".new2 should be the same as ordinal" do
Date.new2(2008, 10).should == Date.ordinal(2008, 10)
View
@@ -57,6 +57,12 @@
Date.parse('2008-10-11', true, 1).should == Date.civil(2008, 10, 11)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.parse.should be_kind_of(c)
+ c.parse('20081011').should be_kind_of(c)
+ end
+
it "raises errors for invalid dates" do
lambda { Date.parse("") }.should raise_error(ArgumentError)
lambda { Date.parse("2009-02-29") }.should raise_error(ArgumentError)
View
@@ -84,5 +84,16 @@
it ".xmlschema should parse an ISO8601 format" do
Date.xmlschema("2009-01-02").should == Date.new(2009, 1, 2)
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.httpdate("Fri, 02 Jan 2009 00:00:00 GMT").should be_kind_of(c)
+ c.iso8601("2009-01-02").should be_kind_of(c)
+ c.jisx0301("H21.01.02").should be_kind_of(c)
+ c.rfc2822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c)
+ c.rfc822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c)
+ c.rfc3339("2009-01-02T00:00:00+00:00").should be_kind_of(c)
+ c.xmlschema("2009-01-02").should be_kind_of(c)
+ end
end
end
View
@@ -128,4 +128,10 @@
count.should == 0
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.step(c.jd + 2) do |d|
+ d.should be_kind_of(c)
+ end.should be_kind_of(c)
+ end
end
@@ -22,6 +22,12 @@
Date.strptime('2008-10-11', '%Y-%m-%d', 1).should == Date.civil(2008, 10, 11)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.strptime.should be_kind_of(c)
+ c.strptime('20081011', '%Y%m%d').should be_kind_of(c)
+ end
+
it "raises errors for invalid dates" do
lambda { Date.strptime("") }.should raise_error(ArgumentError)
lambda { Date.strptime("", "") }.should raise_error(ArgumentError)
View
@@ -14,6 +14,11 @@
ds.succ.should == Date.ordinal(2009, 1)
end
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.succ.should be_kind_of(c)
+ end
+
it "should be aliased as next" do
Date.civil(2008, 10, 11).next.should == Date.civil(2008, 10, 12)
end
View
@@ -12,4 +12,9 @@
it ".today should have an optional sg value" do
Date.today(1).should == Date.today
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.today.should be_kind_of(c)
+ end
end
View
@@ -14,4 +14,11 @@
count.should == 13
end
+
+ it "should keep the same class as the receiver" do
+ c = Class.new(Date)
+ c.jd.upto(c.jd + 2) do |d|
+ d.should be_kind_of(c)
+ end.should be_kind_of(c)
+ end
end

0 comments on commit 3640f9c

Please sign in to comment.