27 const std::string& test_input,
28 const std::string& test_base) {
30 std::string_view test_view(test_input.data(), test_input.size());
31 auto test_result = pattern.test(test_view,
nullptr);
35 if (!test_base.empty()) {
36 std::string_view base_view(test_base.data(), test_base.size());
37 auto test_result_with_base = pattern.test(test_view, &base_view);
38 (void)test_result_with_base;
42 auto exec_result = pattern.exec(test_view,
nullptr);
43 if (exec_result && exec_result->has_value()) {
44 const ada::url_pattern_result& match = **exec_result;
45 volatile size_t len = 0;
47 auto exercise_component =
48 [&len](
const ada::url_pattern_component_result& c) {
49 len += c.input.size();
50 for (
const auto& [k, v] : c.groups) {
57 exercise_component(match.protocol);
58 exercise_component(match.username);
59 exercise_component(match.password);
60 exercise_component(match.hostname);
61 exercise_component(match.port);
62 exercise_component(match.pathname);
63 exercise_component(match.search);
64 exercise_component(match.hash);
69 if (!test_base.empty()) {
70 std::string_view base_view(test_base.data(), test_base.size());
71 auto exec_with_base = pattern.exec(test_view, &base_view);
72 if (exec_with_base && exec_with_base->has_value()) {
73 const ada::url_pattern_result& match = **exec_with_base;
74 volatile size_t len = 0;
75 auto exercise_component =
76 [&len](
const ada::url_pattern_component_result& c) {
77 len += c.input.size();
78 for (
const auto& [k, v] : c.groups) {
80 if (v.has_value()) len += v->size();
83 exercise_component(match.protocol);
84 exercise_component(match.username);
85 exercise_component(match.password);
86 exercise_component(match.hostname);
87 exercise_component(match.port);
88 exercise_component(match.pathname);
89 exercise_component(match.search);
90 exercise_component(match.hash);
96 ada::url_pattern_init init_input{};
97 init_input.pathname = test_input;
98 auto test_with_init = pattern.test(init_input,
nullptr);
105 std::string_view sv(test_input.data(), test_input.size());
108 volatile bool tc = pattern.test_components(
109 std::string(parsed->get_protocol()),
110 std::string(parsed->get_username()),
111 std::string(parsed->get_password()),
112 std::string(parsed->get_hostname()), std::string(parsed->get_port()),
113 std::string(parsed->get_pathname()),
114 std::string(parsed->get_search()), std::string(parsed->get_hash()));
120 auto match_result = pattern.match(test_view,
nullptr);
125 auto to_ascii = [](
const std::string& source) -> std::string {
127 result.reserve(source.size());
128 for (
char c : source) {
129 result.push_back(
static_cast<unsigned char>(c) % 128);
133 FuzzedDataProvider fdp(data, size);
135 std::string source_1 =
"/" + to_ascii(fdp.ConsumeRandomLengthString(50)) +
136 "/" + to_ascii(fdp.ConsumeRandomLengthString(50));
137 std::string base_source_1 =
"/" +
138 to_ascii(fdp.ConsumeRandomLengthString(50)) +
139 "/" + to_ascii(fdp.ConsumeRandomLengthString(50));
141 std::string source_2 =
"https://ada-url.com/*";
142 std::string base_source_2 =
"https://ada-url.com";
145 std::string test_input =
"https://" +
146 to_ascii(fdp.ConsumeRandomLengthString(30)) +
"/" +
147 to_ascii(fdp.ConsumeRandomLengthString(20));
148 std::string test_base =
"https://ada-url.com";
150 std::array<std::pair<std::string, std::string>, 2> sources = {{
151 {source_1, base_source_1},
152 {source_2, base_source_2},
155 for (
const auto& [source, base_source] : sources) {
158 ada::parse_url_pattern<regex_provider>(source,
nullptr,
nullptr);
165 std::string_view base_source_view(base_source.data(), base_source.length());
166 auto result_with_base = ada::parse_url_pattern<regex_provider>(
167 source, &base_source_view,
nullptr);
168 if (result_with_base) {
174 ada::url_pattern_options options{.ignore_case = fdp.ConsumeBool()};
175 auto result_with_base_and_options = ada::parse_url_pattern<regex_provider>(
176 source, &base_source_view, &options);
177 if (result_with_base_and_options) {
184 int field_index = fdp.ConsumeIntegralInRange(0, 7);
185 std::string random_value = to_ascii(fdp.ConsumeRandomLengthString(50));
186 ada::url_pattern_init init{};
187 switch (field_index) {
189 init.protocol = random_value;
192 init.username = random_value;
195 init.password = random_value;
198 init.hostname = random_value;
201 init.port = random_value;
204 init.pathname = random_value;
207 init.search = random_value;
210 init.hash = random_value;
213 auto result_with_init = ada::parse_url_pattern<regex_provider>(
214 init, &base_source_view,
nullptr);
215 if (result_with_init) {
221 ada::url_pattern_init init_all{};
222 init_all.protocol = to_ascii(fdp.ConsumeRandomLengthString(10));
223 init_all.username = to_ascii(fdp.ConsumeRandomLengthString(10));
224 init_all.password = to_ascii(fdp.ConsumeRandomLengthString(10));
225 init_all.hostname = to_ascii(fdp.ConsumeRandomLengthString(20));
226 init_all.port = to_ascii(fdp.ConsumeRandomLengthString(5));
227 init_all.pathname =
"/" + to_ascii(fdp.ConsumeRandomLengthString(20));
228 init_all.search = to_ascii(fdp.ConsumeRandomLengthString(10));
229 init_all.hash = to_ascii(fdp.ConsumeRandomLengthString(10));
230 auto result_with_init_all =
231 ada::parse_url_pattern<regex_provider>(init_all,
nullptr,
nullptr);
232 if (result_with_init_all) {