-
-
Notifications
You must be signed in to change notification settings - Fork 610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for inner unittests #18696
Labels
Comments
witold.baryluk+d (@baryluk) commented on 2021-05-28T00:09:17ZI agree, this would be useful. I often created inner functions or inner structs in functions, as mini helpers. They are self contained, and only used in one place, so they can be tested on their own, but I don't want to pollute the module level symbols with it, which makes unittesting them harder.
I think it should only be allowed to be attached to static nested functions,
or when running otherwise, should only have access to static functions.
This probably also should apply to the nested structs and nested static classes, and nested static structs.
Using it for non-static nested functions or aggregates, doesn't make sense, because they can have access to some dynamic state, that is not available before the program starts or executes these functions and initializes the dynamic state.
The only issue I can think of it how to deal with instance of unittests in templated functions and classes. This could create many "duplicates" of the unittest, but it actually could be something good and intended.
So for example maybe these two things only for the start:
void main() {
static int sqr(int x) { return x * x; }
unittest {
assert(sqr(3) == 9);
}
}
class A {
static class HelperClass {
int y = 2;
int m(int x) { return x * y; }
}
unittest {
auto c = new HelperClass();
assert(c.m(3) == 6);
}
}
In the second case, maybe the unittest should be inside the nested class itself maybe, or maybe it should have `static` prefix or something.
Named unittests should also work, and probably full name should be a scoped path (i.e. `mod1.main.sqr.unittest.myunittest1`, `mod1.A.HelperClass.myunittest1`). |
witold.baryluk+d (@baryluk) commented on 2021-05-28T00:39:25ZOne would think that it might be possible to access nested static functions using some naming tricks, from outside, like this:
```d
int bar(int a) {
static int d;
static int foo(int b) {
b = d;
return b + 1;
}
return foo(a);
}
unittest {
alias foo = bar.foo;
assert(foo(5) == 6);
}
```
but this have two issues that I can think of:
1) nested static functions can access nested static variables, other nested functions (including themselves), and globals. That can be problematic for unittesting.
2) It is possible to create multiple nested functions with the same name (not just function overloads), for example:
```d
int bar(int a) {
static int d;
if (a > 10) {
static int foo(int b) {
b = d;
return b + 1;
}
return foo(a);
} else {
static int foo(int b) {
b += d * 100;
return b + 100;
}
return foo(a);
}
}
unittest {
bar.foo // refers to which foo?
}
```
or make multiple different symbols with the same name:
```d
int bar(int a) {
static int d;
if (a > 10) {
static int foo(int b) {
b = d;
return b + 1;
}
return foo(a);
} else {
int foo = 5;
return foo + a;
}
}
unittest {
bar.foo // refers to what?
}
```
So, that is going to be too complex and require too much ambiguity.
Directly nested unittest makes this obvious and explicit, by using local scoping rules and lookup:
```
int bar(int a) {
static int d;
if (a > 10) {
static int foo(int b) {
b = d;
return b + 1;
}
unittest {
d = 42;
assert(foo(137) == 43);
}
return foo(a);
} else {
static int foo(int b) {
b += d * 100;
return b + 100;
}
unittest {
d = 1;
assert(foo(137) == 337);
}
return foo(a);
}
}
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bearophile_hugs reported this on 2013-10-14T02:55:43Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=11255
CC List
Description
void main() { int sqr(int x) { return x ^^ 2; } unittest { assert(sqr(3) == 9); } } dmd 2.064beta gives: test.d(3): Error: found 'unittest' instead of statement test.d(6): Error: unrecognized declaration This is kind of necessary to make nested functions usable in real code, because in some cases you can't avoid writing some unit tests for a function.The text was updated successfully, but these errors were encountered: