Tuesday, December 6, 2011

Undefined… uhhh… defined

Yes, we all know it, Javascript has some serious flaws. One of the more disturbing one being that undefined can be defined:

// This is way legal, but way weird:
undefined = “defined”;

Of course, it’s easy enough to avoid this, just don’t f-ing do it. But when writing scripts we are often playing in the same sandbox as the “big bad bullying, just straight up evil kids that has nothing better to do than going around defining undefined” are playing in. That’s why it’s very common to see scripts testing if the type of a value is “undefined” rather than to test if a value is equal to undefined:

// Test...
if (typeof foo === “undefined”) doStuff();
// ... rather than ...
if (foo === undefined) doStuff();

When I was a kid I alway wanted some sort of invisible shield to protected me from the big bad kids. Well, actually what I really, really wanted was some spinach to make me strong as Popey in order to beat the living crap out of the evil kids…

popeye

On the other hand, I guess a shield would do, I mean, even a visible shield would do. Can we please have a shield for our undefined??? Yes we can! And of course it comes in the form of a self invoking function as always when we want to shield our scripts.

(function(undefined) {
    if (something === undefined) doStuff();
}());

As you see here, we have an argument “undefined” in the function, however the function is self invoked without any argument thus the undefined argument has the value undefined. Inside this shield it’s perfectly safe to test for equality of undefined. This can be combined with other arguments as long as the undefined argument is the last one and the function is invoked with one argument less than the length of the arguments list:

(function($, global, undefined) {
    $(document).ready(function() {
        if (something === undefined) doStuff();
    });
}(jQuery, this));

Sunday, April 10, 2011

An alternative to NotImplementedException

It happens from time to time that I forget to implement some code where I’m just throwing a NotImplementedException. Being forgetful I have a habit of coming up with stuff that will help me not to forget. I think my “MustBeImplementedException” is quite useful, it will break the build if the build is not DEBUG.

#if DEBUG

namespace FakeItEasy
{
    using System;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>
    /// An exception that can be thrown before a member has been
    /// implemented, will cause the build to fail when not built in 
    /// debug mode.
    /// </summary>
    [Serializable]
    [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Never used in production.")]
    public class MustBeImplementedException
        : Exception
    {
    }
}

#endif

Saturday, April 2, 2011

An old pain point removed from FakeItEasy

It’s always bittersweet to say that you have introduced a breaking change in an API that people use. Bitter because it will break peoples code. But sweet because IT’S AN AWESOME NEW FEATURE!

I was never really fond of the fact that argument constraints relies on implicit casting in FakeItEasy, this is why you had to write A<IFormattable>.Ignored.Argument but you could write the shorter A<string>.Ignored for non interface types. This had to be done in order for the chaining of argument constraints to work: A<string>.That.Contains(“foo”).And.Not.Contains(“bar”) for example. I thought I was pretty smart when I implemented this, it turns out though that ONCE in SEVERAL THOUSAND tests have I used this feature myself. Smart is never simple, smart is quite often stupid.

Now, I don’t wanna be stupid, so what can I do? I can remove the stupid feature. Said and done, in versions >= 1.7.* you can no longer chain argument constraints (but you weren’t doing that anyway).

Things that will break:

First of all, everything breaks at compile time so you won’t be able to build without fixing the problems. This is one of the benefits of a static type system, the complier will tell you what’s wrong!

.Argument

Any argument constraint will now return an instance of the constrained type (T) and not an ArgumentConstraint<T> as it did in previous versions. This means that there is not property .Argument so you will have to remove any calls to that property from your tests. This might be quite many calls depending on how many tests you have and what you have been testing.

ArgumentConstraint<T>

As I said this class is no more (RIP). The lowest level api for creating constraints is now the “Matches(Func<T, bool> predicate, Action<IOutputWriter> descriptionWriter)” on the IArgumentConstraintManager<T> type. You access an argument constraint manager through the A<T>.That-property. This means that you can much more easily now provide extensions to the That-property, all you have to do is to create an extension method on IArgumentConstraintManager<T> and call the Matches-method inside your extension method. Here’s an example on how the IsNull() argument constraint is implemeneted.

/// <summary>
/// Constrains an argument so that it must be null (Nothing in VB).
/// </summary>
/// <typeparam name="T">The type of the argument.</typeparam>
/// <param name="manager">The constraint manager to match the constraint.</param>
/// <returns>A dummy argument value.</returns>
public static T IsNull<T>(this IArgumentConstraintManager<T> manager) where T : class
{
    return manager.Matches(x => x == null, x => x.Write("NULL"));
}

If you have extended the That-property before all your extensions will have to be rewritten to use the new API, it’s quite a simple task though and you’ll be glad that it will be much easier to create new extensions.

Monday, February 14, 2011

FakeItEasy breaking change for assertions

In the latest version of FakeItEasy (version 1.6.4062.205) there is a breaking change in how repeats are specified in assertions. The reason for this is that the old way – while logically correct – was not intuitive to a lot of people.

Before you could write “Repeated.Once” and that assertion would pass even though the method you were asserting on had been called twice. Now, logically this makes perfect sense, a call that has happened twice has happened once. The problem is that I’ve noticed that people doesn’t think that way and therefore assertions has been wrong.

The reason I hasn’t changed this before is that if I did change it it would be a breaking change and it would just change under the feet of people that had figured the behavior out and I was reluctant to make a breaking change that doesn’t break the build.

The solution I came up with is one that does break the build. You can no longer write “Repeated.Once”, you have to write “Repeated.Exactly.Once” or “Repeated.AtLeast.Once” or “Repeated.NoMoreThan.Once” or any other repeat twice, Times(4) and so forth.

Hopefully you agree with my decision that it was important to break the build in this case and I hope that it doesn’t cause too much frustration, it is actually a quite straight forward matter of find and replace.

Saturday, February 5, 2011

Experimental branches in Mercurial

Branching in Mercurial is easy, it’s so easy that most of the times you’re branching you don’t even know that you’re doing it. Have you ever had to merge? I guess you have, well guess what, when you’re merging, you’re merging two branches! Ever got an error when pushing stating that a push would create two heads in the remote repository? Head == branch.

I had a conversation the other day with a fellow developer about Git, I asked him what the main benefits of Git was. The thing is I’m pretty much Git illiterate. One of the things he said was the ease of branching and how local “throw away” branches can’t be done in Mercurial. First of all, I don’t know exactly how easy this is in Git so it might be harder in Mercurial but it’s definitely not hard. Let me show you!

I’ll use TortoiseHG in this example since it’s visual and makes for better examples but it is just as easy to do it from the command line.

Let’s start with a repository that contains a code file:

image

Now, this class is boring, it only writes hello to the console and I’d like to spice it up a little, so I’ll do a spike. Let’s make it say “Hello Europe!”. Said and done, I edit the file and commit, now my repository looks like this:

image

Now the thing is, while “Hello Europe!” is good I’d like to explore something differnt, let’s make it say “Hello World!” that’s so much more international. Let’s go back to before the change:

image

Now, I change the code again, this time to “Hello World!” then I commit, now the repo looks like this:

image

See, two branches, I could have backed to any point back in the revision history to branch from there. Now I’ve decided to go with the “Hello World!”-change and I want to push it to a central repo, I don’t want to include the “Hello Europe!” spike.

Go into the repository explorer and click the “Determine and mark outgoing changesets”-button. This will mark change sets not already in the repository you’re pushing to with arrows:

image

Right click the head of the branch you want to push and select “Push to here”. Now the repository you were pushing to will contain the following changesets:

image

That’s pretty much all there is to it! One more thing though, what about deleting local branches that you don’t want to keep? This can be done with the strip command in the MqExtensions for Mercurial.

Happy branching!

Monday, October 4, 2010

Fixture initialization in FakeItEasy

I added a new feature to FakeItEasy that makes it – you guessed it – easy to initialize test fixtures with fakes.

Instead of calling A.Fake<WhateverTypeYourFakingHere>() once for every fake you have in your test fixture you can simply tag the variables or properties you want to be fakes with the “FakeAttribute” and then call the method “Fake.InitializeFixture(this)” in your fixture setup:

[TestFixture]
public class InitializeFixtureIntegrationTests
{
    [Fake] IFormatProvider formatProvider;
    [Fake] IFormattable formattable;

