Tim Scott's Blog

April 23, 2010

Bill It – IPhone App – Time Entry On The Go, QuickBooks Integration

Filed under: MonoTouch — Tim Scott @ 5:18 am

Warning: this post is a shameless commercial promotion.

I have a secret. I have been working on an IPhone app. I am proud to announce that it’s finished and for sale in the App Store. Current price: $4.99. It’s called Bill It.

The Problem

I created Bill It because I needed it myself. I am a consultant, and I use QuickBooks to bill my clients. The edition of QuickBooks that I use comes with a nice time entry feature that makes it pretty easy to bill my clients based on time and materials. But it’s inconvenient to open QuickBooks whenever I want to record my time. But if I wait, I forget, and that’s bad. I have used various mobile apps to capture my time — first on a Palm device, then on my IPhone. But this presents a different problem: double entry. It’s a hassle to transcribe hours from one screen to another, but the real problem is accuracy. Each transcription carries with it a small risk of error. Billing errors are bad.

The Solution

So I created Bill It. Bill It lets me enter my time on the go with no friction. The time is accurate because I enter it when it’s fresh in my mind. When billing time rolls around, it’s a couple of taps to send myself an email with a file attached. I open QuickBooks, and with a few clicks the time is imported. No fear of errors, and very little hassle.

Bill It Lite

A pet peeve of mine is paying for an app that I will never use. Even if it’s only a buck. On the other hand I don’t mind paying a premium price for an app I will use regularly. So I created Bill It Lite, which lets users try out every aspect of Bill It before they pay for it. Another pet peeve is when I try out a lite version only to realize that I must redo a bunch of setup and data entry when I buy the full version. Not with Bill It Lite. Users can buy the full version right in the app. No new app. No redoing setup and data entry.

You might also be interested to know that I developed Bill It using MonoTouch and Catnap.

January 10, 2010

ShouldIt Is ILMerged

Filed under: Programming, Test Driven Development, Unit Testing — Tim Scott @ 6:49 pm

ShouldIt is a library of fluent specification extensions that works with all of the popular testing frameworks. My goal with ShouldIt is to provide a robust set of testing extensions that I can drop in to any test project, and it just works.

So far ShouldIt has met that goal, well mostly. One small friction point is the need to reference four DLLs (not counting the testing framework itself) in my test projects. No more. I have added an automated build that ILMerges all the required assemblies. And to make it easy for others to adopt ShouldIt, the download page now has a single file download for each testing framework.

November 30, 2009

A Question Of Astonishment

Filed under: FluentHtml, Programming — Tim Scott @ 5:26 pm

Steve Michelotti recently found a very subtle bug in MvcContrib.FluentHtml.   It provides us with a rather interesting case of applying the Principle Of Least Astonishment (a.k.a. Rule Of Least Surprise).

It turns out that FluentHtml’s select helper lets the user express his intent vaguely.  Consider whether this test should pass:

[Test]
public void when_determining_selected_values_select_should_ignore_selected_method_if_any_options_are_marked_selected()
{
    var list = new List<SelectListItem>
    {
        new SelectListItem { Text = "Acura", Value = "1", Selected = true },
        new SelectListItem { Text = "BMW", Value = "2" },
    };

    var select = new Select("foo.Bar").Selected(2).Options(list);

    var optionNodes select.ToString().ShouldHaveHtmlNode("foo_Bar").ShouldHaveChildNodesCount(2);
    optionNodes[0].ShouldBeSelectedOption(1, "Acura");
    optionNodes[1].ShouldBeUnSelectedOption(2, "BMW");
}

See what we have done here? We have allowed the user to express which options should be selected in two, possibly contradictory ways. In the call to Options, the user has specified that Acura should be selected. In the call to Selected, she has specified that BMW should be selected. How should we interpret what she really wants?

The first path to consider is to change the API to remove the chance for vaugeness. In most cases this is highly preferable. In this case, however, the cat is already out of the bag so to speak. That is, changing the API in this way would be a big breaking change.  Furthermore, it is deliberate and I believe very useful that the API offers a lot of ways to specify select options.

That leaves us to invoke the Rule Of Least Surprise. When a user specifies vague intent, in the manner that we have described, I can see five reasonable outcomes:

  1. Selected items are only those expressed via Selected
  2. Selected items are only those expressed via Options
  3. Selected items are a union of those expressed via Selected and Options
  4. Selected items are only those expressed via Options or Selected, whichever is called last
  5. Selected items are only those expressed via Options unless none, then those expressed via Selected

