August 05, 2013
On Monday, 5 August 2013 at 18:15:22 UTC, Dicebot wrote:
> On Monday, 5 August 2013 at 17:30:38 UTC, monarch_dodra wrote:
>> static assert({int i; assert(i == 0;});
>
> enum i;
> static assert(i == 0);
>
> I am really struggling to understand the use case.
> D has a tool to force CTFE execution - `enum`. It has a tool for compile-time checks - `static assert`. Any possible compile-time test can be expressed via those. All assertCTFEable or similar tool adds is ability to save on some `static` markers.

You are working around the argument. The point is that some calls simply can't be reduced to a single call. How would you deal with testing "parse" then?

assertCTFEable!({ string s =  "1234abc"; assert(parse! int(s) ==  1234 && s == "abc"); });

The point is that you can write "native" runtime code, and then only CTFE test it once. It brings more than just "saving" on markers.

What about, for example:

assertCTFEable!({
    int i = 5;
    string s;
    while (i--)
        s ~= 'a';
    assert(s == "aaaaa");
});

And still, all of these are just simple cases.
August 05, 2013
On Monday, 5 August 2013 at 18:21:37 UTC, Dicebot wrote:
> On Monday, 5 August 2013 at 17:38:22 UTC, monarch_dodra wrote:
>> So sure, I guess that strictly speaking, no, D language doesn't have static unittests. However, when someone asks the question, if you just answer "No" without pointing out that the language allows this semantic:
>>
>> version(unittest) assertCTFEAble!({
>>    //YOUR CODE HERE
>> });
>>
>> Then I believe you are giving an incomplete answer.
>
> Well, the problem is, D does have static unit-tests in a form of `static assert`. But topic starter has immediately provided an example that shows that his understanding of "static unit-tests" is different one, making it pretty hard to reason about proper alternative.
>
> Even assertCTFEAble does not _exactly_ match what was asked here. Thus I feel the need to first ask about specific use case and only then propose any real solutions.
>
> So, yes, of course, it is incomplete - because question is incomplete and requires further clarification. Which is the main point.

Alright. I tend to try to give as much information as possible in answers, even when the question isn't completely clear, or it was not exactly what was asked. With some luck, I can provide enough information to get the question answered, or give enough background to provide better understanding. This may or may not be the best thing to do, and sometimes it may indeed be better to stop and ask for clarification.

I'll agree my answer is not 100% exact, but I feel it does bring something to the conversation. In any case, while it was a reply/quote to what you said, it was not meant as a rebutal to what you were saying.
August 05, 2013
On Monday, 5 August 2013 at 18:27:02 UTC, monarch_dodra wrote:
> ...

Saying "test CTFE function that mutates its arguments" would have been perfectly enough for me :) Okay, that makes sense, thanks for the explanation.
August 10, 2013
On 8/5/13, Bosak <bosak@gmail.com> wrote:
> Are compile-time unittests possible in D? Maybe something like:
>
> static unittest {
>      assert(2 == 1 + 1);
> }

Nope.

Interestingly, in git-head we now have the getUnitTests trait, however this won't allow us to call the tests at compile time, I get back:

Error: __unittestL5_1 cannot be interpreted at compile time, because it has no available source code

This trait is fairly new, so maybe we could expand on this to allow invoking the tests at compile time.

Note of course that fundamentally not all tests can be executed at compile-time (e.g. any kind of use of files makes them non-CTFE-able)
August 10, 2013
On 08/05/13 20:27, monarch_dodra wrote:
> On Monday, 5 August 2013 at 18:15:22 UTC, Dicebot wrote:
>> On Monday, 5 August 2013 at 17:30:38 UTC, monarch_dodra wrote:
>>> static assert({int i; assert(i == 0;});
>>
>> enum i;
>> static assert(i == 0);
>>
>> I am really struggling to understand the use case.
>> D has a tool to force CTFE execution - `enum`. It has a tool for compile-time checks - `static assert`. Any possible compile-time test can be expressed via those. All assertCTFEable or similar tool adds is ability to save on some `static` markers.
> 
> You are working around the argument. The point is that some calls simply can't be reduced to a single call. How would you deal with testing "parse" then?
> 
> assertCTFEable!({ string s =  "1234abc"; assert(parse! int(s) ==  1234 && s == "abc"); });
> 
> The point is that you can write "native" runtime code, and then only CTFE test it once. It brings more than just "saving" on markers.
> 
> What about, for example:
> 
> assertCTFEable!({
>     int i = 5;
>     string s;
>     while (i--)
>         s ~= 'a';
>     assert(s == "aaaaa");
> });
> 
> And still, all of these are just simple cases.

   static assert({
       int i = 5;
       string s;
       while (i--)
           s ~= 'a';
       return s == "aaaaa";
   }());

etc

artur
August 12, 2013
On 2013-08-05 16:24, Andrej Mitrovic wrote:

> Nope.
>
> Interestingly, in git-head we now have the getUnitTests trait, however
> this won't allow us to call the tests at compile time, I get back:
>
> Error: __unittestL5_1 cannot be interpreted at compile time, because
> it has no available source code
>
> This trait is fairly new, so maybe we could expand on this to allow
> invoking the tests at compile time.

It does work, at least when I added it:

http://forum.dlang.org/thread/ks1brj$1l6c$1@digitalmars.com

-- 
/Jacob Carlborg
August 12, 2013
On 8/12/13, Jacob Carlborg <doob@me.com> wrote:
> It does work, at least when I added it:
>
> http://forum.dlang.org/thread/ks1brj$1l6c$1@digitalmars.com

Hmm that does work! Looks like I must have hit some kind of bug somewhere, but I lost the sample code that failed. I'll report it if I run into it again.
August 17, 2013
monarch_dodra got my point. So a static unittest is just like a normal one, but it will be executed in compile time. And every assert in it is a static assert. They will be only used to test CTFE's results and to insure that all constants are initialized correctly.

I really think that this should be added to the language, because it doesn't break stuff and it is useful. And the 'static' keyword is already used in many places like module imports and ifs.
August 17, 2013
On 8/17/13, Borislav Kosharov <boby_dsm@abv.bg> wrote:
> I really think that this should be added to the language, because it doesn't break stuff and it is useful. And the 'static' keyword is already used in many places like module imports and ifs.

Have you tried using the new getUnitTests trait in the git-head version? If not it will be in the 2.064 release.

Btw such a 'static unittest' feature is certainly going to break code because static can be applied as a label, for example:

class C
{
static:
    void foo() { }

    unittest { /* Test the foo method. */ }   // suddenly evaluated at
compile-time
}
August 18, 2013
On Saturday, 17 August 2013 at 17:48:04 UTC, Andrej Mitrovic wrote:
> On 8/17/13, Borislav Kosharov <boby_dsm@abv.bg> wrote:
>> I really think that this should be added to the language, because
>> it doesn't break stuff and it is useful. And the 'static' keyword
>> is already used in many places like module imports and ifs.
>
> Have you tried using the new getUnitTests trait in the git-head
> version? If not it will be in the 2.064 release.
>
> Btw such a 'static unittest' feature is certainly going to break code
> because static can be applied as a label, for example:
>
> class C
> {
> static:
>     void foo() { }
>
>     unittest { /* Test the foo method. */ }   // suddenly evaluated at
> compile-time
> }

Oh I really haven't tough about that. Maybe, I will try this new trait. Or another solution is to add a compiler switch that will try to execute all the tests during compilation or something.