Skip to content

Conversation

@Evangelink
Copy link
Contributor

Fix #568 and overrides #963

I still need to add some tests for IImmutableDictionary and IReadOnlyDictionary but there are multiple ways I could achieve it and I am not sure which one is best:

1/ Add only one test for each type (total new tests = 2).

2/ Add one test per assertion method for each type (total new tests = 2 * number of assertions).

3/ Duplicate the test class for the other 2 interfaces.

4/ (Maybe more complex) Create some helper method that takes a Dictionary, an act Action and an assert Action and runs them onto the Dictionary as itself, as IDictionary, as IReadOnlyDictionary and as IImmutableDictionary.

Any preference?
@dennisdoomen, @jnyrup

@jnyrup
Copy link
Member

jnyrup commented Sep 9, 2019

Is the intention of this PR to cause less breaking changes than #963?

This PR remaps IEnumerable<KeyValuePair<TKey, TValue>>
from GenericCollectionAssertions<KeyValuePair<Tkey, TValue>>
to GenericDictionaryAssertions<TKey, TValue>.

So this e.g. breaks

MyEnumerable.Should().HaveElementAt(0, myItem);

@Evangelink
Copy link
Contributor Author

@jnyrup Sorry about that I opened the PR before leaving on vacations (should have waited to be back). The intent was indeed to provide a less breaking change version than #963 as discussed in the other thread.

Regarding the example you are providing this is indeed a breaking change but the impact is probably quite low. I was also thinking that another way to handle this was to keep this implementation and to provide all assertions from GenericCollectionAssertions to the GenericDictionaryAssertions. Somehow a dictionary, readonly-dictionary or immutable dictionary ARE a specific kind of collections.

WDYT?

@dennisdoomen
Copy link
Member

I was also thinking that another way to handle this was to keep this implementation and to provide all assertions from GenericCollectionAssertions to the GenericDictionaryAssertions.

That could work indeed and prevent breaking changes.

@jnyrup
Copy link
Member

jnyrup commented Jan 10, 2020

I think I quite like this approach as it:

  • Adds support for IReadOnlyDictionary
  • Keeps support for IDictionary
  • With GenericDictionaryAssertions inheriting from GenericCollectionAssertions has minimal impact for IEnumerable<KeyValuePair>

If we further redefine GenericCollectionAssertions as

public class GenericCollectionAssertions<T> :
    GenericCollectionAssertions<T, GenericCollectionAssertions<T>>

public class GenericCollectionAssertions<T, TAssertions> :
    SelfReferencingCollectionAssertions<T, TAssertions>
    where TAssetions : GenericCollectionAssertions<T, TAssertions>

GenericDictionaryAssertions will be able to inherit a lot of assertions while still returning AndConstraint<GenericDictionaryAssertions>. (only 15 tests fail, and that because of slightly different failure messages)

@Evangelink
Copy link
Contributor Author

ALright! I'll work on making this change happen then!

@jnyrup
Copy link
Member

jnyrup commented Jan 11, 2020

@Evangelink Hold your horses.

This PR is competing with #963 and I would like to avoid you or @krajek working needlessly on something that will be abandoned. That would be a waste of your valuable contributions.

But if it's only fun to implement, go ahead and see where it takes this PR. E.g. if you bump into other problems along the way.

@jnyrup
Copy link
Member

jnyrup commented Jan 15, 2020

@Evangelink I've chatted with the others and please continue this approach.
Regarding tests, I'm very satisfied if we cover each line in CountSubjectItems etc.
No need to duplicate each and every test.

@jnyrup jnyrup added this to the 6.0 milestone Jan 23, 2020
@jnyrup
Copy link
Member

jnyrup commented Feb 8, 2020

Fiddled a bit around with this PR in jnyrup@3cc8bf4

  • Let GenericDictionaryAssertions derive from GenericCollectionAssertions to inherit all counting related assertions for free.
  • Abstract IEnumerable<T> into TCollection : IEnumerable<KeyValuePair<K, V>> such that assertions on an IDictionary<K, V> still returns an IDictionary<K, V instead of IEnumerable<KeyValuePair<K, V>>.

@dennisdoomen
Copy link
Member

dennisdoomen commented Feb 9, 2020

Fiddled a bit around with this PR in jnyrup@6773886

What are the pros and cons compared to the other two approaches?

@jnyrup
Copy link
Member

jnyrup commented Feb 9, 2020

It's a continuation of this PR, so the base idea of extending on IEnumerable<KeyValuePair<K, V>> instead of IDictionary<K, V> is still the same, but taken one step further by abstracting IEnumerable<KeyValuePair<K, V>> in to TCollection : IEnumerable<KeyValuePair<K, V>>.
This way the return type of dictionary.Should().Subject will still be IDictionary<K, V> instead of "only" IEnumerable<KeyValuePair<K, V>>.

Pros:

  • [Not]HaveCount, [Not]BeEmpty are inherited from GenericCollectionAssertions.
  • Retains the specific type of dictionary instead of just `IEnumerable<KeyValuePair<K, V>>.
  • Let [Not]Equal take an TCollection, such that it supports both IDictionary and IReadOnlyDictionary.

Cons:

  • ?

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.

3 participants