test: added StorageTestSuite

This change adds the StorageTestSuite that checks whether the ParserClient callbacks cause the right things to be saved.
In order to allow for easier data retrieval the ParserClient callbacks now return the Id of the inserted Token, which
can then be used to retrieve the Token pointer.
This commit is contained in:
Eberhard Graether
2014-08-01 02:10:42 +02:00
parent b110d528dc
commit 5893d0c776
8 changed files with 742 additions and 82 deletions
+87 -29
View File
@@ -39,7 +39,7 @@ void Storage::logLocations() const
}
void Storage::onTypedefParsed(
Id Storage::onTypedefParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType, AccessType access
){
log("typedef", fullName + " -> " + underlyingType.dataType.getFullTypeName(), location);
@@ -48,31 +48,37 @@ void Storage::onTypedefParsed(
addAccess(node, access);
addTokenLocation(node, location);
addTypeEdge(node, Edge::EDGE_TYPEDEF_OF, underlyingType);
return node->getId();
}
void Storage::onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation)
{
Id Storage::onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation
){
log("class", fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_CLASS, fullName);
addAccess(node, access);
addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true);
return node->getId();
}
void Storage::onStructParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation)
{
Id Storage::onStructParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation
){
log("struct", fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_STRUCT, fullName);
addAccess(node, access);
addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true);
return node->getId();
}
void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
Id Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
{
log("global", variable.fullName, location);
@@ -85,14 +91,21 @@ void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseV
addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type);
addTokenLocation(node, location);
return node->getId();
}
void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
Id Storage::onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
{
log("field", variable.fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, variable.fullName);
if (!node->getMemberEdge())
{
LOG_ERROR("Field is not a member of anything.");
}
if (variable.isStatic)
{
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
@@ -101,15 +114,16 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
if (access == ACCESS_NONE)
{
LOG_ERROR("Field needs to have access type [public, protected, private] but has none.");
return;
}
addAccess(node, access);
addTypeEdge(node, Edge::EDGE_TYPE_OF, variable.type);
addTokenLocation(node, location);
return node->getId();
}
void Storage::onFunctionParsed(
Id Storage::onFunctionParsed(
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
){
log("function", function.fullName, location);
@@ -126,9 +140,11 @@ void Storage::onFunctionParsed(
{
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
}
return node->getId();
}
void Storage::onMethodParsed(
Id Storage::onMethodParsed(
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation
){
@@ -138,6 +154,11 @@ void Storage::onMethodParsed(
Node::NODE_METHOD, method.fullName, ParserClient::functionSignatureStr(method)
);
if (!node->getMemberEdge())
{
LOG_ERROR("Method is not a member of anything.");
}
if (method.isConst)
{
node->addComponentConst(std::make_shared<TokenComponentConst>());
@@ -151,7 +172,6 @@ void Storage::onMethodParsed(
if (access == ACCESS_NONE)
{
LOG_ERROR("Method needs to have access type [public, protected, private] but has none.");
return;
}
addAccess(node, access);
@@ -163,40 +183,48 @@ void Storage::onMethodParsed(
{
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
}
return node->getId();
}
void Storage::onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation)
{
Id Storage::onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation
){
log("namespace", fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_NAMESPACE, fullName);
addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true);
return node->getId();
}
void Storage::onEnumParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation)
{
Id Storage::onEnumParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation
){
log("enum", fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_ENUM, fullName);
addAccess(node, access);
addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true);
return node->getId();
}
void Storage::onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
Id Storage::onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
{
log("enum field", fullName, location);
Node* node = m_graph.createNodeHierarchy(Node::NODE_FIELD, fullName);
addTokenLocation(node, location);
return node->getId();
}
void Storage::onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access)
{
Id Storage::onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access
){
log("inheritance", fullName + " : " + baseName, location);
Node* node = m_graph.createNodeHierarchy(fullName);
@@ -206,9 +234,11 @@ void Storage::onInheritanceParsed(
edge->addComponentAccess(std::make_shared<TokenComponentAccess>(convertAccessType(access)));
addTokenLocation(edge, location);
return edge->getId();
}
void Storage::onCallParsed(const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
Id Storage::onCallParsed(const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
{
log("call", caller.fullName + " -> " + callee.fullName, location);
@@ -220,9 +250,11 @@ void Storage::onCallParsed(const ParseLocation& location, const ParseFunction& c
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
addTokenLocation(edge, location);
return edge->getId();
}
void Storage::onCallParsed(const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
Id Storage::onCallParsed(const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
{
log("call", caller.fullName + " -> " + callee.fullName, location);
@@ -234,9 +266,11 @@ void Storage::onCallParsed(const ParseLocation& location, const ParseVariable& c
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
addTokenLocation(edge, location);
return edge->getId();
}
void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
Id Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{
log("field usage", user.fullName + " -> " + usedName, location);
@@ -246,9 +280,11 @@ void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunct
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
addTokenLocation(edge, location);
return edge->getId();
}
void Storage::onGlobalVariableUsageParsed(
Id Storage::onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName
){
log("global usage", user.fullName + " -> " + usedName, location);
@@ -259,15 +295,19 @@ void Storage::onGlobalVariableUsageParsed(
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
addTokenLocation(edge, location);
return edge->getId();
}
void Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
Id Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
{
log("type usage", function.fullName + " -> " + type.dataType.getRawTypeName(), type.location);
Node* functionNode =
m_graph.createNodeHierarchyWithDistinctSignature(function.fullName, ParserClient::functionSignatureStr(function));
addTypeEdge(functionNode, Edge::EDGE_TYPE_USAGE, type);
Edge* edge = addTypeEdge(functionNode, Edge::EDGE_TYPE_USAGE, type);
return edge->getId();
}
Id Storage::getIdForNodeWithName(const std::string& fullName) const
@@ -571,6 +611,24 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile(
return ret;
}
Token* Storage::getTokenWithId(Id tokenId) const
{
return m_graph.getTokenById(tokenId);
}
std::vector<TokenLocation*> Storage::getTokenLocationsForId(Id tokenId) const
{
const std::vector<Id>& locationIds = getTokenWithId(tokenId)->getLocationIds();
std::vector<TokenLocation*> result;
for (Id locationId : locationIds)
{
result.push_back(m_locationCollection.findTokenLocationById(locationId));
}
return result;
}
TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const
{
switch (access)
+20 -16
View File
@@ -26,41 +26,41 @@ public:
void logLocations() const;
// ParserClient implementation
virtual void onTypedefParsed(
virtual Id onTypedefParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
AccessType access);
virtual void onClassParsed(
virtual Id onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
virtual void onStructParsed(
virtual Id onStructParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable);
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
virtual Id onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable);
virtual Id onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
virtual void onFunctionParsed(
virtual Id onFunctionParsed(
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation);
virtual void onMethodParsed(
virtual Id onMethodParsed(
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation);
virtual void onNamespaceParsed(
virtual Id onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation);
virtual void onEnumParsed(
virtual Id onEnumParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName);
virtual Id onEnumFieldParsed(const ParseLocation& location, const std::string& fullName);
virtual void onInheritanceParsed(
virtual Id onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access);
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee);
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee);
virtual void onFieldUsageParsed(
virtual Id onFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
virtual void onGlobalVariableUsageParsed(
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
virtual void onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function);
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function);
// GraphAccess implementation
virtual Id getIdForNodeWithName(const std::string& fullName) const;
@@ -90,6 +90,10 @@ public:
const std::string& filePath, uint firstLineNumber, uint lastLineNumber
) const;
protected:
Token* getTokenWithId(Id tokenId) const;
std::vector<TokenLocation*> getTokenLocationsForId(Id tokenId) const;
private:
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
TokenComponentAccess* addAccess(Node* node, ParserClient::AccessType access);
+18 -16
View File
@@ -4,6 +4,8 @@
#include <string>
#include <vector>
#include "utility/types.h"
struct ParseFunction;
struct ParseLocation;
struct ParseTypeUsage;
@@ -42,44 +44,44 @@ public:
ParserClient();
virtual ~ParserClient();
virtual void onTypedefParsed(
virtual Id onTypedefParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
AccessType access) = 0;
virtual void onClassParsed(
virtual Id onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation) = 0;
virtual void onStructParsed(
virtual Id onStructParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation) = 0;
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable) = 0;
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
virtual Id onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable) = 0;
virtual Id onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
virtual void onFunctionParsed(
virtual Id onFunctionParsed(
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation) = 0;
virtual void onMethodParsed(
virtual Id onMethodParsed(
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation) = 0;
virtual void onNamespaceParsed(
virtual Id onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation) = 0;
virtual void onEnumParsed(
virtual Id onEnumParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation) = 0;
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName) = 0;
virtual Id onEnumFieldParsed(const ParseLocation& location, const std::string& fullName) = 0;
virtual void onInheritanceParsed(
virtual Id onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access) = 0;
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee) = 0;
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee) = 0;
virtual void onFieldUsageParsed(
virtual Id onFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
virtual void onGlobalVariableUsageParsed(
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
virtual void onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function) = 0;
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function) = 0;
};
#endif // PARSER_CLIENT_H
+1
View File
@@ -9,6 +9,7 @@ add_files(
LogManagerTestSuite.h
MessageQueueTestSuite.h
SettingsTestSuite.h
StorageTestSuite.h
TestSuiteFixture.cpp
TestSuiteFixture.h
TextAccessTestSuite.h
+32 -18
View File
@@ -1,7 +1,5 @@
#include "cxxtest/TestSuite.h"
#include <sstream>
#include "data/parser/cxx/CxxParser.h"
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h"
@@ -992,40 +990,45 @@ private:
class TestParserClient: public ParserClient
{
public:
virtual void onTypedefParsed(
virtual Id onTypedefParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
AccessType access
)
{
std::string str = addAccessPrefix(underlyingType.dataType.getFullTypeName() + " -> " + fullName, access);
typedefs.push_back(addLocationSuffix(str, location));
return 0;
}
virtual void onClassParsed(
virtual Id onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation)
{
classes.push_back(addLocationSuffix(addAccessPrefix(fullName, access), location, scopeLocation));
return 0;
}
virtual void onStructParsed(
virtual Id onStructParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation)
{
structs.push_back(addLocationSuffix(addAccessPrefix(fullName, access), location, scopeLocation));
return 0;
}
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
virtual Id onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
{
globalVariables.push_back(addLocationSuffix(variableStr(variable), location));
return 0;
}
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
virtual Id onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
{
fields.push_back(addLocationSuffix(addAccessPrefix(variableStr(variable), access), location));
return 0;
}
virtual void onFunctionParsed(
virtual Id onFunctionParsed(
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
){
functions.push_back(addLocationSuffix(functionStr(function), location, scopeLocation));
@@ -1035,9 +1038,10 @@ private:
{
addTypeUse(parameter);
}
return 0;
}
virtual void onMethodParsed(
virtual Id onMethodParsed(
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const ParseLocation& scopeLocation
){
@@ -1052,60 +1056,70 @@ private:
{
addTypeUse(parameter);
}
return 0;
}
virtual void onNamespaceParsed(
virtual Id onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation)
{
namespaces.push_back(addLocationSuffix(fullName, location, scopeLocation));
return 0;
}
virtual void onEnumParsed(
virtual Id onEnumParsed(
const ParseLocation& location, const std::string& fullName, AccessType access,
const ParseLocation& scopeLocation)
{
enums.push_back(addLocationSuffix(addAccessPrefix(fullName, access), location, scopeLocation));
return 0;
}
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
virtual Id onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
{
enumFields.push_back(addLocationSuffix(fullName, location));
return 0;
}
virtual void onInheritanceParsed(
virtual Id onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access)
{
std::string str = fullName + " : " + addAccessPrefix(baseName, access);
inheritances.push_back(addLocationSuffix(str, location));
return 0;
}
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
{
calls.push_back(addLocationSuffix(functionStr(caller) + " -> " + functionStr(callee), location));
return 0;
}
virtual void onCallParsed(
virtual Id onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
{
calls.push_back(addLocationSuffix(caller.fullName + " -> " + functionStr(callee), location));
return 0;
}
virtual void onFieldUsageParsed(
virtual Id onFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{
usages.push_back(addLocationSuffix(functionStr(user) + " -> " + usedName, location));
return 0;
}
virtual void onGlobalVariableUsageParsed(
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{
usages.push_back(addLocationSuffix(functionStr(user) + " -> " + usedName, location));
return 0;
}
virtual void onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
{
addTypeUse(type, function);
return 0;
}
std::vector<std::string> typedefs;
+545
View File
@@ -0,0 +1,545 @@
#include "cxxtest/TestSuite.h"
#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "data/graph/token_component/TokenComponentStatic.h"
#include "data/location/TokenLocation.h"
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h"
#include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h"
#include "data/Storage.h"
#include "data/type/DataType.h"
class StorageTestSuite: public CxxTest::TestSuite
{
public:
void test_storage_saves_typedef()
{
TestStorage storage;
Id id = storage.onTypedefParsed(validLocation(1), "type", typeUsage("int"), ParserClient::ACCESS_NONE);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "type");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_TYPEDEF);
Edge* typeEdge = node->findEdgeOfType(Edge::EDGE_TYPEDEF_OF);
TS_ASSERT(typeEdge);
TS_ASSERT_EQUALS(typeEdge->getTo()->getFullName(), "int");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 1));
}
void test_storage_saves_class()
{
TestStorage storage;
Id id = storage.onClassParsed(validLocation(1), "Class", ParserClient::ACCESS_NONE, validLocation(2));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Class");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_CLASS);
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 1));
TS_ASSERT(isValidLocation(locations[1], 2));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_struct()
{
TestStorage storage;
Id id = storage.onStructParsed(validLocation(1), "Struct", ParserClient::ACCESS_NONE, validLocation(2));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Struct");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_STRUCT);
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 1));
TS_ASSERT(isValidLocation(locations[1], 2));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_global_variable()
{
TestStorage storage;
Id id = storage.onGlobalVariableParsed(validLocation(42), ParseVariable(typeUsage("char"), "Global", false));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Global");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_GLOBAL_VARIABLE);
TS_ASSERT(!node->getComponent<TokenComponentStatic>());
Edge* typeEdge = node->findEdgeOfType(Edge::EDGE_TYPE_OF);
TS_ASSERT(typeEdge);
TS_ASSERT_EQUALS(typeEdge->getTo()->getFullName(), "char");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 42));
}
void test_storage_saves_global_variable_static()
{
TestStorage storage;
Id id = storage.onGlobalVariableParsed(validLocation(7), ParseVariable(typeUsage("char"), "Global", true));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Global");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_GLOBAL_VARIABLE);
TS_ASSERT(node->getComponent<TokenComponentStatic>());
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 7));
}
void test_storage_saves_field()
{
TestStorage storage;
Id id = storage.onFieldParsed(
validLocation(3), ParseVariable(typeUsage("bool"), "m_field", false), ParserClient::ACCESS_NONE
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "m_field");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_FIELD);
Edge* typeEdge = node->findEdgeOfType(Edge::EDGE_TYPE_OF);
TS_ASSERT(typeEdge);
TS_ASSERT_EQUALS(typeEdge->getTo()->getFullName(), "bool");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 3));
}
void test_storage_saves_field_as_member()
{
TestStorage storage;
Id id = storage.onFieldParsed(
validLocation(11), ParseVariable(typeUsage("bool"), "Struct::m_field", false), ParserClient::ACCESS_PUBLIC
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getName(), "m_field");
TS_ASSERT_EQUALS(node->getFullName(), "Struct::m_field");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_FIELD);
Edge* memberEdge = node->getMemberEdge();
TS_ASSERT(memberEdge);
TS_ASSERT_EQUALS(memberEdge->getType(), Edge::EDGE_MEMBER);
TS_ASSERT(memberEdge->getComponent<TokenComponentAccess>());
TS_ASSERT_EQUALS(
memberEdge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PUBLIC
);
TS_ASSERT_EQUALS(memberEdge->getFrom()->getFullName(), "Struct");
TS_ASSERT_EQUALS(memberEdge->getFrom()->getType(), Node::NODE_UNDEFINED);
Edge* typeEdge = node->findEdgeOfType(Edge::EDGE_TYPE_OF);
TS_ASSERT(typeEdge);
TS_ASSERT_EQUALS(typeEdge->getTo()->getFullName(), "bool");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 11));
}
void test_storage_saves_function()
{
TestStorage storage;
Id id = storage.onFunctionParsed(
validLocation(14), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation(41)
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "isTrue");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_FUNCTION);
Edge* returnEdge = node->findEdgeOfType(Edge::EDGE_RETURN_TYPE_OF);
TS_ASSERT(returnEdge);
TS_ASSERT_EQUALS(returnEdge->getTo()->getFullName(), "bool");
Edge* paramEdge = node->findEdgeOfType(Edge::EDGE_PARAMETER_TYPE_OF);
TS_ASSERT(paramEdge);
TS_ASSERT_EQUALS(paramEdge->getTo()->getFullName(), "char");
TS_ASSERT(node->getComponent<TokenComponentSignature>());
TS_ASSERT_EQUALS(node->getComponent<TokenComponentSignature>()->getSignature(), "isTrue(char)");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 14));
TS_ASSERT(isValidLocation(locations[1], 41));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_method()
{
TestStorage storage;
Id id = storage.onMethodParsed(
validLocation(9),
ParseFunction(typeUsage("void"), "isMethod", parameters("bool")),
ParserClient::ACCESS_NONE,
ParserClient::ABSTRACTION_NONE,
validLocation(4)
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "isMethod");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_METHOD);
Edge* returnEdge = node->findEdgeOfType(Edge::EDGE_RETURN_TYPE_OF);
TS_ASSERT(returnEdge);
TS_ASSERT_EQUALS(returnEdge->getTo()->getFullName(), "void");
Edge* paramEdge = node->findEdgeOfType(Edge::EDGE_PARAMETER_TYPE_OF);
TS_ASSERT(paramEdge);
TS_ASSERT_EQUALS(paramEdge->getTo()->getFullName(), "bool");
TS_ASSERT(node->getComponent<TokenComponentSignature>());
TS_ASSERT_EQUALS(node->getComponent<TokenComponentSignature>()->getSignature(), "isMethod(bool)");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 9));
TS_ASSERT(isValidLocation(locations[1], 4));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_method_static()
{
TestStorage storage;
Id id = storage.onMethodParsed(
validLocation(1),
ParseFunction(typeUsage("void"), "isMethod", parameters("bool"), true),
ParserClient::ACCESS_NONE,
ParserClient::ABSTRACTION_NONE,
validLocation(4)
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "isMethod");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_METHOD);
TS_ASSERT(node->getComponent<TokenComponentStatic>());
}
void test_storage_saves_method_as_member()
{
TestStorage storage;
Id id = storage.onMethodParsed(
validLocation(1),
ParseFunction(typeUsage("void"), "Class::isMethod", parameters("bool")),
ParserClient::ACCESS_PROTECTED,
ParserClient::ABSTRACTION_VIRTUAL,
validLocation(4)
);
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getName(), "isMethod");
TS_ASSERT_EQUALS(node->getFullName(), "Class::isMethod");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_METHOD);
Edge* memberEdge = node->getMemberEdge();
TS_ASSERT(memberEdge);
TS_ASSERT_EQUALS(memberEdge->getType(), Edge::EDGE_MEMBER);
TS_ASSERT(memberEdge->getComponent<TokenComponentAccess>());
TS_ASSERT_EQUALS(
memberEdge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PROTECTED
);
TS_ASSERT_EQUALS(memberEdge->getFrom()->getFullName(), "Class");
TS_ASSERT_EQUALS(memberEdge->getFrom()->getType(), Node::NODE_UNDEFINED);
}
void test_storage_saves_namespace()
{
TestStorage storage;
Id id = storage.onNamespaceParsed(validLocation(1), "utility", validLocation(2));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "utility");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_NAMESPACE);
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 1));
TS_ASSERT(isValidLocation(locations[1], 2));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_enum()
{
TestStorage storage;
Id id = storage.onEnumParsed(validLocation(17), "Category", ParserClient::ACCESS_NONE, validLocation(23));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Category");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_ENUM);
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 2);
TS_ASSERT(isValidLocation(locations[0], 17));
TS_ASSERT(isValidLocation(locations[1], 23));
TS_ASSERT_EQUALS(locations[1]->getType(), TokenLocation::LOCATION_SCOPE);
}
void test_storage_saves_enum_as_member()
{
TestStorage storage;
Id id =
storage.onEnumParsed(validLocation(1), "Class::Category", ParserClient::ACCESS_PRIVATE, validLocation(2));
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "Class::Category");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_ENUM);
Edge* memberEdge = node->getMemberEdge();
TS_ASSERT(memberEdge);
TS_ASSERT_EQUALS(memberEdge->getType(), Edge::EDGE_MEMBER);
TS_ASSERT(memberEdge->getComponent<TokenComponentAccess>());
TS_ASSERT_EQUALS(
memberEdge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PRIVATE
);
TS_ASSERT_EQUALS(memberEdge->getFrom()->getFullName(), "Class");
TS_ASSERT_EQUALS(memberEdge->getFrom()->getType(), Node::NODE_UNDEFINED);
}
void test_storage_saves_enum_field()
{
TestStorage storage;
Id id = storage.onEnumFieldParsed(validLocation(1), "VALUE");
Node* node = storage.getNodeWithId(id);
TS_ASSERT(node);
TS_ASSERT_EQUALS(node->getFullName(), "VALUE");
TS_ASSERT_EQUALS(node->getType(), Node::NODE_FIELD);
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 1));
}
void test_storage_saves_inheritance()
{
TestStorage storage;
storage.onClassParsed(validLocation(), "ClassA", ParserClient::ACCESS_NONE, validLocation());
storage.onClassParsed(validLocation(), "ClassB", ParserClient::ACCESS_NONE, validLocation());
Id id = storage.onInheritanceParsed(validLocation(5), "ClassB", "ClassA", ParserClient::ACCESS_PUBLIC);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_INHERITANCE);
TS_ASSERT(edge->getComponent<TokenComponentAccess>());
TS_ASSERT_EQUALS(edge->getComponent<TokenComponentAccess>()->getAccess(), TokenComponentAccess::ACCESS_PUBLIC);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "ClassB");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "ClassA");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 5));
}
void test_storage_saves_call()
{
TestStorage storage;
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation()
);
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("void"), "func", parameters("bool")), validLocation()
);
Id id = storage.onCallParsed(
validLocation(9),
ParseFunction(typeUsage("bool"), "isTrue", parameters("char")),
ParseFunction(typeUsage("void"), "func", parameters("bool"))
);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_CALL);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "isTrue");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "func");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 9));
}
void test_storage_saves_call_in_global_variable_declaration()
{
TestStorage storage;
storage.onGlobalVariableParsed(validLocation(), ParseVariable(typeUsage("bool"), "global", false));
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation()
);
Id id = storage.onCallParsed(
validLocation(7),
ParseVariable(typeUsage("bool"), "global", false),
ParseFunction(typeUsage("bool"), "isTrue", parameters("char"))
);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_CALL);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "global");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "isTrue");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 7));
}
void test_storage_saves_field_usage()
{
TestStorage storage;
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation()
);
storage.onFieldParsed(
validLocation(), ParseVariable(typeUsage("bool"), "Foo::m_field", false), ParserClient::ACCESS_PRIVATE
);
Id id = storage.onFieldUsageParsed(
validLocation(7),
ParseFunction(typeUsage("bool"), "isTrue", parameters("char")),
"Foo::m_field"
);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_USAGE);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "isTrue");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "Foo::m_field");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 7));
}
void test_storage_saves_global_variable_usage()
{
TestStorage storage;
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation()
);
storage.onGlobalVariableParsed(validLocation(), ParseVariable(typeUsage("bool"), "global", false));
Id id = storage.onGlobalVariableUsageParsed(
validLocation(7),
ParseFunction(typeUsage("bool"), "isTrue", parameters("char")),
"global"
);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_USAGE);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "isTrue");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "global");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 7));
}
void test_storage_saves_type_usage()
{
TestStorage storage;
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), "isTrue", parameters("char")), validLocation()
);
storage.onStructParsed(validLocation(), "Struct", ParserClient::ACCESS_NONE, validLocation());
Id id = storage.onTypeUsageParsed(
typeUsage("Struct"),
ParseFunction(typeUsage("bool"), "isTrue", parameters("char"))
);
Edge* edge = storage.getEdgeWithId(id);
TS_ASSERT(edge);
TS_ASSERT_EQUALS(edge->getType(), Edge::EDGE_TYPE_USAGE);
TS_ASSERT_EQUALS(edge->getFrom()->getFullName(), "isTrue");
TS_ASSERT_EQUALS(edge->getTo()->getFullName(), "Struct");
std::vector<TokenLocation*> locations = storage.getLocationsForId(id);
TS_ASSERT_EQUALS(locations.size(), 1);
TS_ASSERT(isValidLocation(locations[0], 0));
}
private:
class TestStorage
: public Storage
{
public:
Node* getNodeWithId(Id id) const
{
return dynamic_cast<Node*>(getTokenWithId(id));
}
Edge* getEdgeWithId(Id id) const
{
return dynamic_cast<Edge*>(getTokenWithId(id));
}
std::vector<TokenLocation*> getLocationsForId(Id id) const
{
return getTokenLocationsForId(id);
}
};
ParseLocation validLocation(Id locationId = 0) const
{
return ParseLocation("file.cpp", 1, locationId, 1, locationId);
}
bool isValidLocation(TokenLocation* location, Id locationId) const
{
return
location->getFilePath() == "file.cpp" &&
location->getLineNumber() == 1 &&
location->getColumnNumber() == locationId;
}
ParseTypeUsage typeUsage(const std::string& typeName) const
{
return ParseTypeUsage(validLocation(), DataType(typeName));
}
std::vector<ParseTypeUsage> parameters(const std::string& param) const
{
std::vector<ParseTypeUsage> params;
params.push_back(typeUsage(param));
return params;
}
};
-3
View File
@@ -1,8 +1,5 @@
#include "cxxtest/TestSuite.h"
#include <memory>
#include <string>
#include "utility/text/TextAccess.h"
class TextAccessTestSuite : public CxxTest::TestSuite