Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The test that I'm going to implement this time is the following:
Add 3 Bookmarks, call GetEnumerator and verify that the 3 Bookmarks are enumerated
3 seems excessive, I think 2 will be sufficient; here is the test:
[Test]
public void EnumeratorContainsOnlyAddedItems()
{
collection.Add(exampleDotComLabel, exampleDotComUri);
collection.Add(exampleDotNetLabel, exampleDotNetUri);
IEnumerator<KeyValuePair<string, Uri>> enumerator =
collection.GetEnumerator();
Assert.IsTrue(EnumeratorContains(enumerator,
exampleDotComLabel, exampleDotComUri));
Assert.IsTrue(EnumeratorContains(enumerator,
exampleDotNetLabel, exampleDotNetUri));
}
And to get this to work I need to implement the test helper – EnumeratorContains.
private bool EnumeratorContains(
IEnumerator<KeyValuePair<string, Uri>> enumerator,
string label, Uri uri)
{
while (enumerator.MoveNext())
{
KeyValuePair<string, Uri> bookmark = enumerator.Current;
if (bookmark.Key.Equals(label) &&
bookmark.Value.Equals(uri))
return true;
}
return false;
}
Don’t you just love that generics syntax. I am starting to get the C++ template shivers again. There is a big problem with this code but lets get it to work before starting to fix it. Here is the implementation I need to get the test to pass:
public IEnumerator<KeyValuePair<string, Uri>> GetEnumerator()
{
return dictionary.GetEnumerator();
}
This is simple enough, and the tests pass. Now that it works what was that issue? It seems to me that returning a KeyValuePair<string, Uri> exposes too much of the underlying storage mechanism. What if someone wanted to come along and change it? You are potentially looking at a change to the interface or if you are unwilling to do that you would have to adapt to the new interface. Also, the syntax as I mentioned before is not the prettiest. My solution to this problem is to introduce a class called Bookmark. Let’s rewrite the test.
[Test]
public void EnumeratorContainsOnlyAddedItems()
{
collection.Add(exampleDotComLabel, exampleDotComUri);
collection.Add(exampleDotNetLabel, exampleDotNetUri);
IEnumerator<Bookmark> enumerator = collection.GetEnumerator();
Assert.IsTrue(EnumeratorContains(enumerator,
exampleDotComLabel, exampleDotComUri));
Assert.IsTrue(EnumeratorContains(enumerator,
exampleDotNetLabel, exampleDotNetUri));
}
I left out the EnumeratorContains method as an exercise for you, the reader. Here is the corresponding implementation:
public IEnumerator<Bookmark> GetEnumerator()
{
foreach (KeyValuePair<string, Uri> bookmark in dictionary)
yield return new Bookmark(bookmark.Key, bookmark.Value);
}
and the simplest Bookmark class implementation:
public
class Bookmark
{
private string label;
private Uri uri;
public Bookmark(string label, Uri uri)
{
this.label = label;
this.uri = uri;
}
public string Label
{
get { return label; }
}
public Uri Uri
{
get { return uri; }
}
}
When I compile and run this the tests pass. I don’t like that we have to create a new Bookmark to enumerate over the bookmarks so thats where I will pick up next time.