Home » 2010

Yearly Archives: 2010

BBC Top 100 Books

A meme, from No Magic Here.

Today’s challenge, the BBC Top 100.

Instructions: Bold those books you’ve read in their entirety, italicize the ones you started but didn’t finish or read an excerpt.

  1. Pride and Prejudice – Jane Austen
  2. The Lord of the Rings – JRR Tolkien
  3. Jane Eyre – Charlotte Bronte
  4. Harry Potter series – JK Rowling (all)
  5. To Kill a Mockingbird – Harper Lee
  6. The Bible
  7. Wuthering Heights – Emily Bronte
  8. Nineteen Eighty Four – George Orwell
  9. His Dark Materials – Philip Pullman
  10. Great Expectations – Charles Dickens
  11. Little Women – Louisa M Alcott
  12. Tess of the D’Urbervilles – Thomas Hardy
  13. Catch 22 – Joseph Heller
  14. Complete Works of Shakespeare
  15. Rebecca – Daphne Du Maurier
  16. The Hobbit – JRR Tolkien
  17. Birdsong – Sebastian Faulks
  18. Catcher in the Rye – JD Salinger
  19. The Time Traveller’s Wife – Audrey Niffenegger
  20. Middlemarch – George Eliot
  21. Gone With The Wind – Margaret Mitchell
  22. The Great Gatsby – F Scott Fitzgerald
  23. Bleak House – Charles Dickens
  24. War and Peace – Leo Tolstoy
  25. The Hitch Hiker’s Guide to the Galaxy – Douglas Adams
  26. Brideshead Revisited – Evelyn Waugh
  27. Crime and Punishment – Fyodor Dostoyevsky
  28. Grapes of Wrath – John Steinbeck
  29. Alice in Wonderland – Lewis Carroll
  30. The Wind in the Willows – Kenneth Grahame
  31. Anna Karenina – Leo Tolstoy
  32. David Copperfield – Charles Dickens
  33. Chronicles of Narnia – CS Lewis
  34. Emma – Jane Austen
  35. Persuasion – Jane Austen
  36. The Lion, The Witch and The Wardrobe – CS Lewis
  37. The Kite Runner – Khaled Hosseini
  38. Captain Corelli’s Mandolin – Louis De Berniere
  39. Memoirs of a Geisha – Arthur Golden
  40. Winnie the Pooh – AA Milne
  41. Animal Farm – George Orwell
  42. The Da Vinci Code – Dan Brown
  43. One Hundred Years of Solitude – Gabriel Garcia Marquez
  44. A Prayer for Owen Meaney – John Irving
  45. The Woman in White – Wilkie Collins
  46. Anne of Green Gables – LM Montgomery
  47. Far From The Madding Crowd – Thomas Hardy
  48. The Handmaid’s Tale – Margaret Atwood
  49. Lord of the Flies – William Golding
  50. Atonement – Ian McEwan
  51. Life of Pi – Yann Martel
  52. Dune – Frank Herbert
  53. Cold Comfort Farm – Stella Gibbons
  54. Sense and Sensibility – Jane Austen
  55. A Suitable Boy – Vikram Seth
  56. The Shadow of the Wind – Carlos Ruiz Zafon
  57. A Tale Of Two Cities – Charles Dickens
  58. Brave New World – Aldous Huxley
  59. The Curious Incident of the Dog in the Night-time – Mark Haddon
  60. Love In The Time Of Cholera – Gabriel Garcia Marquez
  61. Of Mice and Men – John Steinbeck
  62. Lolita – Vladimir Nabokov
  63. The Secret History – Donna Tartt
  64. The Lovely Bones – Alice Sebold
  65. Count of Monte Cristo – Alexandre Dumas
  66. On The Road – Jack Kerouac
  67. Jude the Obscure – Thomas Hardy
  68. Bridget Jones’s Diary – Helen Fielding
  69. Midnight’s Children – Salman Rushdie
  70. Moby Dick – Herman Melville
  71. Oliver Twist – Charles Dickens
  72. Dracula – Bram Stoker
  73. The Secret Garden – Frances Hodgson Burnett
  74. Notes From A Small Island – Bill Bryson
  75. Ulysses – James Joyce
  76. The Bell Jar – Sylvia Plath
  77. Swallows and Amazons – Arthur Ransome
  78. Germinal – Emile Zola
  79. Vanity Fair – William Makepeace Thackeray
  80. Possession – AS Byatt
  81. A Christmas Carol – Charles Dickens
  82. Cloud Atlas – David Mitchell
  83. The Color Purple – Alice Walker
  84. The Remains of the Day – Kazuo Ishiguro
  85. Madame Bovary – Gustave Flaubert
  86. A Fine Balance – Rohinton Mistry
  87. Charlotte’s Web – EB White
  88. The Five People You Meet In Heaven – Mitch Albom
  89. Adventures of Sherlock Holmes – Sir Arthur Conan Doyle
  90. The Faraway Tree Collection – Enid Blyton
  91. Heart of Darkness – Joseph Conrad
  92. The Little Prince – Antoine De Saint-Exupery
  93. The Wasp Factory – Iain Banks
  94. Watership Down – Richard Adams
  95. A Confederacy of Dunces – John Kennedy Toole
  96. A Town Like Alice – Nevil Shute
  97. The Three Musketeers – Alexandre Dumas
  98. Hamlet – William Shakespeare
  99. Charlie and the Chocolate Factory – Roald Dahl
  100. Les Miserables – Victor Hugo
