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

Return returned value of invokant when using yields* and callsArg* #1724

Merged
merged 6 commits into from Mar 15, 2018

Conversation

ungrim97
Copy link
Contributor

@ungrim97 ungrim97 commented Mar 5, 2018

Purpose

Ensure that the yields* and callsArg* methods of the stub cause the stub to return the returned value of the invoked callback. Will defer to all other return value handlers (returns, returnsThis, resolves, rejects ect)

Background

#1689 allows the yield* and callArg* methods to return the value returned by the invoked callback. It is preferable that the stub methods of yields* and callsArg* provide the same functionality to allow testing of functions that are invoked as a callback on the stub that return a promise.

This prevents the need for the test to wait for Process.nextTick() to check if the promise has resolved but can instead us await or .then to do so instead. Thus guaranteeing that the promise is resolved

Solution

Adds a new property to the behaviour of yields that is set to true for all yields* and callsArg* methods in default-behaviour.js.

Ensure that if the yields property is true, and no other return setting is enabled (such as returns, returnsThis ect) then the returned value of the invoked callback is returned. by the invoke function in behaviour.js

How to verify

  1. Check out this branch
  2. npm install
  3. npm test

Checklist for author

  • npm run lint passes
  • References to standard library functions are cached.

@@ -156,7 +158,12 @@ var proto = {
return (this.promiseLibrary || Promise).reject(this.returnValue);
} else if (this.callsThrough) {
return this.stub.wrappedMethod.apply(context, args);
} else if (this.returnValueDefined) {
Copy link
Member

Choose a reason for hiding this comment

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

Where is returnValueDefined being set? I don't see it anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its set in default-behaviour.js for returns, and resolves. Not sure it was the perfect answer. Original thought of typeof this.returnValue !== "undefined". Open to suggestions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have gone back and used typeof this.returnValue !== "undefined" as methods such as returnsThis don't set returnValueDefined

@@ -156,7 +158,12 @@ var proto = {
return (this.promiseLibrary || Promise).reject(this.returnValue);
} else if (this.callsThrough) {
return this.stub.wrappedMethod.apply(context, args);
} else if (this.returnValueDefined) {
return this.returnValue;
} else if (this.yields) {
Copy link
Member

Choose a reason for hiding this comment

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

Is a new property really required? I think checking for callsArgAt would also do, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would seem that callArgAt will work for this.

it("returns the result of the yielded callback", function () {
var stub = createStub().yields();
var callback = createStub().returns("return value");
assert.same(stub(callback), "return value");
Copy link
Member

Choose a reason for hiding this comment

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

Minor styling: Can you separate setup / testing code from assertions with a blank line? This style should be used everywhere. You did it right in the first few tests already. It makes the tests easier to read :)

@mantoni
Copy link
Member

mantoni commented Mar 5, 2018

Nice pull request with very good description and testing. Thanks!

I've added a few comments. Maybe @mroderick or @fatso83 have something to add?

@ungrim97
Copy link
Contributor Author

ungrim97 commented Mar 5, 2018

  • Add spaces between setup and assertions in tests
  • Use callArgAt property rather than new property
  • Use returnValue rather than returnValueDefined

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.

Great work!

Just one comment from me

@@ -1496,6 +1555,50 @@ describe("stub", function () {
this.stub(callback);
});
});

it("plays nice with throws", function () {
Copy link
Member

Choose a reason for hiding this comment

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

plays nice with ... is not descriptive of what the expectation of the system is. If a reader has to read the implementation of the test to understand the expectation, then we're opening up for some very difficult to fix bugs/misunderstandings. We are likely to have minor defects or unclear code in the implementation, especially as code changes over the years. The expectation should be clear and specific from the beginning, so Future Developer won't misinterpret it.

I appreciate that this is a pattern that was well established in the codebase, and that you've been diligent at following established patterns. However, I think that in this case, the established pattern should be avoided.

Would you mind rephrasing the new expectations in this test file to be very specific about what expected behaviour is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not at all. Does "Throws takes precedent over yields return value" work here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mroderick Done

@ungrim97
Copy link
Contributor Author

ungrim97 commented Mar 6, 2018

  • Rename new "plays well with X" tests to have more explicit test names

@ungrim97
Copy link
Contributor Author

ungrim97 commented Mar 8, 2018

@mroderick Your requested change should be implemented now.

@mantoni
Copy link
Member

mantoni commented Mar 8, 2018

@mroderick @fatso83 Feel free to merge this. I’m AFK for a couple of days.

@mroderick
Copy link
Member

@ungrim97 very nice! There's a minor misspelling: "precident" => "precedent" ... would you mind fixing that before we merge it?

@ungrim97
Copy link
Contributor Author

@mroderick fixed

@mroderick
Copy link
Member

This has been published as sinon@4.4.6 on npm

This was referenced Mar 16, 2018
franck-romano pushed a commit to franck-romano/sinon that referenced this pull request Oct 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants