Idea (and patch if requested) To Reduce Noise

Oct 9, 2009 at 11:11 PM

I just found this for the first time today. Wow. Its awesome! Thanks!

After diving into the source, I've implemented an improvement imo. I'd like to hear your thoughts.

Basically I feel like the use of lambda expressions everywhere really adds noise the the semantics. So my thought was to simply get rid of them. This is what I ended up with:

[Test]
public void WritingExecutableSpecificationsAsActions()
{

/// story stuff .WithScenario("Writing specifications") .Given(ACompleteContext) .When(TheTestIs_, "run") .Then(The_ShouldBe_, "result", "passed"); story.Assert(); }
static void TheTestIs_()
{
	Assert.IsTrue(true);
}

static void ACompleteContext()
{
	Assert.IsTrue(true);
}

static void The_ShouldBe_()
{
	Assert.IsTrue(true);
}

 

The method name place holders are filled by the param object[] array. So 'The_ShouldBe_', in the example above, ends up looking like: "The result should be passed".

Because of the above change, if you still want to use an expression and have its method body properly parsed, you need to call:

.Fragment(Narrative.Exec(() => My_Method("myPlaceholderValue")))

The advantage is a much cleaner syntax imo. However, there are two draw backs to this approach:

  • Since Expression<Action> can be cast to Action, passing an expression without calling Narrative.Exec compiles and executes fine. The description, however, can't be parsed from the method call body since there is no way of actually knowing there is a method body. The code just assumes its an action and not an expression.
  • Its a semi breaking change. Existing code will still work but, as indicated above, unless the expressions are removed and replaced with simple delegates {e.g. ".Fragment(() => MyMethod())" is replaced with ".Fragment(MyMethod)"} the description doesn't parse correctly.
For me, those limitations won't be a problem. I'm starting fresh. For others, its a matter of deleting a bunch of extra () and =>. They might welcome it. Its also consistent change.
If this is something you guys would consider migrating into the framework I can send a patch. Let me know.
Coordinator
Oct 15, 2009 at 11:39 AM

Hi Dane

Would love to see how you did this. I've got a new version on the roadmap, and will migrate this in if possible.

Cheers - Rob

Nov 8, 2009 at 1:59 PM

StoryQ is a great tool.  I really prefer it to NBehave.

My only quibble is with the 'noisy' syntax.  With that in mind, I created a fork of StoryQ called StoryQSlim to support the 'quiet' syntax.  The url is at http://storyqslim.codeplex.com.

If/when StoryQ supports this, I plan to close StoryQSlim.

 

Coordinator
Nov 9, 2009 at 1:25 PM

Hi Aporia

oddly enough, a colleague showed me the same bit of code (getting a method name from a plain delegate, which I can't believe i didn't know about) just last week.

I've already got plans underway to change storyq to work this way, removing the noise expression syntax. We'll be using http://flit.codeplex.com to generate all that boilerplate code.

In the meantime, however, it's great that you've created this fork. Can I recommend that you put a release up and some basic documentation on your homepage, since that's the sort of thing that gets new users going the fastest

 

Cheers - Rob

Nov 14, 2009 at 4:21 PM

Hi Rob,

I've played around a little more with my fork and found some counterintuitive behavior.

using NUnit.Framework;
using StoryQ.Framework;

namespace StoryQ.Tests
{
    public static class ActionSteps
    {
        public static void theSumShouldBe_(int actual, int expected)
        {
            Assert.That(expected, Is.EqualTo(actual));
        }

        public static void IHaveACalculator(out Calculator calculator)
        {
            calculator = new Calculator();
        }

        public static void IAdd_And_Together(int x, int y, Calculator calculator, out int sum)
        {
            sum = calculator.Add(x, y);
        }
    }

    [TestFixture]
    public class ExampleProblem
    {
        [Test]
        public void Case1()
        {
            Calculator calculator = null;
            int sum = 0;

            var story = new Story("add");
            
            story.WithScenario("two small numbers")
                
                .Given_(() => ActionSteps.IHaveACalculator(out calculator)) // I am using Given_ instead of Given to tell StoryQSlim to parse an expression
                .When_(() => ActionSteps.IAdd_And_Together(2, 3, calculator, out sum)) // I am using When_ instead of When to tell StoryQSlim to parse an expression
                .Then(ActionSteps.theSumShouldBe_, 5, sum); // Then (no underscore) tells StoryQSlim to parse an Action

            story.Assert();
        }
    }

    public class Calculator
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

If you run the test, you will see that it fails. This seems to happen because StoryQSlim evaluates arguments in an Expression at a different time than arguments to an Action.  Because of this, I think a little more thought would need to be put into integrating daneconner's suggestion, than what I did with StoryQSlim.

 

 

Coordinator
Nov 17, 2009 at 6:20 AM

Hi Aporia

I've emailed Dane, so fingers crossed. In the meantime, however, you might like to have a look at the latest code in the branch "FlitBased" to see where the next version of storyQ is heading. I don't think we'll be able to retain backwards compatibility (like Dane explains), but it should provide the syntax you prefer.

Cheers - Rob

Nov 17, 2009 at 2:20 PM
Edited Nov 17, 2009 at 2:44 PM

Hey guys,

I can throw this patch together later on this week. Sorry I've been MIA, I'd switched gears by the time you got back to me and its been taking me a while to switch back :). (To many things + no time = the usual for all of us I'm sure).

Nov 17, 2009 at 2:23 PM

Actually, I'll just do it right now. I just went to look at my changes and there weren't too many. I'm gonna go through them real quick and submit. If you have any questions let me know.

 

Nov 17, 2009 at 2:44 PM

Submitted.

Coordinator
Nov 17, 2009 at 3:13 PM

Thanks Dane!

Your changes were as I expected, in fact, i've already checked very similar code into the branch. Once the "flitbased" branch is complete I think you'll be very happy with the new StoryQ