convex-test handling dates differently than convex runtime
I've encountered the following two so far:
- local timezone is used instead of UTC (this is a big one)
-
Date.prototype.toString()
and Date.prototype.toISOString()
both work as expected (timezone aside), but when a Date
is coerced to a string without directly calling one of these methods, the mock test environment seems to use toISOString()
, whereas the convex runtime correctly produces the result of toString()
.13 Replies
Ah actually it seems that second point reflects the convex runtime being more similar to a browser environment, while the mock environment is based on Node, maybe? Is the convex runtime v8 based and the mock is node based perhaps?
Tangentially, I'm a bit curious why the actual convex runtime can't be used in convex-test, but I'm guessing that would require provisioning convex locally.
convex-test is a more like a library that provides mocks of
ctx
than a full runtime. the runtime is determined by how you run tests, like jest or vitest, which is probably Node. I suppose the package could mock out Date stuff too, but mocking a full convex runtime within Node sounds tricky. If you want the actual Convex runtime, that would run separately like https://stack.convex.dev/testing-with-local-oss-backendStack
Running tests using a local open-source backend
Convex recently released an open source version of the backend. We can use this to unit test Convex functions by running them with a local backend. Th...
Are you using "edge-runtime," that should help with this https://docs.convex.dev/testing/convex-test#multiple-environments
convex-test | Convex Developer Hub
The convex-test library provides a mock implementation of the Convex backend
Ah okay, that makes sense
Yes, using edge runtime per the docs
There's an environment variable to set for timezone stuff, https://stackoverflow.com/a/9849524/398212
Stack Overflow
How can I set the default timezone in node.js?
How do I set the default timezone in node.js?
But the print interesting, I hope the convex runtime matches the chrome browser. If it does then toString isn't standardized, toISOstring should always be used for portable code. If it's not, the Convex runtime is deviating from standard and we need to look into it.
Convex runtime does match chrome, it's node that does it different
that's annoying then but at least consistent
Yeah, agreed. The real issue is time not being in UTC, that will probably lead to false negatives in tests (as it is currently for me).
oh env var, just saw your other comment
will try that
This solution from another SO post should be added to the convex-test getting started guide:
Create a file
vitest.global-setup.ts
Then add it to test.globalSetup
in vitest.config.ts
SO answer: https://stackoverflow.com/a/76971168/1556245 (which borrowed from a GitHub issue)
Tested and working for the issue I was experiencing.Nice! Can you write an example of a test where this matters?
I have a lot of date based functionality, and I use simple ISO's (yyyy-MM-dd) everywhere. So there's a lot of conversion between string dates and js
Date
s. Because Convex runtime only supports number dates in new Date()
, this is everywhere:
Notice Date.parse()
creates a Date
with time set to midnight in the local timezone.
In Convex, that's UTC, but for my local that's EST. And May 5th at midnight EST is May 4th at 9pm UTC. A whole lot of date calculations and comparisons go off by one.Is your Convex code hardcoding the UTC timezone somewhere?
What I'm looking for is:
1. This is my convex-test test
2. This is my Convex function
3. This test (say) fails in convex-test but passes when running against a real convex backend
That'll help explain it in docs
hmmm it looks like I'm using date parsing from date-fns in a lot of places, that's the rub
the method above is timezone agnostic, there's is not
okay, good point, this does appear to be a me problem
I'd still say the timezone diff is worth noting in the docs, but it was really only exposing a flaw in my code in this case.
cannot overstate how much I dislike how dates work in js