Advertisements

Office Adventure: Hard Drive Shuffle

It’s fashionable to complain about the IT department at the Day Job, but sometimes we get pretty good service. I had occasion to contact them today for two unrelated problems. The first, an issue with a Lotus Notes upgrade, was quickly resolved over the phone. The other problem involved hardware, and I’m well on the way to a resolution, with one minor snag.

While rebooting to pick up part of the Notes fix, I noticed something strange on my BIOS screen. I have two hard drives in my workstation, RAID-1ed together. The BIOS displayed one drive as green, and one red. Red is bad. I mentioned this to the Notes Fixer. Half an hour later I was contacted by a different IT guy. He wanted to come by and take the bad drive so he could order another one. “Sure!” said I.

IT Guy rebooted my machine again so he could see which drive was faulty. Then powered it down, popped open the case, extracted the hard drive and blew on it, releasing a cloud of toxic dust right above my tea. All this in less time than it takes to type it. He popped closed the case, and off he went.

I started booting. I also powered up my computer. The computer beeped funny as it started up. I checked out the BIOS screen. One red drive.

No green drive.

“He took the wrong one!” I said, and hared off after him.

There I was, running through the halls, wearing one boot and one sock. Thump-thump. Thump-thump. Thump-thump.

“IT Guy,” I called, as he hove into view. You see, I wanted to make sure I got him before he put the drive under the Big Magnet. Also, I didn’t know where he sits.

I explained the problem.

B: You took the wrong drive. I’d like that one back.
ITG: Oh! Right. Thanks for coming after me.
B: No problem. Of course, it wasn’t for your benefit.

We walked back to my cubicle, where he swapped drives and all was well. Then he left, with a cheerful, “We should have the new drive by tomorrow morning. Hey, where’s your shoe?”

Growing an MVVM Framework in 2003, part IV – Unit Tests

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

In parts 1 and 3 (and 2, but I like part 3 better) I showed a tiny “framework” for binding View properties and events to properties and methods on a ViewModel. In addition to avoiding the tedium and noise of wiring up events by hand, I’d hoped to implement a structure that would make unit testing easier. Let’s see how that went.

Event handlers just work. Almost

Recall that event handlers are defined on the ViewModel as plain old methods that happen to take a specific set of arguments – usually object and something that derives from EventArgs. This means that nothing special has to be done in order to exercise the methods during a unit test. The test doesn’t have to trick the ViewModel into registering with an event or anything. The test just calls the method. And if the method doesn’t care much about its arguments like FindClick doesn’t, you can pass in nonsense:

public class BookListViewModel
{
    public void FindClick(object sender, EventArgs e)
    {
        ICollection books = bookDepository.Find(TitleText.Value);
        IList bookListItems = BookListItems.Value;

        bookListItems.Clear();
        foreach ( string book in books )
        {
             bookListItems.Add(book);
        }
    }
}

