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

Add ability to provide a 'do' action on Arg.Is #780

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

asos-AdamCox
Copy link

This change allows NSubstitute to support Capture.In functionality

@asos-AdamCox asos-AdamCox changed the title Added ability to provide filter on Arg.Do Add ability to provide filter on Arg.Do Feb 15, 2024
@asos-AdamCox
Copy link
Author

One question around this stuff - should this be an overload of Arg.Do (as it currently is in the PR) or Arg.Is or maybe some other method being as it does both things? (IsDo?)

@asos-AdamCox
Copy link
Author

I realised yesterday that Arg.Do can be used both when setting up the mock and also when verifying and the changes I'd made only worked during setup - I've now added a test for the usage during verification and implemented the changes required for the test. Is anyone available to review this PR?

@asos-AdamCox asos-AdamCox changed the title Add ability to provide filter on Arg.Do Add ability to provide a 'do' action on Arg.Is Mar 18, 2024
@asos-AdamCox
Copy link
Author

I'm really very sorry to keep chasing about this - is there some step I'm missing to get this PR moving forward?

@dtchepak
Copy link
Member

dtchepak commented Apr 10, 2024

Hi @asos-AdamCox ,

Thanks a lot for this MR, and apologies for the delay in looking at it.

should this be an overload of Arg.Do (as it currently is in the PR) or Arg.Is or maybe some other method being as it does both things? (IsDo?)

Yeah I'm not sure about this either. Arg.Is(match, doThing) doesn't read that nicely imo.

What about something like this?

public class Match<T>
{
    private Expression<Predicate<T>> matches;
    private Action<T> action;

    internal Match(Expression<Predicate<T>> matches, Action<T> action)
    {
        this.matches = matches;
        this.action = action;
    }

    public Match<T> AndDo(Action<T> action) =>
        new Match<T>(matches, x => { this.action(x); action(x); });

    public static implicit operator T(Match<T> match) =>
        ArgumentMatcher.Enqueue<T>(
            new ExpressionArgumentMatcher<T>(match.matches),
            x => match.action((T)x)
        );

}

public static class Match
{

    public static Match<T> When<T>(Expression<Predicate<T>> matches) =>
        new Match<T>(matches, x => { });
}

Then the test becomes:

            var stringArgs = new List<string>();
            _sub.Bar(
                Match.When<string>(x => x.StartsWith("h"))
                .AndDo(x => stringArgs.Add(x)),
                Arg.Any<int>(),
                _someObject
            );

WDYT?

⚠️ Haven't tested received, reports of non-matches, by-ref, or other use cases that could cause issues 😅

@asos-AdamCox
Copy link
Author

Hi @dtchepak, thanks for getting back to me - I like the Match syntax my only reservation is that by introducing Match it'll mean setups and verifications then may have a combination of Arg and Match and Arg.Is<T>(Expression<Predicate<T>> predicate) is exactly the same as Match.When<T>(Expression<Predicate<T>> predicate) which feels a little odd to me and feels like it might be confusing to consumers. Having said that I'm not familiar enough with this library to propose any more alternatives so I'm happy to go with Match if that's your preference.

For now I've added Match to the PR and left unit tests in place for both approaches to allow you to compare - please let me know your preference. I've also renamed the Is method to IsAndDo in case that's any better?

with regards to:

Haven't tested received, reports of non-matches, by-ref, or other use cases that could cause issues

I will try to spend some time of the next few days investigating where there's missing unit tests - if you know off-hand please let me know.

Renamed Arg.Is to IsAndDo
@dtchepak dtchepak self-assigned this May 5, 2024
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.

2 participants