www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can we get unitests to not run with program start ?

reply deadalnix <deadalnix gmail.com> writes:
Seriously that makes no sense, almost everybody has it own hack 
to have a different main when building for unitests, and we look 
like clown.

We all like to talk about language feature and all, but 
seriously, this kind of thing is what hurts us the most. We kind 
of live with it because we all have our workaround here, but 
really, it looks stupid to anyone that don't the tricks, and 
really, it should looks silly to anyone that knows the trick.

Can I have my unittest build do not complain if there is no main 
and not run main ?
Oct 25 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wednesday, October 26, 2016 05:24:45 deadalnix via Digitalmars-d wrote:
 Seriously that makes no sense, almost everybody has it own hack
 to have a different main when building for unitests, and we look
 like clown.

 We all like to talk about language feature and all, but
 seriously, this kind of thing is what hurts us the most. We kind
 of live with it because we all have our workaround here, but
 really, it looks stupid to anyone that don't the tricks, and
 really, it should looks silly to anyone that knows the trick.

 Can I have my unittest build do not complain if there is no main
 and not run main ?
Ideally, the -unittest build would just replace main (whatever it was) or run something instead of main without actually starting main, and if there were no main, it wouldn't complain about the lack thereof. That being said, using -main when unit testing libraries and declaring main in applications to look something like version(unittest) void main() {} else int main(string[] args) {...} doesn't seem like all that big a deal to me. Not ideal, but not a big deal. Regardless, I really don't think that it ever makes sense to actually run main after running the unit tests. So, in that sense, what dmd does with -unittest is downright weird. I assume that it just seemed like the easiest way to integrate them though and that that's why it was done that way. And I wouldn't mind it if it were fixed so that declaring main for unit tests was not required and that main never actually ran after the unit tests. However, I bet that if we changed it, _someone_ would complain. Someone always does, even if the change makes perfect sense and the previous behavior didn't. - Jonathan M Davis
Oct 25 2016
next sibling parent deadalnix <deadalnix gmail.com> writes:
On Wednesday, 26 October 2016 at 05:32:51 UTC, Jonathan M Davis 
wrote:
 That being said, using -main when unit testing libraries and 
 declaring main in applications to look something like

 version(unittest) void main() {}
 else int main(string[] args) {...}

 doesn't seem like all that big a deal to me. Not ideal, but not 
 a big deal.
It is. once you need to put that in the file, there is a ton of automation that can't happen anymore. Also, to anyone outside this forum, it feels like this: https://www.youtube.com/watch?v=szdbKz5CyhA
 Regardless, I really don't think that it ever makes sense to 
 actually run main after running the unit tests. So, in that 
 sense, what dmd does with -unittest is downright weird.
It indeed never makes any sense to do it that way.
 However, I bet that if we changed it, _someone_ would complain. 
 Someone always does, even if the change makes perfect sense and 
 the previous behavior didn't.
Well obviously, but that's not a good reason.
Oct 25 2016
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 26 October 2016 at 05:32:51 UTC, Jonathan M Davis 
wrote:
 However, I bet that if we changed it, _someone_ would complain.
Let them complain. At some point, we gotta rip off the band aid, let it go, the past is in the past.
Oct 26 2016
prev sibling next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Wednesday, 26 October 2016 at 05:24:45 UTC, deadalnix wrote:
 Seriously that makes no sense, almost everybody has it own hack 
 to have a different main when building for unitests, and we 
 look like clown.
 [...]
 Can I have my unittest build do not complain if there is no 
 main and not run main ?
What would be possible is a "-fdmain" switch (force dummy main). Its role would be: if a functionDeclaration named "main" is present then this normal "main" is not used (technically erased from the AST or something like that). Then acts like "-main". If I understand correctly the real problem happens when modules have to be tested but the real program "main()" must be skipped. All the other scenarios can be handled easily. For example an IDE can lookup in the AST and automatically add "-main" when the "main" declaration misses (and obviously if "-unittest" is defined).
Oct 26 2016
next sibling parent reply pineapple <meapineapple gmail.com> writes:
On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:
 What would be possible is a "-fdmain" switch (force dummy 
 main). Its role would be: if a functionDeclaration named "main" 
 is present then this normal "main" is not used (technically 
 erased from the AST or something like that). Then acts like 
 "-main".
Just using `-main` has worked well enough for me
Oct 26 2016
parent Basile B. <b2.temp gmx.com> writes:
On Wednesday, 26 October 2016 at 09:22:23 UTC, pineapple wrote:
 On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:
 What would be possible is a "-fdmain" switch (force dummy 
 main). Its role would be: if a functionDeclaration named 
 "main" is present then this normal "main" is not used 
 (technically erased from the AST or something like that). Then 
 acts like "-main".
Just using `-main` has worked well enough for me
For me too but once again I think that the issue is when you wish to test functions defined in the module where's main() is declared and when the main() content should be skipped. In this case stuff like "version(unittest) return 0;" must be added at the beginning of the main().
Oct 26 2016
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:
 What would be possible is a "-fdmain" switch (force dummy main).