public class BookListViewModelTests
{
    [Test]
    public void CallFindClick()
    {
        vm.FindClick(null, null);
    }
}

Of course, this isn’t much of a test. Usually we’ll want to set up some initial state for the ViewModel, and verify that the correct actions have been taken. In fact, as things stand, the property fields will all be null, so TitleText.Value and BookListItems.Value will error out.

Putting something behind the properties

Most event handlers will need to access the properties on the ViewModel, so the tests must hook up the properties.

Provide stub properties

Last time I mentioned that the PropertyStorageStrategy would bring value. This is it. Recall the definitions of the ListProperty and the PropertyStorageStrategy:

public class ListProperty: Property
{
    public ListProperty(PropertyStorageStrategy storage): base(storage)
    {}

    public IList Value
    {
        get { return (IList) storage.Get(); }
        set { storage.Set(value); }
    }
}

 public interface PropertyStorageStrategy
 {
     object Get();
     void Set(object value);
 }

The ListProperty (and BoolProperty and StringProperty) merely consult a PropertyStorageStrategy to obtain a value and they cast it to the correct type. Providing a dumb strategy that, instead of proxying a property on a View control, just holds a field will produce a property that can be used in tests:

public class ValuePropertyStrategy: PropertyStorageStrategy 
{
      private object obj;

      public ValuePropertyStrategy(object initialValue)
      {
         this.obj = initialValue;
      }

      public void Set(object value) { obj = value; }
      public object Get() { return obj; }
}

Then the test fixture setup can bind properties to the ViewModel:

[SetUp]
public void SetUp()
{
    vm = new BookListViewModel(new Control(), new FakeBookDepository());
    vm.TitleText = new StringProperty(new ValuePropertyStrategy(""));
    vm.BookListItems = new ListProperty(new ValuePropertyStrategy(new ArrayList()));
    ...
}

And tests can be constructed to provide initial property values (if the default isn’t good enough) and interrogate them afterward.

[Test]
public void FindClick_WithTitleG_FindsEndersGame()
{
    vm.TitleText.Value = "G";
    vm.FindClick(null, null);

    Assert.IsTrue(vm.BookListItems.Value.Contains("Ender's Game"));
}

Auto-wiring the properties

This works, and pretty well. There’s not that much noise associated with setting up the fake properties. Still, why should there be any? After so much trouble to remove the tedious wiring up from the production code, it seems wrong to leave it in the testing code.
Also, I’m against anything that adds a barrier to writing tests. And having to hand-wire a few (or a dozen) properties before you can start testing is definitely a barrier.

So, let’s write a little code to handle the tedium for us.

public class ValuePropertyBinder
{
      public static void Bind(ViewModelBase viewModel)
      {
          foreach ( FieldInfo field in viewModel.PropertyFields() )
          {
              ValuePropertyStrategy propertyStorageStrategy = new ValuePropertyStrategy(MakeStartingValue(field.FieldType));

              ConstructorInfo propertyConstructor = field.FieldType.GetConstructor(new Type[] {typeof (PropertyStorageStrategy)});
              object propertyField = propertyConstructor.Invoke(new object[] {propertyStorageStrategy});
              field.SetValue(viewModel, propertyField);
          }
      }

      private static object MakeStartingValue(Type fieldType)
      {
         Type propertyType = fieldType.GetProperty("Value").PropertyType;
         
         if ( propertyType == typeof(IList) ) { return new ArrayList(); }
         if ( propertyType == typeof(string) ) { return ""; }
         if ( propertyType == typeof(bool) ) { return false; }
         else
         { 
              throw new NotImplementedException("no known starting value for type " + propertyType);
         }
      }
}

This is very similar to the wiring we’ve seen before – find property fields, construct an object to implement the property, and hook it up. The only thing likely to need attention in the future is MakeStartingValue. A new property type(like DateTime), will require an expansion to the if chain. But that should be very infrequent.

Now it’s much easier to use the ViewModel in tests:

[SetUp]
public void SetUp()
{
   vm = new BookListViewModel(new Control(), new FakeBookDepository());
   ValuePropertyBinder.Bind(vm);
}

An alternative: brute force and ignorance

