test: added QueryTree tests checking correct query syntax
This commit is contained in:
@@ -40,11 +40,6 @@ bool QueryCommand::isComplete() const
|
|||||||
void QueryCommand::print(std::ostream& ostream) const
|
void QueryCommand::print(std::ostream& ostream) const
|
||||||
{
|
{
|
||||||
ostream << m_name;
|
ostream << m_name;
|
||||||
|
|
||||||
if (!isComplete())
|
|
||||||
{
|
|
||||||
ostream << " INVALID";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryCommand::CommandType QueryCommand::getType() const
|
QueryCommand::CommandType QueryCommand::getType() const
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
QueryNode::QueryNode()
|
QueryNode::QueryNode()
|
||||||
: m_isGroup(false)
|
: m_isGroup(false)
|
||||||
|
, m_isComplete(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,6 +29,11 @@ void QueryNode::print(std::ostream& ostream, int n) const
|
|||||||
ostream << ')';
|
ostream << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_isComplete || !isComplete())
|
||||||
|
{
|
||||||
|
ostream << " INVALID";
|
||||||
|
}
|
||||||
|
|
||||||
ostream << '\n';
|
ostream << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,3 +46,8 @@ void QueryNode::setIsGroup(bool isGroup)
|
|||||||
{
|
{
|
||||||
m_isGroup = isGroup;
|
m_isGroup = isGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QueryNode::setIsComplete(bool isComplete)
|
||||||
|
{
|
||||||
|
m_isComplete = isComplete;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,8 +21,11 @@ public:
|
|||||||
bool isGroup() const;
|
bool isGroup() const;
|
||||||
void setIsGroup(bool isGroup);
|
void setIsGroup(bool isGroup);
|
||||||
|
|
||||||
|
void setIsComplete(bool isComplete);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_isGroup;
|
bool m_isGroup;
|
||||||
|
bool m_isComplete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QUERY_NODE_H
|
#endif // QUERY_NODE_H
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ bool QueryOperator::isComplete() const
|
|||||||
|
|
||||||
void QueryOperator::print(std::ostream& ostream) const
|
void QueryOperator::print(std::ostream& ostream) const
|
||||||
{
|
{
|
||||||
ostream << m_type;
|
ostream << getOperator(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueryOperator::print(std::ostream& ostream, int n) const
|
void QueryOperator::print(std::ostream& ostream, int n) const
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void QueryTree::print(std::ostream& ostream) const
|
|||||||
|
|
||||||
if (!m_valid)
|
if (!m_valid)
|
||||||
{
|
{
|
||||||
ostream << " INVALID";
|
ostream << "INVALID";
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream << '\n';
|
ostream << '\n';
|
||||||
@@ -61,6 +61,12 @@ std::shared_ptr<QueryNode> QueryTree::buildTree(std::deque<std::string>& tokens,
|
|||||||
std::shared_ptr<QueryNode> node = getNextNode(tokens);
|
std::shared_ptr<QueryNode> node = getNextNode(tokens);
|
||||||
std::shared_ptr<QueryOperator> operatorNode = std::dynamic_pointer_cast<QueryOperator>(node);
|
std::shared_ptr<QueryOperator> operatorNode = std::dynamic_pointer_cast<QueryOperator>(node);
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
m_valid = false;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (frontNode)
|
if (frontNode)
|
||||||
{
|
{
|
||||||
if (node->isComplete())
|
if (node->isComplete())
|
||||||
@@ -109,7 +115,7 @@ std::shared_ptr<QueryNode> QueryTree::buildTree(std::deque<std::string>& tokens,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->isComplete())
|
if (!node || !node->isComplete())
|
||||||
{
|
{
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
@@ -122,6 +128,8 @@ std::shared_ptr<QueryNode> QueryTree::buildGroup(std::deque<std::string>& tokens
|
|||||||
std::deque<std::string> group;
|
std::deque<std::string> group;
|
||||||
std::string name;
|
std::string name;
|
||||||
char delimiter = QueryOperator::getOperator(closeType);
|
char delimiter = QueryOperator::getOperator(closeType);
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
while (tokens.front() != std::string(1, delimiter) && tokens.size())
|
while (tokens.front() != std::string(1, delimiter) && tokens.size())
|
||||||
{
|
{
|
||||||
group.push_back(tokens.front());
|
group.push_back(tokens.front());
|
||||||
@@ -135,6 +143,7 @@ std::shared_ptr<QueryNode> QueryTree::buildGroup(std::deque<std::string>& tokens
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
valid = false;
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,14 +152,18 @@ std::shared_ptr<QueryNode> QueryTree::buildGroup(std::deque<std::string>& tokens
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QueryNode> groupNode;
|
||||||
if (closeType == QueryOperator::OPERATOR_NAME)
|
if (closeType == QueryOperator::OPERATOR_NAME)
|
||||||
{
|
{
|
||||||
return std::make_shared<QueryToken>(name);
|
groupNode = std::make_shared<QueryToken>(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
groupNode = buildTree(group, nullptr);
|
||||||
|
groupNode->setIsGroup(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QueryNode> groupNode = buildTree(group, nullptr);
|
groupNode->setIsComplete(valid);
|
||||||
groupNode->setIsGroup(true);
|
|
||||||
|
|
||||||
return groupNode;
|
return groupNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +208,7 @@ std::shared_ptr<QueryNode> QueryTree::createCommand(std::string name)
|
|||||||
if (node->getType() == QueryCommand::COMMAND_INVALID)
|
if (node->getType() == QueryCommand::COMMAND_INVALID)
|
||||||
{
|
{
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@@ -100,8 +100,11 @@ ContainerType utility::tokenize(const ContainerType& list, const std::string& de
|
|||||||
|
|
||||||
for (std::string str : list)
|
for (std::string str : list)
|
||||||
{
|
{
|
||||||
ContainerType c2 = tokenize<ContainerType>(str, delimiter);
|
if (str.size())
|
||||||
c.insert(c.end(), c2.begin(), c2.end());
|
{
|
||||||
|
ContainerType c2 = tokenize<ContainerType>(str, delimiter);
|
||||||
|
c.insert(c.end(), c2.begin(), c2.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ add_files(
|
|||||||
GraphTestSuite.h
|
GraphTestSuite.h
|
||||||
LogManagerTestSuite.h
|
LogManagerTestSuite.h
|
||||||
MessageQueueTestSuite.h
|
MessageQueueTestSuite.h
|
||||||
|
QueryTreeTestSuite.h
|
||||||
SettingsTestSuite.h
|
SettingsTestSuite.h
|
||||||
StorageTestSuite.h
|
StorageTestSuite.h
|
||||||
TextAccessTestSuite.h
|
TextAccessTestSuite.h
|
||||||
|
|||||||
@@ -0,0 +1,351 @@
|
|||||||
|
#include "cxxtest/TestSuite.h"
|
||||||
|
|
||||||
|
#include "data/query/QueryTree.h"
|
||||||
|
|
||||||
|
class QueryTreeTestSuite : public CxxTest::TestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void test_empty_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree(""),
|
||||||
|
|
||||||
|
"INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree(" -"),
|
||||||
|
|
||||||
|
"- INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_command_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("class"),
|
||||||
|
|
||||||
|
"class \n"
|
||||||
|
"class\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_command_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("banana"),
|
||||||
|
|
||||||
|
"banana INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_token_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\""),
|
||||||
|
|
||||||
|
"\" A \" \n"
|
||||||
|
"\"A\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_token_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A"),
|
||||||
|
|
||||||
|
"\" A INVALID\n"
|
||||||
|
"\"A\" INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"\""),
|
||||||
|
|
||||||
|
"\" \" INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("A\""),
|
||||||
|
|
||||||
|
"A \" INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_not_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("!field"),
|
||||||
|
|
||||||
|
"! field \n"
|
||||||
|
"!\n"
|
||||||
|
" field\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("!!field"),
|
||||||
|
|
||||||
|
"! ! field \n"
|
||||||
|
"!\n"
|
||||||
|
" !\n"
|
||||||
|
" field\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_operator_not_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("!"),
|
||||||
|
|
||||||
|
"! INVALID\n"
|
||||||
|
"! INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("field!"),
|
||||||
|
|
||||||
|
"field ! INVALID\n"
|
||||||
|
" field\n"
|
||||||
|
"! INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_sub_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\".\"B\""),
|
||||||
|
|
||||||
|
"\" A \" . \" B \" \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
".\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_operator_sub_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\"."),
|
||||||
|
|
||||||
|
"\" A \" . INVALID\n"
|
||||||
|
" \"A\"\n"
|
||||||
|
". INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("."),
|
||||||
|
|
||||||
|
". INVALID\n"
|
||||||
|
". INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree(".\"A\""),
|
||||||
|
|
||||||
|
". \" A \" INVALID\n"
|
||||||
|
". INVALID\n"
|
||||||
|
" \"A\"\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\"..\"B\""),
|
||||||
|
|
||||||
|
"\" A \" . . \" B \" INVALID\n"
|
||||||
|
" \"A\"\n"
|
||||||
|
".\n"
|
||||||
|
" . INVALID\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_has_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\":\"B\""),
|
||||||
|
|
||||||
|
"\" A \" : \" B \" \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
":\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_and_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\"&\"B\""),
|
||||||
|
|
||||||
|
"\" A \" & \" B \" \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
"&\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_or_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\"|\"B\""),
|
||||||
|
|
||||||
|
"\" A \" | \" B \" \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
"|\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_group_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("(\"A\")"),
|
||||||
|
|
||||||
|
"( \" A \" ) \n"
|
||||||
|
"(\"A\")\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("(\"A\"|\"B\")"),
|
||||||
|
|
||||||
|
"( \" A \" | \" B \" ) \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
"(|)\n"
|
||||||
|
" \"B\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_invalid_operator_group_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("()"),
|
||||||
|
|
||||||
|
"( ) INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("(\"A\""),
|
||||||
|
|
||||||
|
"( \" A \" INVALID\n"
|
||||||
|
"(\"A\") INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\")"),
|
||||||
|
|
||||||
|
"\" A \" ) INVALID\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree(")("),
|
||||||
|
|
||||||
|
") ( INVALID\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_implicit_operator_sub_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("\"A\"(\"B\")"),
|
||||||
|
|
||||||
|
"\" A \" ( \" B \" ) \n"
|
||||||
|
" \"A\"\n"
|
||||||
|
".\n"
|
||||||
|
" (\"B\")\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_precedence_not_before_sub()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("!method.!const"),
|
||||||
|
|
||||||
|
"! method . ! const \n"
|
||||||
|
" !\n"
|
||||||
|
" method\n"
|
||||||
|
".\n"
|
||||||
|
" !\n"
|
||||||
|
" const\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_precedence_sub_before_has()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("namespace.class:method"),
|
||||||
|
|
||||||
|
"namespace . class : method \n"
|
||||||
|
" namespace\n"
|
||||||
|
" .\n"
|
||||||
|
" class\n"
|
||||||
|
":\n"
|
||||||
|
" method\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_precedence_has_before_or()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("class:method|field"),
|
||||||
|
|
||||||
|
"class : method | field \n"
|
||||||
|
" class\n"
|
||||||
|
" :\n"
|
||||||
|
" method\n"
|
||||||
|
"|\n"
|
||||||
|
" field\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_operator_precedence_respects_groups()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("namespace.(class:method)"),
|
||||||
|
|
||||||
|
"namespace . ( class : method ) \n"
|
||||||
|
" namespace\n"
|
||||||
|
".\n"
|
||||||
|
" class\n"
|
||||||
|
" (:)\n"
|
||||||
|
" method\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree("class:(method|field)"),
|
||||||
|
|
||||||
|
"class : ( method | field ) \n"
|
||||||
|
" class\n"
|
||||||
|
":\n"
|
||||||
|
" method\n"
|
||||||
|
" (|)\n"
|
||||||
|
" field\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_spaces_get_stripped_out_of_query()
|
||||||
|
{
|
||||||
|
TS_ASSERT_EQUALS(
|
||||||
|
printedQueryTree(" \"Field \":(method | field) .const | public "),
|
||||||
|
|
||||||
|
"\" Field \" : ( method | field ) . const | public \n"
|
||||||
|
" \"Field\"\n"
|
||||||
|
" :\n"
|
||||||
|
" method\n"
|
||||||
|
" (|)\n"
|
||||||
|
" field\n"
|
||||||
|
" .\n"
|
||||||
|
" const\n"
|
||||||
|
"|\n"
|
||||||
|
" public\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string printedQueryTree(std::string query) const
|
||||||
|
{
|
||||||
|
QueryTree tree(query);
|
||||||
|
std::stringstream ss;
|
||||||
|
tree.print(ss);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user