• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 package com.android.providers.tv.util;
18 
19 import android.annotation.Nullable;
20 import android.test.AndroidTestCase;
21 import android.util.Pair;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.function.Consumer;
26 
27 /**
28  * Tests for {@link SqliteTokenFinder}.
29  *
30  * Modified from
31  * packages/providers/ContactsProvider/tests/src/com/android/providers/contacts/sqlite/SqlCheckerTest.java
32  */
33 public class SqliteTokenFinderTest extends AndroidTestCase {
getTokens(String sql)34     private List<Pair<Integer, String>> getTokens(String sql) {
35         List<Pair<Integer, String>> tokens = new ArrayList<>();
36         SqliteTokenFinder.findTokens(sql, new Consumer<Pair<Integer, String>>() {
37             @Override
38             public void accept(Pair<Integer, String> pair) {
39                 tokens.add(pair);
40             }
41         });
42         return tokens;
43     }
44 
checkTokens(String sql, Pair<Integer, String>... tokens)45     private void checkTokens(String sql, Pair<Integer, String>... tokens) {
46         final List<Pair<Integer, String>> expected = Arrays.asList(tokens);
47 
48         assertEquals(expected, getTokens(sql));
49     }
50 
checkTokensRegular(String sql, @Nullable String tokens)51     private void checkTokensRegular(String sql, @Nullable String tokens) {
52         List<Pair<Integer, String>> expected = new ArrayList<>();
53 
54         if (tokens != null) {
55             for (String token : tokens.split(" ")) {
56                 expected.add(Pair.create(SqliteTokenFinder.TYPE_REGULAR, token));
57             }
58         }
59 
60         assertEquals(expected, getTokens(sql));
61     }
62 
assertInvalidSql(String sql, String message)63     private void assertInvalidSql(String sql, String message) {
64         try {
65             getTokens(sql);
66             fail("Didn't throw Exception");
67         } catch (Exception e) {
68             assertTrue("Expected " + e.getMessage() + " to contain " + message,
69                     e.getMessage().contains(message));
70         }
71     }
72 
testWhitespaces()73     public void testWhitespaces() {
74         checkTokensRegular("  select  \t\r\n a\n\n  ", "select a");
75         checkTokensRegular("a b", "a b");
76     }
77 
testComment()78     public void testComment() {
79         checkTokensRegular("--\n", null);
80         checkTokensRegular("a--\n", "a");
81         checkTokensRegular("a--abcdef\n", "a");
82         checkTokensRegular("a--abcdef\nx", "a x");
83         checkTokensRegular("a--\nx", "a x");
84         checkTokensRegular("a--abcdef", "a");
85         checkTokensRegular("a--abcdef\ndef--", "a def");
86 
87         checkTokensRegular("/**/", null);
88         assertInvalidSql("/*", "Unterminated comment");
89         assertInvalidSql("/*/", "Unterminated comment");
90         assertInvalidSql("/*\n* /*a", "Unterminated comment");
91         checkTokensRegular("a/**/", "a");
92         checkTokensRegular("/**/b", "b");
93         checkTokensRegular("a/**/b", "a b");
94         checkTokensRegular("a/* -- \n* /* **/b", "a b");
95     }
96 
testSingleQuotes()97     public void testSingleQuotes() {
98         assertInvalidSql("'", "Unterminated quote");
99         assertInvalidSql("a'", "Unterminated quote");
100         assertInvalidSql("a'''", "Unterminated quote");
101         assertInvalidSql("a''' ", "Unterminated quote");
102         checkTokens("''", Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, ""));
103 
104         // 2 consecutive quotes inside quotes stands for a quote. e.g.'let''s go' -> let's go
105         checkTokens(
106                 "''''",
107                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "\'"));
108         checkTokens(
109                 "a''''b",
110                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
111                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "\'"),
112                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
113         checkTokens(
114                 "a' '' 'b",
115                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
116                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, " \' "),
117                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
118         checkTokens("'abc'", Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "abc"));
119         checkTokens("'abc\ndef'", Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "abc\ndef"));
120         checkTokens(
121                 "a'abc\ndef'",
122                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
123                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "abc\ndef"));
124         checkTokens(
125                 "'abc\ndef'b",
126                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "abc\ndef"),
127                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
128         checkTokens("a'abc\ndef'b",
129                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
130                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "abc\ndef"),
131                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
132         checkTokens(
133                 "a'''abc\nd''ef'''b",
134                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
135                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "\'abc\nd\'ef\'"),
136                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
137     }
138 
testDoubleQuotes()139     public void testDoubleQuotes() {
140         assertInvalidSql("\"", "Unterminated quote");
141         assertInvalidSql("a\"", "Unterminated quote");
142         assertInvalidSql("a\"\"\"", "Unterminated quote");
143         assertInvalidSql("a\"\"\" ", "Unterminated quote");
144         checkTokens("\"\"", Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, ""));
145         checkTokens("\"\"\"\"", Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "\""));
146         checkTokens(
147                 "a\"\"\"\"b",
148                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
149                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "\""),
150                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
151         checkTokens("a\"\t\"\"\t\"b",
152                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
153                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "\t\"\t"),
154                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
155         checkTokens("\"abc\"", Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "abc"));
156         checkTokens(
157                 "\"abc\ndef\"",
158                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "abc\ndef"));
159         checkTokens(
160                 "a\"abc\ndef\"",
161                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
162                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "abc\ndef"));
163         checkTokens(
164                 "\"abc\ndef\"b",
165                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "abc\ndef"),
166                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
167         checkTokens("a\"abc\ndef\"b",
168                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
169                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "abc\ndef"),
170                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
171         checkTokens("a\"\"\"abc\nd\"\"ef\"\"\"b",
172                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
173                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "\"abc\nd\"ef\""),
174                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
175     }
176 
testBackquotes()177     public void testBackquotes() {
178         assertInvalidSql("`", "Unterminated quote");
179         assertInvalidSql("a`", "Unterminated quote");
180         assertInvalidSql("a```", "Unterminated quote");
181         assertInvalidSql("a``` ", "Unterminated quote");
182         checkTokens("``", Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, ""));
183         checkTokens("````", Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "`"));
184         checkTokens(
185                 "a````b",
186                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
187                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "`"),
188                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
189         checkTokens(
190                 "a`\t``\t`b",
191                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
192                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "\t`\t"),
193                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
194         checkTokens("`abc`", Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "abc"));
195         checkTokens(
196                 "`abc\ndef`",
197                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "abc\ndef"));
198         checkTokens(
199                 "a`abc\ndef`",
200                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
201                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "abc\ndef"));
202         checkTokens(
203                 "`abc\ndef`b",
204                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "abc\ndef"),
205                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
206         checkTokens(
207                 "a`abc\ndef`b",
208                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
209                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "abc\ndef"),
210                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
211         checkTokens(
212                 "a```abc\nd``ef```b",
213                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
214                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "`abc\nd`ef`"),
215                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
216     }
217 
testBrackets()218     public void testBrackets() {
219         assertInvalidSql("[", "Unterminated quote");
220         assertInvalidSql("a[", "Unterminated quote");
221         assertInvalidSql("a[ ", "Unterminated quote");
222         assertInvalidSql("a[[ ", "Unterminated quote");
223         checkTokens("[]", Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, ""));
224         checkTokens("[[]", Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "["));
225         checkTokens(
226                 "a[[]b",
227                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
228                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "["),
229                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
230         checkTokens(
231                 "a[\t[\t]b",
232                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
233                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "\t[\t"),
234                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
235         checkTokens("[abc]", Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "abc"));
236         checkTokens(
237                 "[abc\ndef]",
238                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "abc\ndef"));
239         checkTokens(
240                 "a[abc\ndef]",
241                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
242                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "abc\ndef"));
243         checkTokens(
244                 "[abc\ndef]b",
245                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "abc\ndef"),
246                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
247         checkTokens(
248                 "a[abc\ndef]b",
249                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
250                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "abc\ndef"),
251                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
252         checkTokens(
253                 "a[[abc\nd[ef[]b",
254                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
255                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "[abc\nd[ef["),
256                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "b"));
257     }
258 
testTokens()259     public void testTokens() {
260         checkTokensRegular("a,abc,a00b,_1,_123,abcdef", "a abc a00b _1 _123 abcdef");
261         checkTokens(
262                 "a--\nabc/**/a00b''_1'''ABC'''`_123`abc[d]\"e\"f",
263                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a"),
264                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "abc"),
265                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "a00b"),
266                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, ""),
267                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "_1"),
268                 Pair.create(SqliteTokenFinder.TYPE_IN_SINGLE_QUOTES, "'ABC'"),
269                 Pair.create(SqliteTokenFinder.TYPE_IN_BACKQUOTES, "_123"),
270                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "abc"),
271                 Pair.create(SqliteTokenFinder.TYPE_IN_BRACKETS, "d"),
272                 Pair.create(SqliteTokenFinder.TYPE_IN_DOUBLE_QUOTES, "e"),
273                 Pair.create(SqliteTokenFinder.TYPE_REGULAR, "f"));
274     }
275 }
276