This approach didn’t occur to me until the project was over. Sigh.
The production code works by binding the ViewModel to a View. The test setup could do that. I’d taken pains to keep any kind of code or behaviour out of the View, so there shouldn’t be any side effects, and there’s no need to show any of the GUI elements. Honestly, the technical downsides seem pretty limited.

Even so, I don’t like this solution. For the BookFinder application, the View is simple enough that I’m confident the approach would work, but I have concerns over using it in a more complex application. Also, I prefer to reduce the amount of auxiliary production code that’s used in tests. In the off chance that something does go wrong, it’s nice to be able to have a small set of production code to look at

Summing up

With the ValuePropertyBinder (or much-maligned “just bind the ViewModel to the actual Model”), tests are really easy to set up and run. As easy as writing the production code. And they’re readable. The only troublesome dependencies are the models. Totally worth the effort.

Growing an MVVM Framework in 2003, part III – Properties Redux

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

A Change of Plans

Last time I showed how I managed the binding of ViewModel properties to the properties on the View’s controls. I promised to talk this time about how the use of the mini-framework affected the testability of the code. I changed my mind – I want to return to the whole properties discussion.

Festering Dissatisfaction

The method I had for binding ViewModel properties to the View worked, but it left a bad taste in my mouth. A few things bothered me about the implementation. Recall that to add a bound property the ViewModel had to have code something like this:

private Property bookListItems;
public string BookListItems
{
    get { return bookListItems.AsList(); }
    set { bookListItems.Value = value; }
}

I have a couple of problems with this.

  1. it’s pretty chatty
  2. the client programmer has to know when to use .AsList() or not, since strings and bools don’t require it
  3. the viewbinding code had to look for the private field, and that just felt gross

Poor man’s generics

When I first wrote the code, I was bothered a little by the weaknesses in the property bindings. It wasn’t until I wrote about the code here that the suck really started to get to me. And worse, I was unhappy with what I’d wrote. One phrase from the post kept coming back to me:

At this point, I was really missing generics.

What did I mean by that? Why did I miss generics? I hadn’t explained that well, even to myself. So I thought about it. What would I do with the generics if I had them? And I thought for a bit longer. Then I had it. I’d make a Property class to proxy the view’s properties – that would tighten up the code and relieve programmers of the burden of knowing when to us .AsList..

Well, I don’t have generics, but I do have Manual Type Creation. That’s somewhat less convenient, but it’s not like I’m going to need dozens of different property types – 3 will do for a start. So I decided to see what I could do with a little Property type hierarchy.

public abstract class Property
{
    protected PropertyStorageStrategy storage;

    protected Property(PropertyStorageStrategy storage)
    {
        this.storage = storage;
    }
}

public class ListProperty: Property
{
    public ListProperty(PropertyStorageStrategy storage): base(storage)
    {}

    public IList Value
    {
        get { return (IList) storage.Get(); }
        set { storage.Set(value); }
    }
}

public class StringProperty: Property
{
    // pretty much what you'd expect
}

public class BoolProperty: Property
{
    // pretty much what you expected above, only more Bool-y
}

There’s not a terrible amount here, just a family of properties. Each concrete class is responsible for providing a Value property that will return (or accept) a typed value. The real work is done by the storage member – it keeps track of the untyped value that the concrete class will take or dole out. As the name PropertyStorageStrategy suggests, a Property can vary the source and sink for its value via the Strategy design pattern.

I was holding it for a friend

Let’s look at the storage strategy that defers to a property on another object.

 public interface PropertyStorageStrategy
 {
     object Get();
     void Set(object value);
 }

public class BoundPropertyStrategy: PropertyStorageStrategy 
{
      private object obj;
      private PropertyInfo propertyInfo;

      public BoundPropertyStrategy(object obj, PropertyInfo property)
      {
         this.obj = obj;
         this.propertyInfo = property;
      }

      public void Set(object value)
      {
         propertyInfo.SetValue(obj, value, null);
      }

      public object Get()
      {
         return propertyInfo.GetValue(obj, null); 
      }
}