I will reject #4 out of hand.  FluentHtml helpers are essentially builders.  And with builders, order should never be important.  #1 and #2 are the next to go.  I cannot think of a better argument for either, and so the choice would be arbitrary.  It’s a rather close call between #3 and #5, but I will choose #5.  Here is the thinking.   If the user has specified selected items within the options themselves, then calling Selected is clearly a mistake on his part and he should expect it to be ignored.  On the other hand, if he did not specify selected items within the options list, then he could reasonably expect the call to Selected to be honored.

Would you make a different choice?

November 5, 2009

MVC 2 Areas Gotchas

Filed under: MS MVC — Tim Scott @ 12:24 am

I am adding ASP.NET MVC to a legacy WebForms application. Hallelujah! 

The process has gone very well.  I am here to report, do not fear the hybrid application!  At first we put the MVC parts directly into the legacy app.  It only required a bit of fiddling around to create a custom view engine. Later we decided to move the MVC parts into an “area project” using the new MVC 2.  This MSDN walkthrough was our guide.  The purpose of this post is to report a couple tricky gotchas that we encountered along the way.

GOTCHA #1:  By default, the area folder is named after the assembly, not the area name.

The walkthrough shows code for an AreaRegistration class:

public class Routes : AreaRegistration
{
    public override string AreaName
    {
        get { return "Store"; }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Store_Default",
            "Store/{controller}/{action}/{id}",
            new { controller = "Products", action = "List", id = "" }
        );
    }
}

Notice that the Name property is “Store” which matches the first node of the route.  It might seem that this is significant, but as far as I can tell it is not.  What is significant is that the project name “Store” matches the first node of the route.  So route needs to start with your assembly name.  

Okay, but what if my porject is named “Foo.Bar.Store”?  I don’t want my route to be “Foo.Bar.Store/{controller}/{action}/{id}”.  Fortuantely you can change this.  Here’s how.

The walkthrough gives instructions to modify the project files, which includes adding the following AfterBuild task to your “area project:”

<CreateAreaManifest AreaName=”$(AssemblyName)” AreaType=”ChildAreaPath=”$(ProjectDir)” ManifestPath=”$(AreasManifestDir)” ContentFiles=”@(Content)” />

Change it to this:

<CreateAreaManifest AreaName=”StoreAreaType=”ChildAreaPath=”$(ProjectDir)” ManifestPath=”$(AreasManifestDir)” ContentFiles=”@(Content)” />

What this does is tells MSBuild to copy the view folders from the “area project” into the parent project to a location named “Views/Areas/Store” rather than “Views/Areas/Foo.Bar.Store”.

GOTCHA #2: Manifest files are not recreated with every build.

The CreateAreaManifest task does not actually tell MS Build where to copy the view files and folders.  Rather it tells MSBuild how to create a manifest file.  This file contains the details that MSBuild will later use to copy the view files and folders.  But there is a gotcha.  Once a manifest file has been created, subsequent builds add to it, rather than to trash it and create a fresh one.  Therefore, if you change the CreateManifestArea task in the project file, you will need to manually delete the corresponding manifest file. This is a real pain, and maybe there’s some way around it, but not that I know about.

September 29, 2009

The Tale Of The Tape

Filed under: Programming — Tim Scott @ 4:44 am

Joel Spolsky recently set off another flurry of discussion in the blogosphere with his post extolling the noble duct tape programmer.  Most of it was not too bad.  But what could have been a nice rant against architecture astronauts was ruined when he drew a false dichotomy between overwrought architecture and duct tape.

Which brings me to my story.

Just today I came across a charming little piece of duct tape. Here’s how I imagine it got there.  During construction of the system some tester reported a problem: “When I do [x] I get an ugly error, and I cannot complete the task.”  The job of fixing the error was quickly dispatched to a clever duct tape programmer who “solved” it equally quickly by wrapping about 100 lines of code in a try-catch block that swallows the exception.  Before you groan too loudly I should mention that this code has been in production for a year or more.  Does that prove that duct tape was the right tool?

Not so fast.  Back to what happened today.  A colleague and I spent about an hour scratching our heads over a failing acceptance test.  It turned out that this little piece of tape was masking a problem elsewhere in the code.  What should have taken five minutes to solve took two person hours.