It should just be implied by -unittest! The only cast I'd be worried about is an explicit version(unittest) main() {}... then maybe the user wanted something special. And even then, meh, 99% of those cases are just fixing the broken default anyway. Otherwise, let's make the default sane.
Oct 26 2016
next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 10/26/2016 09:25 AM, Adam D. Ruppe wrote:
 On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:
 What would be possible is a "-fdmain" switch (force dummy main).
It should just be implied by -unittest! The only cast I'd be worried about is an explicit version(unittest) main() {}... then maybe the user wanted something special. And even then, meh, 99% of those cases are just fixing the broken default anyway. Otherwise, let's make the default sane.
+1
Oct 26 2016
parent reply Timothee Cour via Digitalmars-d <digitalmars-d puremagic.com> writes:
 It should just be implied by -unittest!
+1 On Wed, Oct 26, 2016 at 7:49 AM, Nick Sabalausky via Digitalmars-d < digitalmars-d puremagic.com> wrote:
 On 10/26/2016 09:25 AM, Adam D. Ruppe wrote:

 On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:

 What would be possible is a "-fdmain" switch (force dummy main).
It should just be implied by -unittest! The only cast I'd be worried about is an explicit version(unittest) main() {}... then maybe the user wanted something special. And even then, meh, 99% of those cases are just fixing the broken default anyway. Otherwise, let's make the default sane.
+1
Oct 26 2016
parent reply Basile B. <b2.temp gmx.com> writes:
On Wednesday, 26 October 2016 at 16:12:26 UTC, Timothee Cour 
wrote:
 It should just be implied by -unittest!
+1 On Wed, Oct 26, 2016 at 7:49 AM, Nick Sabalausky via Digitalmars-d < digitalmars-d puremagic.com> wrote:
 On 10/26/2016 09:25 AM, Adam D. Ruppe wrote:

 On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. 
 wrote:

 What would be possible is a "-fdmain" switch (force dummy 
 main).
It should just be implied by -unittest! The only cast I'd be worried about is an explicit version(unittest) main() {}... then maybe the user wanted something special. And even then, meh, 99% of those cases are just fixing the broken default anyway. Otherwise, let's make the default sane.
+1
It looks fairly simple to do in dmd, like this (with breakage in case the user-defined main() did something useful): 1. deactivate the main functionDeclaration un funcs.d .... final bool isMain() { return ident == Id.main && linkage != LINKc && !isMember() && !isNested() && !global.params.useUnitTests; } ... 2. forces -main in params.d: ... else if (strcmp(p + 1, "unittest") == 0) { global.params.useUnitTests = true; global.params.addMain = true; } ... I see no reason to discuss much about this. People that are pro should just agree on how this should be done and someone makes a PR. Maybe the little issue would be with LDMD2 and GDMD. Since these programs are just bridges they cannot do point 1, and LDC2 and GDC would have to follow this behavior.
Oct 26 2016
parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 26 October 2016 at 21:57:59 UTC, Basile B. wrote:
 It looks fairly simple to do in dmd, like this (with breakage 
 in case the user-defined main() did something useful):

 1. deactivate the main functionDeclaration un funcs.d

 ....
 final bool isMain()
 {
    return ident == Id.main && linkage != LINKc && !isMember() 
 && !isNested()
     && !global.params.useUnitTests;
 }
 ...

 2. forces -main in params.d:

 ...
 else if (strcmp(p + 1, "unittest") == 0)
 {
     global.params.useUnitTests = true;
     global.params.addMain = true;
 }
 ...

 I see no reason to discuss much about this. People that are pro 
 should just agree on how this should be done and someone makes 
 a PR.

 Maybe the little issue would be with LDMD2 and GDMD. Since 
 these programs are just bridges they cannot do point 1, and 
 LDC2 and GDC would have to follow this behavior.
I tried that and it doesn't work. addMain actualy just inject a main function as a mixin in the module. Yes this is a string, it is parsed and all. The problem is that this function that is injected is then not wired in as main, because isMain returns false. Any tips appreciated.
Nov 17 2016
parent Basile B. <b2.temp gmx.com> writes:
On Friday, 18 November 2016 at 07:51:35 UTC, deadalnix wrote:
 On Wednesday, 26 October 2016 at 21:57:59 UTC, Basile B. wrote:
 It looks fairly simple to do in dmd, like this (with breakage 
 in case the user-defined main() did something useful):

 1. deactivate the main functionDeclaration un funcs.d
 [...]
 2. forces -main in params.d:
 [...]
 I see no reason to discuss much about this. People that are 
 pro should just agree on how this should be done and someone 
 makes a PR.

 Maybe the little issue would be with LDMD2 and GDMD. Since 
 these programs are just bridges they cannot do point 1, and 
 LDC2 and GDC would have to follow this behavior.
I tried that and it doesn't work. addMain actualy just inject a main function as a mixin in the module. Yes this is a string, it is parsed and all.
Sorry to learn that. To be honest I didn't try. For now and since three or four months I use an IDE solution. It detects the main() function and sets the -main switch accordingly. Anyway I would prefer something similar directly in the compiler.
 The problem is that this function that is injected is then not 
 wired in as main, because isMain returns false.

 Any tips appreciated.