    [SetUp]
    public void SetUp()
    {
        Fake.InitializeFixture(this);
    }

        
    [Test]
    public void Should...

Sunday, September 26, 2010

Extending exception messages in FakeItEasy

One of the main features of FakeItEasy is the informative exception messages, let’s say we have the following types:

public interface IPersonRepository
{
    void Save(Person personToSave);
}

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime DateOfBirth { get; set; }
}

Now, let’s create a test that shows us what the exception messages in fake it easy looks like when asserting:

public void Extending_exception_messages()
{
    var repository = A.Fake<IPersonRepository>();

    repository.Save(new Person { FirstName = "Patrik", LastName = "Hägne", DateOfBirth = new DateTime(1977, 4, 5) });

    A.CallTo(() => repository.Save(A<Person>.Ignored)).MustNotHaveHappened();
}

This will yield an exception message that looks like this:

  Assertion failed for the following call:
    'FakeItEasy.Examples.IPersonRepository.Save()'
  Expected to find it exactly never but found it #1 times among the calls:
    1.  'FakeItEasy.Examples.IPersonRepository.Save(
            personToSave: FakeItEasy.Examples.Person)'

While this is a good exception message it doesn't say a whole lot about the person object that was used in the call to save. You could ofcourse in this particular instance override the ToString-method of person to fix this, but a lot of times you don’t have control over the types you use (for example the framework types). Now, fortunately, in the latest release of FakeItEasy, there is a dead simple way for you to provide your own formatter for printed argument values.

All you have to do is in your testproject define a class that inherits the FakeItEasy.ArgumentValueFormatter<T>-class where T is the type of class you wish to provide custom formatting for.

Here’s an example of such a formatter for the Person-type:

public class PersonArgumentFormatter
    : ArgumentValueFormatter<Person>
{
    protected override string GetStringValue(Person argumentValue)
    {
        return string.Format("Person named {0} {1}, date of birth {2:yyyy-MM-dd} ({3} days old).",
            argumentValue.FirstName,
            argumentValue.LastName,
            argumentValue.DateOfBirth,
            DateTime.Now.Subtract(argumentValue.DateOfBirth).TotalDays);
    }
}

Now, let’s run the same test again and see what the exception message looks like: (I’ve split the message over several lines in this post so that the message will not be truncated by the blog).

  Assertion failed for the following call:
    'FakeItEasy.Examples.IPersonRepository.Save()'
  Expected to find it exactly never but found it #1 times among the calls:
    1.  'FakeItEasy.Examples.IPersonRepository.Save(
            personToSave: Person named Patrik Hägne,
                          date of birth 1977-04-05 (12227,874689919 days old).)'