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

Fill Readonly Collection Properties Behavior #1177

Merged
merged 15 commits into from
Apr 14, 2021
Merged

Fill Readonly Collection Properties Behavior #1177

merged 15 commits into from
Apr 14, 2021

Conversation

charles-salmon
Copy link
Contributor

This PR addresses #341.

I've implemented this using a behavior, per the recommendation of @zvirja. However, I have a slight concern with this, in that I do not believe it is possible to determine whether or not a given property has been marked with an OmitSpecimen signal from the context of a behavior (e.g. the addition of this behavior will still populate readonly collection properties, if OmitAutoProperties has been called or if Without has been used to explicitly exclude a particular property). I'm prepared to make any changes necessary, following on from feedback in this regard.

Is anyone potentially able to take a look at this? @ploeh @moodmosaic @adamchester @ecampidoglio @zvirja @sgryt

This is my first contribution to AutoFixture, so please feel free to be critical.

@charles-salmon charles-salmon changed the title #341 Fill Readonly Collection Properties Behavior Fill Readonly Collection Properties Behavior May 2, 2020
@ecampidoglio ecampidoglio linked an issue May 14, 2020 that may be closed by this pull request
@WestDiscGolf
Copy link

We were just having a discussion about this at work and were excited to see this PR. Hope it makes the next version 👍

Copy link
Member

@aivascu aivascu left a comment

Choose a reason for hiding this comment

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

@charles-salmon first of all, thank you for the contribution! This is a feature expected by many.

Overall the PR looks good in terms of implemented functionality. 👍

I left some comments on some code-convention and design choices. My hope is you will not get scared away by them. 🙂 I am open for discussion around any comment.
If you need it I can make a commit to better exemplify the code changes I've requested.

I still need to investigate on my own the concerns you have raised and how to mitigate them, so I'll get back with more info when I find anything.

…nto fill-readonly-collection-properties-behavior
…changes the object type of elements in an `IEnumerable<object>`.
…ection properties. Introduce the `IPropertyQuery` abstraction to separate away the responsibility of selecting applicable properties from the `ReadonlyCollectionPropertiesCommand`. Swallow `NotSupportedException`s that arise from invoking `Add` methods in the `ReadonlyCollectionPropertiesCommand` (e.g. `SortedList`). Determine the specimen type to be created based on the parameter type of the `Add` method, as opposed to the generic argument of `ICollection<>`. Ensure that the `ReadonlyCollectionPropertiesBehavior` does not apply to `Fixture` or `IFixture`.
@charles-salmon
Copy link
Contributor Author

@aivascu Thank you very much for taking a look at this. I sincerely apologize that it took me several months to find the time to action the feedback that you'd given, but I finally managed to block out a chunk of time to get to this, and have responded to all of the issues that you've raised.

Also, in response to:

I've implemented this using a behavior, per the recommendation of @zvirja. However, I have a slight concern with this, in that I do not believe it is possible to determine whether or not a given property has been marked with an OmitSpecimen signal from the context of a behavior (e.g. the addition of this behavior will still populate readonly collection properties, if OmitAutoProperties has been called or if Without has been used to explicitly exclude a particular property). I'm prepared to make any changes necessary, following on from feedback in this regard.

I took a closer look at this. When a property is explicitly excluded using the Without method on a readonly property, an appropriate exception is thrown, indicating that the property is not writable. This is thus much lesser of a concern that I had first thought.

Let me know if you're happy with how this has shaped up! 😄

Copy link
Member

@aivascu aivascu left a comment

Choose a reason for hiding this comment

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

@charles-salmon amazing work! The PR looks good aside from a couple moments, most important of which is whether the behavior should be ON by default.
@ecampidoglio @zvirja I'd like to know what you think. Should we enable this by default?

Src/AutoFixture/Fixture.cs Outdated Show resolved Hide resolved
Src/AutoFixture/Kernel/CollectionPropertyQuery.cs Outdated Show resolved Hide resolved
@charles-salmon
Copy link
Contributor Author

@aivascu Thanks once again for the review! I have actioned the feedback that you've given, and agree that this should perhaps not be a default behavior.

Copy link
Member

@aivascu aivascu left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@aivascu aivascu merged commit c127ca4 into AutoFixture:master Apr 14, 2021
/// returns an enumerable containing a single <see cref="InstanceMethod"/> otherwise.</returns>
public IEnumerable<IMethod> SelectMethods(Type type = default)
{
var method = this.Owner.GetType().GetTypeInfo().GetMethod(this.MethodName);

Choose a reason for hiding this comment

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

I am getting AmbiguosMatchFound Exception here, the Collection that I am using is RepeatedField from protobuf, Not sure if this can happen anywhere else, but maybe worth checking in.
I have solved it like:

public IEnumerable<IMethod> SelectMethods()
        {
            if(Owner == null) return Array.Empty<IMethod>();
            var methods = this.Owner.GetType().GetMethods();
            foreach (var methodInfo in methods)
            {
                if (methodInfo.Name == MethodName && methodInfo.GetParameters().Length == 1)
                {
                    return new IMethod[]
                    {
                        new InstanceMethod(methodInfo, this.Owner)
                    };
                }
            }
            
            return Array.Empty<IMethod>();
        }

Not sure if ideal, but desperate time - require desperate measures :)

@pentarex pentarex mentioned this pull request Jun 10, 2022
2 tasks
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.

Populating classes with non-settable collections
4 participants