Unsurprisingly, this looks a lot like the BoundProperty class from last time. After all, the core functionality is pretty much the same. So, inject a BoundProperty into one of ListProperty, StringProperty, or BoolProperty, and we get a strongly-typed proxy for the underlying object.

Tying it together

Of course the new classes required a change to the ViewModel/Model binding code. Locating the ViewModel fields to bind is pretty much the same as it was, except only public fields that derive from Property are considered. The BindFieldToControl becomes the slightly-better named BindPropertyToControl:

private bool BindPropertyToControl(Control control, FieldInfo field)
{
    string controlPropertyName = ControlAttributeName(control, field.Name);
    if ( controlPropertyName == null )
    {
        return false;
    }

    PropertyInfo controlProperty = control.GetType().GetProperty(controlPropertyName, myBindingFlags);
    if ( controlProperty == null )
    {
        return false;
    }
     
    BoundPropertyStrategy strategy = new BoundPropertyStrategy(control, controlProperty);
    ConstructorInfo constructor = field.FieldType.GetConstructor(new Type[] {typeof (PropertyStorageStrategy)});
    object propertyField = constructor.Invoke(new object[] {strategy});
    field.SetValue(this, propertyField);
    return true;
}

The first part of the method just makes sure that the control we’ve found has a name that matches the first part of the property. Then we look for a property on the control that completes the name. Once those hurdles are past, the magic happens:

  1. create a new BoundProperty to proxy the control’s property value
  2. take the property field type and find the constructor that takes a PropertyStorageStrategy
  3. make a new property object, passing in our BoundProperty
  4. set the property object onto the ViewModel

How’s it work?

Overall, I think okay. Here’s a sample of the ViewModel code.

public StringProperty TitleText;
public BoolProperty FindEnabled;
public ListProperty BookListItems;

public void TitleTextChanged(object sender, EventArgs e)
{
    string newText = TitleText.Value;
    FindEnabled.Value = (newText != null & newText.Length > 0);
}

public void FindClick(object sender, EventArgs e)
{
    ICollection books = bookDepository.Find(TitleText.Value);
    IList bookListItems = BookListItems.Value;

    bookListItems.Clear();
    foreach ( string book in books )
    {
        bookListItems.Add(book);
    }
}

The client developer has to remember to use the funny property types, but this isn’t that much harder than, say Func. At least the names make some sense.
The .Value could get a little old, but I prefer having it on both the get and the set even over just on the set. I like having the strong-typing built in to the type, rather than forcing the client developer to do the conversion in a property.

On the downside, additional property types will have to be added to the framework by hand, but that shouldn’t come up too often. Also, the storage strategy for the properties is maybe a little complicated, but at least clients of the framework never have to deal with it directly. The observant among you will probably criticize the strategy because so far there’s no use for it. Bear with me. Next time I’ll show you how the strategy adds value.

AutoTest.Net updated – now (and then) notices broken builds

I received a useful comment on Friday’s post about AutoTest.Net. In the wee hours of Saturday, Greg Young, wrote to say

It should detect broken builds without any problem. We have been running it daily for about 1.5 months.

Perhaps you could grab me via email and reproduce it?

Well, I wasn’t going to pass up that offer. Off to GMail!

7:15 I grabbed him
7:20 he was making specific requests for additional information, the output of test runs through the console runner, and the like.
8:00 he had dived into the code to verify that things were working as they should, and asked for a sample project that exhibited the bug.
8:20 I sent the code
8:31 I e-mailed that I’d accidentally sent a project that complied
8:34 Greg reproduced the problem

8:54 he sent me a replacement .zip file

9:04 it worked!

As soon as I broke the compilation, the monitor lit up, showing me which project failed and where:

[Info] 'AutoTest.Console.ConsoleApplication' Preparing build(s) and test run(s)
[Info] 'AutoTest.Console.ConsoleApplication' Error: D:\bconrad\Documents\Source\BlogExamples\2010-11-autotest\BookFinder\BookFinder.Core\BookListViewModel.cs(50,17) CS1002: ; expected [D:\bconrad\Documents\Source\BlogExamples\2010-11-autotest\BookFinder\BookFinder.Core\BookFinder.Core.csproj]
[Info] 'AutoTest.Console.ConsoleApplication' Ran 1 build(s) (0 succeeded, 1 failed) and 0 test(s) (0 passed, 0 failed, 0 ignored)

