-
-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable use of assignment in the presence of accessors #2538
Enable use of assignment in the presence of accessors #2538
Conversation
Codecov ReportAll modified lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2538 +/- ##
==========================================
+ Coverage 95.95% 96.03% +0.07%
==========================================
Files 40 40
Lines 1904 1916 +12
==========================================
+ Hits 1827 1840 +13
+ Misses 77 76 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
Looks good. While the name is okay, I'm also wondering about alternatives. Suggestion: Another question: should the whole thing fail with a specific error message if the flag is specified, but no accessor pair is found? |
One more thought: Since this is a completely different approach to swapping out a function, we could also introduce |
Maybe that's just as good? We would then have define, inject and replace, all with dedicated use cases. |
I had just about finished the changes when I found that we already have Sandbox#inject, doing something completely different (injecting a subset of the sandbox's functionality on an object). Pretty sure it is not the most well-known function and frankly I am not totally sure what its usecase outside of internal use. We even do not have any documentation on it and it is only used once (in lib/sinon/create-sandbox.js (line 53)). All of that sandbox setup related code is basically shrouded in mystery by now, so I have no idea how all of this works. So ... I need a new name.
Currently voting for
|
I agree that The very last thing I can thing of: I checked the work on |
I am just thinking What about ... namespacing it? It is kind of a special case of |
I agree with the intent argument. It's a different thing and we should probably not mix them I'm not really happy with the this, but can't think of anything better. Maybe @mroderick has more ideas? |
I'm not 100% sold on having a fourth argument with an obscure name that people have to remember in order to replace accessors... especially considering we already have If we adopt the fourth argument, should we then deprecate |
I think we already agreed to forego the fourth argument. The discussion now is basically about which dedicated name to use. This is not about replacing accessors, Morgan, so the existing functions for replacing accessors should stay as they are. This is just about assigning values using the accessors, without replacing them. See the expanded discussion. |
@hexeberlin and I had a look at this, and now I think I'm actually caught up and understand what's going on. How about We can modify Thoughts? |
I like it! Makes it clear that it is a special case. I can just update this and get this merged if there's agreement. |
Go ahead! |
4dd185b
to
e71b0c9
Compare
20b9061
to
93f8fe2
Compare
When actually writing it out, I had second thoughts about |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one tiny comment. 👍
Purpose
Allows specifying a fourth argument, an options bag, to
sandbox.replace()
to make it possible to override the default behaviour of throwing when encountering accessor methods (getters/setters).This means we will pass the supplied replacement to the setter and vice-versa get the original value from the getter when restoring.
P.S. I am not sold on the options name, so could be something else like "allowUsingAccessor". Was just inspired by the original issue.
Background (Problem in detail) - optional
Issue #2403 made the case for using assignment, instead of defining object descriptors, in injection methods. Enabling this in all existing methods would probably break some projects in unforeseen ways. It would also mean adding yet another argument to most of these, which would make them harder to use, as some of them (spy) already have optional third arguments today.
The discussion in #2403 revealed we already had a "special case" in our
Sandbox#replace
method, as this already uses basic assignment. The only thing preventing it from being used was that it tries to prevent false usage by throwing on encounter accessor methods for the given property. Thus this PR simply opens up for circumenting this.This opens up for some exotic cases, such as manual setups for stubbing the exports of true ESM modules through the innards of the module, in the way described in that feature:
my-module.mjs
my-module.test.mjs
Alternatively one could, of course, not do this change, and instead say that this manual stubbing setup is already doable by exposing functions for setting the corresponding exports and manually invoking these. The downside is that this will cause lots of manual restore code, which would otherwise by handled by Sinon.
How to verify - mandatory
Run tests and alternatively try the copy-pasting the example above into the root of the repo, then run
node *.test.mjs
.Checklist for author
npm run lint
passes