Skip to content

Conversation

runjak
Copy link
Contributor

@runjak runjak commented May 26, 2025

Hey 👋

so I'm enjoying use of both: ladle and date-fns. And this leads me to a situation where I'm using date-fns isValid and isDate to check some data. In particular we've got a component that does date based calculations based on a MockDate.

My understanding is that date-fns depends on the global Date object in code like this:

// node_modules/date-fns/isDate.js
export function isDate(value) {
  return (
    value instanceof Date ||
    (typeof value === "object" &&
      Object.prototype.toString.call(value) === "[object Date]")
  );
}

So when calculating new dates we get instances of RealDate, and check whether a RealDate is instanceof a MockDate, because MockDate rightly replaces the global date when mocking with ladle.

For inheritance this is usually the wrong way: a parent is not an instance of the child class. My suggestions would be to treat it as that though in case of MockDate with the following snippet:

static [Symbol.hasInstance](instance: unknown): boolean {
    return instance instanceof RealDate;
  }

I've tested it by test-wise appending (but not comitting) this code to packages/ladle/lib/app/src/mock-date.ts:

let d = new RealDate();
let m = new MockDate();

console.log({ l: m, d });

console.table([
  ["d instanceof RealDate", d instanceof RealDate],
  ["m instanceof RealDate", m instanceof RealDate],
  ["m instanceof MockDate", m instanceof MockDate],
  ["d instanceof MockDate", d instanceof MockDate],
]);

It leads to output like this:

❯ node packages/ladle/lib/app/src/mock-date.ts
{ l: 2025-05-26T15:36:10.887Z, d: 2025-05-26T15:36:10.887Z }
┌─────────┬─────────────────────────┬──────┐
│ (index) │ 0                       │ 1    │
├─────────┼─────────────────────────┼──────┤
│ 0       │ 'd instanceof RealDate' │ true │
│ 1       │ 'm instanceof RealDate' │ true │
│ 2       │ 'm instanceof MockDate' │ true │
│ 3       │ 'd instanceof MockDate' │ true │
└─────────┴─────────────────────────┴──────┘

Copy link

changeset-bot bot commented May 26, 2025

🦋 Changeset detected

Latest commit: 3c3bf25

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@ladle/react Patch
example Patch
test-addons Patch
test-babel Patch
test-config Patch
test-config-ts Patch
test-css Patch
test-decorators Patch
test-playwright Patch
test-programmatic Patch
test-provider Patch
test-baseweb Patch
test-msw Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@runjak
Copy link
Contributor Author

runjak commented May 28, 2025

@tajo would you like me to add a Changeset to this PR?

@runjak
Copy link
Contributor Author

runjak commented Jun 11, 2025

Note that the original MockDate as implemented in https://github.com/boblauer/MockDate/blob/master/src/mockdate.ts#L41 sets the prototype like this:

MockDate.prototype = RealDate.prototype;

With modern JS this leads to the following TypeError:

MockDate.prototype = RealDate.prototype;
                   ^
TypeError: Cannot assign to read only property 'prototype' of function 'class Date extends RealDate {
                         ...<omitted>...
}'

I believe this to be the reason why the prototype line has been omitted from ladles mock date, and it is also what causes the issue in date-fns isDate and when using instanceof between MockDate and Date objects.

That is why I'm asking to adjust the implementation of Symbol.hasInstance.

@tajo
Copy link
Owner

tajo commented Jul 20, 2025

@runjak makes sense. Can you please add some unit test and changeset? Thanks!

@runjak runjak force-pushed the mock-date-instanceof branch from 6d33f81 to cdcc615 Compare July 26, 2025 19:50
By adding Symbol.hasInstance to MockDate we allow for instanceof to work with mocked Dates.
When the global Date object is replaced with a mocked one unmocked Dates
are also instances of MockedDate and vice versa.
@runjak runjak force-pushed the mock-date-instanceof branch from cdcc615 to 3c3bf25 Compare July 26, 2025 20:36
@runjak
Copy link
Contributor Author

runjak commented Jul 26, 2025

@tajo thanks for the reply 🙏
I've made the adjustments and hope this fits your requirements :)

@runjak
Copy link
Contributor Author

runjak commented Sep 9, 2025

Hey, I hope I'm not bothering you with this and you're doing fine stress-wise.

Just wanted to note that from my perspective all should be fine here and if you like you could merge my changes.

@runjak runjak mentioned this pull request Sep 16, 2025
@tajo tajo merged commit 33586a0 into tajo:main Oct 2, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants