regextest.cpp 16.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Tencent is pleased to support the open source community by making RapidJSON available.
// 
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed 
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
// specific language governing permissions and limitations under the License.

#include "unittest.h"
#include "rapidjson/internal/regex.h"

using namespace rapidjson::internal;

Milo Yip's avatar
Milo Yip committed
20 21 22
TEST(Regex, Single) {
    Regex re("a");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
23 24 25 26
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("b"));
Milo Yip's avatar
Milo Yip committed
27 28
}

miloyip's avatar
miloyip committed
29
TEST(Regex, Concatenation) {
30
    Regex re("abc");
31
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
32 33 34 35 36 37 38
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("abcd"));
39 40
}

miloyip's avatar
miloyip committed
41
TEST(Regex, Alternation1) {
42 43
    Regex re("abab|abbb");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
44 45 46 47 48 49 50 51
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abab"));
    EXPECT_TRUE(rs.Match("abbb"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("ababa"));
    EXPECT_FALSE(rs.Match("abb"));
    EXPECT_FALSE(rs.Match("abbbb"));
52 53
}

miloyip's avatar
miloyip committed
54
TEST(Regex, Alternation2) {
55 56
    Regex re("a|b|c");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
57 58 59 60 61 62 63
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("c"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match("ab"));
64 65
}

miloyip's avatar
miloyip committed
66
TEST(Regex, Parenthesis1) {
67 68
    Regex re("(ab)c");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
69 70 71 72 73 74 75
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("abcd"));
76 77
}

miloyip's avatar
miloyip committed
78
TEST(Regex, Parenthesis2) {
79 80
    Regex re("a(bc)");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
81 82 83 84 85 86 87
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("abcd"));
88 89
}

miloyip's avatar
miloyip committed
90
TEST(Regex, Parenthesis3) {
91 92
    Regex re("(a|b)(c|d)");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
93 94 95 96 97 98 99 100
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ac"));
    EXPECT_TRUE(rs.Match("ad"));
    EXPECT_TRUE(rs.Match("bc"));
    EXPECT_TRUE(rs.Match("bd"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("cd"));
101
}
miloyip's avatar
miloyip committed
102 103 104 105

TEST(Regex, ZeroOrOne1) {
    Regex re("a?");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
106 107 108 109
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match(""));
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
110 111 112 113 114
}

TEST(Regex, ZeroOrOne2) {
    Regex re("a?b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
115 116 117 118 119 120 121
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match("bb"));
    EXPECT_FALSE(rs.Match("ba"));
miloyip's avatar
miloyip committed
122 123 124 125 126
}

TEST(Regex, ZeroOrOne3) {
    Regex re("ab?");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
127 128 129 130 131 132 133
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match("bb"));
    EXPECT_FALSE(rs.Match("ba"));
miloyip's avatar
miloyip committed
134 135 136 137 138
}

TEST(Regex, ZeroOrOne4) {
    Regex re("a?b?");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
139 140 141 142 143 144 145 146 147
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match(""));
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_FALSE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match("bb"));
    EXPECT_FALSE(rs.Match("ba"));
    EXPECT_FALSE(rs.Match("abc"));
miloyip's avatar
miloyip committed
148 149 150 151 152
}

TEST(Regex, ZeroOrOne5) {
    Regex re("a(ab)?b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
153 154 155 156 157
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aabb"));
    EXPECT_FALSE(rs.Match("aab"));
    EXPECT_FALSE(rs.Match("abb"));
miloyip's avatar
miloyip committed
158 159 160 161 162
}

TEST(Regex, ZeroOrMore1) {
    Regex re("a*");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
163 164 165 166 167 168
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match(""));
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ab"));
miloyip's avatar
miloyip committed
169 170 171 172 173
}

TEST(Regex, ZeroOrMore2) {
    Regex re("a*b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
174 175 176 177 178 179
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aab"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("bb"));
miloyip's avatar
miloyip committed
180 181 182 183 184
}

TEST(Regex, ZeroOrMore3) {
    Regex re("a*b*");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
185 186 187 188 189 190 191 192 193
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match(""));
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("aa"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("bb"));
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aabb"));
    EXPECT_FALSE(rs.Match("ba"));
miloyip's avatar
miloyip committed
194 195 196 197 198
}

TEST(Regex, ZeroOrMore4) {
    Regex re("a(ab)*b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
199 200 201 202 203 204
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aabb"));
    EXPECT_TRUE(rs.Match("aababb"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
205 206 207 208 209
}

TEST(Regex, OneOrMore1) {
    Regex re("a+");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
210 211 212 213 214 215
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("aa"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ab"));
miloyip's avatar
miloyip committed
216 217 218 219 220
}

TEST(Regex, OneOrMore2) {
    Regex re("a+b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
221 222 223 224 225
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aab"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("b"));
miloyip's avatar
miloyip committed
226 227 228 229 230
}

TEST(Regex, OneOrMore3) {
    Regex re("a+b+");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
231 232 233 234 235 236 237 238
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ab"));
    EXPECT_TRUE(rs.Match("aab"));
    EXPECT_TRUE(rs.Match("abb"));
    EXPECT_TRUE(rs.Match("aabb"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("ba"));
miloyip's avatar
miloyip committed
239 240 241 242 243
}

TEST(Regex, OneOrMore4) {
    Regex re("a(ab)+b");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
244 245 246 247 248
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("aabb"));
    EXPECT_TRUE(rs.Match("aababb"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("ab"));
miloyip's avatar
miloyip committed
249
}
miloyip's avatar
miloyip committed
250

miloyip's avatar
miloyip committed
251 252 253
TEST(Regex, QuantifierExact1) {
    Regex re("ab{3}c");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
254 255 256 257 258 259
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbc"));
    EXPECT_FALSE(rs.Match("ac"));
    EXPECT_FALSE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match("abbc"));
    EXPECT_FALSE(rs.Match("abbbbc"));
miloyip's avatar
miloyip committed
260 261 262 263 264
}

TEST(Regex, QuantifierExact2) {
    Regex re("a(bc){3}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
265 266 267 268 269 270
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abcbcbcd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abcd"));
    EXPECT_FALSE(rs.Match("abcbcd"));
    EXPECT_FALSE(rs.Match("abcbcbcbcd"));
miloyip's avatar
miloyip committed
271 272 273 274 275
}

TEST(Regex, QuantifierExact3) {
    Regex re("a(b|c){3}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
276 277 278 279 280 281 282 283
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbd"));
    EXPECT_TRUE(rs.Match("acccd"));
    EXPECT_TRUE(rs.Match("abcbd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abbd"));
    EXPECT_FALSE(rs.Match("accccd"));
    EXPECT_FALSE(rs.Match("abbbbd"));
miloyip's avatar
miloyip committed
284 285 286 287 288
}

TEST(Regex, QuantifierMin1) {
    Regex re("ab{3,}c");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
289 290 291 292 293 294 295
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbc"));
    EXPECT_TRUE(rs.Match("abbbbc"));
    EXPECT_TRUE(rs.Match("abbbbbc"));
    EXPECT_FALSE(rs.Match("ac"));
    EXPECT_FALSE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match("abbc"));
miloyip's avatar
miloyip committed
296 297 298 299 300
}

TEST(Regex, QuantifierMin2) {
    Regex re("a(bc){3,}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
301 302 303 304 305 306
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abcbcbcd"));
    EXPECT_TRUE(rs.Match("abcbcbcbcd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abcd"));
    EXPECT_FALSE(rs.Match("abcbcd"));
miloyip's avatar
miloyip committed
307 308 309 310 311
}

TEST(Regex, QuantifierMin3) {
    Regex re("a(b|c){3,}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
312 313 314 315 316 317 318 319
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbd"));
    EXPECT_TRUE(rs.Match("acccd"));
    EXPECT_TRUE(rs.Match("abcbd"));
    EXPECT_TRUE(rs.Match("accccd"));
    EXPECT_TRUE(rs.Match("abbbbd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abbd"));
miloyip's avatar
miloyip committed
320 321 322 323 324
}

TEST(Regex, QuantifierMinMax1) {
    Regex re("ab{3,5}c");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
325 326 327 328 329 330 331 332
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbc"));
    EXPECT_TRUE(rs.Match("abbbbc"));
    EXPECT_TRUE(rs.Match("abbbbbc"));
    EXPECT_FALSE(rs.Match("ac"));
    EXPECT_FALSE(rs.Match("abc"));
    EXPECT_FALSE(rs.Match("abbc"));
    EXPECT_FALSE(rs.Match("abbbbbbc"));
miloyip's avatar
miloyip committed
333 334 335 336 337
}

TEST(Regex, QuantifierMinMax2) {
    Regex re("a(bc){3,5}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
338 339 340 341 342 343 344 345
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abcbcbcd"));
    EXPECT_TRUE(rs.Match("abcbcbcbcd"));
    EXPECT_TRUE(rs.Match("abcbcbcbcbcd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abcd"));
    EXPECT_FALSE(rs.Match("abcbcd"));
    EXPECT_FALSE(rs.Match("abcbcbcbcbcbcd"));
miloyip's avatar
miloyip committed
346 347 348 349 350
}

TEST(Regex, QuantifierMinMax3) {
    Regex re("a(b|c){3,5}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
351 352 353 354 355 356 357 358 359 360 361 362
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("abbbd"));
    EXPECT_TRUE(rs.Match("acccd"));
    EXPECT_TRUE(rs.Match("abcbd"));
    EXPECT_TRUE(rs.Match("accccd"));
    EXPECT_TRUE(rs.Match("abbbbd"));
    EXPECT_TRUE(rs.Match("acccccd"));
    EXPECT_TRUE(rs.Match("abbbbbd"));
    EXPECT_FALSE(rs.Match("ad"));
    EXPECT_FALSE(rs.Match("abbd"));
    EXPECT_FALSE(rs.Match("accccccd"));
    EXPECT_FALSE(rs.Match("abbbbbbd"));
miloyip's avatar
miloyip committed
363 364
}

365 366 367 368
// Issue538
TEST(Regex, QuantifierMinMax4) {
    Regex re("a(b|c){0,3}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
369 370 371 372 373 374 375 376 377 378 379 380 381
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ad"));
    EXPECT_TRUE(rs.Match("abd"));
    EXPECT_TRUE(rs.Match("acd"));
    EXPECT_TRUE(rs.Match("abbd"));
    EXPECT_TRUE(rs.Match("accd"));
    EXPECT_TRUE(rs.Match("abcd"));
    EXPECT_TRUE(rs.Match("abbbd"));
    EXPECT_TRUE(rs.Match("acccd"));
    EXPECT_FALSE(rs.Match("abbbbd"));
    EXPECT_FALSE(rs.Match("add"));
    EXPECT_FALSE(rs.Match("accccd"));
    EXPECT_FALSE(rs.Match("abcbcd"));
382 383 384 385 386 387
}

// Issue538
TEST(Regex, QuantifierMinMax5) {
    Regex re("a(b|c){0,}d");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
388 389 390 391 392 393 394 395 396 397 398 399 400 401
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("ad"));
    EXPECT_TRUE(rs.Match("abd"));
    EXPECT_TRUE(rs.Match("acd"));
    EXPECT_TRUE(rs.Match("abbd"));
    EXPECT_TRUE(rs.Match("accd"));
    EXPECT_TRUE(rs.Match("abcd"));
    EXPECT_TRUE(rs.Match("abbbd"));
    EXPECT_TRUE(rs.Match("acccd"));
    EXPECT_TRUE(rs.Match("abbbbd"));
    EXPECT_TRUE(rs.Match("accccd"));
    EXPECT_TRUE(rs.Match("abcbcd"));
    EXPECT_FALSE(rs.Match("add"));
    EXPECT_FALSE(rs.Match("aad"));
402 403
}

Milo Yip's avatar
Milo Yip committed
404
#define EURO "\xE2\x82\xAC" // "\xE2\x82\xAC" is UTF-8 rsquence of Euro sign U+20AC
405 406

TEST(Regex, Unicode) {
miloyip's avatar
miloyip committed
407 408
    Regex re("a" EURO "+b"); 
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
409 410 411 412 413
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a" EURO "b"));
    EXPECT_TRUE(rs.Match("a" EURO EURO "b"));
    EXPECT_FALSE(rs.Match("a?b"));
    EXPECT_FALSE(rs.Match("a" EURO "\xAC" "b")); // unaware of UTF-8 will match
miloyip's avatar
miloyip committed
414
}
415 416 417 418

TEST(Regex, AnyCharacter) {
    Regex re(".");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
419 420 421 422 423 424
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match(EURO));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("aa"));
425 426
}

miloyip's avatar
miloyip committed
427 428 429
TEST(Regex, CharacterRange1) {
    Regex re("[abc]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
430 431 432 433 434 435 436 437
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("c"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("`"));
    EXPECT_FALSE(rs.Match("d"));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
438 439 440 441 442
}

TEST(Regex, CharacterRange2) {
    Regex re("[^abc]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
443 444 445 446 447 448 449 450
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("`"));
    EXPECT_TRUE(rs.Match("d"));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("c"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
451 452 453 454 455
}

TEST(Regex, CharacterRange3) {
    Regex re("[a-c]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
456 457 458 459 460 461 462 463
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("b"));
    EXPECT_TRUE(rs.Match("c"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("`"));
    EXPECT_FALSE(rs.Match("d"));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
464 465 466 467 468
}

TEST(Regex, CharacterRange4) {
    Regex re("[^a-c]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
469 470 471 472 473 474 475 476
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("`"));
    EXPECT_TRUE(rs.Match("d"));
    EXPECT_FALSE(rs.Match("a"));
    EXPECT_FALSE(rs.Match("b"));
    EXPECT_FALSE(rs.Match("c"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("aa"));
miloyip's avatar
miloyip committed
477 478 479 480 481
}

TEST(Regex, CharacterRange5) {
    Regex re("[-]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
482 483 484 485
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("-"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("a"));
miloyip's avatar
miloyip committed
486 487 488 489 490
}

TEST(Regex, CharacterRange6) {
    Regex re("[a-]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
491 492 493 494 495 496
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("-"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("`"));
    EXPECT_FALSE(rs.Match("b"));
miloyip's avatar
miloyip committed
497 498 499 500 501
}

TEST(Regex, CharacterRange7) {
    Regex re("[-a]");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
502 503 504 505 506 507
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("a"));
    EXPECT_TRUE(rs.Match("-"));
    EXPECT_FALSE(rs.Match(""));
    EXPECT_FALSE(rs.Match("`"));
    EXPECT_FALSE(rs.Match("b"));
miloyip's avatar
miloyip committed
508 509 510 511 512
}

TEST(Regex, CharacterRange8) {
    Regex re("[a-zA-Z0-9]*");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
513 514 515 516 517 518
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("Milo"));
    EXPECT_TRUE(rs.Match("MT19937"));
    EXPECT_TRUE(rs.Match("43"));
    EXPECT_FALSE(rs.Match("a_b"));
    EXPECT_FALSE(rs.Match("!"));
miloyip's avatar
miloyip committed
519 520
}

521 522 523
TEST(Regex, Search) {
    Regex re("abc");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
524 525 526 527 528 529 530 531 532 533 534
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Search("abc"));
    EXPECT_TRUE(rs.Search("_abc"));
    EXPECT_TRUE(rs.Search("abc_"));
    EXPECT_TRUE(rs.Search("_abc_"));
    EXPECT_TRUE(rs.Search("__abc__"));
    EXPECT_TRUE(rs.Search("abcabc"));
    EXPECT_FALSE(rs.Search("a"));
    EXPECT_FALSE(rs.Search("ab"));
    EXPECT_FALSE(rs.Search("bc"));
    EXPECT_FALSE(rs.Search("cba"));
535 536 537 538 539
}

TEST(Regex, Search_BeginAnchor) {
    Regex re("^abc");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
540 541 542 543 544 545 546 547 548 549
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Search("abc"));
    EXPECT_TRUE(rs.Search("abc_"));
    EXPECT_TRUE(rs.Search("abcabc"));
    EXPECT_FALSE(rs.Search("_abc"));
    EXPECT_FALSE(rs.Search("_abc_"));
    EXPECT_FALSE(rs.Search("a"));
    EXPECT_FALSE(rs.Search("ab"));
    EXPECT_FALSE(rs.Search("bc"));
    EXPECT_FALSE(rs.Search("cba"));
550 551 552 553 554
}

TEST(Regex, Search_EndAnchor) {
    Regex re("abc$");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
555 556 557 558 559 560 561 562 563 564
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Search("abc"));
    EXPECT_TRUE(rs.Search("_abc"));
    EXPECT_TRUE(rs.Search("abcabc"));
    EXPECT_FALSE(rs.Search("abc_"));
    EXPECT_FALSE(rs.Search("_abc_"));
    EXPECT_FALSE(rs.Search("a"));
    EXPECT_FALSE(rs.Search("ab"));
    EXPECT_FALSE(rs.Search("bc"));
    EXPECT_FALSE(rs.Search("cba"));
565 566 567 568 569
}

TEST(Regex, Search_BothAnchor) {
    Regex re("^abc$");
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
570 571 572 573 574 575 576
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Search("abc"));
    EXPECT_FALSE(rs.Search(""));
    EXPECT_FALSE(rs.Search("a"));
    EXPECT_FALSE(rs.Search("b"));
    EXPECT_FALSE(rs.Search("ab"));
    EXPECT_FALSE(rs.Search("abcd"));
577 578
}

579
TEST(Regex, Escape) {
580
    const char* s = "\\^\\$\\|\\(\\)\\?\\*\\+\\.\\[\\]\\{\\}\\\\\\f\\n\\r\\t\\v[\\b][\\[][\\]]";
581 582
    Regex re(s);
    ASSERT_TRUE(re.IsValid());
Milo Yip's avatar
Milo Yip committed
583 584 585
    RegexSearch rs(re);
    EXPECT_TRUE(rs.Match("^$|()?*+.[]{}\\\x0C\n\r\t\x0B\b[]"));
    EXPECT_FALSE(rs.Match(s)); // Not escaping
586 587
}

588 589 590 591 592 593 594
TEST(Regex, Invalid) {
#define TEST_INVALID(s) \
    {\
        Regex re(s);\
        EXPECT_FALSE(re.IsValid());\
    }

595
    TEST_INVALID("");
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
    TEST_INVALID("a|");
    TEST_INVALID("()");
    TEST_INVALID(")");
    TEST_INVALID("(a))");
    TEST_INVALID("(a|)");
    TEST_INVALID("(a||b)");
    TEST_INVALID("(|b)");
    TEST_INVALID("?");
    TEST_INVALID("*");
    TEST_INVALID("+");
    TEST_INVALID("{");
    TEST_INVALID("{}");
    TEST_INVALID("a{a}");
    TEST_INVALID("a{0}");
    TEST_INVALID("a{-1}");
    TEST_INVALID("a{}");
612
    // TEST_INVALID("a{0,}");   // Support now
613 614 615 616
    TEST_INVALID("a{,0}");
    TEST_INVALID("a{1,0}");
    TEST_INVALID("a{-1,0}");
    TEST_INVALID("a{-1,1}");
Milo Yip's avatar
Milo Yip committed
617 618 619
    TEST_INVALID("a{4294967296}"); // overflow of unsigned
    TEST_INVALID("a{1a}");
    TEST_INVALID("[");
620 621 622 623 624 625 626 627
    TEST_INVALID("[]");
    TEST_INVALID("[^]");
    TEST_INVALID("[\\a]");
    TEST_INVALID("\\a");

#undef TEST_INVALID
}

628 629 630 631 632
TEST(Regex, Issue538) {
    Regex re("^[0-9]+(\\\\.[0-9]+){0,2}");
    EXPECT_TRUE(re.IsValid());
}

Milo Yip's avatar
Milo Yip committed
633 634 635 636 637
TEST(Regex, Issue583) {
    Regex re("[0-9]{99999}");
    ASSERT_TRUE(re.IsValid());
}

638
#undef EURO