pgLab/tests/pglabtests/tst_SqlLexer.cpp
eelke 0cd019db92 Fix for $-quoted strings
Note this does not solve all issues because we are tokenizing contents of strings of which we do not know they contains SQL
when the string is actually not SQL and contains $ the tokenizer gets confused.
2023-01-07 07:41:58 +01:00

154 lines
4 KiB
C++

#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
#include "SqlLexer.h"
#include "PrintTo_Qt.h"
using namespace testing;
TEST(SqlLexer, emptyInput)
{
QString input;
SqlLexer lexer(input, LexerState::Null);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT(tokentype, Eq(BasicTokenType::End));
}
TEST(SqlLexer, emptyDollarQuote)
{
QString input = "$$";
SqlLexer lexer(input, LexerState::Null);
int startpos = -1, length = -1;
BasicTokenType tokentype = BasicTokenType::None;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT("$$", Eq(out));
ASSERT_THAT(tokentype, Eq(BasicTokenType::DollarQuote));
}
TEST(SqlLexer, filledDollarQuote)
{
QString input = "$body$";
SqlLexer lexer(input, LexerState::Null);
int startpos = -1, length = -1;
BasicTokenType tokentype = BasicTokenType::None;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT("$body$", Eq(out));
ASSERT_THAT(tokentype, Eq(BasicTokenType::DollarQuote));
}
TEST(SqlLexer, lexer)
{
QString input = " SELECT ";
SqlLexer lexer(input, LexerState::Null);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(1));
ASSERT_THAT(length, Eq(6));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol));
ASSERT_THAT( out, Eq(QString("SELECT")) );
}
TEST(SqlLexer, lexerWithWhiteSpace)
{
QString input = " SELECT ";
SqlLexer lexer(input, LexerState::Null, true);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT(length, Eq(1));
ASSERT_THAT(tokentype, Eq(BasicTokenType::WhiteSpace));
ASSERT_THAT(out, Eq(QString(" ")) );
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(1));
ASSERT_THAT(length, Eq(6));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol));
ASSERT_THAT(out, Eq(QString("SELECT")) );
}
TEST(SqlLexer, lexer_quote_in_string)
{
QString input = " 'abc''def' ";
SqlLexer lexer(input, LexerState::Null);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(1));
ASSERT_THAT(length, Eq(10));
ASSERT_THAT(tokentype, Eq(BasicTokenType::QuotedString));
ASSERT_THAT(out, Eq(QString("'abc''def'")) );
}
TEST(SqlLexer, lexer_comma_handling)
{
QString input = "abc,def";
SqlLexer lexer(input, LexerState::Null);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT(length, Eq(3));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol));
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(3));
ASSERT_THAT(length, Eq(1));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Comma));
ASSERT_THAT(out, Eq(QString(",")));
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(4));
ASSERT_THAT(length, Eq(3));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol));
}
TEST(SqlLexer, lexer_cast)
{
QString input = "'1'::integer";
SqlLexer lexer(input, LexerState::Null);
int startpos, length;
BasicTokenType tokentype;
QString out;
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(0));
ASSERT_THAT(length, Eq(3));
ASSERT_THAT(tokentype, Eq(BasicTokenType::QuotedString));
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(3));
ASSERT_THAT(length, Eq(2));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Cast));
lexer.nextBasicToken(startpos, length, tokentype, out);
ASSERT_THAT(startpos, Eq(5));
ASSERT_THAT(length, Eq(7));
ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol));
}