April 25, 2014
On Thursday, 24 April 2014 at 18:53:22 UTC, Jacob Carlborg wrote:
> On 2014-04-23 15:24, Atila Neves wrote:
>> Like testing with Cucumber? Wish you could call native D code with it?
>> Now you can!
>>
>> http://code.dlang.org/packages/unencumbered
>> https://github.com/atilaneves/unencumbered
>>
>> I especially like registering functions that take the parameters with
>> the types they need from the regexp captures, as well as the
>> compile-time failures that come from that if done incorrectly.
>>
>> Now I just need to use in "real life".
>
> BTW, why is the description passed as a template argument to the Cucumber keywords. @Given!("foo") instead of @Given("foo")?

Ehm... because until now I didn't know that @Given("foo") was possible. In my head I was doing compile-time stuff so everything had to be compile-time, if that makes any sense.

After I read the above I wasn't even sure how @Given("foo") would work so I wrote some code and now know that all I need is a struct with a regular string field. I think the documenation on http://dlang.org/attribute.html is severely lacking.

I think I have some refactoring to do now. Thanks for pointing this out!


Atila
April 25, 2014
On Friday, 25 April 2014 at 08:45:20 UTC, Atila Neves wrote:
> On Thursday, 24 April 2014 at 18:53:22 UTC, Jacob Carlborg wrote:
>> On 2014-04-23 15:24, Atila Neves wrote:
>>> Like testing with Cucumber? Wish you could call native D code with it?
>>> Now you can!
>>>
>>> http://code.dlang.org/packages/unencumbered
>>> https://github.com/atilaneves/unencumbered
>>>
>>> I especially like registering functions that take the parameters with
>>> the types they need from the regexp captures, as well as the
>>> compile-time failures that come from that if done incorrectly.
>>>
>>> Now I just need to use in "real life".
>>
>> BTW, why is the description passed as a template argument to the Cucumber keywords. @Given!("foo") instead of @Given("foo")?
>
> Ehm... because until now I didn't know that @Given("foo") was possible. In my head I was doing compile-time stuff so everything had to be compile-time, if that makes any sense.
>
> After I read the above I wasn't even sure how @Given("foo") would work so I wrote some code and now know that all I need is a struct with a regular string field. I think the documenation on http://dlang.org/attribute.html is severely lacking.
>
> I think I have some refactoring to do now. Thanks for pointing this out!
>
>
> Atila

Hmm. So for the string argument is fine, unfortunately I also need to know the line number of the step definition, and that doesn't work:

struct Given {
    this(string s, ulong l = __LINE__) {
        this.s = s;
        this.l = l;
    }
    string s;
    ulong l;
}


@Given("foobar")
auto func() pure nothrow @safe {

}

void main() {
    foreach(attr; __traits(getAttributes, func)) {
        pragma(msg, "s is ", __traits(getMember, attr, "l"));
    }
}


I get:

s is attr_str.d(21): Error: variable attr cannot be read at compile time
attr_str.d(21):        while evaluating pragma(msg, __traits(getMember, attr, "l"))

April 25, 2014
On Friday, 25 April 2014 at 08:52:18 UTC, Atila Neves wrote:
> On Friday, 25 April 2014 at 08:45:20 UTC, Atila Neves wrote:
>> On Thursday, 24 April 2014 at 18:53:22 UTC, Jacob Carlborg wrote:
>>> On 2014-04-23 15:24, Atila Neves wrote:
>>>> Like testing with Cucumber? Wish you could call native D code with it?
>>>> Now you can!
>>>>
>>>> http://code.dlang.org/packages/unencumbered
>>>> https://github.com/atilaneves/unencumbered
>>>>
>>>> I especially like registering functions that take the parameters with
>>>> the types they need from the regexp captures, as well as the
>>>> compile-time failures that come from that if done incorrectly.
>>>>
>>>> Now I just need to use in "real life".
>>>
>>> BTW, why is the description passed as a template argument to the Cucumber keywords. @Given!("foo") instead of @Given("foo")?
>>
>> Ehm... because until now I didn't know that @Given("foo") was possible. In my head I was doing compile-time stuff so everything had to be compile-time, if that makes any sense.
>>
>> After I read the above I wasn't even sure how @Given("foo") would work so I wrote some code and now know that all I need is a struct with a regular string field. I think the documenation on http://dlang.org/attribute.html is severely lacking.
>>
>> I think I have some refactoring to do now. Thanks for pointing this out!
>>
>>
>> Atila
>
> Hmm. So for the string argument is fine, unfortunately I also need to know the line number of the step definition, and that doesn't work:
>
> struct Given {
>     this(string s, ulong l = __LINE__) {
>         this.s = s;
>         this.l = l;
>     }
>     string s;
>     ulong l;
> }
>
>
> @Given("foobar")
> auto func() pure nothrow @safe {
>
> }
>
> void main() {
>     foreach(attr; __traits(getAttributes, func)) {
>         pragma(msg, "s is ", __traits(getMember, attr, "l"));
>     }
> }
>
>
> I get:
>
> s is attr_str.d(21): Error: variable attr cannot be read at compile time
> attr_str.d(21):        while evaluating pragma(msg, __traits(getMember, attr, "l"))

