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

ContinueWith overloads #16

Merged
merged 5 commits into from Apr 26, 2018
Merged

ContinueWith overloads #16

merged 5 commits into from Apr 26, 2018

Conversation

AlphaGremlin
Copy link
Contributor

Add ContinueWith overloads with the state parameter.

Found a few more that I'd missed in the previous PR, so I've added those.
Also, I've switched to handling the state value manually, because the compiler was creating 20 separate copies of exactly the same underlying class.

Add ContinueWith overloads with the state parameter
/// <param name="task">The target Task</param>
/// <param name="action">The continuation method to execute</param>
/// <param name="state">A state object to pass to the continuation</param>
/// <returns>A task representing the continuation status</returns>
Copy link
Collaborator

@jnm2 jnm2 Apr 21, 2018

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea of copying the documentation also brings to light that the BCL uses the parameter name continuationAction which we should follow for source compatibility if people use named parameters.

Copy link
Collaborator

@jnm2 jnm2 left a comment

Choose a reason for hiding this comment

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

I like it!
I would feel most comfortable with test coverage of every code path, boring as that is. 😬 Sorry to be a stick-in-the mud!

private sealed class ContinueWithState
{
private readonly Action<Task, object> _Callback;
private readonly object _State;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've never seen the _Upper naming convention before. I apologize that we don't have an .editorconfig set up.
The polyfill code, copying Microsoft, uses m_camelCase. My personal preference for private fields would be camelCase but if you don't like that, _camelCase would be fine.

/// <param name="task">The target Task</param>
/// <param name="action">The continuation method to execute</param>
/// <param name="state">A state object to pass to the continuation</param>
/// <returns>A task representing the continuation status</returns>
Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea of copying the documentation also brings to light that the BCL uses the parameter name continuationAction which we should follow for source compatibility if people use named parameters.

/// <returns>A task representing the continuation status</returns>
public static Task ContinueWith(this Task task, Action<Task, object> action, object state)
{
return task.ContinueWith(new ContinueWithState(action, state).ContinueWith);
Copy link
Collaborator

@jnm2 jnm2 Apr 21, 2018

Choose a reason for hiding this comment

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

Please match BCL behavior by throwing new ArgumentNullException(nameof(continuationAction)). Right now ContinueWithState.ContinueWith throws a NullReferenceException when the continuation executes rather than throwing an ArgumentNullException before even scheduling the continuation, as the BCL does.

(That's a reminder to me that we need tests verifying this behavior too.)

Added XML documentation from ReferenceSource
Changed parameter names to be compatible
@AlphaGremlin
Copy link
Contributor Author

So, apparently the AsyncTargetingPack does not include any ContinueWith extension methods. I'll have to disable the ContinueWith tests for that target.

Added ContinueWith overload tests
Copy link
Collaborator

@jnm2 jnm2 left a comment

Choose a reason for hiding this comment

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

One last thing I missed until I ran code coverage! I added integration with codecov.io, so if you rebase the PR on the latest updates to master, you'll get to see it here.

public void Action()
{
var GotState = false;
TestUtils.RunAsync(() => TaskEx.Run(() => { }).ContinueWith((task, state) => GotState = (bool)state, true));
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't actually testing the Action<Task, object> overload. Because of the lambda's expression body, the compiler is inferring it as Func<Task, object, bool>.
You can see that by the red lines in the coverage report here: https://codecov.io/gh/OmerMor/AsyncBridge/src/2806bdff8e65cfb4be247c1595fc319cdc3baa19/src/AsyncBridge/AsyncCompatLibExtensions.cs#L779...797

(needs to be fixed in 5 places)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Damn it! I'll fix that up.

One thing I really miss from SharpDevelop is the code coverage integration. VS only offers it in the enterprise version.

public void ActionResult()
{
var GotState = false;
TestUtils.RunAsync(() => TaskEx.Run(() => true).ContinueWith((task, state) => GotState = (bool)state, true));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same deal, testing the Func<Task<bool>, object, bool> overload instead of the Action<Task<bool>, object> overload.

https://codecov.io/gh/OmerMor/AsyncBridge/src/2806bdff8e65cfb4be247c1595fc319cdc3baa19/src/AsyncBridge/AsyncCompatLibExtensions.cs#L799...817

(5 places)

Fixed tests using the wrong overloads
@codecov-io
Copy link

codecov-io commented Apr 25, 2018

Codecov Report

Merging #16 into master will increase coverage by 4.61%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #16      +/-   ##
=========================================
+ Coverage   58.78%   63.4%   +4.61%     
=========================================
  Files          17      17              
  Lines         461     511      +50     
  Branches       60      64       +4     
=========================================
+ Hits          271     324      +53     
+ Misses        166     163       -3     
  Partials       24      24
Impacted Files Coverage Δ
src/AsyncBridge/AsyncCompatLibExtensions.cs 87.09% <100%> (+53.76%) ⬆️
...cBridge/Runtime/TargetedPatchingOptOutAttribute.cs 0% <0%> (ø) ⬆️
src/AsyncBridge/Threading.Tasks/TaskEx.cs 70.29% <0%> (+2.97%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e0ab620...c7593cb. Read the comment docs.

@AlphaGremlin
Copy link
Contributor Author

I think I did the rebase correctly...? It seems to have code coverage now. That should have fixed the tests.

@jnm2
Copy link
Collaborator

jnm2 commented Apr 25, 2018

@AlphaGremlin Awesome! All the code looks ready! A quick explanatory detour next, for which I apologize!

ℹ You did a merge, which is different than a rebase. A merge is when you join back together at the end with a merge commit that has two parent comments. A rebase is when you rewrite your commits to change your first commit's parent commit.

GitHub reviews just happen to not work very well when you merge the master branch into your topic branch (PR branch). It counts all these changes from master as part of your diff, so it's hard to tell what you wrote versus what you pulled in from master. There's also a superfluous merge commit at the end:

image

This explains why Codecov is still complaining that it can't find coverage for the master commit you're based off of, 6cb68ef. With a rebase, your first commit's parent would be d5ff32a instead (the current tip of master).

➡ Don't worry about rebasing in this PR. I can see that your changes have 100% coverage and I'd like to merge them.

⚠ I'd prefer to undo the merge with master first, though, so the diff in this PR is usable for anyone that looks back at it. Sorry about that! It's super easy though:

  • git reset c7593cb --hard
    This makes your local continuewith branch point at c7593cb, “Fixed overload tests.” The merge commit no longer has something pointing at it, so it will be discarded. Now your history and diff is fixed!

  • git push -f
    This makes your remote origin/continuewith branch point at the same commit as your local branch. -f (--force) is needed because we are causing the remote branch to rewind its history by dropping that merge commit.

You've been really great and put up with a lot through this whole process and I appreciate that very much! I can't wait to get this in. 👍

@AlphaGremlin
Copy link
Contributor Author

Done :)

@jnm2 jnm2 merged commit a49f0f0 into OmerMor:master Apr 26, 2018
@jnm2
Copy link
Collaborator

jnm2 commented Apr 26, 2018

🎉 Your tireless work is much appreciated! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants