-
Notifications
You must be signed in to change notification settings - Fork 150
Add helper DictionaryExtensions.SequenceEqual
#7722
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| using System.Collections; | ||
| using System.Collections.Concurrent; | ||
| using System.Collections.Generic; | ||
| using System.Collections.ObjectModel; | ||
| using Datadog.Trace.Util; | ||
|
|
||
| namespace Datadog.Trace.ExtensionMethods | ||
|
|
@@ -128,5 +129,42 @@ public static TV Get<TK, TV>(this Dictionary<TK, TV> map, TK key, Func<TK, TV> c | |
| map[key] = newVal; | ||
| return newVal; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Checks if two dictionaries contain the same keys and values. | ||
| /// Note that this method assumes the two dictionaries use the same | ||
| /// <see cref="IEqualityComparer"/>; using different comparers in each | ||
| /// dictionary is not supported. | ||
| /// </summary> | ||
| public static bool SequenceEqual( | ||
| this ReadOnlyDictionary<string, string> dict1, | ||
| ReadOnlyDictionary<string, string> dict2, | ||
|
Comment on lines
+140
to
+141
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason to not doing it in a Generic way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, mostly because it's unnecessary, so extra abstraction doesn't seem worth it 🤷♂️ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, auto merge just went ahead with it 😓 |
||
| StringComparison valueComparison = StringComparison.Ordinal) | ||
| { | ||
| if (dict1 is null && dict2 is null) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| if (dict1 is null || dict2 is null || dict1.Count != dict2.Count) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| if (dict1.Count == 0 && dict2.Count == 0) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| foreach (var kvp1 in dict1) | ||
| { | ||
| if (!dict2.TryGetValue(kvp1.Key, out var val2) || !string.Equals(kvp1.Value, val2, valueComparison)) | ||
| { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // <copyright file="DictionaryExtensionsTests.cs" company="Datadog"> | ||
| // Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. | ||
| // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. | ||
| // </copyright> | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Collections.ObjectModel; | ||
| using Datadog.Trace.ExtensionMethods; | ||
| using Datadog.Trace.Util; | ||
| using FluentAssertions; | ||
| using Xunit; | ||
|
|
||
| namespace Datadog.Trace.Tests.ExtensionMethods; | ||
|
|
||
| public class DictionaryExtensionsTests | ||
| { | ||
| [Fact] | ||
| public void SequenceEqual_HandlesBothNull() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = null; | ||
| dict1!.SequenceEqual(null).Should().BeTrue(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_HandlesOneNull() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = null; | ||
| ReadOnlyDictionary<string, string> dict2 = ReadOnlyDictionary.Empty; | ||
| dict1!.SequenceEqual(dict2).Should().BeFalse(); | ||
| dict2!.SequenceEqual(dict1).Should().BeFalse(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_HandlesEmpty() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = ReadOnlyDictionary.Empty; | ||
| ReadOnlyDictionary<string, string> dict2 = ReadOnlyDictionary.Empty; | ||
| dict1.SequenceEqual(dict2).Should().BeTrue(); | ||
| dict2.SequenceEqual(dict1).Should().BeTrue(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_HandlesDifferentSizes() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string> { { "key", "value" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = ReadOnlyDictionary.Empty; | ||
| dict1.SequenceEqual(dict2).Should().BeFalse(); | ||
| dict2.SequenceEqual(dict1).Should().BeFalse(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_HandlesDifferentKeys() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string> { { "key1", "value" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = new(new Dictionary<string, string> { { "key2", "value" } }); | ||
| dict1.SequenceEqual(dict2).Should().BeFalse(); | ||
| dict2.SequenceEqual(dict1).Should().BeFalse(); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData("value2")] | ||
| [InlineData("VALUE1")] | ||
| [InlineData("value1 ")] | ||
| [InlineData(" value1 ")] | ||
| [InlineData("")] | ||
| [InlineData(null)] | ||
| public void SequenceEqual_HandlesDifferentValues(string value) | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string> { { "key", "value1" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = new(new Dictionary<string, string> { { "key", value } }); | ||
| dict1.SequenceEqual(dict2).Should().BeFalse(); | ||
| dict2.SequenceEqual(dict1).Should().BeFalse(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_UsesDictionaryKeyComparer() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "key", "value" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = new(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "KEY", "value" } }); | ||
| dict1.SequenceEqual(dict2).Should().BeTrue(); | ||
| dict2.SequenceEqual(dict1).Should().BeTrue(); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SequenceEqual_UsesDictionaryWithDifferentComparersIsNotSupported() | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string>(StringComparer.Ordinal) { { "key", "value" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = new(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "KEY", "value" } }); | ||
|
|
||
| // reversing the order changes the result | ||
| dict1.SequenceEqual(dict2).Should().BeTrue(); | ||
| dict2.SequenceEqual(dict1).Should().BeFalse(); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(StringComparison.Ordinal, "value", true)] | ||
| [InlineData(StringComparison.Ordinal, "VALUE", false)] | ||
| [InlineData(StringComparison.OrdinalIgnoreCase, "VALUE", true)] | ||
| public void SequenceEqual_UsesComparer(StringComparison comparison, string value, bool expected) | ||
| { | ||
| ReadOnlyDictionary<string, string> dict1 = new(new Dictionary<string, string> { { "key", "value" } }); | ||
| ReadOnlyDictionary<string, string> dict2 = new(new Dictionary<string, string> { { "key", value } }); | ||
|
|
||
| // reversing the order changes the result | ||
| dict1.SequenceEqual(dict2, comparison).Should().Be(expected); | ||
| dict2.SequenceEqual(dict1, comparison).Should().Be(expected); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.