Skip to content

Commit eae2ed4

Browse files
committed
Fix Issue 17501 - Runnable unittest problem with AST rewrite
1 parent d3569b3 commit eae2ed4

File tree

1 file changed

+90
-15
lines changed

1 file changed

+90
-15
lines changed

assert_writeln_magic.d

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@ private string formatNode(T)(const T t)
4343
return writer.data;
4444
}
4545

46-
class TestVisitor : ASTVisitor
46+
class TestVisitor(Out) : ASTVisitor
4747
{
4848
import dparse.lexer : tok, Token;
4949

50-
this(string fileName, string destFile)
50+
this(Out fl)
5151
{
52-
this.fileName = fileName;
53-
fl = FileLines(fileName, destFile);
52+
this.fl = fl;
5453
}
5554

5655
alias visit = ASTVisitor.visit;
@@ -77,6 +76,10 @@ class TestVisitor : ASTVisitor
7776
if (inFunctionCall)
7877
return;
7978

79+
// only look at `a == b` within the AssertExpression
80+
if (typeid(expr.assertion) != typeid(CmpExpression))
81+
return;
82+
8083
lastAssert = expr;
8184
inAssert = true;
8285
expr.accept(this);
@@ -172,15 +175,26 @@ private:
172175
Rebindable!(const AssertExpression) lastAssert;
173176
Rebindable!(const EqualExpression) lastEqualExpression;
174177

175-
string fileName;
176-
FileLines fl;
178+
Out fl;
177179
}
178180

179-
void parseFile(string fileName, string destFile)
181+
void parseString(Visitor)(ubyte[] sourceCode, string fileName, Visitor visitor)
180182
{
181183
import dparse.lexer;
182184
import dparse.parser : parseModule;
183185
import dparse.rollback_allocator : RollbackAllocator;
186+
187+
LexerConfig config;
188+
auto cache = StringCache(StringCache.defaultBucketCount);
189+
const(Token)[] tokens = getTokensForParser(sourceCode, config, &cache).array;
190+
191+
RollbackAllocator rba;
192+
auto m = parseModule(tokens, fileName, &rba);
193+
visitor.visit(m);
194+
}
195+
196+
void parseFile(string fileName, string destFile)
197+
{
184198
import std.array : uninitializedArray;
185199

186200
auto inFile = File(fileName);
@@ -192,14 +206,9 @@ void parseFile(string fileName, string destFile)
192206
return;
193207

194208
inFile.rawRead(sourceCode);
195-
LexerConfig config;
196-
auto cache = StringCache(StringCache.defaultBucketCount);
197-
const(Token)[] tokens = getTokensForParser(sourceCode, config, &cache).array;
198-
199-
RollbackAllocator rba;
200-
auto m = parseModule(tokens, fileName, &rba);
201-
auto visitor = new TestVisitor(fileName, destFile);
202-
visitor.visit(m);
209+
auto fl = FileLines(fileName, destFile);
210+
auto visitor = new TestVisitor!(typeof(fl))(fl);
211+
parseString(sourceCode, fileName, visitor);
203212
delete visitor;
204213
}
205214

@@ -211,6 +220,7 @@ string rebasePath(string path, string oldBase, string newBase)
211220
return buildPath(newBase, path.absolutePath.relativePath(oldBase.absolutePath));
212221
}
213222

223+
version(unittest) { void main(){} } else
214224
void main(string[] args)
215225
{
216226
import std.file;
@@ -324,3 +334,68 @@ struct FileLines
324334
lines[i] = line;
325335
}
326336
}
337+
338+
version(unittest)
339+
{
340+
struct FileLinesMock
341+
{
342+
string[] lines;
343+
string opIndex(size_t i) { return lines[i]; }
344+
void opIndexAssign(string line, size_t i) {
345+
lines[i] = line;
346+
}
347+
}
348+
auto runTest(string sourceCode)
349+
{
350+
import std.string : representation;
351+
auto mock = FileLinesMock(sourceCode.split("\n"));
352+
auto visitor = new TestVisitor!(typeof(mock))(mock);
353+
parseString(sourceCode.representation.dup, "testmodule", visitor);
354+
delete visitor;
355+
return mock;
356+
}
357+
}
358+
359+
360+
unittest
361+
{
362+
"Running tests for assert_writeln_magic".writeln;
363+
364+
// purposefully not indented
365+
string testCode = q{
366+
unittest
367+
{
368+
assert(equal(splitter!(a => a == ' ')("hello world"), [ "hello", "", "world" ]));
369+
assert(equal(splitter!(a => a == 0)(a), w));
370+
}
371+
};
372+
auto res = runTest(testCode);
373+
assert(res.lines[3 .. $ - 2] == [
374+
"assert(equal(splitter!(a => a == ' ')(\"hello world\"), [ \"hello\", \"\", \"world\" ]));",
375+
"assert(equal(splitter!(a => a == 0)(a), w));"
376+
]);
377+
}
378+
379+
unittest
380+
{
381+
string testCode = q{
382+
unittest
383+
{
384+
assert(1 == 2);
385+
assert(foo() == "bar");
386+
assert(foo() == bar);
387+
assert(arr == [0, 1, 2]);
388+
assert(r.back == 1);
389+
}
390+
};
391+
auto res = runTest(testCode);
392+
assert(res.lines[3 .. $ - 2] == [
393+
"writeln(1); // 2",
394+
"writeln(foo()); // \"bar\"",
395+
"writeln(foo()); // bar",
396+
"writeln(arr); // [0, 1, 2]",
397+
"writeln(r.back); // 1",
398+
]);
399+
400+
"Successfully ran tests for assert_writeln_magic".writeln;
401+
}

0 commit comments

Comments
 (0)