It turns out that the bug had already been fixed on trunk version of the code, but for some reason hadn’t been built into the Windows installer. Turnaround time: 1 hour 49 minutes from my initial e-mail, and that included:

  • me drifting off to other tasks between e-mails, increasing delays
  • a session of trying to work around GMail hating the zip file I tried to send
  • a delay imposed by my having sent a bad test project

I’m sure those things added a good half hour to the required time.

Then he spent another 40 minutes on a non-existent problem that I reported. I’d left an older AutoTest.Net WinForms monitor running during the debugging, so when things finally settled down, I got a pair of toasts from Growl – one reporting build failures, and one reporting successful builds when there weren’t any.
When I discovered that, Greg was already installing a new Growl for Windows to try it out. And he was very gracious about my error and his wasted time.

I’m hardly the first to point it out, but this is one of the great things about open software. It’s great getting that kind of service so quickly. And on a weekend no less.

Will this encourage me to use AutoTest.Net

Sure. My primary complaint with it has been resolved.
Moreover, I’d be even more inclined to see what comes of Mighty Moose, now that I see the dedication of the developers behind it.

Hasty impressions: Continuous testing using AutoTest.NET

Rinat Abdullin recently posted about Mighty Moose and AutoTest.NET, two projects for continuous testing in the .NET/Mono space. My interest was immediately piqued, as I’m a huge fan of continuous testing. I’ve been using py.test to run my Python unit tests for years now, almost solely because it offers this feature.

I’m taking a look at AutoTest.Net first. Mostly because it’s free. If I’m going to use something at home, it won’t be for-pay, and the Day Job has been notoriously slow at shelling out for developer tools.

Update: there was a bug that had been fixed on trunk, but not in the installer that I used. AutoTest.Net is better at detecting broken builds than I report below.

Setting up AutoTest.NET

Download and installation were straightforward. I opted to use the Windows installer package, AutoTest.Net-v1.0.1beta (Windows Installer).zip. I just unzipped, ran the MSI, let it install both VS 2008 and VS 2010 Add-Ins (the other components are required, it seems), and that was that.

Then I cracked open the configuration file (at c:\Program Files\AutoTest.Net\AutoTest.config). I just changed two entries:

  • BuildExecutable, and
  • NUnitTestRunner

That’s it. Well, for the basic setup.

Running the WinForms monitor

I opened a command prompt to the root of a small project and ran the WinForms monitor, telling it to look for changes in the current directory.

& 'C:\Program Files\AutoTest.Net\AutoTest.WinForms.exe' .

The application started, presenting me with a rather frightening window

I mean, it makes sense. I have neither built nor run yet, so what did I expect? Still, I was taken aback by the plainness of it. Only temporarily daunted, I then hit the tiny unlabelled button in the northeast corner and got a new window. This was less scary.

Everything seemed to be in order. I hadn’t specified MS Test or XUnit runners, nor a code editor. It says it’s watching my files. So let’s test it.

Mucking with the source

It’s supposed to watch my source changes and Do The Right Thing. Let’s see about that.

A benign modification to one test file

I changed the text in one of my test files. No functionality was changed – it was purely cosmetic. AutoTest.Net noticed, rebuilt the solution, and ran the tests! Pretty slick. Things moved quickly, but here’s what I saw from the application:

A benign modification to one “core” file

Next I changed the text in one of the core files – this file is part of a project that’s referenced by the BookFinder GUI project, and the test project. Again, this was a cosmetic change only, just to see what AutoTest.NET would do.
It did what it should – built the three projects and ran the tests. See?

A core change that breaks a test

So, now I’ll modify the core code in a way that breaks a test.
It picks up the change, builds, tests, and does a really nice job of showing me the failure. I see the test that failed, and when I click it, am presented with the stack trace, including hyperlink to the source.

Unfortunately, clicking the hyperlink didn’t go so well:

That was a little disappointing. On the brighter side, hitting “Continue” did continue, with no seeming ill-effects.

Redemption

Confession time. I hadn’t checked the CodeEditor section of the configuration file. As it turns out, it had a slightly different path to my devenv than the correct one. I fixed up the path and tried again. This time, clicking on the hyperlink opened devenv at the right spot.

