better assertions and __FILE__ (compile time functions)
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Wed Aug 22 15:31:53 PDT 2007
Bruce Adams wrote:
> Hi all,
> Still stuck. How do I get the template to include the name of a run-time variable at compile-time? Please somebody put me out of my misery.
>
> template assertEqual8(actual_, expected_)
> {
> const char[] assertEqual8(actual_ a_, expected_ e_) {
> return
> "mixin(assertEqual5!("[]
> ~actual_.stringof
> ~")("[]
> ~a_.stringof
> ~","[]
> ~e_.stringof
> ~"));"[];
> }
> }
> alias assertEqual8!(int, int) assertEqual9;
>
> unittest {
> // all fine
> // writes: "mixin(assertEqual5!(int)(a_,e_));" when var5, var6 wanted
> writefln(assertEqual9(var5,var6));
>
> // not allowed at CT :(
> mixin(assertEqual9(var5,var6))
> }
>
> UnitTest.d(246): Error: variable var5 is used before initialization
> UnitTest.d(246): Error: cannot evaluate assertEqual8(var5,var6) at compile time
> UnitTest.d(246): Error: argument to mixin must be a string, not (assertEqual8(va
> r5,var6))
>
>
> Bruce Adams Wrote:
>
>> Right, thanks. I'm nearly there.
>> Here's where I'm at:
>>
>> // for example only
>> void assertWrapper(char[] file_, uint line_) {
>> _d_assert(file_,line_);
>> }
>>
>> // the run-time assert part
>> void assertEqual(Type)(Type actual_, Type expected_,
>> char[] file_,
>> uint line_) {
>> if (actual_ != expected_) {
>> writefln("Equality assertion failed");
>> writefln("actual: '", actual_, "'");
>> writefln("expected: '", expected_, "'");
>> }
>> assertWrapper(file_,line_);
>> }
>>
>> const char[] assertEqual4(const char[] actualVar_, const char[] expectedVar_) {
>> return "assertEqual!(int)("[]
>> ~actualVar_
>> ~","[]
>> ~expectedVar_
>> ~",cast(char[])(__FILE__),__LINE__);"[];
>> }
>>
>> const char[] assertEqual5(T)(const char[] actualVar_, const char[] expectedVar_) {
>> return "assertEqual!("
>> ~typeof(T).stringof
>> ~")("[]
>> ~actualVar_
>> ~","[]
>> ~expectedVar_
>> ~",cast(char[])(__FILE__),__LINE__);"[];
>> }
>>
>> unittest {
>> // declare at run-time
>> const int var3 = 1;
>> const int var4 = 2;
>>
>> int var5 = 1;
>> int var6 = 2;
>>
>> // okay - but must give name of variables
>> writefln(assertEqual4("var5"[],"var6"[]));
>> mixin(assertEqual4("var5"[],"var6"[]));
>>
>> // must provide name and type
>> mixin(assertEqual5!(int)("var5"[],"var6"[]));
>>
>> // must provide name and type
>> mixin(assertEqual5!(typeof(var5))(var5.stringof,var6.stringof));
>> }
>>
>> I reckon "mixin(assertEqual(var5,var6));" should be possible but I haven't quite figured it out yet.
>>
>> Regards,
>>
>> Bruce.
>>
>>
>> Lutger Wrote:
>>
>> [Some helpful stuff]
>>
>
Try this...
void assertEqual (T) (T actual, T expected, char[] file, uint line) {
if (actual != expected) {
writeln("Equality assertion failed.");
writefln(" actual: '%s'", actual);
writefln(" expected: '%s'", expected);
_d_assert(file, line);
}
}
template MAssertEqual (alias actual, alias expected) {
const MAssertEqual =
`assertEqual(`
~actual.stringof~
`, `
~expected.stringof~
`, __FILE__, __LINE__);`
;
}
unittest {
int var5 = 1;
int var6 = 2;
mixin(MAssertEqual!(var5, var6)); // -> assertEqual(var5, var6, __FILE__, __LINE__);
}
Note: Untested.
-- Chris Nicholson-Sauls
More information about the Digitalmars-d-learn
mailing list