try to fix git tangle
[ghsmtp.git] / Domain-test.cpp
blob5c9af3597a1a6835b6cb94c3eed9f403520f67e9
1 #include "Domain.hpp"
3 #include <iostream>
5 #include <glog/logging.h>
7 #include <fmt/format.h>
8 #include <fmt/ostream.h>
10 template <>
11 struct fmt::formatter<Domain> : ostream_formatter {};
13 using namespace std::string_literals;
15 int main(int argc, char const* argv[])
17 std::string msg;
19 auto const raw_ips = "123.123.123.123";
20 auto const add_lit = "[123.123.123.123]";
21 CHECK_EQ(Domain{raw_ips}, Domain{add_lit});
23 Domain d0{"EXAMPLE.COM"};
24 Domain d1{"example.com."};
25 CHECK_EQ(d0, d1);
27 Domain const d3{""};
28 Domain const d4{"."};
29 CHECK_EQ(d3, d4);
31 Domain const dom2{"黒川.日本"};
32 Domain const dom3{"xn--5rtw95l.xn--wgv71a"};
33 CHECK_EQ(dom2, dom3);
35 Domain const poop1{"💩.la"};
36 Domain const poop2{"xn--ls8h.la"};
37 CHECK_EQ(poop1, poop2);
39 Domain const norm0{"hi⒌com"}; // non-ascii "dot" before "com"
40 Domain const norm1{"hi5.com"};
41 CHECK_EQ(norm0, norm1);
43 Domain dom;
44 CHECK(Domain::validate("hi⒌com", msg, dom));
45 CHECK(Domain::validate("hi5.com", msg, dom));
47 CHECK(!Domain::validate("$?%^&*(", msg, dom));
48 CHECK_EQ(msg, "failed to parse domain «$?%^&*(»"s);
50 CHECK(!Domain::validate("email@123.123.123.123", msg, dom));
51 CHECK_EQ(msg, "failed to parse domain «email@123.123.123.123»"s);
53 CHECK(!Domain::validate("email@[123.123.123.123]", msg, dom));
54 CHECK_EQ(msg, "failed to parse domain «email@[123.123.123.123]»"s);
56 auto constexpr long_dom =
57 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
58 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
59 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
60 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
61 CHECK(Domain::validate(long_dom, msg, dom)) << msg;
63 CHECK(!Domain::validate(
64 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
65 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
66 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
67 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com",
68 msg, dom));
69 CHECK_EQ(msg,
70 "domain name "
71 "«xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
72 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
73 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
74 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com» "
75 "too long");
77 CHECK(!Domain::validate(
78 "a.b.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
79 "com",
80 msg, dom));
81 CHECK_EQ(
82 msg,
83 "domain label «xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx» too long"s);
85 CHECK(!Domain::validate(
86 "💩.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com",
87 msg, dom));
88 CHECK_EQ(
89 msg,
90 "domain label «💩.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com» too long"s);
92 CHECK(!Domain::validate(
93 "💩."
94 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
95 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
96 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
97 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
98 msg, dom));
99 CHECK_EQ(
100 msg,
101 "domain name «"
102 "💩."
103 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
104 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
105 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
106 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx» too long"s);
108 try {
109 Domain const junk{"$?%^&*("};
110 // idn2 allows this
111 LOG(FATAL) << "should have thrown";
113 catch (std::exception const& ex) {
114 CHECK_EQ(0, strcmp(ex.what(), "failed to parse domain"));
117 try {
118 Domain const ip_addr{"[127.0.0.1]"};
119 CHECK(ip_addr.is_address_literal());
121 catch (std::exception const& ex) {
122 LOG(FATAL) << "should not throw " << ex.what();
125 try {
126 Domain const ip_addr{"127.0.0.1"};
127 CHECK(ip_addr.is_address_literal());
129 catch (std::exception const& ex) {
130 LOG(FATAL) << "should not throw " << ex.what();
133 CHECK_EQ(Domain{"127.0.0.1"}, Domain{"[127.0.0.1]"});
135 Domain const mixed_case{"ExAmPle.COM"};
136 CHECK_EQ(mixed_case.ascii(), "example.com");
138 CHECK(domain::is_fully_qualified(Domain{"foo.bar"}, msg));
140 CHECK(!domain::is_fully_qualified(Domain{"foo.b"}, msg));
141 CHECK_EQ(msg, "TLD «b» must be two or more octets");
143 CHECK(!domain::is_fully_qualified(Domain{"foo"}, msg));
144 CHECK_EQ(msg, "domain «foo» must have two or more labels");
146 for (auto arg{1}; arg < argc; ++arg) {
147 Domain const a{argv[arg]};
148 std::cout << a << '\n';