On Monday, April 02, 2018 12:55:05 H. S. Teoh via Digitalmars-d wrote: > On Mon, Apr 02, 2018 at 03:28:02PM -0400, Steven Schveighoffer via > Digitalmars-d wrote: [...] > > > We really need to change the unittest import strategy. > > [...] > > I think this has been established beyond reasonable doubt for the last > little while. What about we start hashing out a solution? > > AFAIK, the current proposal is to make it so that `-unittest` only takes > effect on modules that are being compiled (i.e., specified on the > command-line). Imported modules will *not* have unittests compiled, > unless they have also been specified on the command-line. > > The only thing blocking this proposal that I'm aware of, is that it will > break __traits(getUnitTests). But I'm not sure if that's actually a > serious problem at all. What if we make it so that a unittest block in > an imported module that isn't specified on the command-line is basically > treated as a template? I.e., parse the AST, but don't do anything with > it. Don't bother running semantic, don't bother resolving identifiers > (in particular, import statements inside the unittest), etc.. Just leave > it in the AST as essentially translated syntax. Then if > __traits(getUnitTests) is ever invoked, run semantic on the unittests in > the targeted module. > > I'm not 100% certain, but I have a suspicion that this will mitigate the > breakage to __traits(getUnitTests) without compromising on the "don't > compile unittests outside the current list of modules to compile" fix.
Having never used __traits(getUnitTest), I'm not very familiar with it, but depending on what it does, it might be enough to register the fact that a unittest block exists in the file, and then the unittest block itself only needs to be analyzed enough to parse passed it. But I don't know. I'll have to study up on what it does exactly to say much intelligent about it. One concern I have is version(unittest) blocks. In order to avoid code breakage, those would need to still be compiled in. I know that I've personally used version(unittest) blocks that had package access level and were then imported in the unit tests within that package in order to avoid declaring helper types or functions in each module. So, treating version(unittest) blocks like they're not there when importing a module would definitely break som existing code. It could be argued that such uses should be deprecated in some manner, but simply not compiling in anything related to -unittest in imported modules would be a problem. However, aside from maybe __traits(getUnitTests), I don't see why it would be a problem to ignore code inside a unittest block except for when that module is being compiled (or when that unittest block is inside a template that's being compiled). - Jonathan M Davis