Search And Destroy

Look out honey, ’cause I’m using technology!

Archive for November, 2010

On Why I Hate Regular Code Generation, Yet Put Up With It In Ruby On Rails

Posted by kilfour on November 30, 2010

The short answer : ‘It has never gotten in my way in Ruby On Rails.’

A longer answer would need to describe the difference in intent.

In most code generation frameworks I’ve seen so far, the framework takes an ‘I know this stuff much better than you’ attitude, and aggressively interferes with the code you’ve allready written.
The intent here is to shield the code from the dev’s stupidity.

In Rails the code generation is there in order to get you started, it actually explains a lot of the conventions being used, and it encourages you to not use it too much.
The intent here is to help the dev.

I prefer tools that don’t treat me like an idiot.

Posted in Rants, Ruby | Leave a Comment »

On What’s On My Mind, Data Access

Posted by kilfour on November 27, 2010

I really like the ‘NHibernate – ConfOrm – Migrator – QuickGenerate’ combo.

If we need to add a persistent entity to our model, these are the steps :

Define the entity :

public class StarShip : Entity
{
    public virtual string SuperMan { get; set; }
    public virtual string MaryPoppins { get; set; }
    public virtual string God { get; set; }
}

Write the CrudTest :
public class StarShipCrudTest : CrudTest<StarShip> { }

Run the test and watch it fail :
Test 'IntegrationTests.StarShipCrudTest.CrudTest`1.AddEntity_EntityWasAdded' failed: NHibernate.Exceptions.GenericADOException : could not insert: [Core.StarShip][SQL: INSERT INTO StarShip (SuperMan, MaryPoppins, God) VALUES (?, ?, ?); select SCOPE_IDENTITY()]
  ----> System.Data.SqlClient.SqlException : Invalid object name 'StarShip'.
....
0 passed, 4 failed, 0 skipped, took 2,48 seconds (NUnit 2.5.5).

Add a migration :
[Migration(004)]
public class M004_StarShip : Migration
{
    private static string TableName = "StarShip";

    public override void Up()
    {
        Database
            .AddTable(
                TableName,
                new Column("Id", DbType.Int64, ColumnProperty.PrimaryKeyWithIdentity),
                new Column("SuperMan", DbType.String, 255, ColumnProperty.Null),
                new Column("MaryPoppins", DbType.String, 255, ColumnProperty.Null),
                new Column("God", DbType.String, 255, ColumnProperty.Null));
    }

    public override void Down()
    {
        Database.RemoveTable(TableName);
    }
}

Rerun the crudtest and watch it pass :
4 passed, 0 failed, 0 skipped, took 1,93 seconds (NUnit 2.5.5).

Done !

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Setup So Far

Posted by kilfour on November 25, 2010

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On Ruby, First Impressions

Posted by kilfour on November 23, 2010

I have been interested in Ruby for a while now.
The main reason I had never given it a try is : there’s only twenty-four hours in a day.

Sometime last week I installed ruby on my Windows 7 machine and started playing around.

Today I bought a macbook for the first time in my life, mainly because I wanted to program in ruby without any friction.

No other language has ever made me buy a machine.

Posted in Rants, Ruby | Leave a Comment »

On What’s On My Mind, QuickPlanner, Story Seven, Reusing Test Code

Posted by kilfour on November 23, 2010

Story seven :
– Monthly View should allow the user to change a ‘vacation’ to working day.

Here’s the acidtest :

public class GoToWorkAcidTest : MonthViewAcidTest, IDisposable
{
    public void Dispose()
    {
        ReportSpecsTested();
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeWorkingDay_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "workingday");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeVacation_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "vacation");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeNotWeekend_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type != "weekend");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec WeekendsCannotBeChangedtoWorkingday(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "weekend");
    }
}

As you can see, it is pretty much a mirror image from the TakeTheDayOff one.
Except this test outputs something like :
Test 'Registered Spec not evaluated' failed: QuickNet.Exceptions.UnregisteredPropertiesException : GoToWorkTransition ChangeVacation_ShouldBeWorkingDay

	C:\Projects\quicknet\ quicknet\QuickNet\Reporting\TestRunReport.cs(58,0): at QuickNet.Reporting.TestRunReport.CheckForRegisteredButUntestedSpecs()

Output from Registered Spec not evaluated:
  733 : GoToWorkTransition ChangeWorkingDay_ShouldBeWorkingDay.
  733 : GoToWorkTransition ChangeNotWeekend_ShouldBeWorkingDay.
  267 : GoToWorkTransition WeekendsCannotBeChangedtoWorkingday.
  ------------------------------------------------------------
  Registered but untested : 
  GoToWorkTransition ChangeVacation_ShouldBeWorkingDay
  ------------------------------------------------------------

