I ran into something really weird with FitNesse (the acceptance testing framework) today. Chances are, it’s something I’ve done wrong - but I can’t work out what. If you know, please comment below!– Updated below with the solution.

Boiling the whole thing down into a simple test case, what I’ve found is the following.

First, create the following Query test fixture on a page of it’s own:

|Query:Find Constants|
|Name         |Nick  |
|Donald Duck  |Don   |

Next, create a simple C# class that returns two rows. Run the test, and get these results:

| Query:Find Constants           |
| Name                    | Nick |
| [Donald Duck] missing   | Don  |
| [William Gates] surplus | Bill |
| [Adam Smith] surplus    | Adam |

Now, modify the test fixture to wrap Don with square brackets:

|Query:Find Constants|
|Name         |Nick  |
|Donald Duck  |[Don] |

This time, when you run the test, it fails with a stacktrace:

__EXCEPTION__:System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at fitSharp.Slim.Service.Document.IsList(String input)
at fitSharp.Slim.Service.Document.Read(String input)
at fitSharp.Slim.Service.Document.ReadList(String input)
at fitSharp.Slim.Service.Document.Read(String input)
at fitSharp.Slim.Service.Document.ReadList(String input)
at fitSharp.Slim.Service.Document.Read(String input)
at fitSharp.Slim.Service.Document.ReadList(String input)
at fitSharp.Slim.Service.Document.Read(String input)
at fitSharp.Slim.Service.Document.ReadList(String input)
at fitSharp.Slim.Service.Document.Read(String input)
at fitSharp.Slim.Service.Interpreter.ExecuteInstruction(String instruction)
at fitSharp.Slim.Service.Interpreter.Execute(String instruction)

This is with Release v20090818 of FitNesse.

Interestingly, the exception only seems to happen when something short is wrapped in [ ]. If I instead wrap Name, thusly:

|Query:Find Constants|
|Name         |Nick  |
|[Donald Duck]|Don   |

then everything works fine.

Update

After some feedback from Uncle Bob Martin, I did some digging in the source code for fitSharp, and found the source of the problem. Check out this method, from fitSharp.Slim.Service.Document:

private static bool IsList(string input)
{
    int result;
    return input.StartsWith("[") 
           && input.Substring(7, 1) == ":" 
           && input.EndsWith("]") 
           && int.TryParse(input.Substring(1, 6), out result);        
}

The problem here is that the Substring() call will throw an exception if the string is short. To fix this, we just need to add another check on the length of the string:

private static bool IsList(string input)
{
    int result;
    return input.Length >= 9  // Add this check
           && input.StartsWith("[") 
           && input.Substring(7, 1) == ":" 
           && input.EndsWith("]") 
           && int.TryParse(input.Substring(1, 6), out result);        
}

Comments

blog comments powered by Disqus