1

I have some database functions which I'm testing (to make sure my queries etc. work) -- in them, I'm de/serialising records (via Database.Esqueleto.Experimental) and these contain values of type UTCTime (and Maybe UTCTime, etc.).

The problem is that I get these sorts of errors in my tests:

1) Vulture.Database.EventRepository.addEvents correctly sets the event properties
       expected: 2023-05-06 21:52:13.441270819 UTC
        but got: 2023-05-06 21:52:13.441271 UTC

This is sort of annoying, but I don't know how to either manipulate UTCTime values to change the precision, or to change the way the equality works here.

Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
GTF
  • 8,031
  • 5
  • 36
  • 59
  • 1
    Do you need to test timestamps at all? There are certainly cases where it matters, but there are a lot of cases where all you're doing is testing the database. Your tests should cover your code, not an external component. – Carl May 08 '23 at 23:50
  • Well, "Your tests should cover your code" I agree -- what I'm trying to have test coverage over is the translation of my domain entities into the data-storage so that when I get them back out again, I have the right properties in the right places. These timestamps are part of the domain data, they aren't created/updated timestamps, so yeah I would like to be able to test them. – GTF May 09 '23 at 13:19

1 Answers1

1

As you've noticed, UTCTime by itself has a pretty sparse api. Just about everything interesting involves going via NominalDiffTime. For this case, I think you're best served by getting the difference between the two times and then making sure it's below some epsilon. For this, the relevant time function is diffUTCTime, and the rest takes advantage of the extensive set of instances available for NominalDiffTime. Thanks to the Num instance, we have abs available. Thanks to the Num and Fractional instances, we can use literals to create NominalDiffTime values. And of course there's Ord for comparisons...

let eps = 1e-5 in abs (diffUTCTime t1 t2) < eps

Feel free to adjust eps as desired. And of course, you might need to adjust the structure of the whole thing to get good diagnostics out of the test framework.

Remember this as the basic framework for working with UTCTime - those values are just points in time. The really interesting stuff involves working with NominalDiffTime values which represent intervals between UTCTime values. Those intervals have a much richer API for manipulating them then the points have.

Carl
  • 26,500
  • 4
  • 65
  • 86
  • 1
    Thanks. FWIW I defined an assertion for HSpec to capture this: ```shouldBeCloseTo :: HasCallStack => UTCTime -> UTCTime -> Expectation ``` – GTF May 09 '23 at 18:31