Monday, September 10, 2012

Surrealism

I can’t believe I’ve never heard this joke before today, but it makes me smile:

Two penguins are sitting on an ice floe, drifting helplessly north into warmer waters. The penguins are quite fond of each other, but they don’t speak English very well. Suddenly, cra-a-a-a-a-ck, the ice floe splits in two, right between the penguins. As they drift apart, one penguin sadly waves a flipper and calls out, “Chocolate milk!”.

Happy Monday!

Friday, August 17, 2012

NDoc3 - a modern-day Lazarus

Back in the early days, the nDoc utility was the go-to solution for auto-generating API documentation for .NET applications. The build engine would parse the XML comments that the developer decorated class members with, and nDoc would take those results and produce MSDN-style web pages based on it. As an open source product, it attracted quite a following.
However, with the release of .NET Framework v2, nDoc failed to make the jump and instead imploded, being at the time quite a high-profile example of the risks of running an open source project:
  • the community might love your product, but if they don’t contribute something back (whether code, time or money) then it may not be possible for you to continue to develop it;
  • the vendor whose environment you are working in (in this case, Microsoft, but it could easily be another company. Apple, anyone?) can move into your space and deliver something that is good enough to draw mindshare away from your target audience. Actually, Sandcastle has never really been as good as, nor as easy to use as, nDoc, but the damage was done;
Fast-forward to the near-present time, and while Sandcastle continues to be unwieldy, the open source community is once again picking up the nDoc baton, this time in the form of nDoc3. In its current state, nDoc3 brings to the table support for .NET 3.5, but if you’re prepared to download the source code and build it yourself, you can get .NET 4 support as well. Of course, Microsoft moved the goalposts slightly this week with the release of .NET 4.5, so the cycle continues!
If you do want to try getting .NET 4 support, these are the steps that I had to go through (and a few hoops that I needed to jump through):
  1. Download the source code from Sourceforge, and extract the tarball to the file system;
  2. Rather than opening in VS2008 as the README file directs, I fired up VS2010;
  3. Building threw up a whole host of warnings, so I decided to try the provided NAnt build scripts;
  4. Building threw up a whole host of warnings, mostly about missing NAnt targets; in the end, I had to hack the NAnt.build file to pieces, first commenting out the references to the JavaDoc, Latex and LinearHtml documenters which, though references in the build file, don’t exist in the source code; I also had to comment out all the code related to testing, as again it referred to folders and/or files that don’t exist;
  5. I also needed to remove a duplicate AssemblyVersion attribute from Core\AssemblyInfo.cs;
  6. This at least allowed me to compile and run the application; however, when I tried to get it to document one of my own pieces of code, it quickly threw an exception which I traced back to an already-reported issue; fortunately, the user who raised the issue also submitted a patch, which while it has not been applied to the source tree, at least fixes the problem.
So now I have nDoc3 happily spitting out documentation for me; perhaps if time allows, I will look into writing a Wiki-format documenter.

Thursday, August 02, 2012

That didn't take long

I've been a devotee of the Sparrow mail app for Mac since it first came out. Its clean interface and seamless integration with GMail put it head-and-shoulders above Apple's own Mail application.

Unfortunately, those days are numbered - Google's recent acquisition of Sparrow is a near-guarantee that the application will receive no further work, beyond promised bug fixes. The timing couldn't be worse - with Apple having just released OS X Mountain Lion, there are bound to be problems with third-party applications, and it seems that Sparrow is already showing some.

I've been finding the UI locks up on me when composing or sending emails; labelling emails I want to keep isn't happening, nor is the deleting of emails that I don't. I can receive emails OK, so it's not a problem with my network or account. Quitting the application tends to cause it to hang, until I kill its process with extreme prejudice. And it's not just me who's seeing this:



All in all, the sort of experience that third-party developers would be rushing to fix; but with Google now calling the shots, how quickly will this happen? I'm not holding my breath.

Meanwhile, in the interest of actually Getting Things Done, I'm making do with Mail again.

Friday, January 27, 2012

A nice little trick with FluentAssertions

I love using FluentAssertions when writing tests for my code, it just makes the code so expressive in plain language. Recently I’ve been working on tests which involve the testing of lots of properties on a test result, and was looking for a way to remove a lot of the repetition involved.

Usually when asserting the properties on a test result, you can do it in three different ways. If I have my test class defined as below:

[TestFixture]
public class MyTestFixture
{
    private MyClass _subject; 
    private MyOtherClass _result;
 
    [SetUp]
    public void ExecuteTest() 
    { 
        _subject = new MyClass(); 
        _subject.Initialise(/*.. Some parameters here ..*/); 
        _result = _subject.SomeOperation();
    }
}

