Skip to content
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

Calling replaceGetter invokes the original function #2589

Closed
egmacke opened this issue Feb 27, 2024 · 4 comments
Closed

Calling replaceGetter invokes the original function #2589

egmacke opened this issue Feb 27, 2024 · 4 comments
Labels
Bug Difficulty: Medium Help wanted semver:patch changes will cause a new patch version

Comments

@egmacke
Copy link

egmacke commented Feb 27, 2024

Describe the bug
Using sinon.replaceGetter correctly replaces the getter, but in the process it appears to invoke the original get function.

This causes issues when the getter is non-trivial and relies on class state which may not be correctly setup in a test environment.

To Reproduce
Steps to reproduce the behavior:

  • Define getter with side effects
  • call sinon.replaceGetter
  • Observe side effects happening

Reproduction here: https://replit.com/@egmacke/Sinon-replaceGetter-bug

Expected behavior

Expect that the getter is replaces without invoking the original implementation.

Context (please complete the following information):

  • Sinon version : 17.0.1
  • Runtime: node
  • Output of npx envinfo --browsers --binaries:
  ~/Sinon-replaceGetter-bug$ npx envinfo  --browsers --binaries

  Binaries:
    Node: 18.12.1 - /nix/store/dj805sw07vvpbxx39c8g67x8qddg0ikw-nodejs-18.12.1/bin/node
    Yarn: 1.22.19 - /nix/store/zdcnqq55qi214j46zgw2qa1jp4dpdf2m-yarn-1.22.19/bin/yarn
    npm: 8.19.2 - /nix/store/dj805sw07vvpbxx39c8g67x8qddg0ikw-nodejs-18.12.1/bin/npm
@fatso83
Copy link
Contributor

fatso83 commented Feb 27, 2024

Good repro! Thanks.

@fatso83 fatso83 added Difficulty: Medium Help wanted semver:patch changes will cause a new patch version and removed Unverified labels Feb 27, 2024
@fatso83
Copy link
Contributor

fatso83 commented Feb 27, 2024

Do you want to take a stab at it? I am guessing it is not a very hard fix. We have good test coverage.

@alewilliam789
Copy link

For this given replit if you print the source for the object whose getter is being replaced(using descriptor.get.toString()), the function has changed to the replacement. The console output you see is coming from line 246 in the function getFakeRestorers when the getter is executed to potentially set the field if forceAssignment is true.

Logically it needs to execute this way because restorers need to resolve the getter to be able to restore the original value you had in that function.

A good example is the test starting on line 1119 in sandbox-test where you have a variable that is being get and set by an object. Even if you try to delay the execution of the getter it will return you the most recent value of that variable, not the past value that needs to be restored. In the case that you just have simple output like a constant ('original' or 'fake') it's obviously different because you could get the descriptor for foo and then use the getter in that descriptor.

From my understanding getters should be pretty simple and should avoid side effects to begin with, so the solution in my opinion here should be to avoid side effects in your getters.

@fatso83
Copy link
Contributor

fatso83 commented Apr 25, 2024

This is the code in question that is a bit too simple:
image

The simple direct access is the issue.
image

Since we only need the direct value when forcing use of accessors, we can check for that case. Fix upcoming.

fatso83 added a commit that referenced this issue Apr 25, 2024
of creating restorerer function. Check for the odd case
where we actually force setting a value through accessor
functions and only look up the value at that time.

The alternative would be more elaborate, check if the
descriptor had a `get` or a `value` field, and then
decide, but this should do the trick.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Difficulty: Medium Help wanted semver:patch changes will cause a new patch version
Projects
None yet
Development

No branches or pull requests

3 participants