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

Fix TryGetValue for dictionary like enumerables #1786

Merged
merged 1 commit into from Jan 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions Src/FluentAssertions/Common/DictionaryHelpers.cs
Expand Up @@ -58,9 +58,17 @@ static bool ContainsKey(TCollection collection, TKey key)
static bool TryGetValue(TCollection collection, TKey key, out TValue value)
{
Func<TKey, TKey, bool> areSameOrEqual = ObjectExtensions.GetComparer<TKey>();
KeyValuePair<TKey, TValue> matchingPair = collection.FirstOrDefault(kvp => areSameOrEqual(kvp.Key, key));
value = matchingPair.Value;
return matchingPair.Equals(default(KeyValuePair<TKey, TValue>));
foreach (var kvp in collection)
{
if (areSameOrEqual(kvp.Key, key))
{
value = kvp.Value;
return true;
}
}

value = default;
return false;
}
}

Expand Down
Expand Up @@ -874,7 +874,7 @@ public void When_asserting_dictionary_with_items_is_not_empty_it_should_succeed(
dictionary.Should().NotBeEmpty();
}

#if !NET5_0_OR_GREATER
#if !NET5_0_OR_GREATER

[Fact]
public void When_asserting_dictionary_with_items_is_not_empty_it_should_enumerate_the_dictionary_only_once()
Expand All @@ -889,7 +889,7 @@ public void When_asserting_dictionary_with_items_is_not_empty_it_should_enumerat
trackingDictionary.Enumerator.LoopCount.Should().Be(1);
}

#endif
#endif

[Fact]
public void When_asserting_dictionary_without_items_is_not_empty_it_should_fail()
Expand Down Expand Up @@ -2638,6 +2638,15 @@ public void When_a_dictionary_like_collection_contains_the_expected_key_it_shoul
act.Should().NotThrow();
}

[Theory]
[MemberData(nameof(SingleDictionaryData))]
public void When_a_dictionary_like_collection_contains_the_expected_key_and_value_it_should_succeed<T>(T subject)
where T : IEnumerable<KeyValuePair<int, int>>
{
// Assert
subject.Should().Contain(1, 42);
}

[Theory]
[MemberData(nameof(SingleDictionaryData))]
public void When_a_dictionary_like_collection_contains_the_expected_value_it_should_succeed<T>(T subject)
Expand Down Expand Up @@ -2675,6 +2684,19 @@ private static object[] Dictionaries()
};
}

[Fact]
public void When_a_dictionary_like_collection_contains_the_default_key_it_should_succeed()
{
// Arrange
var subject = new List<KeyValuePair<int, int>>() { new(0, 0) };

// Act
Action act = () => subject.Should().Contain(0, 0);

// Assert
act.Should().NotThrow();
}

/// <summary>
/// This class only implements <see cref="IReadOnlyDictionary{TKey, TValue}"/>,
/// as <see cref="ReadOnlyDictionary{TKey, TValue}"/> also implements <see cref="IDictionary{TKey, TValue}"/>.
Expand Down
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Expand Up @@ -20,6 +20,7 @@ sidebar:
* Variable name is not captured after await assertion - [#1770](https://github.com/fluentassertions/fluentassertions/pull/1770)
* `OccurredEvent` ordering on monitored object is now done via thread-safe counter - [#1773](https://github.com/fluentassertions/fluentassertions/pull/1773)
* Avoid a `NullReferenceException` when testing an application compiled with .NET Native - [#1776](https://github.com/fluentassertions/fluentassertions/pull/1776)
* `[Not]Contain(key, value)` for dictionary-like enumerables incorrectly checked if the key was present - [#1786](https://github.com/fluentassertions/fluentassertions/pull/1786)

## 6.3.0

Expand Down