Replace Paper with Unit Tests: Code Snippets Edition

In my previous post about making mental notes about condition tests or new features through unit tests I offered an example of making a live template in ReSharper to automate some of the process.

This post is about achieving a similar thing in plain Visual Studio with the help of the Code Snippets feature.

Introduction to Code Snippets

In a nutshell, a code snippet in Visual Studio is either a template or a static chunk of code that is stored in a specific location and is available through IntelliSense. Visual Studio comes with some snippets pre-configured, such as “ctor“, which creates a default constructor for a class.

To use a snippet, start typing out its shortcut – either type the whole thing or wait for IntelliSense to pop up and complete it for you – and then press TAB key twice to expand the snippet into code.

There’s a detailed guide to using and creating snippets available on MSDN. For the rest of this post, I will just show what I did for my purposes.

Snippet Location and Creating New Snippets

Snippets are located in a specific folder under your installation of Visual Studio, so you’ll have a snippet collection per VS version. On my machine, where I used default installation paths, C# snippets for VS 2008 and 2010 are in the following folders:

C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#

C:\Program Files\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Visual C#

You can use the Code Snippet Manager (available through Tools->Code Snippets Manager… menu item) to explore currently installed snippets for various languages.

To create a new snippet, you can simply write its XML definition (see below for my example or read the MSDN guide for more info), save the file with the .snippet extension and drop it in the appropriate folder. Visual Studio will see it without needing to restart.

You can also use a visual editor such as the open source Snippet Editor, which now includes support for Visual Studio 2010.

Unimplemented Unit Test Snippet

Here’s my code snippet in its entirety:

<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Unimplemented Unit Test</Title>
<Shortcut>test</Shortcut>
<Description>Code snippet for a failing test placeholder</Description>
<Author>Anna Lear (http://annalear.ca)</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>testName</ID>
<ToolTip>Descriptive test name</ToolTip>
<Default>NewTest</Default>
</Literal>
<Literal>
<ID>testBody</ID>
<ToolTip>Test contents</ToolTip>
<Default>Assert.Fail("Implement me!");</Default>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[
[Test]
public void $testName$()
{
$testBody$
}
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

I wrote it within Visual Studio 2010 and it helpfully provided IntelliSense support and guidance, which made writing the XML really easy.

Now when I type in “test” in a class and press TAB twice, the code within the CDATA portion of the snippet gets pasted into my code. “NewTest” and “Assert.Fail(“Implement me!”);” lines will be highlighted and I can navigate between then with TAB and Shift-TAB if I need to edit them. I typically always edit the name of the test, and only edit the body when I intend to implement the test at the same time.

Couple things to keep in mind:

1. When you add literals to a snippet, their IDs are case-sensitive.

2. If you want to preserve your formatting (multiple lines, etc.), make sure that you’re code is within a single CDATA element. Otherwise you’ll end up with all your code on the same line, which probably isn’t what you want.

Download

You can either copy the snippet above and do the legwork of placing it in a file and the correct location, or download the .snippet file or the .vsi installer, the latter of which will allow you to easily install the above snippet into any version of Visual Studio (2005 or newer) that you have on your machine.

Advertisement

Sorting a C# dictionary by value

This is fairly simple: create a list to hold your dictionary’s objects and use a delegate to provide a custom sorting mechanism.

Dictionary<int, double> myDictionary = new Dictionary<int, double>();

public Dictionary<int, double> SortMyDictionaryByValue()
{
    List<KeyValuePair<int, double>> tempList = new List<KeyValuePair<int, double>>(myDictionary);

    tempList.Sort(delegate(KeyValuePair<int, double> firstPair, KeyValuePair<int, double> secondPair)
                    {
                        return firstPair.Value.CompareTo(secondPair.Value);
                    }
                 );

    Dictionary<int, double> mySortedDictionary = new Dictionary<int, double>();
    foreach(KeyValuePair<int, double> pair in tempList)
    {
        mySortedDictionary.Add(pair.Key, pair.Value);
    }

    return mySortedDictionary;
}

Problems with anchors and visual control inheritance

I have just spent a couple days playing around with the UI designer in Visual Studio. Now, there is an argument to be made for a UI framework that provides all the common controls and a few layout managers without involving any sort of visual designer tool. But when you’re working in .NET already and all you need is a quick and dirty mock-up of a dialog, it’s hard to beat the Designer. So, I have a form that I use a base for my dialogs. It looks roughly like this:
Base Form A panel for a header, a panel for a footer, and a button nested within the bottom panel. Pretty typical stuff that saves me a lot of time on each of the mock forms, since I don’t have to repeat the same steps every time. The bottom panel is docked to the bottom of the form and the button is anchored to Right and Bottom. When the button’s accessibility modifier in the base form is “private”, everything is groovy. But I want to be able to change the button’s text in the child dialogs, so I make the button “protected” instead. One size doesn’t fit all where forms and dialogs are concerned, so I resize my child forms and observe something that seems very strange — the inherited button moves outside the boundaries of the child form. Child Form (Broken)

Why does this happen?

When the button in the base form is protected and the child form is resized, the designer.cs file of the child form stores the new location of the button:

this.button1.Location = new System.Drawing.Point(274, 3);

When the form is resized, the bottom panel that contains the button resized with it. The button then moves along the X-axis by the width difference between the child panel and the base panel. For example, the bottom panel in the Base Form above is 199 pixels wide. The bottom panel in one of my child forms was 352 pixels wide. So when I saved the child form and opened it later, the button started out at (274, 3) and then shifted right by 352 – 199 = 153 pixels and rendered itself at (427, 3). Roland Weigelt wrote a very nice and detailed post on this almost 6 years ago. The “DockPadding” property he mentions has since become “Padding”, but the advice otherwise seems to still hold. He suggests the following solution:

The secret is the right combination of docking and dock padding.

That’s it right there. I went back to the base form and adjusted the following:

  • Set bottom panel’s Padding to Left = 0, Top = 5, Bottom = 5, Right = 4;
  • Set the button’s Dock to “Right”;
  • Rebuild my solution.

Here’s the result:

Child Form (Fixed)