So the problems was ultimately my fault, but I can’t help but wish for more graceful behaviour – how about a “I couldn’t find your editor” dialogue? Ah, well. The product’s young. Polish will no doubt come.

I repaired the code that broke the tests, and AutoTest.Net was happy again after rebuilding and rerunning the tests.

Syntax Error

For my last test, I decided to actually break the compile. This was kind of disappointing. It claimed to run the 3 builds and the tests, and said that everything passed. I’m not sure why this would be – I was really hoping for an indication that the compilation failed, but nope. Everything was rainbows and puppies. Spurious rainbows and puppies.

The VS Add-In

There’s an add-in. You can activate it under the “Tools” menu. It looks and behaves like the WinForms app.

The Console Monitor

I am used to running py.test in the console, so I thought I’d check out AutoTest’s console monitor next. I started it up, made a benign change, and then made a test-breaking change. Here’s what I saw:

[Info] 'Default' Starting up AutoTester
[Info] 'AutoTest.Console.ConsoleApplication' Starting AutoTest.Net and watching "." and all subdirectories.
[Warn] 'AutoTest.Console.ConsoleApplication' XUnit test runner not specified. XUnit tests will not be run.
[Info] 'AutoTest.Console.ConsoleApplication' Tracker type: file change tracking
[Warn] 'AutoTest.Console.ConsoleApplication' MSTest test runner not specified. MSTest tests will not be run.
[Info] 'AutoTest.Console.ConsoleApplication'
[Info] 'AutoTest.Console.ConsoleApplication' Preparing build(s) and test run(s)
[Info] 'AutoTest.Console.ConsoleApplication' Ran 3 build(s) (3 succeeded, 0 failed) and 2 test(s) (2 passed, 0 failed, 0 ignored)
[Info] 'AutoTest.Console.ConsoleApplication'
[Info] 'AutoTest.Console.ConsoleApplication' Preparing build(s) and test run(s)
[Info] 'AutoTest.Console.ConsoleApplication' Ran 3 build(s) (3 succeeded, 0 failed) and 2 test(s) (1 passed, 1 failed, 0 ignored)
[Info] 'AutoTest.Console.ConsoleApplication' Test(s) failed for assembly BookFinder.Tests.dll
[Info] 'AutoTest.Console.ConsoleApplication'     Failed -> BookFinder.Tests.BookListViewModelTests.FindClick_WithTitleG_FindsEndersGame:
[Info] 'AutoTest.Console.ConsoleApplication'

Not bad, but I have no stack trace for the failed test. Just the name. I’m a little sad to lose functionality relative the WinForms runner. I know I wouldn’t be able to click on source code lines, but still.

Gravy – Hooking up Growl

Undeterred by the disappointing performance in the Syntax Error test, I soldiered on. I use Growl for Windows for notifications, and I was keen to see the integration. I went back to the configuration file and input the growlnotify path. While I was there, I set notify_on_run_started to false (after all, I know when I hit “save”), and notify_on_run_completed to true. Then I fixed my compile error and saved the file.
In addition to the usual changes to the output window, I saw some happy toast:

Honestly, with a GUI or text-based component around, I’m not sure how much benefit this will be, but I guess I can minimize the main window and so long as tests keep passing, I can get some feedback. Still it’s kind of fun.

Impressions

I really like the idea of this tool. I love the idea of watching my code and continuously running the tests. The first steps are very good – I like the clickonable line numbers to locate my errors, and I think the Growl support is cute, but probably more of a toy than an actual useful feature.

Will I Use It?

Not now, and probably never at the Day Job. The inability to detect broken builds is pretty disappointing.
Also, at work, I have ReSharper to integrate my unit tests. I’ve bound “rerun the previous test set” to a key sequence, so it’s just as easy for me to trigger as it is to save a file.

At home? Maybe. If AutoTest.Net starts noticing when builds fail, then I probably will use it when I’m away from ReSharper and working in .NET.

Growing an MVVM Framework in 2003, part II – Properties

This is second post in a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