Nov 18 2016
prev sibling parent reply =?UTF-8?Q?S=c3=b6nke_Ludwig?= <sludwig outerproduct.org> writes:
Am 26.10.2016 um 15:25 schrieb Adam D. Ruppe:
 On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote:
 What would be possible is a "-fdmain" switch (force dummy main).
It should just be implied by -unittest! The only cast I'd be worried about is an explicit version(unittest) main() {}... then maybe the user wanted something special. And even then, meh, 99% of those cases are just fixing the broken default anyway. Otherwise, let's make the default sane.
How would a custom unit test runner such as "unit-threaded" or "tested" work in that case?
Oct 26 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 26 October 2016 at 16:08:23 UTC, Sönke Ludwig wrote:
 How would a custom unit test runner such as "unit-threaded" or 
 "tested" work in that case?
http://dpldocs.info/experimental-docs/core.runtime.Runtime.moduleUnitTester.1.html http://dlang.org/phobos/core_runtime.html#.Runtime.moduleUnitTester
Oct 26 2016
parent reply =?UTF-8?Q?S=c3=b6nke_Ludwig?= <sludwig outerproduct.org> writes:
Am 26.10.2016 um 18:32 schrieb Adam D. Ruppe:
 On Wednesday, 26 October 2016 at 16:08:23 UTC, Sönke Ludwig wrote:
 How would a custom unit test runner such as "unit-threaded" or
 "tested" work in that case?
http://dpldocs.info/experimental-docs/core.runtime.Runtime.moduleUnitTester.1.html http://dlang.org/phobos/core_runtime.html#.Runtime.moduleUnitTester
Thanks, that should work! I misremembered this as getting called once per module, which would have been insufficient.
Oct 26 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 26 October 2016 at 17:47:51 UTC, Sönke Ludwig wrote:
 I misremembered this as getting called once per module, which 
 would have been insufficient.
Yeah, I don't love the name either. But you should be able to set that in a static module ctor in your library (bonus points, even compare the old against the default and have a runtime warning about combining two incompatible test libraries) then go nuts with it. I think currently the ModuleInfo unittests property combines all of them into a single function, so to get more granularity, you have to do CT reflection, which means listing all the modules... which kinda sucks right now. It might be nice some day to make that easier. Separate out the runtime thing to return function array instead of one combined function, and perhaps some kind of assistance in walking the whole program import graph. Regardless, unittests without main() should be perfectly doable today!
Oct 26 2016
parent =?UTF-8?Q?S=c3=b6nke_Ludwig?= <sludwig outerproduct.org> writes:
Am 26.10.2016 um 19:58 schrieb Adam D. Ruppe:
 On Wednesday, 26 October 2016 at 17:47:51 UTC, Sönke Ludwig wrote:
 I misremembered this as getting called once per module, which would
 have been insufficient.
Yeah, I don't love the name either. But you should be able to set that in a static module ctor in your library (bonus points, even compare the old against the default and have a runtime warning about combining two incompatible test libraries) then go nuts with it. I think currently the ModuleInfo unittests property combines all of them into a single function, so to get more granularity, you have to do CT reflection, which means listing all the modules... which kinda sucks right now. It might be nice some day to make that easier. Separate out the runtime thing to return function array instead of one combined function, and perhaps some kind of assistance in walking the whole program import graph. Regardless, unittests without main() should be perfectly doable today!
Yeah, for being able to enumerate the modules, DUB in fact generates a special module if a custom unit test runner is used (well, actually it is currently tied to the "tested" runner for historic reasons, which should really be changed).
Oct 26 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/26/16 1:24 AM, deadalnix wrote:
 Seriously that makes no sense, almost everybody has it own hack to have
 a different main when building for unitests, and we look like clown.

 We all like to talk about language feature and all, but seriously, this
 kind of thing is what hurts us the most. We kind of live with it because
 we all have our workaround here, but really, it looks stupid to anyone
 that don't the tricks, and really, it should looks silly to anyone that
 knows the trick.

 Can I have my unittest build do not complain if there is no main and not
 run main ?
I'm with you 100%. This isn't even that hard, and doesn't require DMD changes. The runtime can exit if it runs any unit tests before calling main. -Steve
Oct 27 2016
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/27/16 9:09 AM, Steven Schveighoffer wrote:
 On 10/26/16 1:24 AM, deadalnix wrote:
 Seriously that makes no sense, almost everybody has it own hack to have
 a different main when building for unitests, and we look like clown.

 We all like to talk about language feature and all, but seriously, this
 kind of thing is what hurts us the most. We kind of live with it because
 we all have our workaround here, but really, it looks stupid to anyone
 that don't the tricks, and really, it should looks silly to anyone that
 knows the trick.

 Can I have my unittest build do not complain if there is no main and not
 run main ?
I'm with you 100%. This isn't even that hard, and doesn't require DMD changes. The runtime can exit if it runs any unit tests before calling main.
This was pretty easy, please review/comment: https://github.com/dlang/druntime/pull/1685 -Steve
Oct 27 2016