Is it a good trade off?  Absolutely!  Um well, unless the business needs to change.  The thing is, it does need to change.  It needs to change a lot.  I will venture to say that all businesses need to change all the time.  This particular system was built by a team of duct tapers.  So our little struggle today is repeated over and over all day every day.  The net result is that it takes many times longer than it “should” to maintain and extend the system.  Indeed, some extenstions seem out of reach.  Conclusion: while duct tape systems may get to v1 faster, they can be very very expensive over the long term in terms of programming labor and worse yet in terms of  lost opportunity.

July 17, 2009

ShouldIt Gets More Fluent

Filed under: C#, Test Driven Development, Unit Testing — Tim Scott @ 3:26 am

ShouldIt now gives you the option to use a more fluent syntax.  For example, the following:

result.ShouldNotBeNull();

Can now be expressed as:

result.Should().Not.Be.Null();

You can still chain asserts as before.  So this:

personList
    .ShouldCount(1)
    .ShouldContainOne(x => x.Id == exptected.Id)
    .FirstName.ShouldEqual("Jim")

Can now alternatively be expressed as:

shouldList
    .Should().Count.Exactly(1)
    .Should().Contain.One(x => x.Id == exptected.Id)
    .FirstName.Should().Equal("Jim");

The new syntax can be found in the ShouldIt.Clr.Fluent namespace in the Should.Clr assembly.

Why the new syntax?  Whether it’s more or less readable is largely a matter of taste.  For me, words separated by dots are an improvement over Pascal cased phrases.    However, the extra parentheses surely do not help. (Anyone else wish that parens were optional for calls to methods with no parameters?)  Nonetheless, I think that the new syntax has some nice advantages.

  1. Better Intellisense. With the old style, Intellisense offers a long list of every possible assertion for the target type.  It’s annoying to scroll through the list and/or type the entire word “should” plus one more letter before the list shirinks.  Using the new style, only one extension method appears at first.   As you type each new node, the list remains very small until you narrow down to the assertion that you want.   Overall I believe that this will facilitate faster and more accurate coding.
  2. More Maintainable And Extensible. The original extension methods all live together in one big fat static class.  The new code is more object oriented and spreads responsibilities over more small classes.  While this does not immediately provide any value to the user, it will make it easier to add nice features over time.

Give it a try and let me know what you think.

May 31, 2009

Reusable “Should” Extensions

Filed under: Test Driven Development, Unit Testing — Tim Scott @ 4:06 am

Should Extensions

UPDATE (6/9/09): Get the code here.

Some months ago I started wrapping my test asserts in fluent “should” extensions, like this:

public static T ShouldEqual<T>(this T actual, T expected)
{
    Assert.AreEqual(expected, actual);
    return actual;
}

Some of these extensions do a little more than just wrap assertions, for example:

public static T ShouldContainOne<T>(this IEnumerable<T> e, Func<T, bool> predicate)
{
    var match = e.ShouldContainAtLeastOne(predicate);
    if (match.Count() != 1)
    {
        Assert.Fail("Expecting 1 matching item.  Found {0}.", match.Count());
    }
    return match.First();
}

Reuse Dilemma

I put these extension methods in a static class in a helper project for re-use across test projects within the application.  Then one day I began work on a new application for a new client.  I love my “should” extensions and felt I could not live without them. Cut-and-paste to the rescue. Yuck. Now I am on to another application. Cut-and-paste again. Get me off this merry-go-round!

I considered creating a common assembly to share across my projects. However, as a consultant I prefer not to leave behind binary bits with this client and that client.

Making matters worse, the aforementioned applications do not all use the same testing framework.

Solution

So I have started developing a library of reusable “should” extensions that I am planning to release as open source – tentatively named “ShouldIt.” It will plug-and-play with all the major unit testing frameworks – with zero configuration using MEF.  To use it, with NUnit for example, you will reference ShouldIt.Core, ShouldIt.Clr and ShouldIt.NUnit in your test project.

You might be wondering, what is ShouldIt.Clr, and why is it separate from ShouldIt.Core?  ShouldIt.Clr will provide extensions to the CLR base class library types.  This leaves room to add, for example, ShouldIt.Watin.

By the way I considered writing my own assertions instead of wrapping those provided by the testing framework.  Then I opened NUnit and MbUnit in Reflector.  Whew!  There’s a lot more to those simple-looking assertions than I had expected.

Challenges And Questions

The biggest challenge I foresee is managing multiple binary dependencies to the testing frameworks.  This is mitigated by the fact that references will not be version specific.  Hence, pain will only be felt when the Assert APIs, more specifically those methods that ShouldIt calls, are changed.  I expect that those APIs are fairly stable.  That said, we can expect major releases to have breaking changes, as we have seen recently with MbUnit 3 (Gallio).

