digitalmars.D.learn - Unttests for nested functions
- BCS (24/24) May 27 2006 how do I unittest bar?
- BCS (29/53) May 27 2006 OK, after think about it for a while, I have come up with a possible sol...
- Derek Parnell (37/38) May 28 2006 Currently one can't directly test it using unit tests, however on the
- BCS (4/9) May 29 2006 that is what I was expecting. :P Any thoughts on how to make it so you ...
- Derek Parnell (14/27) May 29 2006 The obvious way would be to allow unit test blocks to be nested inside
- Daniel Keep (73/86) May 29 2006 I suppose the problem is that the inner function is inseperable from the
- BCS (8/15) May 30 2006 That's about what I was thinking.
how do I unittest bar? int foo(int i) { int j=0; int bar(int k) ////////// { j+=k; } /+ cant make unit test here unittest { bar(0); } +/ while(i); bar(i--); return j; } /+ cant access nested function here unittest { bar(0); } +/
May 27 2006
OK, after think about it for a while, I have come up with a possible solution. It amounts to a small change to the semantics of D, and (maybe, depending on the implementation) a little quirk in the code generator. First from the semantic standpoint, allow a unittest inside of a function. Just like in a normal nested function, the unit test will have access to the variables in the other function. Secondly, when implementing this unittest, a fake stack frame is generated for the function it is nested inside of. That way the unittest can have a context to call the nested function with. This stack frame could be the first part of the unittest's stack frame in such a way the calling the nested function from the unittest works just like calling it from it's enclosing function. A purposeless example: void fn() { int i; void nf() { i--; } unittest { i=2; nf(); assert(1==i); } i=10; while(i) nf(); } In article <e5b2u0$1ncl$1 digitaldaemon.com>, BCS says...how do I unittest bar? int foo(int i) { int j=0; int bar(int k) ////////// { j+=k; } /+ cant make unit test here unittest { bar(0); } +/ while(i); bar(i--); return j; } /+ cant access nested function here unittest { bar(0); } +/
May 27 2006
On Sun, 28 May 2006 02:46:24 +0000 (UTC), BCS wrote:how do I unittest bar?Currently one can't directly test it using unit tests, however on the assumption that the outer function uses the inner function I guess you can test it indirectly, plus you can also use inner asserts and DbC. int foo(int i) { int j=0; int bar(int k) out(x) { assert( x == j - k); } body { int ov = j; j += k; return ov; // The old value. } while(i) bar(i--); return j; } unittest { assert (foo(0) == 0); assert (foo(1) == 1); assert (foo(10) == 55); } void main() { } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 29/05/2006 10:38:21 AM
May 28 2006
that is what I was expecting. :P Any thoughts on how to make it so you can? (ref. my second post) In article <1o4n88vezpkym$.1cj5tqvwrl0up$.dlg 40tude.net>, Derek Parnell says...On Sun, 28 May 2006 02:46:24 +0000 (UTC), BCS wrote:[...]how do I unittest bar?Currently one can't directly test it using unit tests, however on the assumption that the outer function uses the inner function I guess you can test it indirectly, plus you can also use inner asserts and DbC.
May 29 2006
On Mon, 29 May 2006 23:15:00 +0000 (UTC), BCS wrote:that is what I was expecting. :P Any thoughts on how to make it so you can? (ref. my second post) In article <1o4n88vezpkym$.1cj5tqvwrl0up$.dlg 40tude.net>, Derek Parnell says...The obvious way would be to allow unit test blocks to be nested inside functions, classes, and structs too. And if we are going that way, allow 'import' statements to allowed inside unit test blocks. Yes, I know there are technical issues to solve but Walter's a smart cookie and will be able to solve them to the benefit of the D language. If D wants to have a few differentiating points then comprehensive DbC and quality control is a good place to start. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 30/05/2006 9:45:48 AMOn Sun, 28 May 2006 02:46:24 +0000 (UTC), BCS wrote:[...]how do I unittest bar?Currently one can't directly test it using unit tests, however on the assumption that the outer function uses the inner function I guess you can test it indirectly, plus you can also use inner asserts and DbC.
May 29 2006
I suppose the problem is that the inner function is inseperable from the outer function. Since the inner function shares the outer function's stack, you can't really call it without the outer function. The problem here is that unittests are run on program *startup*. That means that in order those unittests inside a function, it would have to... uh... I dunno; maybe "fake" the function's stack. But then you just end up with random garbage data in the inner function. The one idea I *could* come up with was this: firstly, pull the inner function out into a template. Then, in your unittest, mix the template into a dummy stub function whose only job is to call the inner function and return it's result. So your example: Would become something like: Please note that I have *not* tested the above. Should work... the only possible problem would be if the template wants a proper reference to 'j' (in that case, just pass it in as an alias). Hope this helps. -- Daniel BCS wrote:that is what I was expecting. :P Any thoughts on how to make it so you can? (ref. my second post) In article <1o4n88vezpkym$.1cj5tqvwrl0up$.dlg 40tude.net>, Derek Parnell says...-- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/On Sun, 28 May 2006 02:46:24 +0000 (UTC), BCS wrote:[...]how do I unittest bar?Currently one can't directly test it using unit tests, however on the assumption that the outer function uses the inner function I guess you can test it indirectly, plus you can also use inner asserts and DbC.
May 29 2006
That's about what I was thinking. Really all that is needed is a chunk of memory that the unittest can manipulate and pass off to the nested function. It's own stack frame would do as long as all of the variables from the other function are mapped the same (&i == FramePointer + TheSameSomethin in both functions). I'm not sure where variable alignment is decided, so I don't know how hard this would be to implement, but it's not that complicated conceptually. In article <e5gl5v$2icg$1 digitaldaemon.com>, Daniel Keep says...I suppose the problem is that the inner function is inseperable from the outer function. Since the inner function shares the outer function's stack, you can't really call it without the outer function. The problem here is that unittests are run on program *startup*. That means that in order those unittests inside a function, it would have to... uh... I dunno; maybe "fake" the function's stack. But then you just end up with random garbage data in the inner function.
May 30 2006