Comparing Resource Dictionaries in Unit Tests

  • submit to reddit

Christopher Bennage is an SDE2 with patterns & practices at Microsoft. Christopher began programming on his Texas Instrument in elementary school, but fell in love with computers with the advent of the Commodore Amiga. More recently he's been attracted to client technologies like XAML, HTML5, and JavaScript. In his free time, Christopher is usually very distracted by a dozen different, competing creative ideas. He lives in Kirkland, WA with his wife, Sandra, and their three children. Read more on http://dev.bennage.com Christopher is a DZone MVB and is not an employee of DZone and has posted 30 posts at DZone. View Full User Profile

Working on the ÜberProf has presented some interesting scenarios. As you might have picked up from Ayende’s blog, the vast majority of the source is shared between all the products. This is especially true in the UI layer.

Now, Ayende wanted to have a distinct color scheme for each application. That by itself wasn’t a big deal, switching out resource dictionary is well documented and very straight forward. The architecture we choose resulted in a resource dictionary for each application with a set of identical keys. Additionally, and because of our design choices, we have to reference everything using DynamicResource. I was concerned about the possibility of omitting a key from one of the dictionaries and consequently breaking the UI. (I know that some people feel the UI is already broken. Don’t be a hater. It will get better.)

I decided to write a test to compare the dictionaries and check for omitted keys. I designated the NHProf dictionary as the “master”. It is the standard that the others are compared against.

Here’s what one of the actual test looks like:

 public class EnsureColorsAndBrushesAreConsistentFor  
{
[Fact]
public void LinqToSql()
{
var master = GetMasterListOfKeys();

var linq2sql = new Client.Resources.LinqToSql.ColorsAndBrushes();
linq2sql.InitializeComponent();

var missing = from resource in master
where !linq2sql.Contains(resource)
select resource;

Assert.True(
missing.Count() == 0,
MissingMessage("LinqToSql", missing));
}

private static IEnumerable<object> keys;

private static IEnumerable<object> GetMasterListOfKeys()
{
if (keys == null)
{
var master = new ColorsAndBrushes();
master.InitializeComponent();
keys = master.Keys.Cast<object>();
}
return keys;
}

private static string MissingMessage(string dictionaryName, IEnumerable<object> missing)
{
return missing.Aggregate(
string.Format("ColorsAndBrushes.xaml for {0} is missing the following: ", dictionaryName),
(seed, key) => seed + "\n" + key);
}
}

In order for this to work, I had to turn each of the resource dictionaries into a class. This is very easy to do, you only need to add the x:Class attribute to the root.

<ResourceDictionary x:Class="HibernatingRhinos.Profiler.Client.Resources.LinqToSql.ColorsAndBrushes"  
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

There are similar tests for each of the applications.

 

References
0

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)