struct Given {
    this(ulong l = __LINE__)(string s) {
        this.s = s;
		this.l = l;
    }
    string s;
    ulong l;
}


@Given("foobar")
auto func() pure nothrow @safe {

}

void main() {
	pragma(msg, "s is ", getGivenL!func);
}

pure ulong getGivenL(alias symbol)() {
	foreach(attr; __traits(getAttributes, func)) {
		static if (is(typeof(attr) == Given)) {
			return attr.l;	
		}
	}
	assert(0);
}

Basically move the "checking" of UDA's to specialist functions that are reusable.
Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.
April 25, 2014
On Friday, 25 April 2014 at 09:45:06 UTC, Rikki Cattermole wrote:
> Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.

This is antipattern. Default function arguments for __LINE__ and __FILE__ are also evaluated at call site. Moving this to template parameter creates huge amount of template bloat and must be used only if there is no other way around (that usually implies variadic arguments)
April 25, 2014
On Friday, 25 April 2014 at 10:02:45 UTC, Dicebot wrote:
> On Friday, 25 April 2014 at 09:45:06 UTC, Rikki Cattermole wrote:
>> Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.
>
> This is antipattern. Default function arguments for __LINE__ and __FILE__ are also evaluated at call site. Moving this to template parameter creates huge amount of template bloat and must be used only if there is no other way around (that usually implies variadic arguments)

True in this specific case it might be over the top.
April 25, 2014
On Friday, 25 April 2014 at 10:20:47 UTC, Rikki Cattermole wrote:
> On Friday, 25 April 2014 at 10:02:45 UTC, Dicebot wrote:
>> On Friday, 25 April 2014 at 09:45:06 UTC, Rikki Cattermole wrote:
>>> Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.
>>
>> This is antipattern. Default function arguments for __LINE__ and __FILE__ are also evaluated at call site. Moving this to template parameter creates huge amount of template bloat and must be used only if there is no other way around (that usually implies variadic arguments)
>
> True in this specific case it might be over the top.

It was a template parameter before anyway. Also, this is for acceptance/feature/integration testing, so I doubt anyone would care how much bloat it generates as long as it gets the job done.

Is there any other way to achieve @Given("regexp") that also gets passed in the line number automatically without the template param? If so I'll glady use it, if not I think Rikki's solution seems to be the simplest so far.

Atila
April 25, 2014
On Friday, 25 April 2014 at 11:11:18 UTC, Atila Neves wrote:
> Is there any other way to achieve @Given("regexp") that also gets passed in the line number automatically without the template param? If so I'll glady use it, if not I think Rikki's solution seems to be the simplest so far.
>
> Atila

Just change struct constructor back to
    this(string s, ulong l = __LINE__) {
in Riki's snippet
April 25, 2014
On Friday, 25 April 2014 at 11:11:18 UTC, Atila Neves wrote:
> On Friday, 25 April 2014 at 10:20:47 UTC, Rikki Cattermole wrote:
>> On Friday, 25 April 2014 at 10:02:45 UTC, Dicebot wrote:
>>> On Friday, 25 April 2014 at 09:45:06 UTC, Rikki Cattermole wrote:
>>>> Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.
>>>
>>> This is antipattern. Default function arguments for __LINE__ and __FILE__ are also evaluated at call site. Moving this to template parameter creates huge amount of template bloat and must be used only if there is no other way around (that usually implies variadic arguments)
>>
>> True in this specific case it might be over the top.
>
> It was a template parameter before anyway. Also, this is for acceptance/feature/integration testing, so I doubt anyone would care how much bloat it generates as long as it gets the job done.

It will hurt build-times, so it's worth avoiding.
April 25, 2014
On Friday, 25 April 2014 at 12:18:41 UTC, John Colvin wrote:
> On Friday, 25 April 2014 at 11:11:18 UTC, Atila Neves wrote:
>> On Friday, 25 April 2014 at 10:20:47 UTC, Rikki Cattermole wrote:
>>> On Friday, 25 April 2014 at 10:02:45 UTC, Dicebot wrote:
>>>> On Friday, 25 April 2014 at 09:45:06 UTC, Rikki Cattermole wrote:
>>>>> Also when using things like __LINE__ keep them to template args, as they are inferred to the initiation if possible.
>>>>
>>>> This is antipattern. Default function arguments for __LINE__ and __FILE__ are also evaluated at call site. Moving this to template parameter creates huge amount of template bloat and must be used only if there is no other way around (that usually implies variadic arguments)
>>>
>>> True in this specific case it might be over the top.
>>
>> It was a template parameter before anyway. Also, this is for acceptance/feature/integration testing, so I doubt anyone would care how much bloat it generates as long as it gets the job done.
>
> It will hurt build-times, so it's worth avoiding.

Normally I'd agree. But it'll take longer to run the server and the tests themselves than it'll take to build anyway, so it really doesn't matter that much.

Now, if it were for _unit_ tests... hmm, speaking of which I should probably try and optimise that for unit-threaded. But that means profiling the compiler I guess.

Atila
April 25, 2014
>> whilst bootstrapping the process and also for some tests I wrote for my
>> MQTT broker. I think this should work but I can't try it right

You have a MQTT broker? Free? Open-source? Can I haz teh code plx!