My questions for you:

  1. Anyone else feeling this pain?
  2. Has someone solved this already and I just have not seen it?
  3. Can you think of a better name than “ShouldIt?”

May 18, 2009

Use MvcContrib.FluentHtml With Spark View Engine

Filed under: FluentHtml, MS MVC, Spark View Engine — Tim Scott @ 11:04 pm

Introduction

MvcContrib.FluentHtml is a library of extensible HTML helpers for MS MVC.  It works out of the box with the WebForms view engine. As it turns out, it’s not very hard to use with other view engines.  Read on to see how to use FluentHtml with the Spark view engine.

View Class

First, you need to add a class to your project, something like this:

public abstract class SparkModelViewPage<T> : SparkView<T>, IViewModelContainer<T> where T : class
{
    private readonly List<IBehaviorMarker> behaviors = new List<IBehaviorMarker>();

    protected SparkModelViewPage()
    {
        behaviors.Add(new ValidationBehavior(() => ViewData.ModelState));
        //add any other desired behaviors here
    }

    public string HtmlNamePrefix { get; set; }

    public T ViewModel
    {
        get { return Model; }
    }

    public IEnumerable<IBehaviorMarker> Behaviors
    {
        get { return behaviors; }
    }
}

NOTE: I updated this class since the original post. I removed constructors overrides that pass in behaviors ad htlmPrefix. You don’t need these unless you expect to further derive this class.

Configuration

Then apply a little configuration – either in the config file or in code. Refer to the Spark config documentation for details.

var settings = new SparkSettings()
    .SetPageBaseType("SparkModelViewPage")
    .AddAssembly("MvcContrib.FluentHtml")
    .AddNamespace("MvcContrib.FluentHtml")
    ...yadda yadda;
ViewEngines.Engines.Add(new SparkViewFactory(settings));

PageBaseType tells the Spark view engine to use your new class as the base class for all views.  The other two settings tell the Spark view engine to use FluentHtml in views.

Usage

That’s it.  Then you can use FluentHtml in your views like so:

<viewdata model="MyApp.Models.Person"/>  

<%=this.TextBox(x => x.FirstName).Label("First Name") %>
<%=this.TextBox(x => x.LastName).Label("Last Name") %>

Conclusion

I should add one caveat. I have tested only the most naive scenarios, and I have not used Spark for any production work at all. Please comment on any issues you encounter in using FluentHtml with Spark.

February 5, 2009

Eliminate Magic Strings In Javascript With MvcContrib.FluentHtml

Filed under: FluentHtml, MS MVC — Tim Scott @ 3:27 am

MvcContrib.FluentHtml provides a library of HTML helper methods that use expressions with strongly typed views to generate HTML elements. Not too long after that MS MVC beta introduced HtmlHelper<T> which allows users to create extension methods that use expressions in the same way.   The benefits are obvious.  By trading magic strings for expressions we gain compile time checking, better refactoring, etc.

So this:

<%=this.TextBox(x => x.User.FirstName)%>

Generates this:

<input type="text" name="User.FirstName" id="User_FirstName" value="Joe"/>

This is very nice, but what about all the other magic strings in our view?  I’m talking of course about Javascript. Does this look familiar?

$('#User_FirstName').change(doSomething);

Doh!  We just can’t escape those magic strings. Or can we?  How about this?

$('#<%=this.IdFor(x => x.User.FirstName)%>').change(doSomething);

MsMvc.FluentHtml has introduced IdFor and NameFor. Okay, so we won’t eliminate all magic string in Javascript but perhaps quite a few. Perhaps we give up a tiny bit of readability, but I think it’s worth it to stop fretting whether some refactor is going to break a bunch of Javascript.

I owe credit to Jimmy Bogard for planting this idea in my mind in one of his tweets.

January 13, 2009

Editing a Variable Length List Of Items With MvcContrib.FluentHtml – Take 2

Filed under: FluentHtml, MS MVC — Tim Scott @ 11:48 pm

In a previous post, I showed how to edit a variable length list using MvcContrib.FluentHtml.  The post was inspired by a post on the same topic by Steve Sanderson.  Steve commented on my post pointing out some limitations.  To address these limitations required some enhancements to MvcContrib.FluentHtml and some changes to my example.  So here we go with take 2.

MvcContrib.FluentHtml Enhancements

