I occasionally get this error: 1) ''A puzzle once featured, should no longer be nominated'' FAILED expected: Sun May 04 09:10:26 -0700 2008, got: Sun May 04 09:10:26 -0700 2008 (using ==) ./spec/models/puzzle_spec.rb:180: So, the dates looks the same to me. Any ideas for how to debug? Joe
I''ve seen that one too. Maybe has to do with how equality is defined in the Time or DateTime class. I get around it by comparing the string-ified versions: foo.time.to_s.should == expected_time.to_s On Sat, May 3, 2008 at 9:17 AM, Joe Van Dyk <joe at pinkpucker.net> wrote:> I occasionally get this error: > > 1) > ''A puzzle once featured, should no longer be nominated'' FAILED > expected: Sun May 04 09:10:26 -0700 2008, > got: Sun May 04 09:10:26 -0700 2008 (using ==) > ./spec/models/puzzle_spec.rb:180: > > > > So, the dates looks the same to me. Any ideas for how to debug? > > Joe > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080503/7cb8294b/attachment.html>
On Sat, May 3, 2008 at 12:17 PM, Joe Van Dyk <joe at pinkpucker.net> wrote:> I occasionally get this error: > > 1) > ''A puzzle once featured, should no longer be nominated'' FAILED > expected: Sun May 04 09:10:26 -0700 2008, > got: Sun May 04 09:10:26 -0700 2008 (using ==) > ./spec/models/puzzle_spec.rb:180: > > > > So, the dates looks the same to me. Any ideas for how to debug?Just because too objects have the same to_s representation don''t mean they are equal: Are these, perhaps times rather than dates? k$ irb irb(main):001:0> Time.now == Time.now => false irb(main):002:0> a, b = Time.now, Time.now => [Sat May 03 12:23:12 -0400 2008, Sat May 03 12:23:12 -0400 2008] irb(main):003:0> a == b => false This is a similar issue to Floats where there''s more precision than the exernal representation shows. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
> > Just because too objects have the same to_s representation don''t mean > they are equal:The important equality in this case is what matters to the tester.> > This is a similar issue to Floats where there''s more precision than > the exernal representation shows. >Is there more precision than seconds in a Time instance? irb(main):006:0> a,b = Time.now, Time.now => [Sat May 03 11:06:31 -0700 2008, Sat May 03 11:06:31 -0700 2008] irb(main):007:0> puts a.to_i, b.to_i 1209837991 1209837991 => nil -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080503/6aee46f4/attachment.html>
On Sat, May 3, 2008 at 1:12 PM, Steve Downey <steve.downtown at gmail.com> wrote:> Is there more precision than seconds in a Time instance? > > irb(main):006:0> a,b = Time.now, Time.now > => [Sat May 03 11:06:31 -0700 2008, Sat May 03 11:06:31 -0700 2008] > irb(main):007:0> puts a.to_i, b.to_i > 1209837991 > 1209837991 > => nilThis came up this morning in #rspec; Time tracks microseconds which blows up equality:>> a, b = Time.now, Time.now=> [Sat May 03 13:15:31 -0500 2008, Sat May 03 13:15:31 -0500 2008]>> a == b=> false>> [a.usec, b.usec]=> [93308, 93309] Because of this, I tend to use ''should be_between()'' when handling times; someone else suggested the .to_i trick which is probably closer to what is intended, but for some reason I find it confusing. k
On May 3, 2008, at 2:16 PM, Kyle Hargraves wrote:> On Sat, May 3, 2008 at 1:12 PM, Steve Downey > <steve.downtown at gmail.com> wrote: >> Is there more precision than seconds in a Time instance? >> >> irb(main):006:0> a,b = Time.now, Time.now >> => [Sat May 03 11:06:31 -0700 2008, Sat May 03 11:06:31 -0700 2008] >> irb(main):007:0> puts a.to_i, b.to_i >> 1209837991 >> 1209837991 >> => nil > > This came up this morning in #rspec; Time tracks microseconds which > blows up equality: > >>> a, b = Time.now, Time.now > => [Sat May 03 13:15:31 -0500 2008, Sat May 03 13:15:31 -0500 2008] >>> a == b > => false >>> [a.usec, b.usec] > => [93308, 93309] > > Because of this, I tend to use ''should be_between()'' when handling > times; someone else suggested the .to_i trick which is probably closer > to what is intended, but for some reason I find it confusing.If I''m in a rails project, I like to use to_s(:db) to compare the times - that''s how they are stored in the database. Any greater precision (at least in MySQL) gets lost when the datetime is read out of the database. Scott
Hi-- On May 3, 2008, at 9:17 AM, Joe Van Dyk wrote:> I occasionally get this error: > > 1) > ''A puzzle once featured, should no longer be nominated'' FAILED > expected: Sun May 04 09:10:26 -0700 2008, > got: Sun May 04 09:10:26 -0700 2008 (using ==) > ./spec/models/puzzle_spec.rb:180: > > > > So, the dates looks the same to me. Any ideas for how to debug? > > JoeI monkeypatched DateTime (aieeeeee!) to get this effect. A custom matcher is probably a better solution. Here''s the monkeypatch: require File.dirname(__FILE__) + ''/../spec_helper'' class DateTime def close?(other_date, difference) (other_date.to_time.to_i - DateTime.now.to_time.to_i).abs < difference end end #Delete this context and add some real ones context "should be able to create a project viewer" do fixtures :project_viewers specify "fixtures should load two ProjectViewers" do pb = ProjectViewer.create(:comments => ''a comment'', :last_viewed_at => DateTime.now) pb.last_viewed_at.should_be_close(DateTime.now, 100) end end
If your code uses Date#now, always make sure you stub it in your specs. Always. On 5. mai. 2008, at 05.42, "s.ross" <cwdinfo at gmail.com> wrote:> Hi-- > > On May 3, 2008, at 9:17 AM, Joe Van Dyk wrote: > >> I occasionally get this error: >> >> 1) >> ''A puzzle once featured, should no longer be nominated'' FAILED >> expected: Sun May 04 09:10:26 -0700 2008, >> got: Sun May 04 09:10:26 -0700 2008 (using ==) >> ./spec/models/puzzle_spec.rb:180: >> >> >> >> So, the dates looks the same to me. Any ideas for how to debug? >> >> Joe > > I monkeypatched DateTime (aieeeeee!) to get this effect. A custom > matcher is probably a better solution. Here''s the monkeypatch: > > require File.dirname(__FILE__) + ''/../spec_helper'' > > class DateTime > def close?(other_date, difference) > (other_date.to_time.to_i - DateTime.now.to_time.to_i).abs < > difference > end > end > > #Delete this context and add some real ones > context "should be able to create a project viewer" do > fixtures :project_viewers > > specify "fixtures should load two ProjectViewers" do > pb = ProjectViewer.create(:comments => ''a > comment'', :last_viewed_at => DateTime.now) > pb.last_viewed_at.should_be_close(DateTime.now, 100) > end > end > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Yes, that was my first idea as well. The Time class is a little fucked up in that < a, b = Time.now, Time.now < a == b #=> false So if you''re using Time anywhere, you really ought to be stubbing it. "always" :) Pat On Sun, May 4, 2008 at 11:07 PM, Aslak Helles?y <aslak.hellesoy at gmail.com> wrote:> If your code uses Date#now, always make sure you stub it in your specs. > Always. > > > > On 5. mai. 2008, at 05.42, "s.ross" <cwdinfo at gmail.com> wrote: > > > > Hi-- > > > > On May 3, 2008, at 9:17 AM, Joe Van Dyk wrote: > > > > > > > I occasionally get this error: > > > > > > 1) > > > ''A puzzle once featured, should no longer be nominated'' FAILED > > > expected: Sun May 04 09:10:26 -0700 2008, > > > got: Sun May 04 09:10:26 -0700 2008 (using ==) > > > ./spec/models/puzzle_spec.rb:180: > > > > > > > > > > > > So, the dates looks the same to me. Any ideas for how to debug? > > > > > > Joe > > > > > > > I monkeypatched DateTime (aieeeeee!) to get this effect. A custom matcher > is probably a better solution. Here''s the monkeypatch: > > > > require File.dirname(__FILE__) + ''/../spec_helper'' > > > > class DateTime > > def close?(other_date, difference) > > (other_date.to_time.to_i - DateTime.now.to_time.to_i).abs < > difference > > end > > end > > > > #Delete this context and add some real ones > > context "should be able to create a project viewer" do > > fixtures :project_viewers > > > > specify "fixtures should load two ProjectViewers" do > > pb = ProjectViewer.create(:comments => ''a comment'', :last_viewed_at => > DateTime.now) > > pb.last_viewed_at.should_be_close(DateTime.now, 100) > > end > > end > > > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 5.5.2008, at 11.02, Pat Maddox wrote:> Yes, that was my first idea as well. The Time class is a little > fucked up in that > > < a, b = Time.now, Time.now > < a == b #=> falseThat''s definitely a gotcha but I wouldn''t necessarily say it''s fucked up. It''s just that Time#now returns the current (exact) point of time, so running it successively on the same machine will by definition return different values (by a tiny margin but still). The fact that the textual representation of the two look exactly the same certainly makes it confusing the first time get bitten by it, though :-) Cheers, //jarkko -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080505/37c5ca88/attachment.bin>
The (pretty much universal) problem with dates and times is that people use "date" and "time" to mean different things. There''s a java library called joda that provides a really clean vocabulary around this. An *instant* is a point in time. You shouldn''t be able to ask for two instants and get the same answer however close together you ask. (There''s probably something philosophical in there somewhere.) A *datetime* is a type of instant with millisecond precision that can tell you the time and date it represents, based on a timezone. The Ruby Time class represents an instant but renders itself as a datetime, hence the confusion (it has microsecond precision that you only get to see if you know to ask). A *local date* is a day when something happens, say 4th May 2008. My understanding of 4th May in the UK is bounded by different start and end instants than, say, David''s in the US, because of timezones, but we both know what we "mean" by 4th May 2008. A *duration* is a length of time in milliseconds. Given these atoms you can have fairly sensible conversations about times and dates. For instance, in the current example I might do this: Instant = Time # make it clear what I''m using it for ... Instant.new == Instant.new # false, but now I know why Cheers, Dan ps. and as Aslak says, make sure you control "time" in your examples - either by stubbing Time or by injecting your own Clock abstraction. 2008/5/5 Jarkko Laine <jarkko at jlaine.net>:> On 5.5.2008, at 11.02, Pat Maddox wrote: > > Yes, that was my first idea as well. The Time class is a little > > fucked up in that > > > > < a, b = Time.now, Time.now > > < a == b #=> false > > > > That''s definitely a gotcha but I wouldn''t necessarily say it''s fucked up. > It''s just that Time#now returns the current (exact) point of time, so > running it successively on the same machine will by definition return > different values (by a tiny margin but still). > > The fact that the textual representation of the two look exactly the same > certainly makes it confusing the first time get bitten by it, though :-) > > Cheers, > //jarkko > > -- > Jarkko Laine > http://jlaine.net > http://dotherightthing.com > http://www.railsecommerce.com > http://odesign.fi > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080505/acc33871/attachment.html>
On May 4, 2008, at 11:07 PM, Aslak Helles?y wrote:> If your code uses Date#now, always make sure you stub it in your > specs. Always.Yes, but the OP''s question was why do two "same" date objects compare as different. This is a typical problem with floating-point and anything that counts time. I used DateTime.now in my sample code below, but certainly I agree that specifying an exact object either by stubbing or explicit constant specification is a better idea. There will be cases, however, where a strict equality test can''t be trusted and one must compare something as being within some "close" tolerance. -s> On 5. mai. 2008, at 05.42, "s.ross" <cwdinfo at gmail.com> wrote: > >> Hi-- >> >> On May 3, 2008, at 9:17 AM, Joe Van Dyk wrote: >> >>> I occasionally get this error: >>> >>> 1) >>> ''A puzzle once featured, should no longer be nominated'' FAILED >>> expected: Sun May 04 09:10:26 -0700 2008, >>> got: Sun May 04 09:10:26 -0700 2008 (using ==) >>> ./spec/models/puzzle_spec.rb:180: >>> >>> >>> >>> So, the dates looks the same to me. Any ideas for how to debug? >>> >>> Joe >> >> I monkeypatched DateTime (aieeeeee!) to get this effect. A custom >> matcher is probably a better solution. Here''s the monkeypatch: >> >> require File.dirname(__FILE__) + ''/../spec_helper'' >> >> class DateTime >> def close?(other_date, difference) >> (other_date.to_time.to_i - DateTime.now.to_time.to_i).abs < >> difference >> end >> end >> >> #Delete this context and add some real ones >> context "should be able to create a project viewer" do >> fixtures :project_viewers >> >> specify "fixtures should load two ProjectViewers" do >> pb = ProjectViewer.create(:comments => ''a >> comment'', :last_viewed_at => DateTime.now) >> pb.last_viewed_at.should_be_close(DateTime.now, 100) >> end >> end >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users