Skip to content

Commit

Permalink
Support parsing only specific unittests (e.g. @betterc-test)
Browse files Browse the repository at this point in the history
  • Loading branch information
wilzbach committed Jul 31, 2018
1 parent 28729b5 commit ca5384d
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 13 deletions.
6 changes: 4 additions & 2 deletions posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ $(ROOT)/tests_extractor: tests_extractor.d
################################################################################

test_tests_extractor: $(ROOT)/tests_extractor
$< -i ./test/tests_extractor/ascii.d | diff - ./test/tests_extractor/ascii.d.ext
$< -i ./test/tests_extractor/iteration.d | diff - ./test/tests_extractor/iteration.d.ext
for file in ascii iteration ; do \
$< -i "./test/tests_extractor/$${file}.d" | diff -p - "./test/tests_extractor/$${file}.d.ext"; \
done
$< -a betterc -i "./test/tests_extractor/attributes.d" | diff -p - "./test/tests_extractor/attributes.d.ext";

RDMD_TEST_COMPILERS = $(DMD)
RDMD_TEST_EXECUTABLE = $(ROOT)/rdmd
Expand Down
44 changes: 44 additions & 0 deletions test/tests_extractor/attributes.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module attributes;

enum betterc;

@betterc @safe @("foo") unittest
{
assert(1 == 1);
}

@safe @("foo") unittest
{
assert(2 == 2);
}

///
@("foo") unittest
{
assert(3 == 3);
}

@("foo") @betterc unittest
{
assert(4 == 4);
}

@("betterc") @([1, 2, 3]) unittest
{
assert(5 == 5);
}

@nogc @("foo", "betterc", "bar") @safe unittest
{
assert(6 == 6);
}

@nogc @("foo", "better", "bar") @safe unittest
{
assert(7 == 7);
}

@("betterd") unittest
{
assert(8 == 8);
}
32 changes: 32 additions & 0 deletions test/tests_extractor/attributes.d.ext
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# line 3
unittest
{
import attributes;

assert(1 == 1);
}

# line 19
unittest
{
import attributes;

assert(4 == 4);
}

# line 24
unittest
{
import attributes;

assert(5 == 5);
}

# line 29
unittest
{
import attributes;

assert(6 == 6);
}

66 changes: 55 additions & 11 deletions tests_extractor.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependency "libdparse" version="~>0.8.0"
* Parses all public unittests that are visible on dlang.org
* (= annotated with three slashes)
*
* Copyright (C) 2017 by D Language Foundation
* Copyright (C) 2018 by D Language Foundation
*
* Author: Sebastian Wilzbach
*
Expand All @@ -33,11 +33,13 @@ class TestVisitor : ASTVisitor
File outFile;
ubyte[] sourceCode;
string moduleName;
string[] attributes;

this(File outFile, ubyte[] sourceCode)
this(File outFile, ubyte[] sourceCode, string[] attributes)
{
this.outFile = outFile;
this.sourceCode = sourceCode;
this.attributes = attributes;
}

alias visit = ASTVisitor.visit;
Expand All @@ -58,13 +60,51 @@ class TestVisitor : ASTVisitor

override void visit(const Declaration decl)
{
if (decl.unittest_ !is null && hasDdocHeader(sourceCode, decl))
if (decl.unittest_ !is null && shouldIncludeUnittest(decl))
print(decl.unittest_);

decl.accept(this);
}

private:

bool shouldIncludeUnittest(const Declaration decl)
{
if (!attributes.empty)
return filterForUDAs(decl);
else
return hasDdocHeader(sourceCode, decl);
}

bool filterForUDAs(const Declaration decl)
{
foreach (attr; decl.attributes)
{
// check for @myArg
if (attributes.canFind(attr.atAttribute.identifier.text))
return true;

// support @("myArg") too
if (auto argList = attr.atAttribute.argumentList)
{
foreach (arg; argList.items)
{
if (auto unaryExp = cast(UnaryExpression) arg)
if (auto primaryExp = unaryExp.primaryExpression)
{
auto attribute = primaryExp.primary.text;
if (attribute.length >= 2)
{
attribute = attribute[1 .. $ - 1];
if (attributes.canFind(attribute))
return true;
}
}
}
}
}
return false;
}
void print(const Unittest u)
{
/*
Expand Down Expand Up @@ -93,7 +133,7 @@ private:
}
}

void parseFile(File inFile, File outFile)
void parseFile(File inFile, File outFile, string[] attributes)
{
import dparse.lexer;
import dparse.parser : parseModule;
Expand All @@ -111,11 +151,11 @@ void parseFile(File inFile, File outFile)

RollbackAllocator rba;
auto m = parseModule(tokens.array, inFile.name, &rba);
auto visitor = new TestVisitor(outFile, sourceCode);
auto visitor = new TestVisitor(outFile, sourceCode, attributes);
visitor.visit(m);
}

void parseFileDir(string inputDir, string fileName, string outputDir)
void parseFileDir(string inputDir, string fileName, string outputDir, string[] attributes)
{
import std.path : buildPath, dirSeparator, buildNormalizedPath;

Expand All @@ -132,7 +172,7 @@ void parseFileDir(string inputDir, string fileName, string outputDir)
// convert the file path to a nice output file, e.g. std/uni.d -> std_uni.d
string outName = fileNameNormalized.replace(dirSeparator, "_");

parseFile(File(fileName), File(buildPath(outputDir, outName), "w"));
parseFile(File(fileName), File(buildPath(outputDir, outName), "w"), attributes);
}

void main(string[] args)
Expand All @@ -143,12 +183,15 @@ void main(string[] args)
string inputDir;
string outputDir = "./out";
string ignoredFilesStr;
string modulePrefix = "";
string modulePrefix;
string attributesStr;

auto helpInfo = getopt(args, config.required,
"inputdir|i", "Folder to start the recursive search for unittest blocks (can be a single file)", &inputDir,
"outputdir|o", "Folder to which the extracted test files should be saved (stdout for a single file)", &outputDir,
"ignore", "Comma-separated list of files to exclude (partial matching is supported)", &ignoredFilesStr);
"ignore", "Comma-separated list of files to exclude (partial matching is supported)", &ignoredFilesStr,
"attributes|a", "Comma-separated list of UDAs that the unittest should have", &attributesStr,
);

if (helpInfo.helpWanted)
{
Expand All @@ -162,6 +205,7 @@ to in the output directory.

inputDir = inputDir.asNormalizedPath.array;
Algebraic!(string, File) outputLocation = cast(string) outputDir.asNormalizedPath.array;
auto attributes = attributesStr.split(",");

if (!exists(outputDir))
mkdir(outputDir);
Expand Down Expand Up @@ -196,8 +240,8 @@ to in the output directory.
{
stderr.writeln("parsing ", file);
outputLocation.visit!(
(string outputFolder) => parseFileDir(inputDir, file, outputFolder),
(File outputFile) => parseFile(File(file.name, "r"), outputFile),
(string outputFolder) => parseFileDir(inputDir, file, outputFolder, attributes),
(File outputFile) => parseFile(File(file.name, "r"), outputFile, attributes),
);
}
else
Expand Down

0 comments on commit ca5384d

Please sign in to comment.