1 /*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2016 Tatsuhiro Tsujikawa
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "template_test.h"
26
27 #include <cstring>
28 #include <iostream>
29 #include <sstream>
30
31 #include "munitxx.h"
32
33 #include "template.h"
34
35 using namespace std::literals;
36
37 namespace nghttp2 {
38
39 namespace {
40 const MunitTest tests[]{
41 munit_void_test(test_template_immutable_string),
42 munit_void_test(test_template_string_ref),
43 munit_void_test(test_template_as_uint8_span),
44 munit_test_end(),
45 };
46 } // namespace
47
48 const MunitSuite template_suite{
49 "/template", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
50 };
51
test_template_immutable_string(void)52 void test_template_immutable_string(void) {
53 ImmutableString null;
54
55 assert_string_equal("", null.c_str());
56 assert_size(0, ==, null.size());
57 assert_true(null.empty());
58
59 ImmutableString from_cstr("alpha");
60
61 assert_string_equal("alpha", from_cstr.c_str());
62 assert_size(5, ==, from_cstr.size());
63 assert_false(from_cstr.empty());
64 assert_true("alpha" == from_cstr);
65 assert_true(from_cstr == "alpha");
66 assert_true(std::string("alpha") == from_cstr);
67 assert_true(from_cstr == std::string("alpha"));
68
69 // copy constructor
70 ImmutableString src("charlie");
71 ImmutableString copy = src;
72
73 assert_string_equal("charlie", copy.c_str());
74 assert_size(7, ==, copy.size());
75
76 // copy assignment
77 ImmutableString copy2;
78 copy2 = src;
79
80 assert_string_equal("charlie", copy2.c_str());
81 assert_size(7, ==, copy2.size());
82
83 // move constructor
84 ImmutableString move = std::move(copy);
85
86 assert_string_equal("charlie", move.c_str());
87 assert_size(7, ==, move.size());
88 assert_string_equal("", copy.c_str());
89 assert_size(0, ==, copy.size());
90
91 // move assignment
92 move = std::move(from_cstr);
93
94 assert_string_equal("alpha", move.c_str());
95 assert_size(5, ==, move.size());
96 assert_string_equal("", from_cstr.c_str());
97 assert_size(0, ==, from_cstr.size());
98
99 // from string literal
100 auto from_lit = ImmutableString::from_lit("bravo");
101
102 assert_string_equal("bravo", from_lit.c_str());
103 assert_size(5, ==, from_lit.size());
104
105 // equality
106 ImmutableString eq("delta");
107
108 assert_true("delta1" != eq);
109 assert_true("delt" != eq);
110 assert_true(eq != "delta1");
111 assert_true(eq != "delt");
112
113 // operator[]
114 ImmutableString br_op("foxtrot");
115
116 assert_char('f', ==, br_op[0]);
117 assert_char('o', ==, br_op[1]);
118 assert_char('t', ==, br_op[6]);
119 assert_char('\0', ==, br_op[7]);
120
121 // operator==(const ImmutableString &, const ImmutableString &)
122 {
123 ImmutableString a("foo");
124 ImmutableString b("foo");
125 ImmutableString c("fo");
126
127 assert_true(a == b);
128 assert_true(a != c);
129 assert_true(c != b);
130 }
131
132 // operator<<
133 {
134 ImmutableString a("foo");
135 std::stringstream ss;
136 ss << a;
137
138 assert_stdstring_equal("foo", ss.str());
139 }
140
141 // operator +=(std::string &, const ImmutableString &)
142 {
143 std::string a = "alpha";
144 a += ImmutableString("bravo");
145
146 assert_stdstring_equal("alphabravo", a);
147 }
148 }
149
test_template_string_ref(void)150 void test_template_string_ref(void) {
151 StringRef empty;
152
153 assert_stdsv_equal(""sv, empty);
154 assert_size(0, ==, empty.size());
155
156 // from std::string
157 std::string alpha = "alpha";
158
159 StringRef ref(alpha);
160
161 assert_true("alpha" == ref);
162 assert_true(ref == "alpha");
163 assert_true(alpha == ref);
164 assert_true(ref == alpha);
165 assert_size(5, ==, ref.size());
166
167 // from string literal
168 auto from_lit = "alpha"_sr;
169
170 assert_stdsv_equal("alpha"sv, from_lit);
171 assert_size(5, ==, from_lit.size());
172
173 // from ImmutableString
174 auto im = ImmutableString::from_lit("bravo");
175
176 StringRef imref(im);
177
178 assert_stdsv_equal("bravo"sv, imref);
179 assert_size(5, ==, imref.size());
180
181 // from C-string
182 StringRef cstrref("charlie");
183
184 assert_stdsv_equal("charlie"sv, cstrref);
185 assert_size(7, ==, cstrref.size());
186
187 // from C-string and its length
188 StringRef cstrnref("delta", 5);
189
190 assert_stdsv_equal("delta"sv, cstrnref);
191 assert_size(5, ==, cstrnref.size());
192
193 // operator[]
194 StringRef br_op("foxtrot");
195
196 assert_char('f', ==, br_op[0]);
197 assert_char('o', ==, br_op[1]);
198 assert_char('t', ==, br_op[6]);
199 assert_char('\0', ==, br_op[7]);
200
201 // operator<<
202 {
203 StringRef a("foo");
204 std::stringstream ss;
205 ss << a;
206
207 assert_stdstring_equal("foo", ss.str());
208 }
209
210 // operator +=(std::string &, const StringRef &)
211 {
212 std::string a = "alpha";
213 a += StringRef("bravo");
214
215 assert_stdstring_equal("alphabravo", a);
216 }
217 }
218
test_template_as_uint8_span(void)219 void test_template_as_uint8_span(void) {
220 uint32_t a[2];
221
222 memcpy(&a, "\xc0\xc1\xc2\xc3\xf0\xf1\xf2\xf3", sizeof(a));
223
224 // dynamic extent
225 auto s = as_uint8_span(std::span{a, 2});
226
227 assert_size(sizeof(a), ==, s.size());
228 assert_size(std::dynamic_extent, ==, s.extent);
229 assert_memory_equal(s.size(), &a, s.data());
230
231 // non-dynamic extent
232 auto t = as_uint8_span(std::span<uint32_t, 2>{a, 2});
233
234 assert_size(sizeof(a), ==, t.size());
235 assert_size(sizeof(a), ==, t.extent);
236 assert_memory_equal(t.size(), &a, t.data());
237 }
238
239 } // namespace nghttp2
240