The limitations were mostly related to handling validation.  To support validation using Model State we have added to MvcContrib.FluentHtml:

  • Html Prefix Support
  • A Validation Helper
  • List Indexing Support

Html Prefix Support

HTML elements generated for strongly typed views have no prefix by default.  So elements for ModelViewPage<Person> might look something like this:

<input name="FirstName" id="FirstName" value="Jim" type="text"/>
<input name="LastName" id="LastName" value="Smith" type="text"/>

The problem is, neither MvcContrib’s NameValueSerializer nor MS MVC’s default model binder fully handle this scenario.   While NameValueDeserializer does the binding just fine, it does not place bind errors into ModelState.  The default model binder does not handle quite handle the binding — it does not deserialize enumerable properties when no prefix is used.

To bind everything correctly and get any errors into ModelState we need a prefix.  One way to handle this is to wrap our primary model in a view model. This is a valid pattern. It’s even a standard for some applications. However, we don’t want to have to do this just to get a prefix. So we provide a way to specify a prefix for a strongly typed view.

Either in the code-behind:

public class Index : ModelViewPage<IList<Gift>>
{
    public Index() : base("person") { }
}

Or in the view:

<%this.HtmlNamePrefix = "person"%>

Thus our HTML elements will be prefixed:

<input name="person.FirstName" id="person_FirstName" value="Jim" type="text"/>
<input name="person.LastName" id="person_LastName" value="Smith" type="text"/>

Then in our action method, we can use the default binder without any attribute.  Any bind errors will be captured in ModelState.

[AcceptPost]
public ViewResult Index(Person person)

New Validation Helper

We have added validation support to FluentHtml for strongly typed views. The following works basically the same as HtmlHelper’s ValidationMessage.

<%this.ValidationMessage(x => x.Price, "Price must be numeric.")%>

We have also added a behavior to ModelViewPage<T>, ModelViewMasterPage<T> and ModelViewUserControl<T> which basically mimics validation used by HtmlHelper.  That is, it adds a CSS class “input-validation-error” to any HTML element with an error in ModelState.  If you wish, you can remove this behavior or change the CSS class name in the derived class.

List Indexing Support

MS MVC uses a special technique to deserialize enumerable properties.  With this technique you set an arbitrary value in a specially named hidden element to signify that a group of elements belongs to a particular instance of the enumerable property. This has an advantage over using positional indexes in that it preserves the identity of an instance across posts, which is necessary for ModelState based validation to work properly.

Therefore, we have added support for this to MvcContrib.FluentHtml.  Let’s assume ModelViewPage<IList<Person>> with a prefix of “persons”.  Then this markup:

<%var id = Model[i].Id;%>
<%=this.Index(x => x).Value(id)%>
<%=this.TextBox(x => x[id].FirstName).Value(Model[i].FirstName)%>

Will generate HTML like this:

<input id="persons_Index_123" name="persons.Index" value="123" type="hidden"/>
<input id="persons[123]_FirstName" name="persons[123].FirstName" value="Jim" type="text"/>

Changes To Our Example

So based on these changes to FluentHtml we made a few changes to the “Gift Request Form” demo from the previous post. In the main view:

<%for (var i = 0; i < ViewData.Model.Count; i++) {%>
    <%ViewData["index"] = i;
    Html.RenderPartial("GiftLineItem");%>
<%}%>

And in the user control:

<%var i = (int)ViewData["index"];
  var gift = ViewModel == null ? null : ViewModel[i];
  var id = gift == null ? -1 * new Random().Next() : gift.Id;
  var name = gift == null ? null : gift.Name;
  var price = gift == null ? (decimal?)null : gift.Price;%>
<div class="giftLineItem">
    <%=this.Index(x => x, x => x[i].Id)%>
    <%=this.Hidden(x => x[id].Id).Value(id)%>
    <%=this.TextBox(x => x[id].Name).Value(name).Label("Name of gift:")%>
    <%=this.TextBox(x => x[id].Price).Value(price).Label("Price ($):")%>
    <%=this.ValidationMessage(x => x[id].Price, "Must be a number")%>
    <a href="" class="removeGift">Delete</a>
</div>

Viola, validation works:

showvalidationerror1

Note that we stole Steve’s technique of using random negative Ids for unsaved instances, which we will handle in the save method on the server.

GET THE REVISED CODE
GET THE REVISED CODE, UPDATED FOR MVC 2, SIMPLIFIED, AND USING GUID IDs (2/15/10)

« Newer PostsOlder Posts »

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.