Last time, I introduced a tiny Windows Forms application and described my efforts to make a small MVVM framework for it. At the end of that post, we’d seen one way to use convention to bind View events to ViewModel event handlers.

Today I’ll talk about properties. It’s all very well to have a click on the “Find” button trigger the FindClick method on the ViewModel, but it’s useless unless we know what to look for. I needed a way to pass the Title.Text value to the ViewModel so it could use it for the search.
Then the FindClick method I showed last time would work:

public void FindClick(object sender, EventArgs e)
{
    ICollection books = bookDepository.Find(TitleText);
    BookListItems.Clear();
    foreach ( string book in books )
    {
        BookListItems.Add(book);
    }
}

A Failed Attempt

First I tried using Windows Forms binding, with lamentable results. I wish I’d saved the intermediate steps, as I was probably doing something wrong and could’ve solicited help. Still, whether it was due to a lack of experience on my part, or a flaw in the system, the bindings just wouldn’t work. I could bind bools and strings, but lists were right out.

A Proxy for Properties

I decided to rely on the storage objects that came with the View elements. This meant the ViewModel needed some way to proxy the properties on the View. Then a get or a set on the ViewModel object would flow right through, reading or writing the View’s values.
Here’s what I came up with:

public class BoundProperty: Property
{
    private object obj;
    private PropertyInfo propertyInfo;

    public BoundProperty(object obj, PropertyInfo property)
    {
        this.obj = obj;
        this.propertyInfo = property;
    }

    public override object Value
    {
        get { return propertyInfo.GetValue(obj, null); }
        set { propertyInfo.SetValue(obj, value, null); }
    }
}

Ignore the Property base class for a bit. An instances p of type BoundProperty can be used to get and set values on the proxied object obj like so:

p.Value = valueA;
object valueB = p.Value;

Not incredibly thrilling, but one can work with it. Using the .Value in order to access the value was a little cumbersome, so I added a little syntactic sugar in the Property base class:

public abstract class Property
{
    public abstract object Value { get; set; }

    public static implicit operator string(Property prop)
    {
        return (string) prop.Value;
    }

    public static implicit operator bool(Property prop)
    {
        return (bool) prop.Value;
    }

    public IList AsList()
    {
         return (IList) Value;
    } 
}

I really like the implicit operator functionality, which I’d never used before. I wish it could be used with interfaces, though. There’s probably a good reason why it can’t, but nothing comes to mind. Anyhow, I had to go another route for IList – the somewhat uninspiring AsList method. At this point, I was really missing generics.

Still, it’s nicer to be able to write

string myString = p1;
IList myList = p2.AsList();

instead of

string myString = (string) p1.Value;
IList myList = (IList) p2.Value;

Hooking up the Properties

This is pretty much the same as hooking up the events like the last time. All we have to do is define a field (yes, a field) of type Property in the ViewModel:

private Property titleText;

The ViewModelBase loops over all the Property fields and looks for View controls that have matching property names:

foreach ( FieldInfo field in PropertyFields() )
{
    FindPropertyToBindTo(allControls, field);
}

private void FindPropertyToBindTo(ArrayList allControls, FieldInfo field)
{
    foreach ( Control control in allControls )
    {
        if ( BindFieldToControl(control, field) ) { return; }
    }
}

private bool BindFieldToControl(Control control, FieldInfo field)
{
    string controlPropertyName = ControlAttributeName(control, field);
    if ( controlPropertyName == null ) { return false; }

    PropertyInfo controlProperty = control.GetType().GetProperty(controlPropertyName, myBindingFlags);
    if ( controlProperty != null )
    {
        field.SetValue(this, new BoundProperty(control, controlProperty));
    }
    return true;
}

Technically that’s it, but the rest of the ViewModel’s code is a little cleaner if we self encapsulate the field:

public string TitleText
{
    get { return titleText; }
    set { titleText.Value = value; }
}

Remarks

Once the infrastructure was in place, I really started enjoying developing the application. It was very liberating to add a new event handler just by writing a method with the right name and signature. And even adding access to a new property wasn’t so bad – writing the three lines of code to segregate the conversions and .Values was worth it to keep the event handler bodies nice and clean.

Next time, we’ll see how the design affected the form of the application’s unit tests.