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

Set wrappedMethod on getters/setters #2251

Closed
wants to merge 1 commit into from

Conversation

rgroothuijsen
Copy link
Contributor

@rgroothuijsen rgroothuijsen commented Apr 13, 2020

Purpose

This PR fixes #2198 by wrapping accessors if they are present, rather than the property they belong to.

Background

Because the current wrapMethod implementation only assumes the presence of a single method on a property, trying to set both a getter and a setter will cause the former to be overwritten by the latter, and not added as separate get and set methods. Furthermore, restore() is implemented on the property itself, which does not allow the spy.get.restore() and spy.set.restore() outlined in the documentation.

Solution

This problem was addressed by changing wrapMethod to handle multiple methods per property. This includes a check whether any particular method is an accessor or not, and a method-wrapping implementation is chosen based on this. If the method in question is not a "get" or "set" method, the existing implementation will be used.

In order to satisfy ESLint code quality requirements, some restructuring of wrapMethod has been performed as well. To the extent possible, however, the existing structure has been left alone.

  • restore() was moved because function declarations are not allowed inside a loop
  • Parts of the code have been separated into functions because the complexity of wrapMethod had become too high

How to verify

  1. Check out this branch
  2. npm install
  3. npm test (See included test for details)

@stale
Copy link

stale bot commented Jun 12, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 12, 2020
@stale stale bot closed this Jun 20, 2020
@mroderick mroderick added pinned and removed stale labels Jul 16, 2020
@mroderick
Copy link
Member

Once this is merged, we should reverse the #2270 changes!

Copy link
Member

@mroderick mroderick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for diligently fixing this issue and for your patience with waiting for a review 🏆

I've added a few suggestions around using forEach instead of for loops.

lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
lib/sinon/util/core/wrap-method.js Show resolved Hide resolved
@mroderick mroderick mentioned this pull request Jan 4, 2021
2 tasks
@fatso83
Copy link
Contributor

fatso83 commented Jan 18, 2021

I'll be taking this across the finish line this week (not so heroic as it seems: basically just implementing the feedback).

@mroderick
Copy link
Member

Running the tests in browsers, @hexeberlin and I discovered that this PR fails in IE11 and Safari 9

# internet explorer 11:

  1) spy
       sets wrappedMethod on getter and setter:
     AssertionError: [refute.isUndefined] Expected undefined ('undefined') not to be undefined
      at fail (node_modules/@sinonjs/referee/lib/create-fail.js:15)
      at ctx.fail (node_modules/@sinonjs/referee/lib/define-assertion.js:44)
      at assertion (node_modules/@sinonjs/referee/lib/define-assertion.js:62)
      at referee[type][name] (node_modules/@sinonjs/referee/lib/define-assertion.js:89)
      at Anonymous function (test/spy-test.js:350)

  2) stub
       .get
         can restore stubbed setters for functions:
     AssertionError: [assert.equals] undefined expected to be equal to [Function]
      at fail (node_modules/@sinonjs/referee/lib/create-fail.js:15)
      at ctx.fail (node_modules/@sinonjs/referee/lib/define-assertion.js:44)
      at assertion (node_modules/@sinonjs/referee/lib/define-assertion.js:62)
      at referee[type][name] (node_modules/@sinonjs/referee/lib/define-assertion.js:89)
      at Anonymous function (test/stub-test.js:3298)

  3) stub
       .set
         can restore stubbed setters for functions:
     AssertionError: [assert.equals] undefined expected to be equal to [Function]
      at fail (node_modules/@sinonjs/referee/lib/create-fail.js:15)
      at ctx.fail (node_modules/@sinonjs/referee/lib/define-assertion.js:44)
      at assertion (node_modules/@sinonjs/referee/lib/define-assertion.js:62)
      at referee[type][name] (node_modules/@sinonjs/referee/lib/define-assertion.js:89)
      at Anonymous function (test/stub-test.js:3385)


# Safari 9.0

  1) spy
       sets wrappedMethod on getter and setter:
     [refute.isUndefined] Expected undefined ('undefined') not to be undefined
      fail node_modules/@sinonjs/referee/lib/create-fail.js:5
      fail node_modules/@sinonjs/referee/lib/define-assertion.js:44
      assertion node_modules/@sinonjs/referee/lib/define-assertion.js:62
      node_modules/@sinonjs/referee/lib/define-assertion.js:89
      test/spy-test.js:348

Since we will drop IE11 with #2324 and subsequently allow for more modern syntax and probably require ES5 support as minimum, I propose that we delay fixing #2198 until we've had a chance to refactor wrapMethod to more modern JS.

@fatso83
Copy link
Contributor

fatso83 commented May 11, 2021

I propose that we delay fixing #2198 until we've had a chance to refactor wrapMethod to more modern JS.

Not totally sure what should happen, but we have dropped support for IE11 and Safari 9 with Sinon 10, so ... how do we progress from here? I not totally sure what is supposed to happen first.

@mroderick
Copy link
Member

mroderick commented May 13, 2021

I think we should try rebasing it onto the primary branch, and see if that doesn't fix it. I don't currently have the bandwidth to do that, but might be able to look into it on the weekend.

@fatso83
Copy link
Contributor

fatso83 commented May 20, 2021

Rebased: https://github.com/sinonjs/sinon/compare/master...fatso83:SINON-2198?expand=1

Some conflicts, but I think it's ok. All tests pass, at least.

@fatso83
Copy link
Contributor

fatso83 commented May 25, 2021

Resubmitted as #2378 to get it in.

@fatso83 fatso83 closed this May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

spy.wrappedMethod is not ok when spying getter/setter
3 participants