0 passed, 1 failed, 0 skipped, took 3,64 seconds (xunit).

In order to get quicknet to test that spec and thus pass, we need to setup some vacation days.

Decorating the acidtest with the following :

[Using(typeof(TakeTheDayOffTransition))]

solves the issue and the test now outputs something like :
Output from VerifyAll:
  334 : GoToWorkTransition ChangeWorkingDay_ShouldBeWorkingDay.
  12 : GoToWorkTransition ChangeVacation_ShouldBeWorkingDay.
  346 : GoToWorkTransition ChangeNotWeekend_ShouldBeWorkingDay.
  128 : GoToWorkTransition WeekendsCannotBeChangedtoWorkingday.
  ------------------------------------------------------------

1 passed, 0 failed, 0 skipped, took 3,57 seconds (xunit).

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

Looking Back : Uncle Bob’s Advice*

Posted by kilfour on November 22, 2010

It seems like I have been listening ;-) .

* No, not talking about Mr. Martin.

Posted in Looking Back | Leave a Comment »

On What’s On My Mind, QuickPlanner, Doing The Dishes

Posted by kilfour on November 22, 2010

By which I mean refactoring, removing redundant code, clarifying intent, …

In the test code aswell.

Apply DRY, remove redundant tests, clarify why tests are there, …

public class TakeTheDayOffAcidTest : MonthViewAcidTest, IDisposable
{
    public void Dispose()
    {
        ReportSpecsTested();
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeWorkingDay_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "workingday");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeVacation_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "vacation");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeNotWeekend_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type != "weekend");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec WeekendsCannotBeChangedtoVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "weekend");
    }
}

Outputs :
Output from VerifyAll:
  672 : TakeTheDayOffTransition ChangeWorkingDay_ShouldBeVacation.
  47 : TakeTheDayOffTransition ChangeVacation_ShouldBeVacation.
  719 : TakeTheDayOffTransition ChangeNotWeekend_ShouldBeVacation.
  281 : TakeTheDayOffTransition WeekendsCannotBeChangedtoVacation.
  ------------------------------------------------------------

1 passed, 0 failed, 0 skipped, took 4,22 seconds (xunit).

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, Reflections II

Posted by kilfour on November 22, 2010

Just as with unit-testing, property-based-testing is much easier if you start doing it from the word go and keep it up all the way through.

Posted in Property Based Testing, Rants | Leave a Comment »

On What’s On My Mind, QuickPlanner, Acidifiying

Posted by kilfour on November 22, 2010

By which I mean : organizing one’s tests.

Or in the case of quicknet, transforming functional style tests into oop style tests.
The first style is quicker to write, harder to read, but allows for some extra tricks.
The second more closely resembles a unit test, is much more maintainable and allows for better reuse across tests.

So Transitions become classes, f.i. :

public class TakeTheDayOffTransition : MetaTransitionSut<DateTime, Null, TakeTheDayOffHandler>
{
    public TakeTheDayOffTransition()
    {
        CreateSutFunc = () =>
            new TakeTheDayOffHandler(
                NHibernateHelper.GetCurrentSession(),
                new FindDayOffByDate(NHibernateHelper.GetCurrentSession()));

        SutExecute = (sut, i) => { sut.Handle(i); return null; };

        Generator(() => new DateGenerator());

        ReportInput(i => i.ToString("dd/MM/yyyy"));
    }
}

And specs get organized in AcidTests :
public class TakeTheDayOffAcidTest : AcidTest
{
    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ShouldBeVacation(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type != "weekend")
                .Message(() => string.Format(
                    "{0} should have been marked as vacation, but wasn't.",
                    i.ToString("dd/MM/yyyy")));
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec WeekendsCannotBeChangedtoVacation(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "weekend")
                .Message(() => string.Format(
                    "{0} should have been marked as weekend, but wasn't.",
                    i.ToString("dd/MM/yyyy")));
    }
}

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Story Five, Making It Pass

Posted by kilfour on November 21, 2010

Leading to more unit-tests, domain classes, …

Also this story implies, for the first time, that we need to persist something.
In walks nhibernate.
This I believe must be tested against a real database.
So we write some integration tests :

public class DayOffCrudTest : CrudTest<DayOff>
{
    protected override DayOff BuildEntity()
    {
        return  DayOff.On(new DateTimeGenerator().GetRandomValue());
    }
}

This uses a technique I’ve talked about before and results in :
4 passed, 0 failed, 0 skipped, took 2,06 seconds (xunit).

The tests are defined in the base class, specifically :
– SelectQueryWorks
– AddEntity_EntityWasAdded
– UpdateEntity_EntityWasUpdated
– DeleteEntity_EntityWasDeleted
We test CRUD operations for each entity against a real db in this way.

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.