pattern_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // found in the LICENSE file or at https://opensource.org/licenses/MIT.
  4. #include "third_party/liburlpattern/pattern.h"
  5. #include "testing/gtest/include/gtest/gtest.h"
  6. #include "third_party/liburlpattern/parse.h"
  7. namespace {
  8. absl::StatusOr<std::string> PassThrough(absl::string_view input) {
  9. return std::string(input);
  10. }
  11. } // namespace
  12. namespace liburlpattern {
  13. void RunRegexTest(absl::string_view input,
  14. absl::string_view expected_regex,
  15. std::vector<std::string> expected_name_list,
  16. Options options = Options()) {
  17. auto result = Parse(input, PassThrough, options);
  18. ASSERT_TRUE(result.ok());
  19. auto& pattern = result.value();
  20. std::vector<std::string> name_list;
  21. std::string regex = pattern.GenerateRegexString(&name_list);
  22. EXPECT_EQ(regex, expected_regex);
  23. EXPECT_EQ(name_list, expected_name_list);
  24. }
  25. // The following expected test case values were generated using path-to-regexp
  26. // 6.2.0.
  27. TEST(PatternRegexTest, Fixed) {
  28. RunRegexTest("/foo/bar", R"(^\/foo\/bar[\/#\?]?$)", {});
  29. }
  30. TEST(PatternRegexTest, FixedWithModifier) {
  31. RunRegexTest("{/foo/bar}?", R"(^(?:\/foo\/bar)?[\/#\?]?$)", {});
  32. }
  33. TEST(PatternRegexTest, Name) {
  34. RunRegexTest(":foo", R"(^([^\/#\?]+?)[\/#\?]?$)", {"foo"});
  35. }
  36. TEST(PatternRegexTest, NameWithUnicode) {
  37. RunRegexTest(":fooßar", R"(^([^\/#\?]+?)[\/#\?]?$)", {"fooßar"});
  38. }
  39. TEST(PatternRegexTest, NameWithOptionalModifier) {
  40. RunRegexTest(":foo?", R"(^([^\/#\?]+?)?[\/#\?]?$)", {"foo"});
  41. }
  42. TEST(PatternRegexTest, NameWithZeroOrMoreModifier) {
  43. RunRegexTest(":foo*", R"(^((?:[^\/#\?]+?)*)[\/#\?]?$)", {"foo"});
  44. }
  45. TEST(PatternRegexTest, NameWithOneOrMoreModifier) {
  46. RunRegexTest(":foo+", R"(^((?:[^\/#\?]+?)+)[\/#\?]?$)", {"foo"});
  47. }
  48. TEST(PatternRegexTest, NameWithPrefix) {
  49. RunRegexTest("/foo/:bar", R"(^\/foo(?:\/([^\/#\?]+?))[\/#\?]?$)", {"bar"});
  50. }
  51. TEST(PatternRegexTest, NameWithPrefixAndOptionalModifier) {
  52. RunRegexTest("/foo/:bar?", R"(^\/foo(?:\/([^\/#\?]+?))?[\/#\?]?$)", {"bar"});
  53. }
  54. TEST(PatternRegexTest, NameWithPrefixAndOneOrMoreModifier) {
  55. RunRegexTest("/foo/:bar+",
  56. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))[\/#\?]?$)",
  57. {"bar"});
  58. }
  59. TEST(PatternRegexTest, NameWithPrefixAndZeroOrMoreModifier) {
  60. RunRegexTest("/foo/:bar*",
  61. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))?[\/#\?]?$)",
  62. {"bar"});
  63. }
  64. TEST(PatternRegexTest, Regex) {
  65. RunRegexTest("([a-z]+)", R"(^([a-z]+)[\/#\?]?$)", {"0"});
  66. }
  67. TEST(PatternRegexTest, RegexFullWildcard) {
  68. RunRegexTest("(.*)", R"(^(.*)[\/#\?]?$)", {"0"});
  69. }
  70. TEST(PatternRegexTest, Wildcard) {
  71. RunRegexTest("*", R"(^(.*)[\/#\?]?$)", {"0"});
  72. }
  73. TEST(PatternRegexTest, RegexWithOptionalModifier) {
  74. RunRegexTest("([a-z]+)?", R"(^([a-z]+)?[\/#\?]?$)", {"0"});
  75. }
  76. TEST(PatternRegexTest, WildcardWithOptionalModifier) {
  77. RunRegexTest("*?", R"(^(.*)?[\/#\?]?$)", {"0"});
  78. }
  79. TEST(PatternRegexTest, RegexWithPrefix) {
  80. RunRegexTest("/foo/([a-z]+)", R"(^\/foo(?:\/([a-z]+))[\/#\?]?$)", {"0"});
  81. }
  82. TEST(PatternRegexTest, WildcardWithPrefix) {
  83. RunRegexTest("/foo/*", R"(^\/foo(?:\/(.*))[\/#\?]?$)", {"0"});
  84. }
  85. TEST(PatternRegexTest, RegexWithPrefixAndOptionalModifier) {
  86. RunRegexTest("/foo/([a-z]+)?", R"(^\/foo(?:\/([a-z]+))?[\/#\?]?$)", {"0"});
  87. }
  88. TEST(PatternRegexTest, WildcardWithPrefixAndOptionalModifier) {
  89. RunRegexTest("/foo/*?", R"(^\/foo(?:\/(.*))?[\/#\?]?$)", {"0"});
  90. }
  91. TEST(PatternRegexTest, RegexWithPrefixAndOneOrMoreModifier) {
  92. RunRegexTest("/foo/([a-z]+)+",
  93. R"(^\/foo(?:\/((?:[a-z]+)(?:\/(?:[a-z]+))*))[\/#\?]?$)", {"0"});
  94. }
  95. TEST(PatternRegexTest, WildcardWithPrefixAndOneOrMoreModifier) {
  96. RunRegexTest("/foo/*+", R"(^\/foo(?:\/((?:.*)(?:\/(?:.*))*))[\/#\?]?$)",
  97. {"0"});
  98. }
  99. TEST(PatternRegexTest, RegexWithPrefixAndZeroOrMoreModifier) {
  100. RunRegexTest("/foo/([a-z]+)*",
  101. R"(^\/foo(?:\/((?:[a-z]+)(?:\/(?:[a-z]+))*))?[\/#\?]?$)", {"0"});
  102. }
  103. TEST(PatternRegexTest, WildcardWithPrefixAndZeroOrMoreModifier) {
  104. RunRegexTest("/foo/**", R"(^\/foo(?:\/((?:.*)(?:\/(?:.*))*))?[\/#\?]?$)",
  105. {"0"});
  106. }
  107. TEST(PatternRegexTest, NameWithCustomRegex) {
  108. RunRegexTest(":foo([a-z]+)", R"(^([a-z]+)[\/#\?]?$)", {"foo"});
  109. }
  110. TEST(PatternRegexTest, ManyGroups) {
  111. RunRegexTest("/([a-z])+/:foo/([a-z])+/:bar+",
  112. R"(^(?:\/((?:[a-z])(?:\/(?:[a-z]))*))(?:\/([^\/#\?]+?))(?:\/)"
  113. R"(((?:[a-z])(?:\/(?:[a-z]))*))(?:\/((?:[^\/#\?]+?)(?:\/)"
  114. R"((?:[^\/#\?]+?))*))[\/#\?]?$)",
  115. {"0", "foo", "1", "bar"});
  116. }
  117. TEST(PatternRegexTest, StrictNameWithPrefixAndOneOrMoreModifier) {
  118. RunRegexTest("/foo/:bar+",
  119. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))$)", {"bar"},
  120. {.strict = true});
  121. }
  122. TEST(PatternRegexTest, NoEndNameWithPrefixAndOneOrMoreModifier) {
  123. RunRegexTest("/foo/:bar+",
  124. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))(?:[\/)"
  125. R"(#\?](?=[]|$))?(?=[\/#\?]|[]|$))",
  126. {"bar"}, {.end = false});
  127. }
  128. TEST(PatternRegexTest, NoEndFixedWithTrailingDelimiter) {
  129. RunRegexTest("/foo/bar/", R"(^\/foo\/bar\/(?:[\/#\?](?=[]|$))?)", {},
  130. {.end = false});
  131. }
  132. TEST(PatternRegexTest, StrictNoEndFixedWithTrailingDelimiter) {
  133. RunRegexTest("/foo/bar/", R"(^\/foo\/bar\/)", {},
  134. {.strict = true, .end = false});
  135. }
  136. TEST(PatternRegexTest, StrictNoEndFixedWithoutTrailingDelimiter) {
  137. RunRegexTest("/foo/bar", R"(^\/foo\/bar(?=[\/#\?]|[]|$))", {},
  138. {.strict = true, .end = false});
  139. }
  140. TEST(PatternRegexTest, NoStartNameWithPrefixAndOneOrMoreModifier) {
  141. RunRegexTest("/foo/:bar+",
  142. R"(\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))[\/#\?]?$)",
  143. {"bar"}, {.start = false});
  144. }
  145. TEST(PatternRegexTest, EndsWithNameWithPrefixAndOneOrMoreModifier) {
  146. RunRegexTest("/foo/:bar+",
  147. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))[\/)"
  148. R"(#\?]?(?=[#]|$))",
  149. {"bar"}, {.ends_with = "#"});
  150. }
  151. TEST(PatternRegexTest, EndsWithNoEndNameWithPrefixAndOneOrMoreModifier) {
  152. RunRegexTest("/foo/:bar+",
  153. R"(^\/foo(?:\/((?:[^\/#\?]+?)(?:\/(?:[^\/#\?]+?))*))(?:[\/)"
  154. R"(#\?](?=[#]|$))?(?=[\/#\?]|[#]|$))",
  155. {"bar"}, {.end = false, .ends_with = "#"});
  156. }
  157. void RunPatternStringTest(absl::string_view input,
  158. absl::string_view expected_pattern_string) {
  159. auto result = Parse(input, PassThrough);
  160. ASSERT_TRUE(result.ok());
  161. auto& pattern = result.value();
  162. std::string pattern_string = pattern.GeneratePatternString();
  163. EXPECT_EQ(pattern_string, expected_pattern_string);
  164. // The computed pattern string should be valid and parse correctly.
  165. auto result2 = Parse(pattern_string, PassThrough);
  166. EXPECT_TRUE(result.ok());
  167. // The second Pattern object may or may not be identical to the first
  168. // due to normalization. For example, stripping the unnecessary grouping
  169. // from a `{foo}` term.
  170. // Computing a second pattern string should result in an identical
  171. // value, however.
  172. std::string pattern_string2 = result2.value().GeneratePatternString();
  173. EXPECT_EQ(pattern_string2, pattern_string);
  174. }
  175. TEST(PatternStringTest, Fixed) {
  176. RunPatternStringTest("/foo/bar", "/foo/bar");
  177. }
  178. TEST(PatternStringTest, Group) {
  179. RunPatternStringTest("/foo/{bar}", "/foo/bar");
  180. }
  181. TEST(PatternStringTest, GroupWithRegexp) {
  182. RunPatternStringTest("/foo/{(bar)}", "/foo/{(bar)}");
  183. }
  184. TEST(PatternStringTest, GroupWithPrefixAndRegexp) {
  185. RunPatternStringTest("/foo/{b(ar)}", "/foo/{b(ar)}");
  186. }
  187. TEST(PatternStringTest, GroupWithDefaultPrefixAndRegexp) {
  188. RunPatternStringTest("/foo{/(bar)}", "/foo/(bar)");
  189. }
  190. TEST(PatternStringTest, GroupWithRegexpAndSuffix) {
  191. RunPatternStringTest("/foo/{(ba)r}", "/foo/{(ba)r}");
  192. }
  193. TEST(PatternStringTest, GroupWithDefaultPrefixRegexpAndSuffix) {
  194. RunPatternStringTest("/foo{/(ba)r}", "/foo{/(ba)r}");
  195. }
  196. TEST(PatternStringTest, GroupWithQuestionModifier) {
  197. RunPatternStringTest("/foo/{bar}?", "/foo/{bar}?");
  198. }
  199. TEST(PatternStringTest, GroupWithStarModifier) {
  200. RunPatternStringTest("/foo/{bar}*", "/foo/{bar}*");
  201. }
  202. TEST(PatternStringTest, GroupWithPlusModifier) {
  203. RunPatternStringTest("/foo/{bar}+", "/foo/{bar}+");
  204. }
  205. TEST(PatternStringTest, NamedGroup) {
  206. RunPatternStringTest("/foo/:bar", "/foo/:bar");
  207. }
  208. TEST(PatternStringTest, SegmentWildcardWithoutName) {
  209. RunPatternStringTest("/foo/([^\\/#\\?]+?)", "/foo/([^\\/#\\?]+?)");
  210. }
  211. TEST(PatternStringTest, NamedGroupWithRegexp) {
  212. RunPatternStringTest("/foo/:bar(baz)", "/foo/:bar(baz)");
  213. }
  214. TEST(PatternStringTest, NamedGroupWithEquivalentRegexp) {
  215. RunPatternStringTest("/foo/:bar([^\\/#\\?]+?)", "/foo/:bar");
  216. }
  217. TEST(PatternStringTest, NamedGroupWithWildcardEquivalentRegexp) {
  218. RunPatternStringTest("/foo/:bar(.*)", "/foo/:bar(.*)");
  219. }
  220. TEST(PatternStringTest, NamedGroupWithQuestionModifier) {
  221. RunPatternStringTest("/foo/:bar?", "/foo/:bar?");
  222. }
  223. TEST(PatternStringTest, NamedGroupWithStarModifier) {
  224. RunPatternStringTest("/foo/:bar*", "/foo/:bar*");
  225. }
  226. TEST(PatternStringTest, NamedGroupWithPlusModifier) {
  227. RunPatternStringTest("/foo/:bar+", "/foo/:bar+");
  228. }
  229. TEST(PatternStringTest, Regexp) {
  230. RunPatternStringTest("/foo/(bar)", "/foo/(bar)");
  231. }
  232. TEST(PatternStringTest, RegexpWithQuestionModifier) {
  233. RunPatternStringTest("/foo/(bar)?", "/foo/(bar)?");
  234. }
  235. TEST(PatternStringTest, RegexpWithStarModifier) {
  236. RunPatternStringTest("/foo/(bar)*", "/foo/(bar)*");
  237. }
  238. TEST(PatternStringTest, RegexpWithPlusModifier) {
  239. RunPatternStringTest("/foo/(bar)+", "/foo/(bar)+");
  240. }
  241. TEST(PatternStringTest, Wildcard) {
  242. RunPatternStringTest("/foo/*", "/foo/*");
  243. }
  244. TEST(PatternStringTest, RegexpWildcardEquivalent) {
  245. RunPatternStringTest("/foo/(.*)", "/foo/*");
  246. }
  247. TEST(PatternStringTest, RegexpEscapedNonPatternChar) {
  248. RunPatternStringTest("/foo/\\bar", "/foo/bar");
  249. }
  250. TEST(PatternStringTest, RegexpEscapedPatternChar) {
  251. RunPatternStringTest("/foo/\\:bar", "/foo/\\:bar");
  252. }
  253. TEST(PatternStringTest, RegexpEscapedPatternCharInPrefix) {
  254. RunPatternStringTest("/foo/{\\:bar(foo)}", "/foo/{\\:bar(foo)}");
  255. }
  256. TEST(PatternStringTest, RegexpEscapedPatternCharInSuffix) {
  257. RunPatternStringTest("/foo/{(foo)\\:bar}", "/foo/{(foo)\\:bar}");
  258. }
  259. TEST(PatternStringTest, RegexpFollowedByWildcard) {
  260. RunPatternStringTest("(foo)(.*)", "(foo)(.*)");
  261. }
  262. TEST(PatternStringTest, RegexpWithOptionalModifierFollowedByWildcard) {
  263. RunPatternStringTest("(foo)?(.*)", "(foo)?*");
  264. }
  265. TEST(PatternStringTest, RegexpWithSuffixModifierFollowedByWildcard) {
  266. RunPatternStringTest("{(foo)a}(.*)", "{(foo)a}(.*)");
  267. }
  268. TEST(PatternStringTest, NamedGroupInGroupingFollowedByWildcard) {
  269. RunPatternStringTest("{:foo}(.*)", "{:foo}(.*)");
  270. }
  271. TEST(PatternStringTest, NamedGroupInGroupingFollowedByRegexp) {
  272. RunPatternStringTest("{:foo}(bar)", "{:foo}(bar)");
  273. }
  274. TEST(PatternStringTest, NamedGroupInGroupingFollowedByWildcardInGrouping) {
  275. RunPatternStringTest("{:foo}{(.*)}", "{:foo}(.*)");
  276. }
  277. TEST(PatternStringTest, NamedGroupInGroupingFollowedByWildcardWithSuffix) {
  278. RunPatternStringTest("{:foo}{(.*)bar}", ":foo{*bar}");
  279. }
  280. TEST(PatternStringTest, NamedGroupInGroupingFollowedByWildcardWithPrefix) {
  281. RunPatternStringTest("{:foo}{bar(.*)}", ":foo{bar*}");
  282. }
  283. TEST(PatternStringTest, NamedGroupInGroupingFollowedByWildcardWithCustomName) {
  284. RunPatternStringTest("{:foo}:bar(.*)", ":foo:bar(.*)");
  285. }
  286. TEST(PatternStringTest,
  287. NamedGroupInGroupingWithOptionalModifierFollowedByWildcard) {
  288. RunPatternStringTest("{:foo}?(.*)", ":foo?*");
  289. }
  290. TEST(PatternStringTest, NamedGroupWithEscapedValidNameSuffix) {
  291. RunPatternStringTest("{:foo\\bar}", "{:foo\\bar}");
  292. }
  293. TEST(PatternStringTest, NamedGroupWithEscapedInvalidNameSuffix) {
  294. RunPatternStringTest("{:foo\\.bar}", "{:foo.bar}");
  295. }
  296. TEST(PatternStringTest, NamedGroupInGroupingFollowedByValidNameText) {
  297. RunPatternStringTest("{:foo}bar", "{:foo}bar");
  298. }
  299. TEST(PatternStringTest, NamedGroupFollowedByEscapedValidNameText) {
  300. RunPatternStringTest(":foo\\bar", "{:foo}bar");
  301. }
  302. TEST(PatternStringTest, NamedGroupWithRegexpFollowedByValidNameText) {
  303. RunPatternStringTest(":foo(baz)bar", ":foo(baz)bar");
  304. }
  305. TEST(PatternStringTest, NamedGroupFollowedByEmptyGroupAndWildcard) {
  306. RunPatternStringTest(":foo{}(.*)", "{:foo}(.*)");
  307. }
  308. TEST(PatternStringTest, NamedGroupFollowedByEmptyGroupAndValidNameText) {
  309. RunPatternStringTest(":foo{}bar", "{:foo}bar");
  310. }
  311. TEST(PatternStringTest,
  312. NamedGroupFollowedByEmptyGroupWithOptionalModifierAndValidNameText) {
  313. RunPatternStringTest(":foo{}?bar", "{:foo}bar");
  314. }
  315. TEST(PatternStringTest, NamedGroupWithRegexpFollowedByWildcard) {
  316. RunPatternStringTest(":foo(bar)(.*)", ":foo(bar)(.*)");
  317. }
  318. TEST(PatternStringTest, NamedGroupWithRegexpAndValidNameSuffix) {
  319. RunPatternStringTest("{:foo(baz)bar}", "{:foo(baz)bar}");
  320. }
  321. TEST(PatternStringTest, WildcardSlashAndWildcard) {
  322. RunPatternStringTest("*/*", "*/*");
  323. }
  324. TEST(PatternStringTest, WildcardEscapedSlashAndWildcard) {
  325. // The backslash in the original input forces the `/` to not be an
  326. // implicit prefix for the second `*`. The generated pattern string
  327. // must similarly prevent the implicit prefix from occuring. This
  328. // is done using the `{}` grouping instead, however, as its a bit more
  329. // readable than escape backslashes.
  330. RunPatternStringTest("*\\/*", "*/{*}");
  331. }
  332. TEST(PatternStringTest, WildcardSlashAndWildcardInGrouping) {
  333. RunPatternStringTest("*/{*}", "*/{*}");
  334. }
  335. TEST(PatternStringTest, WildcardSlashSlashAndWildcard) {
  336. RunPatternStringTest("*//*", "*//*");
  337. }
  338. TEST(
  339. PatternStringTest,
  340. WildcardFollowedByEmptyGroupWithZeroOrMoreModifierAndWildcardWithOptionalModifier) {
  341. RunPatternStringTest("*{}**?", "*(.*)?");
  342. }
  343. TEST(PatternStringTest, CaseFromFuzzer) {
  344. RunPatternStringTest(".:bax\\a*{}**", "{.:bax}a*(.*)");
  345. }
  346. struct DirectMatchCase {
  347. absl::string_view input;
  348. bool expected_match = true;
  349. std::vector<std::pair<absl::string_view, absl::optional<absl::string_view>>>
  350. expected_groups;
  351. };
  352. void RunDirectMatchTest(absl::string_view input,
  353. std::vector<DirectMatchCase> case_list) {
  354. auto result =
  355. Parse(input, PassThrough,
  356. {.sensitive = true, .strict = true, .end = true, .start = true});
  357. ASSERT_TRUE(result.ok());
  358. auto& pattern = result.value();
  359. EXPECT_TRUE(pattern.CanDirectMatch());
  360. for (const auto& c : case_list) {
  361. std::vector<std::pair<absl::string_view, absl::optional<absl::string_view>>>
  362. matched_groups;
  363. EXPECT_EQ(c.expected_match, pattern.DirectMatch(c.input, &matched_groups));
  364. ASSERT_EQ(c.expected_groups.size(), matched_groups.size());
  365. for (size_t i = 0; i < matched_groups.size(); ++i) {
  366. EXPECT_EQ(c.expected_groups[i], matched_groups[i]);
  367. }
  368. }
  369. }
  370. void RunDirectMatchUnsupportedTest(absl::string_view input,
  371. Options options = {.sensitive = true,
  372. .strict = true,
  373. .end = true,
  374. .start = true}) {
  375. auto result = Parse(input, PassThrough, options);
  376. ASSERT_TRUE(result.ok());
  377. auto& pattern = result.value();
  378. EXPECT_FALSE(pattern.CanDirectMatch());
  379. }
  380. TEST(PatternDirectMatch, FullWildcardSupported) {
  381. RunDirectMatchTest("*",
  382. {
  383. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  384. {.input = "", .expected_groups = {{"0", ""}}},
  385. });
  386. }
  387. TEST(PatternDirectMatch, FullWildcardInGroupSupported) {
  388. RunDirectMatchTest("{*}",
  389. {
  390. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  391. {.input = "", .expected_groups = {{"0", ""}}},
  392. });
  393. }
  394. TEST(PatternDirectMatch, FullWildcardUsingRegexSupported) {
  395. RunDirectMatchTest("(.*)",
  396. {
  397. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  398. {.input = "", .expected_groups = {{"0", ""}}},
  399. });
  400. }
  401. TEST(PatternDirectMatch, FullWildcardAndOptionalModifierSupported) {
  402. RunDirectMatchTest("*?",
  403. {
  404. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  405. {.input = "", .expected_groups = {{"0", ""}}},
  406. });
  407. }
  408. TEST(PatternDirectMatch, FullWildcardAndOneOrMoreModifierSupported) {
  409. RunDirectMatchTest("*+",
  410. {
  411. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  412. {.input = "", .expected_groups = {{"0", ""}}},
  413. });
  414. }
  415. TEST(PatternDirectMatch, FullWildcardAndZeroOrMoreModifierSupported) {
  416. RunDirectMatchTest("**",
  417. {
  418. {.input = "/foo", .expected_groups = {{"0", "/foo"}}},
  419. {.input = "", .expected_groups = {{"0", ""}}},
  420. });
  421. }
  422. TEST(PatternDirectMatch, FullWildcardWithNameUsingRegexSupported) {
  423. RunDirectMatchTest(
  424. ":name(.*)", {
  425. {.input = "/foo", .expected_groups = {{"name", "/foo"}}},
  426. {.input = "", .expected_groups = {{"name", ""}}},
  427. });
  428. }
  429. TEST(PatternDirectMatch, OptionsFalseStartUnsupported) {
  430. RunDirectMatchUnsupportedTest(
  431. "*", {.sensitive = true, .strict = true, .end = true, .start = false});
  432. }
  433. TEST(PatternDirectMatch, OptionsFalseEndUnsupported) {
  434. RunDirectMatchUnsupportedTest(
  435. "*", {.sensitive = true, .strict = true, .end = false, .start = true});
  436. }
  437. TEST(PatternDirectMatch, OptionsFalseStrictUnsupported) {
  438. RunDirectMatchUnsupportedTest(
  439. "*", {.sensitive = true, .strict = false, .end = true, .start = true});
  440. }
  441. TEST(PatternDirectMatch, OptionsFalseSensitiveUnsupported) {
  442. RunDirectMatchUnsupportedTest(
  443. "*", {.sensitive = false, .strict = true, .end = true, .start = true});
  444. }
  445. TEST(PatternDirectMatch, FullWildcardWithPrefixUnsupported) {
  446. RunDirectMatchUnsupportedTest("/*");
  447. }
  448. TEST(PatternDirectMatch, FullWildcardInGroupWithPrefixUnsupported) {
  449. RunDirectMatchUnsupportedTest("{foo*}");
  450. }
  451. TEST(PatternDirectMatch, FullWildcardInGroupWithSuffixUnsupported) {
  452. RunDirectMatchUnsupportedTest("{*foo}");
  453. }
  454. TEST(PatternDirectMatch, EmptyPatternSupported) {
  455. RunDirectMatchTest("", {
  456. {.input = "", .expected_groups = {}},
  457. {.input = "/", .expected_match = false},
  458. });
  459. }
  460. TEST(PatternDirectMatch, FixedTextSupported) {
  461. RunDirectMatchTest("foo", {
  462. {.input = "foo", .expected_groups = {}},
  463. {.input = "fo", .expected_match = false},
  464. {.input = "foobar", .expected_match = false},
  465. });
  466. }
  467. TEST(PatternDirectMatch, FixedTextInGroupSupported) {
  468. RunDirectMatchTest("{foo}", {
  469. {.input = "foo", .expected_groups = {}},
  470. {.input = "fo", .expected_match = false},
  471. {.input = "foobar", .expected_match = false},
  472. });
  473. }
  474. TEST(PatternDirectMatch, FixedTextInGroupWithOptionalModifierUnsupported) {
  475. RunDirectMatchUnsupportedTest("{foo}?");
  476. }
  477. TEST(PatternDirectMatch, FixedTextInGroupWithZeroOrMoreModifierUnsupported) {
  478. RunDirectMatchUnsupportedTest("{foo}*");
  479. }
  480. TEST(PatternDirectMatch, FixedTextInGroupWithOneOrMoreModifierUnsupported) {
  481. RunDirectMatchUnsupportedTest("{foo}+");
  482. }
  483. TEST(PatternDirectMatch, FixedTextAndFullWildcardUnsupported) {
  484. RunDirectMatchUnsupportedTest("/foo*");
  485. }
  486. TEST(PatternDirectMatch, NamedGroupUnsupported) {
  487. RunDirectMatchUnsupportedTest(":name");
  488. }
  489. TEST(PatternDirectMatch, RegexUnsupported) {
  490. RunDirectMatchUnsupportedTest("(foo)");
  491. }
  492. } // namespace liburlpattern