rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.88k stars 299 forks source link

Assert.SequenceEquals could handle any iterable #4223

Open Greedquest opened 5 years ago

Greedquest commented 5 years ago

I would find the SequenceEquals assertion more useful if it could handle any iterable value, not just arrays. Currently I'm having to convert to arrays to use the test, and my typical call site looks like this: Assert.SequenceEquals Array("0", "0", "1"), IterableToArray(someIterable)

Where IterableToArray recursively extracts an iterable into a multi-dimensional 0-indexed array (0-indexed to match the indexing of Array())

Is there any reason why Rubberduck could not internally carry out this conversion, as most data structures I employ are not arrays, but they are almost always iterable?

rubberduck203 commented 5 years ago

I don’t see why it couldn’t. I’ve often found myself mildly irritated with other unit testing frameworks that can’t compare iterables. Then again, it’s also easier for the client to provide a reasonable ToArray function for their iterable than it is to thoroughly implement this in a generic way on our side.

I would think the team would be open to a pull request.

bclothier commented 5 years ago

Off the cuff, I think it should be possible and easy enough (!) to support objects that implements the IEnumVARIANT interface. That should be the standard approach used in this context.

What I am not too sure about is the homebrewn VBA (VB6?) class posing as a collection. Normally, they do this by implementing the decorated _NewEnum and just forward calls to the underlying class. This might work to enable the "For Each" feature in VBA but I'm not sure that will also implement the required interface for RD to be able to enumerate.

In short, we should be able to support IEnumVARIANT implementators but otherwise need the callers to provide an array or collection for those that are more.... special.

WaynePhillipsEA commented 5 years ago

@bclothier for the homebrew case, you can test if the class object implements the DISPID_ENUM DISPID_NEWENUM (-4) member through IDispatch, and if it does, call it and then query the returned object (IUnknown) for the IEnumVARIANT interface that you want.