This project is read-only.

Modifying or configuring output

Mar 5, 2013 at 2:19 PM
Is there a way to modify or configure the output (both output window and file) to include custom strings? For example, one of my stories requires that a specific exception is thrown. To do this, I catch the exception and save it, then in a separate method test that it's non-null and of the required type. I'd like to be able to append the type of the exception to the output (much like parameters are appended to method calls).

For example
    .Then(ExceptionIsThrown<ArgumentNullException>)
would result in the following output
   then exception is thrown (ArgumentNullException)
Thanks.
Mar 5, 2013 at 4:33 PM
Edited Mar 5, 2013 at 4:34 PM
Please see the original post on StackOverflow.

The API provides an OverrideMethodFormatAttribute (subclassed from the abstract class MethodFormatAttribute), which works if you want to use a specific string constant, but C# doesn't like the method's type parameters in attributes. This doesn't compile due to the T in the attribute:
[OverrideMethodFormat(string.Format("exception is thrown ({0})", typeof(T).Name))]
private void ExceptionIsThrown<T>() where T : Exception
{
    ...
}
The solution is to create another MethodFormatAttribute subclass that specifically searches the method for generic types and output them. This subclass is below:
public class GenericMethodFormatAttribute : MethodFormatAttribute
{
    private readonly string _textFormat;

    public GenericMethodFormatAttribute(string textFormat = null)
    {
        _textFormat = textFormat;
    }

    public override string Format(MethodInfo method, IEnumerable<string> parameters)
    {
        var generics = method.GetGenericArguments();
        if (_textFormat == null)
        {
            var genericsList = string.Join<Type>(", ", generics);
            return string.Format("{0} ({1})", UnCamel(method.Name), genericsList);
        }
        return string.Format(_textFormat, generics);
    }
}
Usage is almost like the supplied attribute, except that you optionally supply a format string instead of a string constant. Omitting the format string un-camel-cases the method name just like the default behavior.
[GenericMethodFormatAttribute]
private void ExceptionIsThrown<T>() where T : Exception
{
    ...
}
This allows me to declare the attribute in my source, while not having to touch the StoryQ code. Ten points to StoryQ for extensibility!