Uh oh!
There was an error while loading. Please reload this page.
lib: allow mocking primordials with --expose-internals - #40733
Conversation
benjamingr
commented
Nov 5, 2021
Initially I thought to optionally do this only if I'm not sure how to test this (similar PRs did not contain tests) but I can add a test with |
fatso83
commented
Nov 5, 2021
Ooh, this would be super useful for Node > 15.7 where the @sinonjs/fake-timers implementations used by Jest and Sinon is not able to do touch the Date implementation used by Node internals like |
addaleax
commented
Nov 5, 2021
I think the real question here is what value we get out of always reading the primordial |
targos
commented
Nov 6, 2021
--expose-internals is not a public API. I'm pretty worried that popular libraries think about using it |
fatso83
commented
Nov 6, 2021
As they say about API design; make the common things easy and the difficult things possible. Currently, a certain use case is no longer possible, and this would make it possible for the ones that cared for it. |
targos
commented
Nov 6, 2021
I'm not saying we shouldn't make it possible. I'm saying that making it possible through |
aduh95
commented
Nov 6, 2021
Note that mutating primordials is not necessary to achieve what is being discussed in the other issue for someone daring enough to use require('internal/http').utcDate=functionutcDate(){return'custom string';};consthttp=require('http');server=http.createServer((req,res)=>{req.on('data',()=>voidnull);req.on('end',()=>{res.writeHead(200);res.end();});});server.listen(8008,()=>{constopts={hostname: 'localhost',method: 'GET',path: '/',port: 8008,family: 4,};constreq=http.request(opts,(res)=>{res.on('data',()=>voidnull);res.on('end',()=>{console.log(res.headers.date==='custom string');});});req.end();}); |
What if we just mock .utcDate if --expose-internals is passed? |
fatso83
commented
Nov 8, 2021
@benjamingr Yeah, I saw that was possible to begin with, but it would not allow us to fully control Date and all that jazz. But then maybe they need to employ DI or something to avoid the |
targos
commented
Nov 9, 2021
I suggest we close this PR and instead open a feature request issue with a description of what API you would like to have (with the goal of not relying on monkey-patching to change the behavior of Node internals). |
benjamingr
commented
Nov 9, 2021
I don't think discussion has died down - but I am not set on this particular solution. The ask is to be able to mock dates (internally) - one (easy) way to achieve this is to be able to override primordials.Date - this is for testing only basically. |
This assumes that Node.js uses the |
benjamingr
commented
Nov 9, 2021
It does, and in general mocking libraries like fake-timers work under the assumption that things like this can/may break. It also "breaks" whenever node adds additional properties to timers and the sinon code would have to be adjusted in those cases. We can choose to just not enable that use case (it's not a timer, sinon only mocks a few properties etc) and allow passing a "start time" or similar to Node.js or suggest the user mocks system time instead for example? |
fatso83
commented
Jan 19, 2022
@benjamingr Did an alternative suggestion come up? |
benjamingr
commented
Jan 19, 2022
@fatso83 no, this just stalled and people haven't asked a lot for this before and sinon never made the guarantee to allow mocking node internal usage of Date (which may be replaced with C++ anyway code in which case it won't help). I can work on a flag for Node.js that allows setting the data on http headers but it's not a common ask |
This pull request allows swapping primordials when
--expose-interalsis passed. This is required for libraries like SinonJS to mockDate.I am not sure why primordials was frozen in the first place since the object is not user-accessible as far as I'm aware.
cc @aduh95@fatso83
Refs: sinonjs/fake-timers#344
Refs: #36872