1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/perfetto_sql/tokenizer/sqlite_tokenizer.h"
18 
19 #include <vector>
20 
21 #include "src/trace_processor/sqlite/sql_source.h"
22 #include "test/gtest_and_gmock.h"
23 
24 namespace perfetto::trace_processor {
25 namespace {
26 
27 using Token = SqliteTokenizer::Token;
28 
29 class SqliteTokenizerTest : public ::testing::Test {
30  protected:
Tokenize(const char * ptr)31   std::vector<SqliteTokenizer::Token> Tokenize(const char* ptr) {
32     tokenizer_.Reset(SqlSource::FromTraceProcessorImplementation(ptr));
33     std::vector<SqliteTokenizer::Token> tokens;
34     for (auto t = tokenizer_.Next(); !t.str.empty(); t = tokenizer_.Next()) {
35       tokens.push_back(t);
36     }
37     return tokens;
38   }
39 
40   SqliteTokenizer tokenizer_{SqlSource::FromTraceProcessorImplementation("")};
41 };
42 
TEST_F(SqliteTokenizerTest,EmptyString)43 TEST_F(SqliteTokenizerTest, EmptyString) {
44   ASSERT_THAT(Tokenize(""), testing::IsEmpty());
45 }
46 
TEST_F(SqliteTokenizerTest,OnlySpace)47 TEST_F(SqliteTokenizerTest, OnlySpace) {
48   ASSERT_THAT(Tokenize(" "), testing::ElementsAre(Token{" ", TK_SPACE}));
49 }
50 
TEST_F(SqliteTokenizerTest,SpaceColon)51 TEST_F(SqliteTokenizerTest, SpaceColon) {
52   ASSERT_THAT(Tokenize(" ;"),
53               testing::ElementsAre(Token{" ", TK_SPACE}, Token{";", TK_SEMI}));
54 }
55 
TEST_F(SqliteTokenizerTest,Select)56 TEST_F(SqliteTokenizerTest, Select) {
57   ASSERT_THAT(
58       Tokenize("SELECT * FROM slice;"),
59       testing::ElementsAre(Token{"SELECT", TK_SELECT}, Token{" ", TK_SPACE},
60                            Token{"*", TK_STAR}, Token{" ", TK_SPACE},
61                            Token{"FROM", TK_FROM}, Token{" ", TK_SPACE},
62                            Token{"slice", TK_ID}, Token{";", TK_SEMI}));
63 }
64 
TEST_F(SqliteTokenizerTest,PastEndErrorToken)65 TEST_F(SqliteTokenizerTest, PastEndErrorToken) {
66   tokenizer_.Reset(SqlSource::FromTraceProcessorImplementation("S"));
67   ASSERT_EQ(tokenizer_.Next(), (Token{"S", TK_ID}));
68 
69   auto end_token = tokenizer_.Next();
70   ASSERT_EQ(end_token, (Token{"", TK_ILLEGAL}));
71   ASSERT_EQ(tokenizer_.AsTraceback(end_token),
72             "  Trace Processor Internal line 1 col 2\n"
73             "    S\n"
74             "     ^\n");
75 }
76 
77 }  // namespace
78 }  // namespace perfetto::trace_processor
79