www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Probably a trivial question regarding version identifier and unittest

reply WhatMeWorry <kheaser gmail.com> writes:
I'm trying to study Adam Ruppe's terminal.d sub-package and I see 
the following code segment:

version(demos) unittest
{
     import arsd.terminal;

     void main()
     {
         // . . .
     }

     main; // exclude from docs
}

Looks like a good baby step to take, so in the command line I use:

C:\dub\path\to\arsdpackage\arsd-official>dmd terminal.d -unittest 
-version=demos
OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Warning 134: No Start Address


Shouldn't the version identifier demos and the unittest option 
activate the test block and therefore defines main() which then 
give the "Start Address"?

Also, what is the isolated main; command right after the main 
function?
May 11 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/11/20 9:54 PM, WhatMeWorry wrote:
 
 I'm trying to study Adam Ruppe's terminal.d sub-package and I see the 
 following code segment:
 
 version(demos) unittest
 {
      import arsd.terminal;
 
      void main()
      {
          // . . .
      }
 
      main; // exclude from docs
 }
 
 Looks like a good baby step to take, so in the command line I use:
 
 C:\dub\path\to\arsdpackage\arsd-official>dmd terminal.d -unittest 
 -version=demos
 OPTLINK (R) for Win32  Release 8.00.17
 Copyright (C) Digital Mars 1989-2013  All rights reserved.
 http://www.digitalmars.com/ctg/optlink.html
 OPTLINK : Warning 134: No Start Address
 
 
 Shouldn't the version identifier demos and the unittest option activate 
 the test block and therefore defines main() which then give the "Start 
 Address"?
That is not a global main, it is inside a unittest block. A unittest block is actually a function. So the main there is a nested function, and not the one that D declares as the entry point.
 Also, what is the isolated main; command right after the main function?
It's calling the inner function. But I'm sure you would realize that if you knew that it's not the true main function. -Steve
May 11 2020
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 May 2020 at 01:54:49 UTC, WhatMeWorry wrote:
 version(demos) unittest
 {
     import arsd.terminal;

     void main()

 Shouldn't the version identifier demos and the unittest option 
 activate the test block and therefore defines main() which then 
 give the "Start Address"?
The unittest {} block is actually a special syntax for a function. So the main function in here is a *nested* function inside the unittest function and thus doesn't count as a starting point. It is like if you defined void MyTest() { void main() {} } The main there is a nested local helper function and thus wouldn't count as a start point either.
 Also, what is the isolated main; command right after the main 
 function?
That's just calling the defined child function so it actually gets executed. (I didn't put the parens there, but you could: `main();`, to make it clear it is just calling the function. You can compile and run the tests btw with the command line: dmd terminal.d -unittest -version=demos -main the -main option at the end tells the compiler to add an empty main() function at top-level for you to satisfy the linker. The reason I wrote it all this way is for the documentation. Look here for an example of how it looks when it is rendered: http://dpldocs.info/experimental-docs/arsd.terminal.html#color The documentation version there is a complete function my readers can copy/paste in their own files to use as a starting point. (the "// exclude from docs" comment is actually recognized by my doc generator to skip that line, see: http://dpldocs.info/experimental-docs/adrdox.syntax.html#documented-unittests which lets me tweak the user-visible output while still keeping it machine-checked internally too.) Now, why is it in a unittest block? Because then the samples are easier for me to compile and run as a batch to help me make sure they still work. (This isn't exactly perfect - since they are still defined in the module, they can see private members and imports, so it is still possible it will work for me but not for my readers. But it makes it less likely to it that problem.) Lastly, why is it in a demos block? That's just because normal unit tests are not supposed to be interactive and these are (interactive things make better doc samples). So the version block makes sure they are not run accidentally like by a user doing `dub test` at an outer layer. You have to opt into running these blocks by adding the version flag to the build too. You can really see this in simpledisplay.d's docs that have full sample games you can copy/paste and tweak! http://dpldocs.info/experimental-docs/arsd.simpledisplay.html#pong source: http://dpldocs.info/experimental-docs/source/arsd.simpledisplay.d.html#L492 except yikes I forgot to put the version thing there! so someone dub testing simpledisplay will have to play through a round of pong and minesweeper to pass the tests :P lol
May 11 2020
parent WhatMe Worry <kheaser gmail.com> writes:
On Tuesday, 12 May 2020 at 02:17:36 UTC, Adam D. Ruppe wrote:
 On Tuesday, 12 May 2020 at 01:54:49 UTC, WhatMeWorry wrote:
 [...]
The unittest {} block is actually a special syntax for a function. So the main function in here is a *nested* function inside the unittest function and thus doesn't count as a starting point. It is like if you defined [...]
This is gold! I've been poking around and reading for days, but you've gotten me further with just a few paragraphs. Cant thank you enough.
May 11 2020