Skip to content

Instantly share code, notes, and snippets.

@njonsson
Created March 20, 2010 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save njonsson/338938 to your computer and use it in GitHub Desktop.
Save njonsson/338938 to your computer and use it in GitHub Desktop.
MultiValueDictionary, a generic collection of keys paired with zero or more values each
namespace System.Collections.Generic
{
/// <summary>
/// Represents a generic collection of keys paired with zero or more values
/// each.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.</typeparam>
/// <typeparam name="TValues">The type of the value list elements in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.</typeparam>
public interface IMultiValueDictionary<TKey, TValues> :
IDictionary<TKey, IEnumerable<TValues>>
{
/// <summary>
/// Adds the specified <paramref name="key" /> and
/// <paramref name="value"/> to the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>. If
/// <paramref name="key"/> already exists in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/> then
/// <paramref name="value"/> is added to the end of the list of values
/// for <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="value">The value of the element to add. The value can
/// be a null reference (<c>Nothing</c> in Visual Basic).</param>
/// <returns><c>true</c> if <paramref name="key"/> and
/// <paramref name="value"/> are not both already present; otherwise,
/// <c>false</c>. This method returns <c>true</c> if
/// <paramref name="value"/> is added to the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
bool AddValue( TKey key, TValues value );
/// <summary>
/// Adds the specified <paramref name="key" /> and
/// <paramref name="values"/> to the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>. If
/// <paramref name="key"/> already exists in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/> then
/// <paramref name="values"/> are added to the end of the list of values
/// for <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="values">The values of the element to add. The values
/// can be null references (<c>Nothing</c> in Visual Basic).</param>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
void AddValues( TKey key, IEnumerable<TValues> values );
/// <summary>
/// Removes the values with the specified <paramref name="key"/> from
/// the <see cref="IMultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <returns><c>true</c> if the values are successfully found and
/// removed; otherwise, <c>false</c>. This method returns <c>false</c>
/// if <paramref name="key"/> is not found in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
bool RemoveKey( TKey key );
/// <summary>
/// Removes the values with the specified <paramref name="keys"/> from
/// the <see cref="IMultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="keys">The keys of the values to remove.</param>
/// <exception cref="ArgumentNullException"><paramref name="keys"/>
/// is a null reference (<c>Nothing</c> in Visual Basic) or any of its
/// elements are null references.</exception>
void RemoveKeys( IEnumerable<TKey> keys );
/// <summary>
/// Removes the specified <param name="value"/> with the specified
/// <paramref name="key"/> from the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <param name="value">The value to remove by
/// <paramref name="key"/>. The value can be a null reference
/// (<c>Nothing</c> in Visual Basic).</param>
/// <returns><c>true</c> if <paramref name="value"/> is successfully
/// found for <paramref name="key"/> and removed; otherwise,
/// <c>false</c>. This method returns <c>false</c> if
/// <paramref name="key"/> is not found in the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
bool RemoveValue( TKey key, TValues value );
/// <summary>
/// Removes the specified <param name="values"/> with the specified
/// <paramref name="key"/> from the
/// <see cref="IMultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <param name="values">The values to remove by
/// <paramref name="key"/>. The values can be null references
/// (<c>Nothing</c> in Visual Basic).</param>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
void RemoveValues( TKey key, IEnumerable<TValues> values );
}
}
namespace System.Collections.Generic
{
/// <summary>
/// Represents a generic collection of keys paired with zero or more values
/// each.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.</typeparam>
/// <typeparam name="TValues">The type of the value list elements in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.</typeparam>
public class MultiValueDictionary<TKey, TValues> :
Dictionary<TKey, IEnumerable<TValues>>,
IMultiValueDictionary<TKey, TValues>
{
/// <summary>
/// Gets or sets the values associated with the specified
/// <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the value to get or set.</param>
/// <returns>The values associated with the specified
/// <paramref name="key"/>. If the specified <paramref name="key"/> is
/// not found, a get operation returns an empty list, and a set
/// operation creates a new element with the specified
/// <paramref name="key"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is
/// (<c>Nothing</c> in Visual Basic), or the list of values is a null
/// reference in a set operation.</exception>
public new IEnumerable<TValues> this[ TKey key ]
{
get
{
IEnumerable<TValues> values;
if ( TryGetValue( key, out values ) ) return values;
return new TValues[ 0 ];
}
set
{
if ( value == null ) throw new ArgumentNullException();
base[ key ] = value;
}
}
/// <summary>
/// Adds the specified <paramref name="key" /> and
/// <paramref name="value"/> to the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>. If
/// <paramref name="key"/> already exists in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/> then
/// <paramref name="value"/> is added to the end of the list of values
/// for <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="value">The value of the element to add. The value can
/// be a null reference (<c>Nothing</c> in Visual Basic).</param>
/// <returns><c>true</c> if <paramref name="key"/> and
/// <paramref name="value"/> are not both already present; otherwise,
/// <c>false</c>. This method returns <c>true</c> if
/// <paramref name="value"/> is added to the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
public bool AddValue( TKey key, TValues value )
{
IEnumerable<TValues> existingValues;
if ( TryGetValue( key, out existingValues ) )
{
var valuesList = new List<TValues>( existingValues );
if ( valuesList.Contains( value ) ) return false;
valuesList.Add( value );
this[ key ] = valuesList.ToArray();
}
else
{
Add( key, new[] { value } );
}
return true;
}
/// <summary>
/// Adds the specified <paramref name="key" /> and
/// <paramref name="values"/> to the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>. If
/// <paramref name="key"/> already exists in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/> then
/// <paramref name="values"/> are added to the end of the list of values
/// for <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="values">The values of the element to add. The values
/// can be null references (<c>Nothing</c> in Visual Basic).</param>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
public void AddValues( TKey key, IEnumerable<TValues> values )
{
IEnumerable<TValues> existingValues;
if ( !TryGetValue( key, out existingValues ) )
{
Add( key, new List<TValues>( values ).ToArray() );
return;
}
var valuesList = new List<TValues>( existingValues );
foreach ( var v in values )
{
if ( valuesList.Contains( v ) ) continue;
valuesList.Add( v );
}
this[ key ] = valuesList.ToArray();
}
/// <summary>
/// Removes the values with the specified <paramref name="key"/> from
/// the <see cref="MultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <returns><c>true</c> if the values are successfully found and
/// removed; otherwise, <c>false</c>. This method returns <c>false</c>
/// if <paramref name="key"/> is not found in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
public bool RemoveKey( TKey key )
{
return Remove( key );
}
/// <summary>
/// Removes the values with the specified <paramref name="keys"/> from
/// the <see cref="MultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="keys">The keys of the values to remove.</param>
/// <exception cref="ArgumentNullException"><paramref name="keys"/>
/// is a null reference (<c>Nothing</c> in Visual Basic) or any of its
/// elements are null references.</exception>
public void RemoveKeys( IEnumerable<TKey> keys )
{
if ( keys == null ) throw new ArgumentNullException( "keys" );
foreach ( var k in keys ) RemoveKey( k );
}
/// <summary>
/// Removes the specified <param name="value"/> with the specified
/// <paramref name="key"/> from the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <param name="value">The value to remove by
/// <paramref name="key"/>. The value can be a null reference
/// (<c>Nothing</c> in Visual Basic).</param>
/// <returns><c>true</c> if <paramref name="value"/> is successfully
/// found for <paramref name="key"/> and removed; otherwise,
/// <c>false</c>. This method returns <c>false</c> if
/// <paramref name="key"/> is not found in the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
public bool RemoveValue( TKey key, TValues value )
{
IEnumerable<TValues> existingValues;
if ( !TryGetValue( key, out existingValues ) ) return false;
var valuesList = new List<TValues>( existingValues );
if ( !valuesList.Remove( value ) ) return false;
this[ key ] = valuesList.ToArray();
return true;
}
/// <summary>
/// Removes the specified <param name="values"/> with the specified
/// <paramref name="key"/> from the
/// <see cref="MultiValueDictionary{TKey,TValues}"/>.
/// </summary>
/// <param name="key">The key of the values to remove.</param>
/// <param name="values">The values to remove by
/// <paramref name="key"/>. The values can be null references
/// (<c>Nothing</c> in Visual Basic).</param>
/// <exception cref="ArgumentNullException"><paramref name="key"/> is a
/// null reference (<c>Nothing</c> in Visual Basic).</exception>
public void RemoveValues( TKey key, IEnumerable<TValues> values )
{
IEnumerable<TValues> existingValues;
if ( !TryGetValue( key, out existingValues ) ) return;
var valuesList = new List<TValues>( existingValues );
foreach ( var v in values ) valuesList.Remove( v );
this[ key ] = valuesList.ToArray();
}
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace System.Collections.Generic
{
public static class ExtensionMethods
{
public static int Count<T>( this IEnumerable<T> @this )
{
return new List<T>( @this ).Count;
}
public static T Get<T>( this IEnumerable<T> @this, int index )
{
return new List<T>( @this )[ index ];
}
}
[TestClass]
public class MultiValueDictionaryTest
{
protected class TestKey
{
public static TestKey One = new TestKey( 1 );
public static TestKey Two = new TestKey( 2 );
public static TestKey Three = new TestKey( 3 );
public TestKey( int id )
{
ID = id;
}
public int ID
{
get;
protected set;
}
public override bool Equals( object obj )
{
var otherTestKey = obj as TestKey;
if ( ( otherTestKey == null ) ||
( otherTestKey.GetType() != GetType() ) )
{
return false;
}
return ID.Equals( otherTestKey.ID );
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
public override string ToString()
{
return ID.ToString();
}
}
protected IMultiValueDictionary<TestKey, string> MultiValueDictionary;
public TestContext TestContext
{
get;
set;
}
[TestInitialize]
public void TestInitialize()
{
MultiValueDictionary = new MultiValueDictionary<TestKey, string>();
}
protected static void AssertAreEqual( IDictionary<TestKey, string[]> expected,
IMultiValueDictionary<TestKey, string> actual )
{
Assert.AreEqual( expected.Count, actual.Count );
foreach ( var k in expected.Keys )
{
var expectedValues = expected[ k ];
var actualValues = actual[ k ];
AssertAreEqual( expectedValues, actualValues );
}
}
protected static void AssertAreEqual( IEnumerable<string> expected,
IEnumerable<string> actual )
{
Assert.AreEqual( expected.Count(), actual.Count() );
for ( var i = 0; i < expected.Count(); i++ )
{
Assert.AreEqual( expected.Get( i ), actual.Get( i ) );
}
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void IndexerGetOperationShouldBehaveAsExpectedWhenPassedANullKey()
{
// ReSharper disable AssignNullToNotNullAttribute
var dummy = MultiValueDictionary[ null ];
// ReSharper restore AssignNullToNotNullAttribute
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void IndexerSetOperationShouldBehaveAsExpectedWhenPassedANullKey()
{
// ReSharper disable AssignNullToNotNullAttribute
MultiValueDictionary[ null ] = new[] { "foo" };
// ReSharper restore AssignNullToNotNullAttribute
}
[TestMethod]
public void IndexerShouldBehaveAsExpectedWhenPassedANewKey()
{
AssertAreEqual( new string[ 0 ], MultiValueDictionary[ TestKey.One ] );
}
[TestMethod]
public void IndexerShouldBehaveAsExpectedWhenPassedAnExistingKey()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
AssertAreEqual( new[] { "foo" }, MultiValueDictionary[ TestKey.One ] );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void AddValueShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.AddValue( null, "foo" );
}
[TestMethod]
public void AddValueShouldBehaveAsExpectedWhenPassedANewKeyAndValue()
{
Assert.IsTrue( MultiValueDictionary.AddValue( TestKey.One, "foo" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValueShouldBehaveAsExpectedWhenPassedAnExistingKeyAndValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsFalse( MultiValueDictionary.AddValue( TestKey.One, "foo" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValueShouldBehaveAsExpectedWhenPassedAnExistingKeyAndANewValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsTrue( MultiValueDictionary.AddValue( TestKey.One, "bar" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValueShouldBehaveAsExpectedWhenPassedANewKeyAndAnExistingValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsTrue( MultiValueDictionary.AddValue( TestKey.Two, "foo" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } },
{ TestKey.Two, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void AddValuesShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.AddValues( null, new[] { "foo" } );
}
[TestMethod]
public void AddValuesShouldBehaveAsExpectedWhenPassedANewKeyAndRepeatedNewValues()
{
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo", "foo" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValuesShouldBehaveAsExpectedWhenPassedANewKeyAndNonRepeatedNewValues()
{
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo", "bar" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValuesShouldBehaveAsExpectedWhenPassedAnExistingKeyAndValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValuesShouldBehaveAsExpectedWhenPassedAnExistingKeyAndANewValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValues( TestKey.One, new[] { "bar" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
public void AddValuesShouldBehaveAsExpectedWhenPassedANewKeyAndAnExistingValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValues( TestKey.Two, new[] { "foo" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } },
{ TestKey.Two, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void RemoveKeyShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.RemoveKey( null );
}
[TestMethod]
public void RemoveKeyShouldBehaveAsExpectedWhenPassedANewKey()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsFalse( MultiValueDictionary.RemoveKey( TestKey.Two ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveKeyShouldBehaveAsExpectedWhenPassedAnExistingKey()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValue( TestKey.Two, "bar" );
Assert.IsTrue( MultiValueDictionary.RemoveKey( TestKey.One ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.Two, new[] { "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedNull()
{
MultiValueDictionary.RemoveKeys( null );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.RemoveKeys( new TestKey[] { null } );
}
[TestMethod]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedRepeatedNewKeys()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.RemoveKeys( new[] { TestKey.Two, TestKey.Two } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedNonRepeatedNewKeys()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.RemoveKeys( new[] { TestKey.Two, TestKey.Three } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedAnExistingKey()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValue( TestKey.Two, "bar" );
MultiValueDictionary.RemoveKeys( new[] { TestKey.One } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.Two, new[] { "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveKeysShouldBehaveAsExpectedWhenPassedAnExistingKeyAndANewKey()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValue( TestKey.Two, "bar" );
MultiValueDictionary.RemoveKeys( new[] { TestKey.One, TestKey.Three } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.Two, new[] { "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void RemoveValueShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.RemoveValue( null, "foo" );
}
[TestMethod]
public void RemoveValueShouldBehaveAsExpectedWhenPassedANewKeyAndValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsFalse( MultiValueDictionary.RemoveValue( TestKey.Two, "bar" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValueShouldBehaveAsExpectedWhenPassedAnExistingKeyAndValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.AddValue( TestKey.Two, "bar" );
Assert.IsTrue( MultiValueDictionary.RemoveValue( TestKey.One, "foo" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new string[0] },
{ TestKey.Two, new[] { "bar" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValueShouldBehaveAsExpectedWhenPassedAnExistingKeyAndANewValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsFalse( MultiValueDictionary.RemoveValue( TestKey.One, "bar" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValueShouldBehaveAsExpectedWhenPassedANewKeyAndAnExistingValue()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
Assert.IsFalse( MultiValueDictionary.RemoveValue( TestKey.Two, "foo" ) );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedANullKey()
{
MultiValueDictionary.RemoveValues( null, new[] { "foo" } );
}
[TestMethod]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedANewKeyAndRepeatedNewValues()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.RemoveValues( TestKey.Two, new[] { "bar", "bar" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedANewKeyAndNonRepeatedNewValues()
{
MultiValueDictionary.AddValue( TestKey.One, "foo" );
MultiValueDictionary.RemoveValues( TestKey.Two, new[] { "bar", "baz" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedAnExistingKeyAndValue()
{
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo", "bar" } );
MultiValueDictionary.AddValue( TestKey.Two, "baz" );
MultiValueDictionary.RemoveValues( TestKey.One, new[] { "foo" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "bar" } },
{ TestKey.Two, new[] { "baz" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedAnExistingKeyAndANewValue()
{
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo", "bar" } );
MultiValueDictionary.AddValue( TestKey.Two, "baz" );
MultiValueDictionary.RemoveValues( TestKey.One, new[] { "bat" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "bar" } },
{ TestKey.Two, new[] { "baz" } }
},
MultiValueDictionary );
}
[TestMethod]
public void RemoveValuesShouldBehaveAsExpectedWhenPassedANewKeyAndAnExistingValue()
{
MultiValueDictionary.AddValues( TestKey.One, new[] { "foo", "bar" } );
MultiValueDictionary.RemoveValues( TestKey.Two, new[] { "foo" } );
AssertAreEqual( new Dictionary<TestKey, string[]>
{
{ TestKey.One, new[] { "foo", "bar" } }
},
MultiValueDictionary );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment