diff --git a/parser/test/parsertest.h b/parser/test/parsertest.h --- a/parser/test/parsertest.h +++ b/parser/test/parsertest.h @@ -24,6 +24,9 @@ namespace go { +class Lexer; +class AstNode; + class ParserTest : public QObject { Q_OBJECT @@ -42,11 +45,15 @@ void testIfClause(); void testFuncTypes(); void testForRangeLoop(); + void testForSingleConditionalLoop(); + void testForWithForClauseLoop(); + void testForWithEmptySingleConditionLoop(); void testEmptyLabeledStmt(); void testMapKeyLiteralValue(); //Go 1.5 feature - +private: + QByteArray getCodeFromNode(const QByteArray &code, go::Lexer *lexer, go::AstNode *node); }; } #endif \ No newline at end of file diff --git a/parser/test/parsertest.cpp b/parser/test/parsertest.cpp --- a/parser/test/parsertest.cpp +++ b/parser/test/parsertest.cpp @@ -181,6 +181,14 @@ KDevPG::QByteArrayIterator iter(code); *lexer = new go::Lexer(iter); (*parser)->setTokenStream(*lexer); + (*parser)->rewind(0); +} + +QByteArray ParserTest::getCodeFromNode(const QByteArray &code, go::Lexer *lexer, go::AstNode *node) +{ + auto startToken = lexer->at(node->startToken); + auto endToken = lexer->at(node->endToken); + return code.mid(startToken.begin, endToken.end - startToken.begin+1); } void ParserTest::testCommentsAreIgnored() @@ -227,9 +235,9 @@ QString content = code; const KDevPG::ListNode *node = ast->complexType->structType->fieldDeclSequence->front(); //qDebug() << code.mid(lexer.at(node->element->startToken).begin, lexer.at(node->element->endToken).end - lexer.at(node->element->startToken).begin+1); - QVERIFY( code.mid(lexer.at(node->element->startToken).begin, lexer.at(node->element->endToken).end - lexer.at(node->element->startToken).begin+1) - == "array [5][2]string"); - + auto actual = getCodeFromNode(code, &lexer, node->element); + QByteArray expected = "array [5][2]string"; + QCOMPARE(actual, expected); } @@ -289,6 +297,96 @@ QVERIFY(session.startParsing()); } +void ParserTest::testForSingleConditionalLoop() +{ + QByteArray code = "for i < 1 { i += 1 }\n"; + QByteArray expectedConditionCode = "i < 1"; + QByteArray expectedBlockCode = "{ i += 1 }"; + go::Parser *parser; + go::Lexer *lexer; + go::StatementsAst* ast; + prepareParser(code, &parser, &lexer); + + bool result = parser->parseStatements(&ast); + QVERIFY(result); + + auto forStmt = ast->statementSequence->front()->element->forStmt; + auto condition = forStmt->initStmtOrCondition; + auto block = forStmt->block; + bool foundCStyleCondition = forStmt->condition; + bool foundPostStmt = forStmt->postStmt; + QVERIFY(condition); + QVERIFY(block); + QVERIFY(!foundCStyleCondition); + QVERIFY(!foundPostStmt); + + auto conditionCode = getCodeFromNode(code, lexer, condition); + auto blockCode = getCodeFromNode(code, lexer, block); + QCOMPARE(conditionCode, expectedConditionCode); + QCOMPARE(blockCode, expectedBlockCode); +} + +void ParserTest::testForWithForClauseLoop() +{ + QByteArray code = "for i := 0; i < 10; i++ { f(i) }\n"; + QByteArray expectedInitStmtCode = "i := 0"; + QByteArray expectedConditionCode = "i < 10"; + QByteArray expectedPostStmtCode = "i++"; + QByteArray expectedBlockCode = "{ f(i) }"; + go::Parser *parser; + go::Lexer *lexer; + go::StatementsAst* ast; + prepareParser(code, &parser, &lexer); + + bool result = parser->parseStatements(&ast); + QVERIFY(result); + + auto forStmt = ast->statementSequence->front()->element->forStmt; + auto initStmt = forStmt->initStmtOrCondition; + auto condition = forStmt->condition; + auto postStmt = forStmt->postStmt; + auto block = forStmt->block; + QVERIFY(initStmt); + QVERIFY(condition); + QVERIFY(postStmt); + QVERIFY(block); + + auto initStmtCode = getCodeFromNode(code, lexer, initStmt); + auto conditionCode = getCodeFromNode(code, lexer, condition); + auto postStmtCode = getCodeFromNode(code, lexer, postStmt); + auto blockCode = getCodeFromNode(code, lexer, block); + QCOMPARE(initStmtCode, expectedInitStmtCode); + QCOMPARE(conditionCode, expectedConditionCode); + QCOMPARE(postStmtCode, expectedPostStmtCode); + QCOMPARE(blockCode, expectedBlockCode); +} + +void ParserTest::testForWithEmptySingleConditionLoop() +{ + QByteArray code = "for { i += 1 }\n"; + QByteArray expectedBlockCode = "{ i += 1 }"; + go::Parser *parser; + go::Lexer *lexer; + go::StatementsAst* ast; + prepareParser(code, &parser, &lexer); + + bool result = parser->parseStatements(&ast); + QVERIFY(result); + + auto forStmt = ast->statementSequence->front()->element->forStmt; + auto conditionNode = forStmt->initStmtOrCondition; + auto block = forStmt->block; + bool foundCStyleCondition = forStmt->condition; + bool foundPostStmt = forStmt->postStmt; + QVERIFY(!conditionNode); + QVERIFY(!foundCStyleCondition); + QVERIFY(!foundPostStmt); + QVERIFY(block); + + auto blockCode = getCodeFromNode(code, lexer, block); + QCOMPARE(blockCode, expectedBlockCode); +} + void ParserTest::testEmptyLabeledStmt() { QString code("package main; func main() { for i:=1; i<5; i++ { a := i; emptylabel: \n } }");