test: added GraphFilter and GraphFilterConductor tests
This commit is contained in:
@@ -4,6 +4,36 @@ Node.cpp WARNING: Cannot change NodeType after it was already set from namespace
|
||||
Edge.cpp ERROR: Nodes are not plain copies.
|
||||
Graph.cpp ERROR: Can't remove member edge, without removing the child node.
|
||||
Edge.cpp ERROR: Edge call can't go from Node undefined to Node undefined
|
||||
Storage.cpp INFO: class: A <input.cc 1:7 1:7>
|
||||
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
|
||||
Storage.cpp INFO: global usage: A::A -> A::count <input.cc 5:3 5:7>
|
||||
Storage.cpp INFO: method: A::getCount <input.cc 8:13 8:20>
|
||||
Storage.cpp INFO: global usage: A::getCount -> A::count <input.cc 10:10 10:14>
|
||||
Storage.cpp INFO: method: A::process <input.cc 14:15 14:21>
|
||||
Storage.cpp INFO: field: A::count <input.cc 17:13 17:17>
|
||||
Storage.cpp INFO: class: B <input.cc 20:7 20:7>
|
||||
Storage.cpp INFO: inheritance: B : A <input.cc 21:4 21:11>
|
||||
Storage.cpp INFO: method: B::process <input.cc 24:15 24:21>
|
||||
Storage.cpp INFO: type usage: B::process -> int <input.cc 26:3 26:5>
|
||||
Storage.cpp INFO: function: main <input.cc 30:5 30:8>
|
||||
Storage.cpp INFO: type usage: main -> B <input.cc 32:2 32:2>
|
||||
Storage.cpp INFO: call: main -> B::B <input.cc 32:4 32:4>
|
||||
Storage.cpp INFO: call: main -> A::getCount <input.cc 34:9 34:21>
|
||||
Storage.cpp INFO: class: A <input.cc 1:7 1:7>
|
||||
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
|
||||
Storage.cpp INFO: global usage: A::A -> A::count <input.cc 5:3 5:7>
|
||||
Storage.cpp INFO: method: A::getCount <input.cc 8:13 8:20>
|
||||
Storage.cpp INFO: global usage: A::getCount -> A::count <input.cc 10:10 10:14>
|
||||
Storage.cpp INFO: method: A::process <input.cc 14:15 14:21>
|
||||
Storage.cpp INFO: field: A::count <input.cc 17:13 17:17>
|
||||
Storage.cpp INFO: class: B <input.cc 20:7 20:7>
|
||||
Storage.cpp INFO: inheritance: B : A <input.cc 21:4 21:11>
|
||||
Storage.cpp INFO: method: B::process <input.cc 24:15 24:21>
|
||||
Storage.cpp INFO: type usage: B::process -> int <input.cc 26:3 26:5>
|
||||
Storage.cpp INFO: function: main <input.cc 30:5 30:8>
|
||||
Storage.cpp INFO: type usage: main -> B <input.cc 32:2 32:2>
|
||||
Storage.cpp INFO: call: main -> B::B <input.cc 32:4 32:4>
|
||||
Storage.cpp INFO: call: main -> A::getCount <input.cc 34:9 34:21>
|
||||
Settings.cpp WARNING: File for Settings not found.
|
||||
ConfigManager.cpp ERROR: value Bool is not present in config.
|
||||
ConfigManager.cpp ERROR: value Int is not present in config.
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ void Project::parseCode()
|
||||
extensions.push_back(".h");
|
||||
extensions.push_back(".hpp");
|
||||
|
||||
CxxParser parser(m_storage);
|
||||
CxxParser parser(m_storage.get());
|
||||
parser.parseFiles(
|
||||
FileSystem::getSourceFilesFromDirectory(ProjectSettings::getInstance()->getSourcePath(), extensions)
|
||||
);
|
||||
|
||||
@@ -628,6 +628,11 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile(
|
||||
return ret;
|
||||
}
|
||||
|
||||
const Graph& Storage::getGraph() const
|
||||
{
|
||||
return m_graph;
|
||||
}
|
||||
|
||||
Token* Storage::getTokenWithId(Id tokenId) const
|
||||
{
|
||||
return m_graph.getTokenById(tokenId);
|
||||
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
) const;
|
||||
|
||||
protected:
|
||||
const Graph& getGraph() const;
|
||||
Token* getTokenWithId(Id tokenId) const;
|
||||
std::vector<TokenLocation*> getTokenLocationsForId(Id tokenId) const;
|
||||
|
||||
|
||||
@@ -118,13 +118,13 @@ std::string Edge::getTypeString(EdgeType type) const
|
||||
case EDGE_MEMBER:
|
||||
return "child";
|
||||
case EDGE_TYPE_OF:
|
||||
return "type use";
|
||||
return "type_use";
|
||||
case EDGE_RETURN_TYPE_OF:
|
||||
return "return type";
|
||||
return "return_type";
|
||||
case EDGE_PARAMETER_TYPE_OF:
|
||||
return "parameter type";
|
||||
return "parameter_type";
|
||||
case EDGE_TYPE_USAGE:
|
||||
return "type usage";
|
||||
return "type_usage";
|
||||
case EDGE_INHERITANCE:
|
||||
return "inheritance";
|
||||
case EDGE_CALL:
|
||||
|
||||
@@ -30,3 +30,24 @@ void FilterableGraph::print(std::ostream& ostream) const
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void FilterableGraph::printBasic(std::ostream& ostream) const
|
||||
{
|
||||
ostream << getNodeCount() << " nodes:";
|
||||
forEachNode(
|
||||
[&ostream](Node* n)
|
||||
{
|
||||
ostream << ' ' << n->getTypeString() << ':' << n->getFullName();
|
||||
}
|
||||
);
|
||||
ostream << '\n';
|
||||
|
||||
ostream << getEdgeCount() << " edges:";
|
||||
forEachEdge(
|
||||
[&ostream](Edge* e)
|
||||
{
|
||||
ostream << ' ' << e->getName();
|
||||
}
|
||||
);
|
||||
ostream << '\n';
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
virtual size_t getEdgeCount() const = 0;
|
||||
|
||||
void print(std::ostream& ostream) const;
|
||||
void printBasic(std::ostream& ostream) const;
|
||||
};
|
||||
|
||||
#endif // FILTERABLE_GRAPH_H
|
||||
|
||||
@@ -14,6 +14,28 @@ Graph::~Graph()
|
||||
m_nodes.clear();
|
||||
}
|
||||
|
||||
Graph& Graph::operator=(const Graph& other)
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
other.forEachNode(
|
||||
[this](Node* node)
|
||||
{
|
||||
addNodeAsPlainCopy(node);
|
||||
}
|
||||
);
|
||||
|
||||
other.forEachEdge(
|
||||
[this](Edge* edge)
|
||||
{
|
||||
addEdgeAsPlainCopy(edge);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Graph::copy(const FilterableGraph* other)
|
||||
{
|
||||
clear();
|
||||
|
||||
@@ -15,6 +15,7 @@ class Graph
|
||||
public:
|
||||
Graph();
|
||||
virtual ~Graph();
|
||||
Graph& operator=(const Graph& other);
|
||||
|
||||
// FilterableGraph implementation
|
||||
virtual void copy(const FilterableGraph* other);
|
||||
@@ -71,8 +72,6 @@ private:
|
||||
Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to);
|
||||
void removeEdgeInternal(Edge* edge);
|
||||
|
||||
const std::string m_delimiter;
|
||||
|
||||
std::map<Id, std::shared_ptr<Node>> m_nodes;
|
||||
std::map<Id, std::shared_ptr<Edge>> m_edges;
|
||||
};
|
||||
|
||||
@@ -268,7 +268,7 @@ std::string Node::getTypeString(NodeType type) const
|
||||
case NODE_UNDEFINED:
|
||||
return "undefined";
|
||||
case NODE_UNDEFINED_FUNCTION:
|
||||
return "undefined function";
|
||||
return "undefined_function";
|
||||
case NODE_CLASS:
|
||||
return "class";
|
||||
case NODE_STRUCT:
|
||||
|
||||
@@ -56,22 +56,22 @@ class GraphFilterCommandNodeType
|
||||
: public GraphFilter
|
||||
{
|
||||
public:
|
||||
GraphFilterCommandNodeType(Node::NodeType type)
|
||||
: m_type(type)
|
||||
GraphFilterCommandNodeType(Node::NodeTypeMask mask)
|
||||
: m_mask(mask)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void visitNode(Node* node)
|
||||
{
|
||||
if (node->getType() == m_type)
|
||||
if (node->isType(m_mask))
|
||||
{
|
||||
addNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Node::NodeType m_type;
|
||||
const Node::NodeTypeMask m_mask;
|
||||
};
|
||||
|
||||
class GraphFilterCommandConst
|
||||
@@ -254,7 +254,6 @@ private:
|
||||
const bool m_super;
|
||||
};
|
||||
|
||||
|
||||
class GraphFilterToken
|
||||
: public GraphFilter
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/Parser.h"
|
||||
|
||||
Parser::Parser(std::shared_ptr<ParserClient> client)
|
||||
Parser::Parser(ParserClient* client)
|
||||
: m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -12,14 +12,14 @@ class TextAccess;
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(std::shared_ptr<ParserClient> client);
|
||||
Parser(ParserClient* client);
|
||||
virtual ~Parser();
|
||||
|
||||
virtual void parseFiles(const std::vector<std::string>& filePaths) = 0;
|
||||
virtual void parseFile(std::shared_ptr<TextAccess> textAccess) = 0;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
ParserClient* m_client;
|
||||
};
|
||||
|
||||
#endif // PARSER_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/cxx/ASTAction.h"
|
||||
|
||||
ASTAction::ASTAction(std::shared_ptr<ParserClient> client)
|
||||
ASTAction::ASTAction(ParserClient* client)
|
||||
: m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
class ASTAction : public clang::ASTFrontendAction
|
||||
{
|
||||
public:
|
||||
explicit ASTAction(std::shared_ptr<ParserClient> client);
|
||||
explicit ASTAction(ParserClient* client);
|
||||
virtual ~ASTAction();
|
||||
|
||||
virtual clang::ASTConsumer* CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
ParserClient* m_client;
|
||||
};
|
||||
|
||||
#endif // AST_ACTION_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/cxx/ASTActionFactory.h"
|
||||
|
||||
ASTActionFactory::ASTActionFactory(std::shared_ptr<ParserClient> client)
|
||||
ASTActionFactory::ASTActionFactory(ParserClient* client)
|
||||
: m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
class ASTActionFactory : public clang::tooling::FrontendActionFactory
|
||||
{
|
||||
public:
|
||||
explicit ASTActionFactory(std::shared_ptr<ParserClient> client);
|
||||
explicit ASTActionFactory(ParserClient* client);
|
||||
virtual ~ASTActionFactory();
|
||||
|
||||
virtual clang::FrontendAction* create();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
ParserClient* m_client;
|
||||
};
|
||||
|
||||
#endif // AST_ACTION_FACTORY
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/cxx/ASTConsumer.h"
|
||||
|
||||
ASTConsumer::ASTConsumer(clang::ASTContext* context, std::shared_ptr<ParserClient> client)
|
||||
ASTConsumer::ASTConsumer(clang::ASTContext* context, ParserClient* client)
|
||||
: m_visitor(context, client)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
class ASTConsumer : public clang::ASTConsumer
|
||||
{
|
||||
public:
|
||||
explicit ASTConsumer(clang::ASTContext* context, std::shared_ptr<ParserClient> client);
|
||||
explicit ASTConsumer(clang::ASTContext* context, ParserClient* client);
|
||||
virtual ~ASTConsumer();
|
||||
|
||||
virtual void HandleTranslationUnit(clang::ASTContext& context);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "data/type/DataType.h"
|
||||
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client)
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, ParserClient* client)
|
||||
: m_context(context)
|
||||
, m_client(client)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef AST_VISITOR_H
|
||||
#define AST_VISITOR_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
|
||||
@@ -14,7 +12,7 @@ class ASTVisitor
|
||||
, public ASTBodyVisitorClient
|
||||
{
|
||||
public:
|
||||
ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client);
|
||||
ASTVisitor(clang::ASTContext* context, ParserClient* client);
|
||||
virtual ~ASTVisitor();
|
||||
|
||||
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
|
||||
@@ -66,7 +64,7 @@ private:
|
||||
ParseFunction getParseFunction(clang::FunctionDecl* declaration) const;
|
||||
|
||||
clang::ASTContext* m_context;
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
ParserClient* m_client;
|
||||
};
|
||||
|
||||
#endif // AST_VISITOR_H
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
CxxParser::CxxParser(std::shared_ptr<ParserClient> client)
|
||||
CxxParser::CxxParser(ParserClient* client)
|
||||
: Parser(client)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class CxxParser: public Parser
|
||||
{
|
||||
public:
|
||||
CxxParser(std::shared_ptr<ParserClient> client);
|
||||
CxxParser(ParserClient* client);
|
||||
~CxxParser();
|
||||
|
||||
virtual void parseFiles(const std::vector<std::string>& filePaths);
|
||||
|
||||
@@ -4,11 +4,16 @@ add_files(
|
||||
TestSuiteFixture.cpp
|
||||
TestSuiteFixture.h
|
||||
|
||||
utilityTest.cpp
|
||||
utilityTest.h
|
||||
|
||||
ConfigManagerTestSuite.h
|
||||
CxxParserTestSuite.h
|
||||
DataTypeTestSuite.h
|
||||
FileSystemTestSuite.h
|
||||
GraphTestSuite.h
|
||||
GraphFilterTestSuite.h
|
||||
GraphFilterConductorTestSuite.h
|
||||
LogManagerTestSuite.h
|
||||
MessageQueueTestSuite.h
|
||||
QueryTreeTestSuite.h
|
||||
|
||||
@@ -975,29 +975,29 @@ public:
|
||||
|
||||
void test_cxx_parser_parses_multiple_files()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
CxxParser parser(client);
|
||||
TestParserClient client;
|
||||
CxxParser parser(&client);
|
||||
|
||||
std::vector<std::string> filePaths;
|
||||
filePaths.push_back("data/CxxParserTestSuite/header.h");
|
||||
filePaths.push_back("data/CxxParserTestSuite/code.cpp");
|
||||
parser.parseFiles(filePaths);
|
||||
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->classes.size(), 4);
|
||||
TS_ASSERT_EQUALS(client->enums.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->enumFields.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->functions.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->fields.size(), 4);
|
||||
TS_ASSERT_EQUALS(client->globalVariables.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->methods.size(), 5);
|
||||
TS_ASSERT_EQUALS(client->namespaces.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->structs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client.typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client.classes.size(), 4);
|
||||
TS_ASSERT_EQUALS(client.enums.size(), 1);
|
||||
TS_ASSERT_EQUALS(client.enumFields.size(), 2);
|
||||
TS_ASSERT_EQUALS(client.functions.size(), 2);
|
||||
TS_ASSERT_EQUALS(client.fields.size(), 4);
|
||||
TS_ASSERT_EQUALS(client.globalVariables.size(), 2);
|
||||
TS_ASSERT_EQUALS(client.methods.size(), 5);
|
||||
TS_ASSERT_EQUALS(client.namespaces.size(), 2);
|
||||
TS_ASSERT_EQUALS(client.structs.size(), 1);
|
||||
|
||||
TS_ASSERT_EQUALS(client->inheritances.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->calls.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->usages.size(), 3);
|
||||
TS_ASSERT_EQUALS(client->typeUses.size(), 8);
|
||||
TS_ASSERT_EQUALS(client.inheritances.size(), 1);
|
||||
TS_ASSERT_EQUALS(client.calls.size(), 2);
|
||||
TS_ASSERT_EQUALS(client.usages.size(), 3);
|
||||
TS_ASSERT_EQUALS(client.typeUses.size(), 8);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1175,7 +1175,7 @@ private:
|
||||
std::shared_ptr<TestParserClient> parseCode(std::string code) const
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
CxxParser parser(client);
|
||||
CxxParser parser(client.get());
|
||||
parser.parseFile(TextAccess::createFromString(code));
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include "cxxtest/TestSuite.h"
|
||||
|
||||
#include "data/graph/filter/GraphFilterConductor.h"
|
||||
#include "data/query/QueryTree.h"
|
||||
#include "utilityTest.h"
|
||||
|
||||
class GraphFilterConductorTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_token_query()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("\"main\""),
|
||||
|
||||
"1 nodes: function:main\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_command_query()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("method"),
|
||||
|
||||
"4 nodes: method:A method:getCount method:process method:process\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("class"),
|
||||
|
||||
"2 nodes: class:A class:B\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_not()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("!method"),
|
||||
|
||||
"7 nodes: "
|
||||
"class:A field:A::count undefined:int undefined:void class:B function:main undefined_function:B::B\n"
|
||||
"7 edges: "
|
||||
"child:A->A::count type_use:A::count->int inheritance:B->A return_type:main->int type_usage:main->B "
|
||||
"child:B->B::B call:main->B::B\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_sub()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("class.base"),
|
||||
|
||||
"1 nodes: class:A\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_has()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("\"A\":field"),
|
||||
|
||||
"1 nodes: field:count\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_or()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("(static|const)"),
|
||||
|
||||
"4 nodes: field:count method:getCount method:process method:process\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_group()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("(static|const).public"),
|
||||
|
||||
"1 nodes: method:getCount\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string printedFilteredTestGraph(std::string query)
|
||||
{
|
||||
QueryTree tree(query);
|
||||
GraphFilterConductor conductor;
|
||||
|
||||
createTestGraph();
|
||||
Graph result;
|
||||
|
||||
conductor.filter(&tree, &m_graph, &result);
|
||||
|
||||
std::stringstream ss;
|
||||
result.printBasic(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void createTestGraph()
|
||||
{
|
||||
if (m_graph.getNodeCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_graph = utility::getGraphForCxxCode(
|
||||
"class A\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" A() {\n"
|
||||
" count++;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static int getCount()\n"
|
||||
" {\n"
|
||||
" return count;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"protected:\n"
|
||||
" virtual void process() const = 0;\n"
|
||||
"\n"
|
||||
"private:\n"
|
||||
" static int count;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"class B\n"
|
||||
" : public A\n"
|
||||
"{\n"
|
||||
"protected:\n"
|
||||
" virtual void process() const\n"
|
||||
" {\n"
|
||||
" int number = 42;\n"
|
||||
" }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" B b;\n"
|
||||
"\n"
|
||||
" return A::getCount();\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
||||
Graph m_graph;
|
||||
};
|
||||
@@ -0,0 +1,232 @@
|
||||
#include "cxxtest/TestSuite.h"
|
||||
|
||||
#include "data/graph/filter/GraphFilter.h"
|
||||
#include "data/graph/filter/GraphFilterImplementations.h"
|
||||
#include "utilityTest.h"
|
||||
|
||||
class GraphFilterTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_empty_GraphFilter()
|
||||
{
|
||||
GraphFilter filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"0 nodes:\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandMember()
|
||||
{
|
||||
GraphFilterCommandMember filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"6 nodes: method:A field:count method:getCount method:process method:process undefined_function:B\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandParent()
|
||||
{
|
||||
GraphFilterCommandParent filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"2 nodes: class:A class:B\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandNodeType()
|
||||
{
|
||||
GraphFilterCommandNodeType filter(Node::NODE_FUNCTION | Node::NODE_METHOD);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"5 nodes: method:A method:getCount method:process method:process function:main\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandConst()
|
||||
{
|
||||
GraphFilterCommandConst filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"2 nodes: method:process method:process\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandStatic()
|
||||
{
|
||||
GraphFilterCommandStatic filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"2 nodes: field:count method:getCount\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandAccessType()
|
||||
{
|
||||
GraphFilterCommandAccessType filter(TokenComponentAccess::ACCESS_PROTECTED);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"2 nodes: method:process method:process\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandAbstractionType()
|
||||
{
|
||||
GraphFilterCommandAbstractionType filter(TokenComponentAbstraction::ABSTRACTION_PURE_VIRTUAL);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"1 nodes: method:process\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandCall()
|
||||
{
|
||||
GraphFilterCommandCall filter(true);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"1 nodes: function:main\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
|
||||
GraphFilterCommandCall filter2(false);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter2),
|
||||
|
||||
"2 nodes: method:getCount undefined_function:B\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandUsage()
|
||||
{
|
||||
GraphFilterCommandUsage filter;
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"6 nodes: method:A field:count method:getCount method:process method:process function:main\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterCommandInheritance()
|
||||
{
|
||||
GraphFilterCommandInheritance filter(true);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"1 nodes: class:A\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
|
||||
GraphFilterCommandInheritance filter2(false);
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter2),
|
||||
|
||||
"1 nodes: class:B\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_GraphFilterToken()
|
||||
{
|
||||
GraphFilterToken filter("main");
|
||||
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph(&filter),
|
||||
|
||||
"1 nodes: function:main\n"
|
||||
"0 edges:\n"
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string printedFilteredTestGraph(GraphFilter* filter)
|
||||
{
|
||||
createTestGraph();
|
||||
Graph result;
|
||||
|
||||
filter->apply(&m_graph, &result);
|
||||
|
||||
std::stringstream ss;
|
||||
result.printBasic(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void createTestGraph()
|
||||
{
|
||||
if (m_graph.getNodeCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_graph = utility::getGraphForCxxCode(
|
||||
"class A\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" A() {\n"
|
||||
" count++;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static int getCount()\n"
|
||||
" {\n"
|
||||
" return count;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"protected:\n"
|
||||
" virtual void process() const = 0;\n"
|
||||
"\n"
|
||||
"private:\n"
|
||||
" static int count;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"class B\n"
|
||||
" : public A\n"
|
||||
"{\n"
|
||||
"protected:\n"
|
||||
" virtual void process() const\n"
|
||||
" {\n"
|
||||
" int number = 42;\n"
|
||||
" }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" B b;\n"
|
||||
"\n"
|
||||
" return A::getCount();\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
||||
Graph m_graph;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "utilityTest.h"
|
||||
|
||||
#include "data/graph/Graph.h"
|
||||
#include "data/Storage.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "data/parser/cxx/CxxParser.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestStorage
|
||||
: public Storage
|
||||
{
|
||||
public:
|
||||
const Graph& getGraph() const
|
||||
{
|
||||
return Storage::getGraph();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Graph utility::getGraphForCxxCode(std::string code)
|
||||
{
|
||||
TestStorage storage;
|
||||
CxxParser parser(&storage);
|
||||
parser.parseFile(TextAccess::createFromString(code));
|
||||
return storage.getGraph();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef UTILITY_TEST_H
|
||||
#define UTILITY_TEST_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Graph;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
Graph getGraphForCxxCode(std::string code);
|
||||
}
|
||||
|
||||
#endif // UTILITY_TEST_H
|
||||
Reference in New Issue
Block a user