Repository: sinonjs/fake-timers (js)

Issue:
ClockTime constructor name is different, breaking mongoose Date checks
<!--
Are you wondering how to do something with FakeTimers, or something else that is purely
usage related? Please post it to StackOverflow using the `sinon` and `lolex` labels.
This makes it possible for the bigger community to help answer your questions.

The issue tracker is solely meant for posting bugs, feature requests and non-usage related issues.
-->

> We understand you have a problem and are in a hurry, but please provide us with some info to make it much more likely for your issue to be understood, worked on and resolved quickly.

-   FakeTimers version : 13.0.2
-   Environment : node 20.18 (macOS)
-   Other libraries you are using: sinon 19.0.2, mongoose 8.7.1

**What did you expect to happen?**
We're using Sinon together with mongoose. When using mongoose's `toJSON` and `toObject` to turn mongoose documents into plain objects while faking timers I'd expect fields with Date objects to remain Date objects (or at least look like them). This is the case in fake-timers 11.2.2.

**What actually happens**
While faking timers, when calling `toJSON` or `toObject` on a mongoose document, it turns any Date fields into a number (unix timestamp). This seems to happen because [mongoose determines whether an object is a Date or not using the constructor name](https://github.com/Automattic/mongoose/blob/0752c5daea10df87183a27ed7a1e2c3be33ef52a/lib/helpers/clone.js#L77-L89).

**How to reproduce**
```js
import mongoose from 'mongoose';
import sinon from 'sinon';

const DocModel = mongoose.model('doc',  new mongoose.Schema({ someDate: { type: Date } }));

const doc = new DocModel({ someDate: new Date() })

const plainDocBefore = doc.toObject()
console.log(plainDocBefore.someDate) // plainDocBefore.someDate is a Date object

sinon.useFakeTimers({ now: new Date(), toFake: ['Date', 'hrtime'] });

const plainDocAfter = doc.toObject()
console.log(plainDocAfter.someDate) // plainDocAfter.someDate is a unix timestamp (number)
```

Hope this is the right place to report this.

Pull request:
Ensure checks based on the constructor property passes for fake Dates
#### Purpose (TL;DR) - mandatory

<!--
> give a concise (one or two short sentences) description of what problem is being solved by this PR
>
> Example: Fix issue #123456 by re-structuring the colour selection conditional in method `paintBlue`
-->
Fixes #510 by mirroring the constructor prop of Date objects

<!--
#### Background (Problem in detail)  - optional
-->
<!--
> When relevant, give a more thorough description of what the problem the PR is trying to solve. Examples of good topics for this section are:
> * Link to an existing GitHub issue describing the problem
> * Describing the problem in greater detail than the TL;DR section above
> * How you discovered the issue if it's not already described as an issue on GitHub
> * Discussion of different approaches to solving this problem and why you chose your proposed solution
-->

<!--
#### Solution  - optional
-->
<!--
> When contributing code (and not just fixing typos, documentation and configuration), please describe why/how your solution works. This helps reviewers spot any mistakes in the implementation.
>
> Example:
> "This solution works by adding a `paintBlue()` method"
> Then your reviewer might spot a mistake in the implementation, if `paintBlue()` uses the colour red.
-->


Patch:
diff --git a/src/fake-timers-src.js b/src/fake-timers-src.js
index 308daf1..f368628 100644
--- a/src/fake-timers-src.js
+++ b/src/fake-timers-src.js
@@ -447,6 +447,10 @@ function withGlobal(_global) {
                 } else {
                     super(...arguments);
                 }
+
+                // ensures identity checks using the constructor prop still works
+                // this should have no other functional effect
+                this.constructor = Date;
             }
 
             static [Symbol.hasInstance](instance) {


Test patch:
diff --git a/test/fake-timers-test.js b/test/fake-timers-test.js
index 7a67b9e..38e08e0 100644
--- a/test/fake-timers-test.js
+++ b/test/fake-timers-test.js
@@ -3200,6 +3200,15 @@ describe("FakeTimers", function () {
             assert(date instanceof realDate.constructor);
         });
 
+        // issue #510
+        it("creates Date objects where the constructor prop matches the original", function () {
+            const realDate = new Date();
+            const date = new this.clock.Date();
+
+            assert.equals(date.constructor.name, realDate.constructor.name);
+            assert.equals(date.constructor, realDate.constructor);
+        });
+
         it("creates Date objects representing clock time", function () {
             const date = new this.clock.Date();