Then I can test the results as follows:

A. Assert all the properties in a test method

    [Test]
    public void ThePropertiesAreSet()
    {
        _result.First.Should().Be("Paula Bean");
        _result.Second.Should().Be("Brillant!");
    }

This is probably the usual way people do this. However, if the first test fails, the second test will never run, and we'll never know if our test method set the second result correctly or not, so we are lacking information as to the overall state of the test. Secondly, as the number of properties to test increases, you end up with a lot of visual noise, although Intellisense will at least take some of the effort out of creating the noise.

B. Assert the properties in a test method per property

    [Test]
    public void TheFirstPropertyIsSet()
    {
        _result.First.Should().Be("Paula Bean");
    }
 
    [Test]
    public void TheSecondPropertyIsSet()
    {
        _result.Second.Should().Be("Brillant!");
    }

With this approach, we now know if the setting of _result.Second was successful, even if _result.First failed. This extra information does come at the expense of more visual noise (the addition of another test method). Also, it allows you to really game the system if you get rewarded for the number of tests in your project :-)

C. Implement IEquatable

As the number of properties on MyOtherClass go up, you'll find a lot of code appearing in the test method. You can remove this by implemeting IEquatable<MyOtherClass> on MyOtherClass:

public class MyOtherClass : IEquatable<MyOtherClass>
{
    public override bool Equals(MyOtherClass other)
    {
        return this.First == other.First && this.Second == other.Second;
    }
}

(please note you should also really implement Object.Equals and Object.GetHashCode if you're going to use IEquatable, and for brevity, I've missed out a lot of the basic implementation of IEquatable<T>)

The result of this is that our test method now becomes:

    [Test]
    public void TheFirstPropertyIsSet()
    {
        MyOtherClass expected = new MyOtherClass { First = "Paula Bean", Second = "Brillant!" };
        _result.Should().Be(expected);
    }

Much cleaner and very expressive, and you'll probably find your code benefits elsewhere from having implementations of IEquatable<T>; but you do have to write that implementation (and perhaps unit test it too!). Yet more code...

This finally leads me to my point:

D. Use anonymous classes and FluentAssertion's AllProperties

How's this for simplicity?

    [Test]
    public void TheFirstPropertyIsSet()
    {
        _result.ShouldHave().AllProperties().EqualTo(new { First = "Paula Bean", Second = "Brillant!" });
    }

ShouldHave().AllProperties() does all the hard work of checking the properties. You can also use SharedProperties() if you only need to test a subset of the properties, and add IncludeNestedObjects if you have a more complex object model.

P.S. I love the story of the Brillant Paula Bean. It confirms all your prejudices about contractors.

Wednesday, January 11, 2012

Adobe Lightroom 4 Beta is out!

Adobe Lightroom 4I’m looking forward to this. I’ve been a user of Lightroom since it first came out as version one, and it’s been indispensible for managing my growing photo collection (I passed the 10000 mark last year).

I’m particularly excited by the long-awaited introduction of proper geocoding support. I bought a GPS logger a year or two ago, and use Dirk Stichling’s My Tracks to add geotag my photos prior to importing them into Lightroom. When I export from Lightroom to iPhoto, the geotags are picked up and displayed nicely in the Places section of iPhoto (and on the iPhone and iPad). However, this only works when importing photos – existing photos cannot be geotagged. Jeffrey Friedl has written a plugin for Lightroom that achieves this, after a fashion, but I prefer my metadata to reside within embedded metadata, rather than in shadow files which are then written on export; and although My Tracks is a good application, I would prefer to have fewer steps in the overall process.

Of course, the ideal would be for Canon to release an accessory that geotags photos when they are taken, but for the moment, they seem to be preferring to take the third-party route.

Friday, January 06, 2012

New Year, New Resolutions

よいお年をお迎えください。

In other words, happy new year!

As far as making and keeping new resolutions go, I’d already failed miserably by January 2nd, probably setting a new low. The resolution was to take a photograph everyday and upload it to Flickr/Facebook, but that just didn’t happen. In fact, I haven’t picked up my camera for a week or two, and only used the camera in my phone to play around with Photosynth, which looks completely out of place on an iPhone, having been built for a Windows-based phone with no effort made to translate the UI design, but nevertheless, works very well.

However, the new year does afford me the chance to indulge in some spring cleaning, even if we are in the early throes of summer here in the Lucky Country. In particular, now that I am back at work, it means opening up the computer case, and having some fun with a rather large air compressor to remove all the dust that has accumulated since the PC was assembled. It also means that I can finally give it a good formatting and install everything afresh, something which every PC user should do at least annually.

