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
Return returned value of invokant when using yields* and callsArg* #1724
Conversation
lib/sinon/behavior.js
Outdated
@@ -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) { |
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.
Where is returnValueDefined
being set? I don't see it anywhere else.
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.
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
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.
I have gone back and used typeof this.returnValue !== "undefined"
as methods such as returnsThis don't set returnValueDefined
lib/sinon/behavior.js
Outdated
@@ -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) { |
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.
Is a new property really required? I think checking for callsArgAt
would also do, no?
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.
It would seem that callArgAt will work for this.
test/stub-test.js
Outdated
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"); |
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.
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 :)
Nice pull request with very good description and testing. Thanks! I've added a few comments. Maybe @mroderick or @fatso83 have something to add? |
…ermine return value
…returnValueDefined property
|
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.
Great work!
Just one comment from me
test/stub-test.js
Outdated
@@ -1496,6 +1555,50 @@ describe("stub", function () { | |||
this.stub(callback); | |||
}); | |||
}); | |||
|
|||
it("plays nice with throws", function () { |
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.
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?
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.
Not at all. Does "Throws takes precedent over yields return value" work here?
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.
@mroderick Done
|
…ield and other return value setters
@mroderick Your requested change should be implemented now. |
@mroderick @fatso83 Feel free to merge this. I’m AFK for a couple of days. |
@ungrim97 very nice! There's a minor misspelling: "precident" => "precedent" ... would you mind fixing that before we merge it? |
@mroderick fixed |
This has been published as |
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 usawait
or.then
to do so instead. Thus guaranteeing that the promise is resolvedSolution
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 inbehaviour.js
How to verify
npm install
npm test
Checklist for author
npm run lint
passes