-
-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathurl_components.cpp
145 lines (129 loc) · 4.93 KB
/
url_components.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <cstring>
#include <filesystem>
#include <iostream>
#include <memory>
#include <set>
#include "simdjson.h"
#include "gtest/gtest.h"
#include "ada.h"
#include "ada/url_components.h"
using namespace simdjson;
#ifndef WPT_DATA_DIR
#define WPT_DATA_DIR "wpt/"
#endif
const char* URLTESTDATA_JSON = WPT_DATA_DIR "urltestdata.json";
// This function copies your input onto a memory buffer that
// has just the necessary size. This will entice tools to detect
// an out-of-bound access.
ada::result<ada::url> ada_parse(std::string_view view,
const ada::url* base = nullptr) {
std::cout << "about to parse '" << view << "' [" << view.size() << " bytes]"
<< std::endl;
std::unique_ptr<char[]> buffer(new char[view.size()]);
memcpy(buffer.get(), view.data(), view.size());
return ada::parse(std::string_view(buffer.get(), view.size()), base);
}
bool file_exists(const char* filename) {
namespace fs = std::filesystem;
std::filesystem::path f{filename};
if (std::filesystem::exists(filename)) {
std::cout << " file found: " << filename << std::endl;
return true;
} else {
std::cout << " file missing: " << filename << std::endl;
return false;
}
}
TEST(url_components, urltestdata_encoding) {
ondemand::parser parser;
size_t counter{};
ASSERT_TRUE(file_exists(URLTESTDATA_JSON));
padded_string json = padded_string::load(URLTESTDATA_JSON);
ondemand::document doc = parser.iterate(json);
for (auto element : doc.get_array()) {
if (element.type() == ondemand::json_type::string) {
std::string_view comment = element.get_string().value();
std::cout << comment << std::endl;
} else if (element.type() == ondemand::json_type::object) {
ondemand::object object = element.get_object();
std::string element_string =
std::string(std::string_view(object.raw_json()));
object.reset();
auto input_element = object["input"];
std::string_view input{};
bool allow_replacement_characters = true;
ASSERT_FALSE(
input_element.get_string(allow_replacement_characters).get(input));
std::cout << "input='" << input << "' [" << input.size() << " bytes]"
<< std::endl;
std::string_view base;
ada::result<ada::url> base_url;
if (!object["base"].get(base)) {
std::cout << "base=" << base << std::endl;
base_url = ada_parse(base);
if (!base_url) {
bool failure = false;
if (!object["failure"].get(failure) && failure == true) {
// We are good. Failure was expected.
continue; // We can't proceed any further.
} else {
ASSERT_TRUE(base_url.has_value());
}
}
}
bool failure = false;
ada::result<ada::url> input_url = (!object["base"].get(base))
? ada_parse(input, &*base_url)
: ada_parse(input);
if (object["failure"].get(failure)) {
auto url = input_url.value();
auto out = url.get_components();
auto href = url.get_href();
ASSERT_EQ(href.substr(0, out.protocol_end), url.get_protocol());
if (!url.username.empty()) {
size_t username_start = href.find(url.username);
ASSERT_EQ(href.substr(username_start, url.username.size()),
url.get_username());
}
if (!url.password.empty()) {
size_t password_start = out.username_end + 1;
ASSERT_EQ(href.substr(password_start, url.password.size()),
url.get_password());
}
size_t host_start = out.host_start;
if (url.has_credentials()) {
ASSERT_EQ(url.get_href()[out.host_start], '@');
host_start++;
}
ASSERT_EQ(href.substr(host_start, url.get_hostname().size()),
url.get_hostname());
if (url.port.has_value()) {
ASSERT_EQ(out.port, url.port.value());
} else {
ASSERT_EQ(out.port, ada::url_components::omitted);
}
if (!url.get_pathname().empty()) {
size_t pathname_end = std::string::npos;
if (out.search_start != ada::url_components::omitted) {
pathname_end = out.search_start;
} else if (out.hash_start != ada::url_components::omitted) {
pathname_end = out.hash_start;
}
ASSERT_EQ(href.substr(out.pathname_start,
pathname_end - out.pathname_start),
url.get_pathname());
}
if (!url.get_search().empty()) {
ASSERT_EQ(href.substr(out.search_start, url.get_search().size()),
url.get_search());
}
if (!url.get_hash().empty()) {
ASSERT_EQ(href.substr(out.hash_start, url.get_hash().size()),
url.get_hash());
}
}
}
}
std::cout << "Tests executed = " << counter << std::endl;
SUCCEED();
}