Clean ALL the things!This of course reminds me just how many applications I have downloaded and installed in the past year. Just installing Windows 7 with all the layers upon layers of patches takes about half a day, and our internet connection at work feels much slower than my home internet connection.

To give you an idea of just how much stuff your typical Windows developer needs to make it through the day, here’s an approximate list. So far it’s taken me a whole day to download and install this lot, and I’m still finding those useful little apps that you forget aren’t included out-of-the-box.

System

  • 7-Zip – beats WinZip for compression any day;
  • DropBox – file synchronisation across almost any device;
  • Google Chrome – the choice of most developers;
  • Mozilla Firefox – the chose of most other developers;
  • Skype – for keeping in touch with our other offices around the world;
  • Virtual CloneDrive – for mounting all those application installation ISOs;
  • Windows Live Essentials – Mail, Messenger, and of course, Writer (which no self-respecting blogger should be without – definitely one of the most useful products to come out of Redmond);

Business Applications

Developer Tools

  • Beyond Compare – the best diff tool that I’ve tried (WinMerge is free and also very good, but I just prefer BC);
  • CruiseControl.NET – nothing inspires confidence in your day’s work like a row of green lights confirming that it compiles, the tests ran successfully, and the installation package is ready to be shipped;
  • Fiddler – if you have to send data across the network, you need this tool;
  • Notepad++ – syntax highlighting for almost every language out there, and tabbed windows too;
  • Smtp4Dev - for testing the sending of emails;
  • SQL Server Compact – for when the application you are developing will not need a full-blown database server;
  • SQL Server Express – for when application you are developing will need a full-blown database server;
  • Subversion (command-line, GUI, and IDE integration) – who wants to be a tightrope walker without a safety net?
  • Visual Studio – where I spend 95% of my time:
  • Windows 7 SDK – essential developer tools;
  • Silverlight – for rich web client development;
  • Silverlight Toolkit – the bits that Microsoft forgot in Silverlight
  • Expression Blend SDK – another set of bits that Microsoft forgot in Silverlight

Friday, March 25, 2011

A craftsman knows his tools

Those who have worked with me for any length of time will know that I’m always looking for ways to improve my ability as a programmer. It may be in researching the latest available tool libraries (my current new favourite is StoryQ, which is great for developing BDD-style tests, and NSubstitute, which is as easy to use as Moq, but without those annoying calls to .Object), or how to write better, more reliable, build scripts. Either way, learning new skills and refining existing skills is an essential part of any craft (I’m deliberately steering clear of the ongoing “software development isn’t a craft”/“oh yes it is argument – this still applies to trades and scientific disciplines).

This week I have been focusing on knowing my tools, and being a developer who works with Microsoft technologies, those tools inevitably centre around Visual Studio. One way to increase your productivity is to reduce the time you spend doing pointless activities, or rather, when faced with two ways of achieving something, to choose the quicker way. The most obvious form for a programmer is to learn to let go of the mouse; a little strange maybe, especially in an operating system that defines itself around the use of the mouse, but it really does act as a great big brake on your productivity. When I first started playing guitar, it would take me several seconds to visualise the necessary finger patterns in my head, and then position my fingers on the fret board. Now after much practising, I can see an F# minor chord written down and play it without having to even think about it.

The first step was to get rid of all the toolbars and icons. If there are no icons on screen, there’s not much point using the mouse to click them! The commands are still all there, and they can be accessed via the menu bar if I get really stuck. As a bonus, suddenly I have much more viewable area to concentrate on what really matters – the code.

So my first shortcut to learn was how to stop a debug session. I knew F5 to launch the debugger, but I always clicked on the Stop icon to stop it; well, it turns out that Shift-F5 was my new best friend. So far, so easy, and not too much time saved.

The next useful one was the Surround-with snippet; this is part of the excellent Resharper which really takes the heavy lifting out of Windows programming). I was working with code which was throwing exceptions, and there was no exception handler. Before, I would have used the mouse to click just above the offending line of code, then typed in the standard try/catch blocks, then selected the offending line of code and cut’n’paste it into the try {} block, then clicked into the catch {} and add the exception handling. That’s a lot of pointless mouse and keyboard work. Now, using the keyboard, I would select the line of text (Shift-End to select to the end of the line), then Ctrl-K,S to bring up the Surround-with snippets, then type try and press Enter to surround my code with a try/catch block and automatically position the cursor in the catch {} block ready to select my exception type. Intellisense camel-case matching helped, so I only had to type in CE to match the ConstraintException I was trying to catch, hit Enter, and job done.

There are only so many hours in the day - reclaim yours by learning how to use the tools you have to get more done in less time.